Question

I'm using Mime::Lite to create and send E-Mails. Now I need to add support for S/Mime-encryption and finally could encrypt my E-Mail (the only Perllib I could install seems broken, so I'm using a systemcall and openssl smime), but when I try to create a mime-object with it, the E-Mail will be broken as soon as I set the Content-Transfer-Encoding to base64. To make it even more curious, it happens only if I set it via $myMessage->attr. If I'm using the constructor ->new everything is fine, besides a little warning which I suppress by using MIME::Lite->quiet(1);

Is it a bug or my fault? Here are the two ways how I create the mime-object.

  1. Setting the Content-Transfer-Encoding via construtor and suppress the warning:

    MIME::Lite->quiet(1); 
    my $msgEncr = MIME::Lite->new(From   =>'me@myhost.com',
                            To     => 'you@yourhost.com',
                           Subject => 'SMIME Test',
                           Data    => $myEncryptedMessage,
                           'Content-Transfer-Encoding' => 'base64');
    
    $msgEncr->attr('Content-Disposition'        =>  'attachment');
    $msgEncr->attr('Content-Disposition.filename'   =>  'smime.p7m');
    $msgEncr->attr('Content-Type' => 'application/x-pkcs7-mime');
    $msgEncr->attr('Content-Type.smime-type' => 'enveloped-data');
    $msgEncr->attr('Content-Type.name' => 'smime.p7m');
    
    $msgEncr->send;             
    
    MIME::Lite->quiet(0);
    
  2. Setting the Content-Transfer-Encoding via $myMessage->attr which breaks the encrypted Data, but won't cause a warning:

    my $msgEncr = MIME::Lite->new(From  => 'me@myhost.com',
                           To         => 'you@yourhost.com',
                           Subject    => 'SMIME Test',
                           Data => $myEncryptedMessage);
    
    $msgEncr->attr('Content-Disposition'        =>  'attachment');
    $msgEncr->attr('Content-Disposition.filename'       =>  'smime.p7m');
    $msgEncr->attr('Content-Type' => 'application/x-pkcs7-mime');
    $msgEncr->attr('Content-Type.smime-type' => 'enveloped-data');
    $msgEncr->attr('Content-Type.name' => 'smime.p7m');
    $msgEncr->attr('Content-Transfer-Encoding' => 'base64');
    
    $msgEncr->send; 
    

I just don't get why my message is broken when I'm using the attribute-setter. Thanks in advance for your help!

Besides that i'm unable to attach any file to this E-Mail without breaking the encrypted message again.

Was it helpful?

Solution 3

As I said in one comment the difference in setting the encoding in the construtor of the mimeobject or with the ->attr-Setter is, that the construtor just sets the encoding in the mimeheader. By using the ->attr-Setter mime encodes the data with base64.

So in my case, my previously generated mimeobject - which is base64-encoded and with s/mime encrypted - read from a file needs to set the encoding in the construtor (and suppress the warning) so no more encoding will be done by mime. Otherwise mime will encode the data again and therefore break the encryption and the email itself.

I finally got attachments to work. To achieve this I create a normal multipart/mixed mimeobject, print this object into a normal file, encrypt this file with openssl smime, read this whole file (except the 6 headerlines) into a variable and use this as the datainput. Additionally I set the Content-Transfer-Encoding to base64 using the construtor (so no encoding is done to my data).

I hope this will help someone else then me ;)

OTHER TIPS

To debug this Make a script call showmail.pl

#!/usr/bin/perl
while (<STDIN>) { print $_; }

Test it like

use MIME::Lite;
use Net::SMTP;
use MIME::Base64;
$myEncryptedMessage = encode_base64("This is not valid encrypted message\n");
MIME::Lite->send('sendmail', "./showmail.pl"); ## Add this for debugging.
MIME::Lite->quiet(1); my $msgEncr = MIME::Lite->new(From   =>'me@localhost',
                 To     => 'you@localhost',
                 Subject => 'SMIME Test',
                 Data    => $myEncryptedMessage,
                 'Content-Transfer-Encoding' => 'base64');
$msgEncr->attr('Content-Disposition'        =>  'attachment');
$msgEncr->attr('Content-Disposition.filename'   =>  'smime.p7m');
$msgEncr->attr('Content-Type' => 'application/x-pkcs7-mime');
$msgEncr->attr('Content-Type.smime-type' => 'enveloped-data');
$msgEncr->attr('Content-Type.name' => 'smime.p7m');
$msgEncr->send();

you should see something like.

MIME-Version: 1.0
Content-Disposition: attachment; filename="smime.p7m"
Content-Length: 49
Content-Type: application/x-pkcs7-mime; name="smime.p7m"; smime-type="enveloped-data"
X-Mailer: MIME::Lite 3.028 (F2.74; B3.07; Q3.07)
Date: Mon, 23 Mar 2012 10:40:51 -0400
From: me@localhost
To: you@localhost
Subject: SMIME Test
Content-Transfer-Encoding: base64

VGhpcyBpcyBub3QgdmFsaWQgZW5jcnlwdGVkIG1lc3NhZ2UK

The message is encoded base64, but the real message still needs to be correctly encypted. You need to make sure that is the case since $myEncryptedMessage is passed in. With the debug output, you can compare with a known good encrypted mail and see if the headers are good, as far as I can see the headers are fine, it is probably the data that is not valid.

I am not able to test this with a real mail client, but this is what I think may work for multi-parts.

use MIME::Lite;
use Net::SMTP;
use MIME::Base64;
MIME::Lite->send('sendmail', "./showmail.pl"); ## <---- for testing only
my $from_address = "nobody@localhost";
my $to_address = "somebody@localhost";
my $mail_host = "localhost";
my $subject = "Subject list";
my $message_body = "Attachment list";
my @files = ("crypt.data1","crypt.data2");
$msg = MIME::Lite->new (
  From => $from_address,
  To => $to_address,
  Subject => $subject,
  Type =>'multipart/mixed'
) or die "Error creating multipart container: $!\n";

foreach $c(@files) {
   $msg->attach (
     Disposition => 'attachment',
     Type => "application/x-pkcs7-mime; name=smime.p7m; smime-type=enveloped-data",
     Path => $c,
   ) or die "Error adding $c: $!\n";
}
$msg->send;

Replace $myEncryptedMessage with encode_base64($myEncryptedMessage)

and use MIME::Base64;

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top