+1 vote
by (180 points)
edited

Today, while searching for literature regarding which order should be preferred, "Sign & Encrypt" or "Encrypt & Sign", I found the interesting paper Defective Sign & Encrypt in S/MIME, PKCS#7, MOSS, PEM, PGP, and XML by Don Davis.

This very interesting and well-written paper was published in 2001 and documents two vulnerabilities in regard to so-called "naïve Sign & Encrypt" which are:

Surreptitious Forwarding

Why is naïve Sign & Encrypt insecure? Most simply, S&E is vulnerable to ``surreptitious forwarding:'' Alice signs & encrypts for Bob's eyes, but Bob re-encrypts Alice's signed message for Charlie to see. In the end, Charlie believes Alice wrote to him directly, and can't detect Bob's subterfuge.

Signature Replacement

Interestingly, naïve Encrypt-then-Sign isn't any better than Sign & Encrypt. In this case, it's easy for any eavesdropper to replace the sender's signature with his own, so as to claim authorship for the encrypted plaintext

The paper then proposes multiple ways of handling this problem, including "triple-wrapping" either via Sign-Encrypt-Sign or Encrypt-Sign-Encrypt or by enclosing sender and/or receiver information into the encrypted and/or signed content.

In each case, the signing layer and the encryption layer become interdependent, binding the sender's name, in one layer, to the recipient's name in the other layer. Any one of these alternatives suffices to establish that Alice authored both the plaintext and the ciphertext. Note though that an effective security standard should require not only that the author must provide one of these five proofs, but also that the recipient must demand some such proof as well. That is, if a naïve Sign & Encrypt message arrives without proof that the signer and encryptor were the same person, then the application software should warn the recipient that the message's privacy and/or authenticity are suspect.

It's the year 2010 now and since the original specification of S/MIME Version 3 in RFC 2633 (June 1999) two other revisions of S/MIME Version 3 were published, namely Version 3.1 in RFC 3851 (July 2004) and Version 3.2 in RFC 5751 (January 2010).

It is my understanding that "header protection" which is implemented by S/MIME Version 3.1 in RFC 3851 is the solution to the above problems. It allows to include MIME header fields in secured/encrypted content, and by including the "From" and "To" header fields the above vulnerabilities would be nullified because then the receiver of the message could validate:

  1. did the alleged sender really encrypt the message (or was the signature replaced?)
  2. was the message signed for the receiver (or was it forwarded and re-encrypted?)

To implement validation the receiver would have to check:

  1. is the "From" address outside of the encrypted content the same as inside?
  2. is the "To" address outside of the signed content the same as inside?

If I did not understand that correctly please let me know.

These are my questions:

  • To what extent does the Secure Mail component handle these issues?
  • Does it implement "header protection"?
  • Which headers does it include in the encrypted/signed content?
  • How does it handle headers when decrypting or validating a signature?
  • Does it simply replace the "outer" headers with the "inner" headers when unwrapping?
  • Does it already check if the headers were altered?
  • Is is possible to check if such header information is present in signed/encrypted content (because if it isn't the message ultimately cannot be trusted, unless another solution - e.g. triple-wrapping - was used)?
Applies to: Rebex Secure Mail

1 Answer

+1 vote
by (147k points)
edited
 
Best answer

Thanks for your detailed analysis, I am sure other readers will find it quite useful!


1) To what extent does the Secure Mail component handle these issues?

2) Does it implement "header protection"?

3) Which headers does it include in the encrypted/signed content?

I will try answering these 3 question at once:

The MailMessage class (in Rebex.Mail namespace) only supports the naïve "Sign & Encrypt" or "Encrypt & Sign".

The MimeMessage class (in Rebex.Mime namespace) is versatile enough to make it possible to produce messages that use the "triple-wrapping" approach and even messages that utilize S/MIME v3.1 header protection with a bit of extra work. The following code creates a message using "header protection", includes all the pre-encryption headers in the encrypted/signed content and copies the specified headers to the outer message:

        using Rebex.Mail;
        using Rebex.Mime.Headers;
        using Rebex.Mime;

        ...

        // get certificates
        Certificate signer = ...
        Certificate recipient = ...

        // construct the message to protect and send
        MailMessage message = new MailMessage();
        message.From = "support@rebex.net";
        message.To = "sales@rebex.net";
        message.Subject = "Protected message";
        message.BodyHtml = "<em>HTML</em> body";
        message.BodyText = "text body";

        // convert it to MimeMessage
        MimeMessage inner = message.ToMimeMessage();

        // wrap the MIME message in a message/rfc822 wrapper in
        // order to apply S/MIME security services to these headers
        // (accoding to RFC 3851)
        MimeEntity wrapped = new MimeEntity();
        wrapped.SetContent(inner);

        // sign the wrapped message
        //MimeEntity signed = new MimeEntity();
        MimeMessage signed = new MimeMessage();
        signed.SetSignedContent(wrapped, signer);
        signed.Sign();

        // encrypt the signed message
        MimeMessage outer = new MimeMessage();
        outer.SetEnvelopedContent(signed, recipient);
        outer.Encrypt();

        // copy the specified headers from
        // the (protected) inner message headers
        outer.From = inner.From;
        outer.To = inner.To;
        outer.Subject = inner.Subject;
        outer.Date = inner.Date;

        // save the outer (S&E with protected headers) message
        // (or send it instead)
        outer.Save(filePath);

Rationale: When we were writing Rebex Secure Mail in 2005&2006, we found out that major email clients lack proper support for S/MIME v3.1 header protection and some even lack support for simple "Encrypt & Sign" (Outlook Express only supported "Sign and Encrypt").

For this reason, we decided to postpone this for one of the future releases. And it looks like this situation has not improved much since - I just tested Outlook 2007 and Mozilla Thunderbird and although they are able to display a message with S/MIME v3.1 header protection, they don't perform any kind of validation and present the inner message as if it were an attachment.


4) How does it handle headers when decrypting or validating a signature?

5) Does it simply replace the "outer" headers with the "inner" headers when unwrapping?

6) Does it already check if the headers were altered?

7) Is is possible to check if such header information is present in signed/encrypted content (because if it isn't the message ultimately cannot be trusted, unless another solution - e.g. triple-wrapping - was used)?

The MailMessage class is able to parse messages that utilize S/MIME v3.1 header protection, but it handles them just like Outlook or Thunderbird do - they present the inner message with protected headers as an attachment. No protected header checking is done out-of-the-box, but with a bit of extra code, you can perform all the checks you need:

        // load the message
        MailMessage outer = new MailMessage();
        outer.Load(filePath);

        // for the sake of simplicity, this code assumes that the input file
        // is "Signed & Encrypted" with S/MIMEv3-style protected headers
        // (production code should make sure this is the case first)
        outer.Decrypt();
        MailSignatureValidity validity = outer.ValidateSignature();
        //...

        // get inner message with protected headers
        MailMessage inner = outer.Attachments[0].ContentMessage;

        // get its body
        string bodyText = inner.BodyText;
        string bodyHtml = inner.BodyHtml;

        // check whether the specified protected headers match
        // the corresponding outer headers
        string innerSender = (inner.Sender != null) ? inner.Sender.ToString() : "";
        string outerSender = (outer.Sender != null) ? outer.Sender.ToString() : "";
        if (innerSender != outerSender)
            throw new ApplicationException("Protected Sender header doesn't match the outer header.");
        if (inner.From.ToString() != outer.From.ToString())
            throw new ApplicationException("Protected From header doesn't match the outer header.");
        if (inner.To.ToString() != outer.To.ToString())
            throw new ApplicationException("Protected To header doesn't match the outer header.");
        if (inner.Subject != outer.Subject)
            throw new ApplicationException("Protected Subject header doesn't match the outer header.");

        //...

The MailMessage class is also able to load triple-wrapped messages (these don't appear as attachments), but the inner headers and signatures are lost in the process.

The MimeMessage class (in Rebex.Mime namespace) is versatile enough to make it possible to load messages using both S/MIMEv3-style protected headers or triple-wrapping and makes all the signatures and headers accessible, but it doesn't perform any checks automatically.


We will strongly consider adding out-of-the-box support for S/MIME v3.1 header protection to one of the next releases of Rebex Secure Mail, although we won't produce such messages unless explicitly instructed to (for compatibility reasons -see above). Thanks for bringing this to our attention!

by (180 points)
Thank you very much for your detailed answer. I understand that you target compatibility with existing mail clients. In my case I don't need to be concerned with that because I control to a great extent the mail clients used for sending and receiving (no standard software). An option to use S/MIME header protection is surely a great idea.
by (147k points)
We have added this to our TODO list. An option to use S/MIME header protection should appear in one of the next releases.
...