You are currently viewing a snapshot of taken on April 21, 2008. Most of this content is highly out of date (some pages haven't been updated since the project began in 1998) and exists for historical purposes only. If there are any pages on this archive site that you think should be added back to, please file a bug.

Table of Contents | Previous | Next | Index

Introduction to the S/MIME Toolkit

Main technical contact: Ian McGreer
Manager: Wan-Teh Chang

S/MIME Types and Structures
Overview of an S/MIME Application

Overview of CMS

This document provides a brief introduction to the S/MIME Toolkit API. More complete descriptions of individual types and functions will be provided at a later time.

The S/MIME Toolkit API reflects the Cryptographic Message Syntax (CMS) Specification (RFC 2630). You should read that document before attempting to use the S/MIME Toolkit API. For information on other relevant RFCs, see Referemces.

CMS, which is based on PKCS #7, describes various message types that can be used to digitally sign and/or encrypt messages transmitted over an unencrypted communications channel. Two of the message types defined by RFC 2630 are relevant for S/MIME: SignedData and EnvelopedData. The corresponding types in the S/MIME Toolkit API are NSSCMSSignedData and NSSCMSSignedData.

This overview uses the RFC names to discuss basic concepts and procedures. The remainder of this document refers to specific S/MIME Toolkit types and functions listed in and, respectively.


An EnvelopedData message contains an "inner" message that is encrypted for a set of recipients. The "inner" message is encrypted with a random key using a fast symmetric encryption algorithm such as RC2 or 3DES. The random key itself is transmitted with the EnvelopedData, encrypted with each recipient's public key, so that it can be decrypted only by the recipients using their private keys.

An EnvelopedData message includes:

  • a set of RecipientInfo structures, each of which contains the encrypted content key and the ID of the recipient's certificate used for this encryption. There is one RecipientInfo per recipient.
  • the encrypted "inner" content
  • information about the encryption algorithms used


A SignedData message contains an unencrypted message, plus one or more "signer" blocks. Each signer block contains the signer’s certificate, digest values for the message that are encrypted using the signer's private key, and other information, such as the signing time.

By decrypting the digest values with the signer's public key, and then checking whether they are equal to newly computed digests, the receiving software can make reasonably sure that (1) the message has not been altered since the signer signed it, and (2) the message was, in fact, signed by the entity/person identified in the message (assuming that the signer's certificate verified correctly and its issuer is trusted by the receiver).

A SignedData message includes:

  • the "inner" content
  • a set of certificates used in processing the message
  • a set of SignerInfo structures, each of which contains signer identification (pointer to signer's certificate), encrypted digest value(s), and other attributes.
  • for S/MIME messages, an attribute that specifies S/MIME preferences, including the sender's encryption algorithm preferences and identification of the certificate the sender prefers to be used for sending encrypted mail back to the sender
  • information about the algorithms used

Since SignedData messages can contain certificate information, they can also be used for simple transport of certificates. In this case, there is no "inner" content and no SignerInfo structures.

Use of Enveloped Data and SignedData in a MIME Message

Content-Type: application/pkcs7-mime

Depending on the smime-type subheader, MIME messages can be signed or enveloped (encrypted) messages. The content is a DER-encoded CMS message that contains the "inner" content of a SignedData or EnvelopedData structure.

Here's an example of a signed message:

Content-Type: application/pkcs7-mime; smime-type=signed-data; name=smime.p7m 
Content-Transfer-Encoding: base64 
Content-Disposition: attachment; filename=smime.p7m 


In this example, the binary data contains a SignedData message, which is the "inner" content plus signature information. The inner content could, for example, expand to this text:

Content-Type: text/plain 

This is a signed message. 

To be displayed appropriately in an email program, the binary data must be fed to a MIME parser and tagged with information about the signatures and their validity.

Alternatively, the inner content can be another S/MIME message, up to arbitrary levels of recursion, with each message in the hierarchy signed or encrypted. A single message that is both signed and encrypted consists of two nested MIME messages.

Binary CMS messages can (but need not) be encoded for 7-bit channels. The information in the Content-Transfer-Encoding header must be used for parsing.

Here's an example of an encrypted message:

Content-Type: application/pkcs7-mime; smime-type=enveloped-data; name=smime.p7m 
Content-Transfer-Encoding: base64 
Content-Disposition: attachment; filename=smime.p7m 


The binary content is a DER-encoded CMS EnvelopedData message containing inner content that must be decrypted before further processing occurs.

Content-Type: multipart/signed

The multipart/signed content type designates clear-signed messages. [what does this mean?] The content to be signed is in the first part (in readable form, with the appropriate content type), and the signature is in the second part (using a SignedData CMS message without inner content). This format is preferred for generation because it can be used even with non-S/MIME enabled user agents. [generation of original message? does this mean that this content type is readable even if the receiving software doesn’t support S/MIME? whereas the other one isn’t?]

Here’s an example of a multipart/signed CMS message:

Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha1; boundary=boundary42 

Content-Type: text/plain

This is a clear-signed message.

Content-Type: application/pkcs7-signature; name=smime.p7s 
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename=smime.p7s 


add the rest of Christian’s text here? heads are:

Advanced Topics
	Triple-Wrapped Messages
	Secure Mail Lists
	Security Labels
	Signed Receipts
Implications for a Mail User Agent Implementation
	MIME Parser Glue Code
	MIME Generator Glue Code
	Message Composition UI
	Message Presentation UI
	Address Book Integration
	S/MIME Preferences

S/MIME Types and Structures

- follows RFC 2630, Cryptographic Message Syntax, exactly.

Basically, you create a NSSCMSMessage structure and populate it with the info re algorithms, data to be signed or encrypted, certs, etc. and then stream your data through it. [???]

A ContentUnion structure is a container that specifies the type of content and the content itself. The content can be unstructured data (SEC_Item), structured data (NSSCMSDigestedData, NSSCMSEncryptedData, NSSCMSEnvelopedData, NSSCMSSignedData), or a pointer to something.

A NSSCMSMessage structure contains an NSSCMSSignedData ocbject

SignedData ::= SEQUENCE {
        version CMSVersion,
        digestAlgorithms DigestAlgorithmIdentifiers,
        encapContentInfo EncapsulatedContentInfo,
        certificates [0] IMPLICIT CertificateSet OPTIONAL,
        crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,
        signerInfos SignerInfos }

	NSSCMSContentInfo - type & content of “outer” data
	memory stuff
	inner stuff:
		sectitem (digests) 
		callback for getting decryption key

Overview of an S/MIME Application

[say something about streaming model here? anything else? e.g. process of building up nested messages?]


Initialization includes initializing the NSPR and NSS libraries, opening the certificate database, and setting the default certificate database. Functions used in the initialization part of an application can include the following:

  • PR_Init. Initializes NSPR. Must be called before any other NSS or S/MIME Toolkit functions.
  • SECU_PKCS11Init. [Initializes PKCS #11? not in SSL Ref, where to document?]
  • SEC_Init. [Initializes NSS library? not in SSL Ref, where to document? Why this and not NSS_Init?]
  • OpenCertDB. Opens the cert database. [Specifies a callback?]
  • CERT_SetDefaultCertDB. Sets the opened cert database to be the default cert database. [not documented in SSL Ref; add it to CERT chapter?]

Building the NSSCMSMessage Object

An NSSCMSMessage object in turn contains nested NSSCMSSignedData, NSSCMSEnvelopedData, and other objects. Each of these CMS objects consists of a content type and content, plus other information required for processing. The basic procedure is to create an NSSCMSMessage, which is the outermost container, and build up the nested objects as necessary for signing or encrypting nested messages.

These are the functions that an S/MIME application typically calls initially to create an NSSCMSMessage object and the chain of objects it contains:

  • NSS_CMSMessage_Create allocates memory for an empty NSSCMSMessage object.
  • NSS_CMSSignedData_Create adds an empty NSSCMSSIgnedData object to an existing NSSCMSMessage object.
  • [others here, e.g. NSS_CMSEnvelopedData_Create?]
  • NSS_CMSMessage_GetContentInfo returns a pointer to the top level contentInfo structure.
  • NSS_CMSSignedData_GetContentInfo returns a pointer to a specified NSSCMSSignedData object's contentinfo. - need to talk more about contentInfo
misc. notes follow
build chain of objects: 
create signeddata object (sigd) with a call to NSS_CMSSignedData_Create
get ref. to contentinfo of your cmsg (cinfo) with a call to NSS_CMSMessage_GetContentInfo
get ref. to contentinfo of your signeddata (sigd) with a call to NSS_CMSSignedData_GetContentInfo

set content of your data with a call to NSS_CMSContentInfo_SetContent

create and attach signer info with NSS_CMSSignerInfo_Create, passing in a cert and an algorithm

if you want to include the cert chain, call NSS_CMSSignerInfo_IncludeCerts
NSS_CMSSignerInfo_AddSigningTime adds signing time to signer info
NSS_CMSSignerInfo_AddSMIMECaps adds profile info (?) to signerinfo

ContentInfo ::= SEQUENCE {
		contentType ContentType,
content [0] EXPLICIT ANY DEFINED BY contentType }

      ContentType ::= OBJECT IDENTIFIER
a name="refs">


[formatting to come]

RFC2633 S/MIME v3 Message Specification. The authoritative document. 
RFC2634 Enhanced Security Services for S/MIME. Some extensions for S/MIME - not required, but growing importance for some. 
RFC2630 Cryptographic Message Syntax. Describes the format of cryptographic messages used in S/MIME (SignedData, EnvelopedData), plus some others
RFC2045-2049 MIME. The basic MIME framework 
RFC2459 Internet X.509 Public Key Infrastructure.