Internet Draft Editor: Paul Hoffman draft-ietf-smime-examples-01.txt Internet Mail Consortium June 25, 1999 Expires in six months Examples of S/MIME Messages Status of this memo Internet-Drafts are working documents of the Internet Engineering Task Force (IETF), its areas, and its working groups. Note that other groups may also distribute working documents as Internet-Drafts. Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet- Drafts as reference material or to cite them other than as "work in progress." To view the list Internet-Draft Shadow Directories, see http://www.ietf.org/shadow.html. This document is an Internet-Draft and is in full conformance with all provisions of Section 10 of RFC2026. Abstract This document gives examples of message bodies formatted using S/MIME. Specifically, it has examples of Cryptographic Message Syntax (CMS) objects, S/MIME messages (including the MIME formatting), and Enhanced Security Services for S/MIME (ESS). It includes examples of most or all common CMS and ESS formats; in addition, it gives examples that show common pitfalls in implementing CMS. The purpose of this document is to help increase interoperability for S/MIME and other protocols that rely on CMS. This draft is being discussed on the 'ietf-smime' mailing list. To join the list, send a message to with the single word "subscribe" in the body of the message. Also, there is a Web site for the mailing list at . 1. Introduction The examples in this document show the structure and format of CMS message bodies, as described in [CMS]. They are useful to implementors who use protocols that rely on CMS, such as the S/MIME message format protocol. There are also examples of simple S/MIME messages [SMIME-MSG] (including the MIME headers), and ESS messages [SMIME-ESS]. Every example in this document has been checked by two different implementors. This strongly indicates (but does not assure) that the examples are correct. All CMS implementors must read the CMS document carefully before implementing from it. No one should use the examples in this document as stand-alone explanations of how to create CMS message bodies. This document explicitly does not attempt to cover many PKIX [PKIX] examples. Documents with examples of that format may be forthcoming. 2. Contributions To This Document The examples shown here were created and validated by many different people. In the example listings, there is a tag with the initials of the creator of the example, and one or more tags for the people who validated the example. Some of the examples are of mis-implementations of CMS and ESS. That is, if a developer reading the CMS or ESS specification created a message body that was illegal, and another developer agreed that the mis-reading was potentially a pitfall for later developers, that message body is also included here. To make it clear which examples are bad, they are all put into a single section of this document with (hopefully) explicit headings. To contribute an implementation of an unimplemented example listed in this document, to verify that you got the same results as an example listed here, or to suggest a new example that should be listed, please contact the document author at the address listed near the end of the document. 3. Constants Used in the Examples This section defines the data used in the rest of the document. The names of the constants indicate their use. For example, AlicePrivDSSSign is the private part of Alice's DSS signing key. - Alice is the creator of the message bodies in this spec. - Bob is the recipient of the messages. - Carl is a CA. - Diane sometimes gets involved with these folks. 3.1 Content of documents ExContent is the following sentence: This is some sample content. That is, it is the string of characters starting with "T" up to and including the ".". The hex for ExContent is 5468 6973 2069 7320 736f 6d65 2073 616d 706c 6520 636f 6e74 656e 742e The MD5 hash of ExContent is 9898 cac8 fab7 691f f89d c207 24e7 4a04 The SHA-1 hash of ExContent is 406a ec08 5279 ba6e 1602 2d9e 0629 c022 9687 dd48 3.2 Keys The following keys are needed to create the samples. Note that BobPubDHEncrypt and DianePubDHEncrypt do *not* share Diffie-Hellman parameters; however, Bob and Erica share Diffie-Hellman parameters. AlicePrivDSSSign = XXXXX AlicePrivRSASign = XXXXX AlicePubDSSSign = XXXXX AlicePubRSASign = XXXXX BobPrivDHEncrypt = XXXXX BobPrivRSAEncrypt = XXXXX BobPubDHEncrypt = XXXXX BobPubRSAEncrypt = XXXXX CarlPrivDSSSign = XXXXX CarlPrivRSASign = XXXXX CarlPubDSSSign = XXXXX CarlPubRSASign = XXXXX DianePubDSSSign = XXXXX DianePubRSASignEncrypt = XXXXX DianePubDHEncrypt = XXXXX EricaPubDHEncryptBobParam = XXXXX EricaPrivDHEncryptBobParam = XXXXX MailListTripleDES = XXXXX MailListRC2 = XXXXX 3.3 Certificates AliceDSSSignByCarlNoInherit = XXXXX AliceRSASignByCarl = XXXXX BobDHEncryptByCarl = XXXXX CarlDSSSelf = XXXXX CarlRSASelf = XXXXX DianeDSSSignByCarlInherit = XXXXX DianeDHEncryptByCarl = XXXXX DianeRSASignEncryptByCarl = XXXXX EricaDHEncryptByCarl = XXXXX 3.4 CRLs CarlCRL is a CRL from Carl that contains three revocations. CarlCRL = XXXXX 4. Trivial Examples This section covers examples of small CMS types. 4.1 ContentInfo with Data type, BER The object is a ContentInfo containing a Data object in BER format that is ExContent. XXXXX 4.2 ContentInfo with Data type, DER The object is a ContentInfo containing a Data object in DER format that is ExContent. DataTypeDER.bin: XXXXX 5. Signed-data 5.1 Basic signed content, DSS A SignedData with no attribute certificates, signed by Alice using DH-DSS, just her certificate (not Carl's root cert), no CRL. The message is ExContent, and is included in the eContent. There are no signed or unsigned attributes. XXXXX 5.2 Basic signed content, RSA Same as 5.1, except using RSA signatures. A SignedData with no attribute certificates, signed by Alice using RSA, just her certificate (not Carl's root cert), no CRL. The message is ExContent, and is included in the eContent. There are no signed or unsigned attributes. XXXXX 5.3 Basic signed content, detached content Same as 5.1, except with no eContent. A SignedData with no attribute certificates, signed by Alice using DH-DSS, just her certificate (not Carl's root cert), no CRL. The message is ExContent, but the eContent is not included. There are no signed or unsigned attributes. XXXXX 5.4 Fancier signed content Same as 5.1, but includes Carl's root cert, Carl's CRL, some signed and unsigned attributes (Countersignature by Diane). A SignedData with no attribute certificates, signed by Alice using DH-DSS, her certificate and Carl's root cert, Carl's DSS CRL. The message is ExContent, and is included in the eContent. The signed attributes are Content Type, Message Digest and Signing Time; the unsigned attributes are XXXXX. XXXXX 5.5 All RSA signed message Same as 5.2, but includes Carl's RSA root cert (but no CRL). A SignedData with no attribute certificates, signed by Alice using RSA, her certificate and Carl's root cert, no CRL. The message is ExContent, and is included in the eContent. There are no signed or unsigned attributes. XXXXX 5.6 Multiple signers Similar to 5.1, but the message is also signed by Diane. Two SignedDatas (one for Alice, one for Diane) with no attribute certificates, each signed using DH-DSS, Alice's and Diane's certificate (not Carl's root cert), no CRL. The message is ExContent, and is included in the eContent. There are no signed or unsigned attributes. XXXXX 5.7 Signing using SKI Same as 5.1, but the signature uses the SKI instead of the issuer/serial number in the cert. A SignedData with no attribute certificates, signed by Alice using DH-DSS, just her certificate (not Carl's root cert), identified by the SKI, no CRL. The message is ExContent, and is included in the eContent. There are no signed or unsigned attributes. XXXXX 5.8 S/MIME multipart/signed message A full S/MIME message, including MIME, that includes the body part from 5.3 and the body containing the content of the message. XXXXX 5.9 S/MIME application/pkcs7-mime signed message A full S/MIME message, including MIME, that includes the body part from 5.1. XXXXX 6. Enveloped-data 6.1 Basic encrypted content, TripleDES and DH An EnvelopedData from Alice to Bob of ExContent using TripleDES for encrypting and Diffie-Hellman for key management. Does not have a OriginatorInfo or any attributes. XXXXX 6.2 Basic encrypted content, TripleDES and RSA Same as 6.1, except with RSA for key management. An EnvelopedData from Alice to Bob of ExContent using TripleDES for encrypting and RSA for key management. Does not have a OriginatorInfo or any attributes. XXXXX 6.3 Basic encrypted content, RC2/40 and RSA Same as 6.1, except using RC2/40 for encryption and RSA for key management. An EnvelopedData from Alice to Bob of ExContent using RC2/40 for encrypting and RSA for key management. Does not have a OriginatorInfo or any attributes. XXXXX 6.4 Encrypted content, two recipients, no shared keying material Same as 6.1, except sent to both Bob and Diane. An EnvelopedData from Alice to Bob and Diane of ExContent using TripleDES for encrypting and Diffie-Hellman for key management. Does not have a OriginatorInfo or any attributes. XXXXX 6.5 Encrypted content, two recipients, shared keying material Same as 6.4, except sent to Bob and Erica using keys that have shared parameters so the result does not include the UKMs. An EnvelopedData from Alice to Bob and Erica of ExContent using TripleDES for encrypting and Diffie-Hellman for key management. Does not have a OriginatorInfo or any attributes. Uses BobPubDHSharedEncrypt and DianePubDHSharedEncrypt for keys. XXXXX 6.6 Encrypted content, TripleDES and DH, previously-distributed keys Same as 6.1, except sent using a previously-distributed key. An EnvelopedData from Alice to Bob of ExContent using TripleDES for encrypting and Diffie-Hellman for key management, using the MailListTripleDES key. Does not have a OriginatorInfo or any attributes. XXXXX 6.7 Encrypted content, RC2/40 and RSA, previously-distributed keys Same as 6.1, except sent using a previously-distributed key. An EnvelopedData from Alice to Bob of ExContent using TripleDES for encrypting and RSA for key management, using the MailListRC2 key. Does not have a OriginatorInfo or any attributes. XXXXX 6.8 S/MIME application/pkcs7-mime encrypted message A full S/MIME message, including MIME, that includes the body part from 6.1. XXXXX 7. Digested-data A DigestedData from Alice to Bob of ExContent using SHA-1. XXXXX 8. Encrypted-data An EncryptedData from Alice to Bob of ExContent with no attributes. XXXXX 9. Authenticated-data 9.1 Authenticated data with no autenticated attributes An AutenticatedData from Alice to Bob using XXXXXXXXXX with no authenticated attributes. XXXXX 9.2 Authenticated data with autenticated attributes An AutenticatedData from Alice to Bob using XXXXXXXXXX with the content-type and message-digest authenticated attributes. XXXXX 10. Key Wrapping This section shows the steps needed to wrap keys, as described in section 12.6 of [CMS]. 10.1 Wrapping RC2 This example shows how to wrap an RC2 key. The CEK to be wrapped is b70a 25fb c9d8 6a86 050c e0d7 11ea d4d9 The hash of the CEK is 0a6f f19f db40 4988 The random value used is 4845 cce7 fd12 50 The CEK initialization vector is c7d9 0059 b29e 97f7 The KEK is fd04 fd08 0607 07fb 0003 feff fd02 fe05 The "Pre Encrypt #1" is 10b7 0a25 fbc9 d86a 8605 0ce0 d711 ead4 d9 4845 cce7 fd12 500a 6ff1 9fdb 4049 88 The "Pre Encrypt #2" is a7f7 1fa3 078a a99f 3299 8eff 9ed7 8cac b870 ce04 f555 8ce4 6012 9337 59a2 1da0 f797 9eb2 5900 d9c7 The wrapped CEK is 70e6 99fb 5701 f783 3330 fb71 e87c 85a4 20bd c99a f05d 22af 5a0e 48d3 5f31 3898 6cba afb4 b28d 4f35 10.2 Wrapping TripleDES XXXXX 11. ESS Examples 11.1 ReceiptRequest Alice asks Bob for a reciept on the message in 5.1. XXXXX 11.2 Receipt Bob gives Alice a receipt for the message in 11.1. XXXXX 11.3 eSSSecurityLabel Alice includes a security label in the message in 5.1. XXXXX 11.4 EquivalentLabels Alice uses an EquivalentLabels in the message in 11.3. XXXXX 11.5 mlExpansionHistory The mailing list sends a message with a mlExpansionHistory attribute. XXXXX 11.6 SigningCertificate Alice uses a SigningCertificate attribute in the message in 5.1. XXXXX 12. Security Considerations Because this document shows examples of S/MIME, CMS, and ESS messages, this document also inherits all of the security considerations from [SMIME-MSG], [CMS], and [SMIME-ESS]. The Perl script in Appendix B writes to the user's local hard drive. A malicious attacker could modify the Perl script in this document. Be sure to read the Perl code carefully before executing it. A. References [CMS] Cryptographic Message Syntax, RFC 2630. [PKIX] PKIX Certificate and CRL Profile, RFC 2459. [SMIME-MSG] S/MIME Version 3 Message Specification. RFC 2633. [SMIME-ESS] Enhanced Security Services for S/MIME, RFC 2634. B. Binaries of the Examples This section contains the binaries of the examples shown in the rest of the document. The binaries are stored in a modified Base64 format. There is a Perl program that, when run over the contents of this document, will extract the following binaries and write them out to disk. The program works with Perl for Unix and Windows 95/98/NT (and possibly Macintosh). B.1 How the binaries and extractor works The program in the next section looks for lines that begin with a '|' character (or some whitespace followed by a '|'), ignoring all other lines. If the line begins with '|', the second character tells what kind of line it is: A line that begins with |* is a comment A line that begins with |> gives the name of a new file to start A line that begins with |< tells to end the file (and checks the file name for sanity) A line that begins with |anythingelse is a Base64 line The program writes out a series of files, so you should run this in an empty directory. The program will overwrite files (if it can), but won't delete other files already in the directory. Run this program with this document as the standard input, such as: extractsample " and "|<" markers, remove any page breaks, and remove the "|" in the first column of each line. The result is a valid Base64 blob that can be processed by any Base64 decoder. B.2 Example extraction program #!/usr/bin/perl # CMS Samples extraction program. v 1.1 # Get all the input as an array of lines @AllIn = (); while () { push(@AllIn, $_) } $Base64Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr' . 'stuvwxyz0123456789+/='; $LineCount = 0; $CurrFile = ''; foreach $Line (@AllIn) { $LineCount++; # Keep the line counter for error messages $Line =~ s/^\s*//; # Get rid of leading whitespace chomp($Line); # Get rid of CR or CRLF at the end of the line if(substr($Line, 0, 1) ne '|') { next } # Not a special line elsif(substr($Line, 1, 1) eq '*') { next } # It is a comment elsif(substr($Line, 1, 1) eq '>') { &StartNewFile(substr($Line, 2)) } # Start a new file elsif(substr($Line, 1, 1) eq '<') { &EndCurrFile(substr($Line, 2)) } # End the current file else { &DoBase64(substr($Line, 1)) } # It is a line of Base64 } sub StartNewFile { $TheNewFile = shift(@_); if($CurrFile ne '') { die "Was about to start a new file at " . "line $LineCount, but the old file, $CurrFile, was open\n" } open(OUT, ">$TheNewFile") or die "Could not open $TheNewFile for writing: $!\n"; $CurrFile = $TheNewFile; $LeftOver = 0; # Amount left from previous Base64 character $NextPos = 0; # Bit position to start the next Base64 character # (bits are numbered 01234567) $OutString = ''; # Holds the text going out to the file } sub EndCurrFile { $FileToEnd = shift(@_); if($CurrFile ne $FileToEnd) { die "Was about to close " . "$FileToEnd at line $LineCount, but that name didn't match " . "the name of the currently open file, $CurrFile\n" } print OUT $OutString; close(OUT); $CurrFile = ''; } sub DoBase64 { $TheIn = shift(@_); if($CurrFile eq '') { die "Got some Base64 at line $LineCount, " . "but appear to not be writing to any particular file" } @Chars = split(//, $TheIn); # Make an array of the characters foreach $ThisChar (@Chars) { # $ThisVal is the position in the string and the Base64 value $ThisVal = index($Base64Chars, $ThisChar); if($ThisVal == -1) { die "At line $LineCount, found the " . "character $ThisChar, which is not a Base64 character\n" } if($ThisVal == 64) { last } # It is a "=", so we're done if ($NextPos == 0 ) { # Don't output anything, just fill the left of $LeftOver $LeftOver = $ThisVal * 4; $NextPos = 6; } elsif ($NextPos == 2) { # Add $ThisVal to $LeftOver, output, and reset $OutString .= chr($LeftOver + $ThisVal); $LeftOver = 0; $NextPos = 0; } elsif ($NextPos == 4) { # Add upper 4 bits of $ThisVal to $LeftOver and output $Upper4 = ($ThisVal & 60); $OutString .= chr($LeftOver + ($Upper4/4)); $LeftOver = (($ThisVal - $Upper4) * 64); $NextPos = 2; } elsif ($NextPos == 6) { # Add upper 2 bits of $ThisVal to $LeftOver and output $Upper2 = ($ThisVal & 48); $OutString .= chr($LeftOver + ($Upper2/16)); $LeftOver = (($ThisVal - $Upper2) * 16); $NextPos = 4; } else { die "\$NextPos has an illegal value: $NextPos." } } } B.3 Examples by section B.3.1 Examples from section 3.1 |* ExContent is just the message; creator: [PH] |>ExContent.bin |VGhpcyBpcyBzb21lIHNhbXBsZSBjb250ZW50Lg== |AlicePrivDSSSign.key |blablahblah |moreblahblahblah |AlicePrivRSASign.key |BlablahblaH |MoreblahblahBlah |RC2CEK.bin |RC2CEKHash.bin |RC2Rand.bin |RC2CEKIV.bin |RC2KEK.bin |RC2Pre1.bin |RC2Pre2.bin |RC2Wrapped.bin |