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 <ietf-smime-request@imc.org> with the
single word "subscribe" in the body of the message.  Also, there is a
Web site for the mailing list at <http://www.imc.org/ietf-smime/>.

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 <draft-ietf-smime-examples

If you want to extract without the program, copy all the lines between
the "|>" 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 (<STDIN>) { 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==
|<ExContent.bin

B.3.2 Examples from section 3.2

|* Here is the gang of keys
|>AlicePrivDSSSign.key
|blablahblah
|moreblahblahblah
|<AlicePrivDSSSign.key
|>AlicePrivRSASign.key
|BlablahblaH
|MoreblahblahBlah
|<AlicePrivRSASign.key
. . .

B.10.1 Examples from section 10.1

|* The CEK to be wrapped
|>RC2CEK.bin
|<RC2CEK.bin

|* The hash of the CEK
|>RC2CEKHash.bin
|<RC2CEKHash.bin

|* The random value used
|>RC2Rand.bin
|<RC2Rand.bin

|* The CEK initialization vector
|>RC2CEKIV.bin
|<RC2CEKIV.bin

|* The KEK
|>RC2KEK.bin
|<RC2KEK.bin

|* The "Pre Encrypt #1"
|>RC2Pre1.bin
|<RC2Pre1.bin

|* The "Pre Encrypt #2"
|>RC2Pre2.bin
|<RC2Pre2.bin

|* The wrapped CEK
|>RC2Wrapped.bin
|<RC2Wrapped.bin


C. Acknowledgments

The following people contributed ideas and/or examples to this
document. They are listed by their real names, with the initials used
in the examples after their names.

Blake Ramsdell [BR]
Paul Hoffman [PH]
Jim Schaad [JS]
. . .

The examples are displayed with a modified version of Peter Gutmann's
"dumpasn1" program.

D. Differences between -00 and -01

Title, Abstract, Intro: Added examples of S/MIME messages (including
the MIME) and ESS messages to the general description.

3.2: Changed Diane's RSA key to be for both signing and encrypting.
Added Erica's DH keys, which share Bob's parameters.

3.3: Changed Alice's DSS cert to explicitly not inherit Carl's DSS
parameters. Changed Diane's DSS cert to explicitly inherit Carl's DSS
parameters. Changed Diane's RSA cert to be for both signing and
encrypting. Gave Erica a DH cert.

5.6, 5.7, 5.8: Renumbered to 5.5, 5.6, 5.7.

5.8, 5.9: New examples of signed S/MIME messages.

6.4: Removed the keys that were used in only that section.

6.8: New example of encrypted S/MIME message.

10: Added entire section.

11: Added entire section.

12: Added entire section.

E. Editor's Address

Paul Hoffman
Internet Mail Consortium
127 Segre Place
Santa Cruz, CA  95060 USA
phoffman@imc.org