Archived Forum Post

Index of archived forum posts

Question:

PKCS7 Signed Emails Preserved after Load and Save?

Jun 15 '12 at 03:08

(This question is from a Chilkat customer via email)

I'm using your components to load, modify some headers and save back an email from VB.NET I'm using something like


Dim email As Chilkat.Email
email = mailman.LoadEml(path)
email.RemoveHeaderField("X-Spam-Processed")
email.RemoveHeaderField("Message-ID")
email.AddHeaderField("Message-ID", NewMsgId)
email.SaveEml(DestFileName)

This causes an issue with PCKS7 signed email as explained in http://www.cknotes.com/?p=174

using


mime.LoadMimeFile(path)
mime.SetHeaderField(...)
mime.SaveMime(path)
will preserve PCKS7 signature? or does it some kind of normalization too?


Answer

The answer is that the MIME API will also normalize header fields to ensure they are well-formed, so it is likely there may be some changes that affect a detached signature (i.e. MIME that uses "multipart/signed" where the signature is contained in an application/x-pkcs7-signature or application/pkcs7-signature part typically located at the very end of the MIME).

Changes in multipart/signed header, which is usually the topmost/outermost header would not have any effect on signature verification. The problematic changes would be from the sub-headers contained between the multipart/signed header and the final application/x-pkcs7-signature part.

If the need is to simply modify header fields in the topmost header, then it can be easily accomplished by writing a bit of string processing code. For example, here are the logical steps one might take to remove a header field named "XYZ":

1) Search for the end of the topmost header by looking for the double CRLF. Save the topmost header in a separate temporary string (call it topmostHeader).

2) Check to see if topmostHeader contains the header "XYZ". If it begins with "XYZ:" or contains the string "nXYZ:", then it does.

3) Given that you know the XYZ header exists in topmostHeader, remove it from the MIME string. Find the index of the start of the XYZ header, then find the index where the XYZ header is finished. (It's not necessarily at the first CRLF. Continuation lines begin with a SPACE or TAB, after each CRLF is found, check the next char. If it's NOT a SPACE/TAB, then you've found the end of the header field.) Once you know the start and end indexes of the XYZ header, it's easy to delete it from the MIME string.

Adding a new header manually is also easy. The order of MIME header fields should be unimportant. The easiest places to add a new header is at the very beginning, or insert just prior to the first double CRLF (i.e. at the end of the header). It should be an easy programming task to do this.

Note: Simple modifications such as adding or removing header fields doesn't require an in-depth MIME parser. For example, you're not going to be doing "Q" or "B" encoding/decoding, you don't need to parse out attribute values found in header sub-fields, etc. You're simply adding an entire line, or removing an entire line (being aware of line continuations)..