RFC 3851

Secure/Multipurpose Internet Mail Extensions (S/MIME) Version 3.1 Message Specification

๐Ÿ“… published July 2004, from ietf

RFC 3851 โœจ S/MIME Version 3.1 Message Specification ๐Ÿ’Œ

Okay bestie, let's get into it ๐ŸŽ€ This is RFC 3851, titled "Secure/Multipurpose Internet Mail Extensions (S/MIME) Version 3.1 Message Specification." It was written by B. Ramsdell as Editor, from Sendmail, Inc., for the Network Working Group, in July 2004. It's a Standards Track document, and it obsoletes RFC 2633 ๐Ÿ’…


Status of this Memo ๐Ÿ“‹

This doc specifies an Internet standards track protocol for the Internet community, and it's literally asking for discussion and suggestions for improvements ๐Ÿซถ For the standardization state and status of this protocol, check the current edition of the "Internet Official Protocol Standards" (STD 1). Distribution of this memo is unlimited ๐ŸŒธ

Copyright (C) The Internet Society (2004). ๐Ÿ’œ

Abstract ๐Ÿฆ‹

Okay so this document defines S/MIME version 3.1 (Secure/Multipurpose Internet Mail Extensions) โœจ S/MIME gives you one consistent way to send and receive secure MIME data, and it's giving reliable ๐Ÿ” Digital signatures bring authentication, message integrity, and non-repudiation with proof of origin. Encryption brings data confidentiality, and compression can shrink the data size ๐Ÿ“ This document obsoletes RFC 2633, so yeah, that one is retired now ๐Ÿ™ˆ

Table of Contents ๐Ÿ—‚๏ธ

1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  2
    1.1.  Specification Overview . . . . . . . . . . . . . . . . .  3
    1.2.  Terminology. . . . . . . . . . . . . . . . . . . . . . .  3
    1.3.  Definitions. . . . . . . . . . . . . . . . . . . . . . .  4
    1.4.  Compatibility with Prior Practice of S/MIME. . . . . . .  5
    1.5.  Changes Since S/MIME v3. . . . . . . . . . . . . . . . .  5
2.  CMS Options. . . . . . . . . . . . . . . . . . . . . . . . . .  5
    2.1.  DigestAlgorithmIdentifier. . . . . . . . . . . . . . . .  5
    2.2.  SignatureAlgorithmIdentifier . . . . . . . . . . . . . .  6
    2.3.  KeyEncryptionAlgorithmIdentifier . . . . . . . . . . . .  6
    2.4.  General Syntax . . . . . . . . . . . . . . . . . . . . .  6
    2.5.  Attributes and the SignerInfo Type . . . . . . . . . . .  7
    2.6.  SignerIdentifier SignerInfo Type . . . . . . . . . . . . 11
    2.7.  ContentEncryptionAlgorithmIdentifier . . . . . . . . . . 12
3.  Creating S/MIME Messages . . . . . . . . . . . . . . . . . . . 14

    3.1.  Preparing the MIME Entity for Signing, Enveloping
          or Compressing . . . . . . . . . . . . . . . . . . . . . 14
    3.2.  The application/pkcs7-mime Type. . . . . . . . . . . . . 19
    3.3.  Creating an Enveloped-only Message . . . . . . . . . . . 21
    3.4.  Creating a Signed-only Message . . . . . . . . . . . . . 22
    3.5.  Creating an Compressed-only Message. . . . . . . . . . . 26
    3.6.  Multiple Operations. . . . . . . . . . . . . . . . . . . 27
    3.7.  Creating a Certificate Management Messagetoc . . . . . . 27
    3.8.  Registration Requests. . . . . . . . . . . . . . . . . . 28
    3.9.  Identifying an S/MIME Message. . . . . . . . . . . . . . 28
4.  Certificate Processing . . . . . . . . . . . . . . . . . . . . 29
    4.1.  Key Pair Generation. . . . . . . . . . . . . . . . . . . 29
5.  Security Considerations. . . . . . . . . . . . . . . . . . . . 29
A.  ASN.1 Module . . . . . . . . . . . . . . . . . . . . . . . . . 31
B.  References . . . . . . . . . . . . . . . . . . . . . . . . . . 32
    B.1.  Normative References . . . . . . . . . . . . . . . . . . 32
    B.2.  Informative References . . . . . . . . . . . . . . . . . 34
C.  Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 35
D.  Editor's Address . . . . . . . . . . . . . . . . . . . . . . . 35
    Full Copyright Statement . . . . . . . . . . . . . . . . . . . 36

1. Introduction ๐Ÿ‘‹

S/MIME (Secure/Multipurpose Internet Mail Extensions) gives you a consistent way to send and receive secure MIME data ๐Ÿ’– It's built on the popular Internet MIME standard, and it brings these cryptographic security services to electronic messaging apps: authentication, message integrity and non-repudiation of origin (using digital signatures), and data confidentiality (using encryption) ๐Ÿ”

S/MIME can be used by traditional mail user agents (MUAs) to add cryptographic security services to mail that gets sent, and to read the cryptographic security services in mail that gets received. But it's not limited to mail! It works with any transport mechanism that carries MIME data, like HTTP ๐ŸŒˆ Since it takes advantage of the object-based features of MIME, secure messages can move around mixed-transport systems, which is so iconic.

Also, S/MIME can be used in automated message transfer agents that do cryptographic work without any human intervention. Think signing software-generated documents, or encrypting FAX messages sent over the Internet ๐Ÿงš

1.1. Specification Overview ๐Ÿ—บ๏ธ

This document describes a protocol for adding cryptographic signature and encryption services to MIME data ๐Ÿ’… The MIME standard [MIME-SPEC] gives a general structure for the content type of Internet messages, and it allows extensions for new content type applications.

This spec defines how to create a MIME body part that's been cryptographically enhanced according to CMS [CMS], which is derived from PKCS #7 [PKCS-7]. It also defines the application/pkcs7-mime MIME type that can be used to transport those body parts โœจ

This document also talks about how to use the multipart/signed MIME type defined in [MIME-SECURE] to transport S/MIME signed messages. multipart/signed gets used together with the application/pkcs7-signature MIME type, which transports a detached S/MIME signature ๐Ÿฆ‹

To create S/MIME messages, an S/MIME agent MUST follow the specifications in this document, as well as the specifications listed in the Cryptographic Message Syntax document [CMS] [CMSALG] ๐ŸŽ€

Throughout this spec, there are requirements and recommendations for how receiving agents handle incoming messages. There are separate requirements and recommendations for how sending agents create outgoing messages. Generally the best strategy is to "be liberal in what you receive and conservative in what you send" ๐Ÿ“ Most of the requirements land on handling incoming messages, and the recommendations are mostly about creating outgoing ones.

Splitting up requirements for receiving agents and sending agents also makes sense, because there will likely be S/MIME systems running software other than traditional Internet mail clients. S/MIME can be used with any system that transports MIME data. An automated process that sends an encrypted message might not be able to receive an encrypted message at all, for example ๐Ÿ™ˆ So the requirements and recommendations for the two types of agents are listed separately when that's appropriate.

1.2. Terminology ๐Ÿ“–

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [MUSTSHOULD]. Yes, these words are the official requirement-level vocab, so read them carefully ๐Ÿซถ

1.3. Definitions ๐Ÿ“š

For the purposes of this specification, the following definitions apply.

ASN.1: Abstract Syntax Notation One, as defined in CCITT X.208 [X.208-88].

BER: Basic Encoding Rules for ASN.1, as defined in CCITT X.209 [X.209-88].

Certificate: A type that binds an entity's name to a public key with a digital signature ๐Ÿ”‘

DER: Distinguished Encoding Rules for ASN.1, as defined in CCITT X.509 [X.509-88].

7-bit data: Text data with lines less than 998 characters long, where none of the characters have the 8th bit set, and there are no NULL characters. <CR> and <LF> occur only as part of a <CR><LF> end of line delimiter.

8-bit data: Text data with lines less than 998 characters, and where none of the characters are NULL characters. <CR> and <LF> occur only as part of a <CR><LF> end of line delimiter.

Binary data: Arbitrary data ๐ŸŒธ

Transfer Encoding: A reversible transformation made on data so 8-bit or binary data can be sent via a channel that only transmits 7-bit data. It's basically a glow-up for data so it can get through a 7-bit channel and come back out fine โœจ

Receiving agent: Software that interprets and processes S/MIME CMS objects, MIME body parts that contain CMS content types, or both.

Sending agent: Software that creates S/MIME CMS content types, MIME body parts that contain CMS content types, or both.

S/MIME agent: User software that is a receiving agent, a sending agent, or both.

1.4. Compatibility with Prior Practice of S/MIME ๐Ÿค

S/MIME version 3.1 agents SHOULD attempt to have the greatest interoperability possible with agents for prior versions of S/MIME. S/MIME version 2 is described in RFC 2311 through RFC 2315, inclusive, and S/MIME version 3 is described in RFC 2630 through RFC 2634 inclusive. RFC 2311 also has historical info about how S/MIME got developed ๐Ÿ•ฐ๏ธ

1.5. Changes Since S/MIME v3 ๐Ÿ†•

Here's the tea โ˜• The RSA public key algorithm was changed to a MUST implement key wrapping algorithm, and the Diffie-Hellman algorithm changed to a SHOULD implement.

The AES symmetric encryption algorithm has been included as a SHOULD implement ๐Ÿ’–

The RSA public key algorithm was changed to a MUST implement signature algorithm ๐Ÿ”ฅ

Ambiguous language about using "empty" SignedData messages to transmit certificates got cleaned up. It now reflects that transmitting certificate revocation lists is also allowed ๐Ÿงพ

The use of binary encoding for some MIME entities is now explicitly discussed ๐ŸŒˆ

Header protection through the use of the message/rfc822 MIME type has been added. Protecting the header, it's giving main character energy ๐Ÿ‘‘

Use of the CompressedData CMS type is allowed, along with required MIME type and file extension additions ๐Ÿฆ‹


2. CMS Options ๐ŸŽ›๏ธ

CMS allows for a wide variety of options in content and algorithm support, which is a lot of choice ๐Ÿ’€ So this section puts forth a number of support requirements and recommendations to get a base level of interoperability among all S/MIME implementations. [CMSALG] has the extra details on using the cryptographic algorithms ๐Ÿ”

2.1. DigestAlgorithmIdentifier ๐Ÿงฉ

Sending and receiving agents MUST support SHA-1 [CMSALG]. Receiving agents SHOULD support MD5 [CMSALG] so they stay backward compatible with MD5-digested S/MIME v2 SignedData objects ๐Ÿซถ

2.2. SignatureAlgorithmIdentifier โœ๏ธ

Receiving agents MUST support id-dsa-with-sha1 defined in [CMSALG]. The algorithm parameters MUST be absent (not encoded as NULL). Receiving agents MUST support rsaEncryption, defined in [CMSALG] ๐Ÿ’œ

Sending agents MUST support either id-dsa-with-sha1 or rsaEncryption ๐ŸŽ€

If you're using rsaEncryption, sending and receiving agents MUST support the digest algorithms in section 2.1 as specified ๐Ÿ“

Note that S/MIME v3 clients might only implement signing or signature verification using id-dsa-with-sha1, and might also use id-dsa as an AlgorithmIdentifier in this field. Receiving clients SHOULD recognize id-dsa as equivalent to id-dsa-with-sha1, and sending clients MUST use id-dsa-with-sha1 if they use that algorithm. Also, S/MIME v2 clients are only required to verify digital signatures using the rsaEncryption algorithm with SHA-1 or MD5, and they might not implement id-dsa-with-sha1 or id-dsa at all ๐Ÿ™ˆโœจ

2.3. KeyEncryptionAlgorithmIdentifier โœจ

okay so bestie, this one's about which key encryption algorithms your agent has to know ๐Ÿ”. Sending and receiving agents MUST support rsaEncryption, which is defined in [CMSALG] ๐Ÿ’–. That part is non-negotiable, no cap ๐Ÿ’….

Sending and receiving agents SHOULD support Diffie-Hellman, also defined in [CMSALG], using the ephemeral-static mode ๐Ÿฆ‹. It's a strong recommendation, not a hard rule, so you'd want it unless you have a good reason not to ๐Ÿซถ.

Also, a little history tea โ˜•: S/MIME v3 clients might only implement key encryption and decryption using the Diffie-Hellman algorithm ๐ŸŒธ. And S/MIME v2 clients are only capable of decrypting content-encryption keys using the rsaEncryption algorithm ๐Ÿ™ˆ. So older clients can be pretty picky, and that's why this stuff matters ๐Ÿ’€.

2.4. General Syntax ๐ŸŽ€

there are a bunch of CMS content types out there, but only four of them are actually used for S/MIME ๐Ÿงš. Those are Data, SignedData, EnvelopedData, and CompressedData ๐Ÿ‘‘. The rest just aren't part of the S/MIME party โœจ.

2.4.1. Data Content Type ๐Ÿ’œ

Sending agents MUST use the id-data content type identifier to identify the "inner" MIME message content ๐Ÿซถ. Let's say you're signing some MIME data. The CMS SignedData encapContentInfo eContentType MUST include the id-data object identifier, and the MIME content MUST be stored in the SignedData encapContentInfo eContent OCTET STRING ๐Ÿ”ฅ. The one exception is when the sending agent is using multipart/signed, because then the eContent is absent, per section 3.4.3 of this document ๐Ÿ™ˆ.

Encryption works the same vibe ๐Ÿ”. When you apply encryption to MIME data, the CMS EnvelopedData encryptedContentInfo contentType MUST include the id-data object identifier, and the encrypted MIME content MUST be stored in the EnvelopedData encryptedContentInfo encryptedContent OCTET STRING ๐Ÿ’….

2.4.2. SignedData Content Type ๐Ÿฆ‹

Sending agents MUST use the SignedData content type to apply a digital signature to a message ๐Ÿ’–. There's also a degenerate case where there's no signature info at all, and then it's just used to convey certificates ๐ŸŒˆ. Applying a signature gives you authentication, message integrity, and non-repudiation of origin, which is a whole lot of main character energy ๐Ÿ‘‘.

2.4.3. EnvelopedData Content Type ๐Ÿ”

This content type is used to apply data confidentiality to a message ๐Ÿคซ. A sender needs to have access to a public key for each intended message recipient to use this service ๐Ÿ—๏ธ.

2.4.4. CompressedData Content Type ๐Ÿ“

This content type is used to apply data compression to a message ๐Ÿ“ฆ. Just so we're clear, it does NOT provide authentication, message integrity, non-repudiation, or data confidentiality ๐Ÿ’€. It's only used to make the message smaller โœจ.

See section 3.6 for further guidance on using this type alongside other CMS types ๐Ÿ“–.

2.5. Attributes and the SignerInfo Type ๐Ÿ’…

The SignerInfo type lets you include unsigned and signed attributes along with a signature ๐ŸŽ€.

Receiving agents MUST be able to handle zero or one instance of each of the signed attributes listed here ๐Ÿ’–. Sending agents SHOULD generate one instance of each of the following signed attributes in each S/MIME message โœจ:

  • signingTime (section 2.5.1 in this document) ๐Ÿ•ฐ๏ธ
  • sMIMECapabilities (section 2.5.2 in this document) ๐ŸŒธ
  • sMIMEEncryptionKeyPreference (section 2.5.3 in this document) ๐Ÿ”‘
  • id-messageDigest (section 11.2 in [CMS]) ๐Ÿงพ
  • id-contentType (section 11.1 in [CMS]) ๐Ÿท๏ธ

Further, receiving agents SHOULD be able to handle zero or one instance in the signingCertificate signed attribute, as defined in section 5 of [ESS] ๐Ÿซถ. Sending agents SHOULD generate one instance of the signingCertificate signed attribute in each SignerInfo structure ๐Ÿ’œ.

Additional attributes and values for these might be defined in the future ๐Ÿ”ฎ. Receiving agents SHOULD handle attributes or values that they don't recognize in a graceful manner ๐Ÿฆข.

Interactive sending agents that include signed attributes not listed here SHOULD display those attributes to the user, so the user knows all of the data being signed ๐Ÿ‘€. Transparency is everything, bestie ๐Ÿ’….

2.5.1. Signing-Time Attribute โฐ

The signing-time attribute conveys the time that a message was signed ๐Ÿ•ฐ๏ธ. The time of signing will most likely be created by a message originator, so it's only as trustworthy as the originator ๐Ÿคทโ€โ™€๏ธ.

Sending agents MUST encode signing time through the year 2049 as UTCTime, and signing times in 2050 or later MUST be encoded as GeneralizedTime ๐Ÿ“…. When the UTCTime CHOICE is used, S/MIME agents MUST interpret the year field (YY) like this ๐Ÿงฎ:

if YY is greater than or equal to 50, the year is interpreted as
19YY; if YY is less than 50, the year is interpreted as 20YY.

2.5.2. SMIMECapabilities Attribute ๐ŸŒˆ

The SMIMECapabilities attribute includes signature algorithms (such as sha1WithRSAEncryption), symmetric algorithms (such as DES-EDE3-CBC), and key encipherment algorithms (such as rsaEncryption) ๐Ÿ”. There are also several identifiers that indicate support for other optional features, like binary encoding and compression ๐Ÿ“ฆ. The SMIMECapabilities were designed to be flexible and extensible, so that in the future, other capabilities and preferences (like certificates) can be added without breaking current clients ๐Ÿฆ‹.

If present, the SMIMECapabilities attribute MUST be a SignedAttribute, and it MUST NOT be an UnsignedAttribute ๐Ÿ”’. CMS defines SignedAttributes as a SET OF Attribute ๐Ÿงฉ. The SignedAttributes in a signerInfo MUST NOT include multiple instances of the SMIMECapabilities attribute ๐Ÿ™…โ€โ™€๏ธ. CMS defines the ASN.1 syntax for Attribute to include attrValues SET OF AttributeValue ๐Ÿ“. A SMIMECapabilities attribute MUST only include a single instance of AttributeValue ๐Ÿ’–. There MUST NOT be zero or multiple instances of AttributeValue present in the attrValues SET OF AttributeValue ๐Ÿšซ.

The semantics of the SMIMECapabilities attribute specify a partial list of what the client announcing it can support ๐Ÿ“. A client does not have to list every capability it supports, and it doesn't need to list all of them so the list doesn't get too long ๐Ÿซถ. In an SMIMECapabilities attribute, the object identifiers (OIDs) are listed in order of preference, but they SHOULD be separated logically along the lines of their categories (signature algorithms, symmetric algorithms, key encipherment algorithms, etc.) ๐Ÿ—‚๏ธ.

The structure of the SMIMECapabilities attribute is meant to make simple table lookups and binary comparisons easy, so matches can be found ๐Ÿ”. For instance, the DER-encoding for the SMIMECapability for DES EDE3 CBC MUST be identically encoded regardless of the implementation ๐Ÿงฌ. Because of that identical-encoding requirement, people documenting algorithms for the SMIMECapabilities attribute SHOULD explicitly document the correct byte sequence for the common cases ๐Ÿ“œ.

For any capability, the associated parameters for the OID MUST specify everything needed to tell apart two instances of the same algorithm ๐Ÿ”Ž. For instance, the number of rounds and the block size for RC5 need to be specified in addition to the key length ๐Ÿง .

The OIDs that correspond to algorithms SHOULD use the same OID as the actual algorithm, except when the algorithm usage is ambiguous from the OID ๐ŸŽฏ. For instance, in an earlier specification, rsaEncryption was ambiguous, because it could refer to either a signature algorithm or a key encipherment algorithm ๐Ÿ˜ตโ€๐Ÿ’ซ. If an OID is ambiguous, the maintainer of the registered SMIMECapabilities list needs to arbitrate which type of algorithm gets the OID, and a new OID MUST be allocated under the smimeCapabilities OID to satisfy the other use ๐Ÿง‘โ€โš–๏ธ.

The registered SMIMECapabilities list specifies the parameters for OIDs that need them, most notably key lengths for variable-length symmetric ciphers ๐Ÿ”‘. If there are no differentiating parameters for a particular OID, the parameters MUST be omitted, and MUST NOT be encoded as NULL ๐Ÿšซ.

Additional values for the SMIMECapabilities attribute might be defined in the future ๐Ÿ”ฎ. Receiving agents MUST handle a SMIMECapabilities object that has values they don't recognize in a graceful manner ๐Ÿซถ.

Section 2.7.1 explains a strategy for caching capabilities ๐Ÿ—„๏ธ.

2.5.2.1. SMIMECapability For the RC2 Algorithm ๐ŸŒธ

For the RC2 algorithm preference SMIMECapability, the capabilityID MUST be set to the value rc2-cbc as defined in [CMSALG] ๐Ÿ’–. The parameters field MUST contain SMIMECapabilitiesParametersForRC2CBC (see appendix A) โœจ.

Please note that SMIMECapabilitiesParametersForRC2CBC is a single INTEGER that holds the effective key length (NOT the corresponding RC2 parameter version value) ๐Ÿ‘€. So, for example, for RC2 with a 128-bit effective key length, the parameter is encoded as the INTEGER value 128, NOT the corresponding parameter version of 58 ๐Ÿ™…โ€โ™€๏ธ๐Ÿ’….

2.5.3. Encryption Key Preference Attribute ๐Ÿ—๏ธ

The encryption key preference attribute lets the signer unambiguously describe which of their certificates holds their preferred encryption key ๐Ÿ”. It's designed to level up interoperability with clients that use separate keys for encryption and signing ๐Ÿฆ‹. Anyone viewing the attribute can see which listed certificate is appropriate for encrypting a session key for future encrypted messages ๐Ÿ‘‘.

If present, the SMIMEEncryptionKeyPreference attribute MUST be a SignedAttribute, and it MUST NOT be an UnsignedAttribute ๐Ÿ”’. CMS defines SignedAttributes as a SET OF Attribute ๐Ÿงฉ. The SignedAttributes in a signerInfo MUST NOT include multiple instances of the SMIMEEncryptionKeyPreference attribute ๐Ÿ™…โ€โ™€๏ธ. CMS defines the ASN.1 syntax for Attribute to include attrValues SET OF AttributeValue ๐Ÿ“. A SMIMEEncryptionKeyPreference attribute MUST only include a single instance of AttributeValue ๐Ÿ’–. There MUST NOT be zero or multiple instances of AttributeValue present in the attrValues SET OF AttributeValue ๐Ÿšซ.

The sending agent SHOULD include the referenced certificate in the set of certificates included in the signed message if this attribute is used ๐Ÿ“จ. The certificate MAY be omitted if it was previously made available to the receiving agent ๐Ÿซถ. Sending agents SHOULD use this attribute if the commonly used or preferred encryption certificate is not the same as the certificate used to sign the message ๐ŸŽฏ.

Receiving agents SHOULD store the preference data if the signature on the message is valid and the signing time is greater than the currently stored value ๐Ÿ—ƒ๏ธ. (As with the SMIMECapabilities, the clock skew SHOULD be checked, and the data should not be used if the skew is too great โณ.) Receiving agents SHOULD respect the sender's encryption key preference attribute if possible ๐Ÿ™. This, however, represents only a preference, and the receiving agent can use any certificate that is valid when replying to the sender ๐Ÿ’Œ.

Section 2.7.1 explains a strategy for caching preference data ๐Ÿง .

2.5.3.1. Selection of Recipient Key Management Certificate โœจ

okay so, if you want to figure out which key management certificate to use when you're sending a future CMS EnvelopedData message to a particular recipient, the following steps SHOULD be followed:

  • If an SMIMEEncryptionKeyPreference attribute is found in a SignedData object received from the desired recipient, that identifies the X.509 certificate that SHOULD be used as the X.509 key management certificate for the recipient. ๐ŸŽฏ
  • If an SMIMEEncryptionKeyPreference attribute is not found in a SignedData object received from the desired recipient, the set of X.509 certificates SHOULD be searched for an X.509 certificate with the same subject name as the signing of an X.509 certificate which can be used for key management. ๐Ÿ”
  • Or use some other method of determining the user's key management key. If an X.509 key management certificate is not found, then encryption cannot be done with the signer of the message. If multiple X.509 key management certificates are found, the S/MIME agent can make an arbitrary choice between them. ๐ŸŽฒ

2.6. SignerIdentifier SignerInfo Type ๐Ÿ’…

S/MIME v3.1 implementations MUST support both issuerAndSerialNumber as well as subjectKeyIdentifier. Messages that use the subjectKeyIdentifier choice cannot be read by S/MIME v2 clients. ๐Ÿ™ˆ

It is important to understand that some certificates use a value for subjectKeyIdentifier that is not suitable for uniquely identifying a certificate. Implementations MUST be prepared for multiple certificates for potentially different entities to have the same value for subjectKeyIdentifier, and MUST be prepared to try each matching certificate during signature verification before indicating an error condition. ๐Ÿ˜ญ

2.7. ContentEncryptionAlgorithmIdentifier ๐Ÿ”ฅ

Sending and receiving agents MUST support encryption and decryption with DES EDE3 CBC, hereinafter called "tripleDES" [CMSALG]. Receiving agents SHOULD support encryption and decryption using the RC2 [CMSALG] or a compatible algorithm at a key size of 40 bits, hereinafter called "RC2/40". Sending and receiving agents SHOULD support encryption and decryption with AES [CMSAES] at a key size of 128, 192, and 256 bits. ๐Ÿ‘‘

2.7.1. Deciding Which Encryption Method To Use ๐ŸŽ€

When a sending agent creates an encrypted message, it has to decide which type of encryption to use. The decision process involves using information garnered from the capabilities lists included in messages received from the recipient, as well as out-of-band information such as private agreements, user preferences, legal restrictions, and so on. ๐Ÿง 

Section 2.5.2 defines a method by which a sending agent can optionally announce, among other things, its decrypting capabilities in its order of preference. The following method for processing and remembering the encryption capabilities attribute in incoming signed messages SHOULD be used. ๐Ÿฆ‹

  • If the receiving agent has not yet created a list of capabilities for the sender's public key, then, after verifying the signature on the incoming message and checking the timestamp, the receiving agent SHOULD create a new list containing at least the signing time and the symmetric capabilities. ๐ŸŒธ
  • If such a list already exists, the receiving agent SHOULD verify that the signing time in the incoming message is greater than the signing time stored in the list and that the signature is valid. If so, the receiving agent SHOULD update both the signing time and capabilities in the list. Values of the signing time that lie far in the future (that is, a greater discrepancy than any reasonable clock skew), or a capabilities list in messages whose signature could not be verified, MUST NOT be accepted. ๐Ÿšซ

The list of capabilities SHOULD be stored for future use in creating messages. ๐Ÿ’œ

Before sending a message, the sending agent MUST decide whether it is willing to use weak encryption for the particular data in the message. If the sending agent decides that weak encryption is unacceptable for this data, then the sending agent MUST NOT use a weak algorithm such as RC2/40. The decision to use or not use weak encryption overrides any other decision in this section about which encryption algorithm to use. โš ๏ธ

Sections 2.7.2.1 through 2.7.2.4 describe the decisions a sending agent SHOULD use in deciding which type of encryption will be applied to a message. These rules are ordered, so the sending agent SHOULD make its decision in the order given. ๐Ÿ“‹

2.7.1.1. Rule 1: Known Capabilities ๐ŸŒˆ

If the sending agent has received a set of capabilities from the recipient for the message the agent is about to encrypt, then the sending agent SHOULD use that information by selecting the first capability in the list (that is, the capability most preferred by the intended recipient) that the sending agent knows how to encrypt. The sending agent SHOULD use one of the capabilities in the list if the agent reasonably expects the recipient to be able to decrypt the message. ๐Ÿฅฐ

2.7.1.2. Rule 2: Unknown Capabilities, Unknown Version of S/MIME ๐Ÿคทโ€โ™€๏ธ

If the following two conditions are met:

  • the sending agent has no knowledge of the encryption capabilities of the recipient,
  • and the sending agent has no knowledge of the version of S/MIME of the recipient,

then the sending agent SHOULD use tripleDES because it is a stronger algorithm and is required by S/MIME v3. If the sending agent chooses not to use tripleDES in this step, it SHOULD use RC2/40. ๐Ÿ›ก๏ธ

2.7.2. Choosing Weak Encryption ๐Ÿฃ

Like all algorithms that use 40 bit keys, RC2/40 is considered by many to be weak encryption. A sending agent that is controlled by a human SHOULD allow a human sender to determine the risks of sending data using RC2/40 or a similarly weak encryption algorithm before sending the data, and possibly allow the human to use a stronger encryption method such as tripleDES. ๐Ÿ™‹โ€โ™€๏ธ

2.7.3. Multiple Recipients ๐Ÿ‘ฏโ€โ™€๏ธ

If a sending agent is composing an encrypted message to a group of recipients where the encryption capabilities of some of the recipients do not overlap, the sending agent is forced to send more than one message. Please note that if the sending agent chooses to send a message encrypted with a strong algorithm, and then send the same message encrypted with a weak algorithm, someone watching the communications channel could learn the contents of the strongly-encrypted message simply by decrypting the weakly-encrypted message. ๐Ÿ‘€

3. Creating S/MIME Messages ๐Ÿ’–

This section describes the S/MIME message formats and how they are created. S/MIME messages are a combination of MIME bodies and CMS content types. Several MIME types as well as several CMS content types are used. The data to be secured is always a canonical MIME entity. The MIME entity and other data, such as certificates and algorithm identifiers, are given to CMS processing facilities which produce a CMS object. Finally, the CMS object is wrapped in MIME. The Enhanced Security Services for S/MIME [ESS] document provides descriptions of how nested, secured S/MIME messages are formatted. ESS provides a description of how a triple-wrapped S/MIME message is formatted using multipart/signed and application/pkcs7-mime for the signatures. โœจ

S/MIME provides one format for enveloped-only data, several formats for signed-only data, and several formats for signed and enveloped data. Several formats are required to accommodate several environments, in particular for signed messages. The criteria for choosing among these formats are also described. ๐ŸŽ

The reader of this section is expected to understand MIME as described in [MIME-SPEC] and [MIME-SECURE]. ๐Ÿ“š

3.1. Preparing the MIME Entity for Signing, Enveloping or Compressing ๐ŸŒท

S/MIME is used to secure MIME entities. A MIME entity can be a sub-part, sub-parts of a message, or the whole message with all its sub-parts. A MIME entity that is the whole message includes only the MIME headers and MIME body, and does not include the RFC-822 headers. Note that S/MIME can also be used to secure MIME entities used in applications other than Internet mail. If protection of the RFC-822 headers is required, the use of the message/rfc822 MIME type is explained later in this section. ๐Ÿ“

The MIME entity that is secured and described in this section can be thought of as the "inside" MIME entity. That is, it is the "innermost" object in what is possibly a larger MIME message. Processing "outside" MIME entities into CMS content types is described in Section 3.2, 3.4, and elsewhere. ๐Ÿงš

The procedure for preparing a MIME entity is given in [MIME-SPEC]. The same procedure is used here with some additional restrictions when signing. Description of the procedures from [MIME-SPEC] are repeated here, but it is suggested that the reader refer to that document for the exact procedure. This section also describes additional requirements. ๐Ÿซถ

A single procedure is used for creating MIME entities that are to have any combination of signing, enveloping, and compressing applied. Some additional steps are recommended to defend against known corruptions that can occur during mail transport that are of particular importance for clear-signing using the multipart/signed format. It is recommended that these additional steps be performed on enveloped messages, or signed and enveloped messages, so that the message can be forwarded to any environment without modification. ๐Ÿ“ฎ

These steps are descriptive rather than prescriptive. The implementer is free to use any procedure as long as the result is the same. ๐Ÿฆ„

Step 1. The MIME entity is prepared according to the local conventions.

Step 2. The leaf parts of the MIME entity are converted to canonical form.

Step 3. Appropriate transfer encoding is applied to the leaves of the MIME entity.

When an S/MIME message is received, the security services on the message are processed, and the result is the MIME entity. That MIME entity is typically passed to a MIME-capable user agent where, it is further decoded and presented to the user or receiving application. ๐Ÿ“ฌ

In order to protect outer, non-content related message headers (for instance, the Subject, To, From and CC fields), the sending client MAY wrap a full MIME message in a message/rfc822 wrapper in order to apply S/MIME security services to these headers. It is up to the receiving client to decide how to present these "inner" headers along with the unprotected "outer" headers. ๐Ÿ•ต๏ธโ€โ™€๏ธ

When an S/MIME message is received, if the top-level protected MIME entity has a Content-Type of message/rfc822, it can be assumed that the intent was to provide header protection. This entity SHOULD be presented as the top-level message, taking into account header merging issues as previously discussed. ๐ŸŽ€๐Ÿ’…

3.1.1. Canonicalization โœจ

Okay so, each MIME entity MUST be converted to a canonical form ๐Ÿ’– that is uniquely and unambiguously representable in the environment where the signature is created AND the environment where it gets verified. MIME entities MUST be canonicalized for enveloping and compressing too, not just signing ๐ŸŽ€

The exact details of canonicalization depend on the actual MIME type and subtype of an entity, and they aren't described here ๐Ÿซถ Instead, the standard for that particular MIME type SHOULD be consulted ๐Ÿ“š. For example, canonicalizing text/plain is different from canonicalizing audio/basic ๐ŸŽง. Outside of text types, most types have only one representation no matter the computing platform or environment, and that can be considered their canonical representation ๐Ÿ’…. In general, canonicalization gets done by the non-security part of the sending agent, not the S/MIME implementation ๐Ÿงš.

The most common and important canonicalization is for text, which is often represented differently across environments ๐Ÿ˜ญ. MIME entities of major type "text" MUST have both their line endings and character set canonicalized ๐Ÿ’…. The line ending MUST be the pair of characters <CR><LF>, and the charset SHOULD be a registered charset [CHARSETS]. The details of the canonicalization are specified in [MIME-SPEC]. The chosen charset SHOULD be named in the charset parameter so the receiving agent can unambiguously figure out which charset was used ๐Ÿฆ‹.

Note that some charsets, such as ISO-2022, have multiple representations for the same characters ๐Ÿคฏ. When preparing that kind of text for signing, the canonical representation specified for the charset MUST be used ๐Ÿ”ฅ.

3.1.2. Transfer Encoding ๐ŸŒธ

When generating any of the secured MIME entities below, except for signing with the multipart/signed format, no transfer encoding is required at all ๐Ÿ™Œ. S/MIME implementations MUST be able to deal with binary MIME objects. If there's no Content-Transfer-Encoding header, the transfer encoding is presumed to be 7BIT ๐Ÿ“.

S/MIME implementations SHOULD however use the transfer encoding described in section 3.1.3 for all MIME entities they secure. The reason for only securing 7-bit MIME entities, even for enveloped data that never touches the transport, is that it lets the MIME entity be handled in any environment without changing it ๐Ÿง. For example, a trusted gateway might remove the envelope, but not the signature, of a message, then forward the signed message to the end recipient so they can verify the signatures directly. If the transport inside the site isn't 8-bit clean (like a wide-area network with a single mail gateway), verifying the signature won't be possible unless the original MIME entity was only 7-bit data ๐Ÿ’€.

S/MIME implementations which "know" that all intended recipient(s) can handle inner (everything except the outermost) binary MIME objects SHOULD use binary encoding instead of a 7-bit-safe transfer encoding for the inner entities. A 7-bit-safe encoding (such as base64) would unnecessarily expand the message size ๐Ÿ“ฆ. Implementations MAY "know" that recipient implementations can handle inner binary MIME entities by interpreting the id-cap-preferBinaryInside sMIMECapabilities attribute, by prior agreement, or by other means ๐Ÿค.

If one or more intended recipients can't handle inner binary MIME objects, or if this capability is unknown for any of the intended recipients, S/MIME implementations SHOULD use the transfer encoding described in section 3.1.3 for all MIME entities they secure ๐Ÿ›ก๏ธ.

3.1.3. Transfer Encoding for Signing Using multipart/signed ๐ŸŽ€

If a multipart/signed entity is ever going to be transmitted over the standard Internet SMTP infrastructure, or any other transport constrained to 7-bit text, it MUST have transfer encoding applied so that it's represented as 7-bit text. MIME entities that are already 7-bit data need no transfer encoding. Entities such as 8-bit text and binary data can be encoded with quoted-printable or base-64 transfer encoding ๐ŸŒˆ.

The main reason for the 7-bit requirement is that the Internet mail transport infrastructure can't guarantee transport of 8-bit or binary data. Lots of parts of the transport infrastructure handle 8-bit and even binary data now, but it's sometimes impossible to know whether the transport path is 8-bit clean. If a mail message with 8-bit data hits a message transfer agent that can't transmit 8-bit or binary data, the agent has three options, and none of them are acceptable for a clear-signed message ๐Ÿ˜ฑ:

  • The agent could change the transfer encoding; this would invalidate the signature.
  • The agent could transmit the data anyway, which would most likely result in the 8th bit being corrupted; this too would invalidate the signature.
  • The agent could return the message to the sender.

[MIME-SECURE] prohibits an agent from changing the transfer encoding of the first part of a multipart/signed message. If a compliant agent that can't transmit 8-bit or binary data runs into a multipart/signed message with 8-bit or binary data in the first part, it would have to return the message to the sender as undeliverable ๐Ÿ“ญ.

3.1.4. Sample Canonical MIME Entity ๐Ÿงš

This example shows a multipart/mixed message with full transfer encoding. The message contains a text part and an attachment. The sample message text includes characters that aren't US-ASCII, so they need to be transfer encoded ๐ŸŒท. Even though it isn't shown here, the end of each line is <CR><LF>. The line ending of the MIME headers, the text, and the transfer encoded parts, all MUST be <CR><LF> ๐Ÿ’œ.

Note that this example is not of an S/MIME message.

Content-Type: multipart/mixed; boundary=bar

--bar
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: quoted-printable

=A1Hola Michael!

How do you like the new S/MIME specification?

It's generally a good idea to encode lines that begin with
From=20because some mail transport agents will insert a greater-
than (>) sign, thus invalidating the signature.

Also, in some cases it might be desirable to encode any   =20
trailing whitespace that occurs on lines in order to ensure  =20
that the message signature is not invalidated when passing =20
a gateway that modifies such whitespace (like BITNET). =20

--bar
Content-Type: image/jpeg
Content-Transfer-Encoding: base64

iQCVAwUBMJrRF2N9oWBghPDJAQE9UQQAtl7LuRVndBjrk4EqYBIb3h5QXIX/LC//
jJV5bNvkZIGPIcEmI5iFd9boEgvpirHtIREEqLQRkYNoBActFBZmh9GC3C041WGq
uMbrbxc+nIs1TIKlA08rVi9ig/2Yh7LFrK5Ein57U/W72vgSxLhe/zhdfolT9Brn
HOxEa44b+EI=

--bar--

3.2. The application/pkcs7-mime Type ๐ŸŽ

The application/pkcs7-mime type is used to carry CMS content types, including EnvelopedData, SignedData, and CompressedData. The details of constructing these entities are described in later sections. This section covers the general characteristics of the application/pkcs7-mime type ๐Ÿ’œ.

The carried CMS object always contains a MIME entity prepared as described in section 3.1 if the eContentType is id-data. Other contents MAY be carried when the eContentType contains different values. See [ESS] for an example of this with signed receipts ๐Ÿงพ.

Since CMS content types are binary data, in most cases base-64 transfer encoding is appropriate, especially when used with SMTP transport. The transfer encoding used depends on the transport the object is sent through, and it isn't a characteristic of the MIME type ๐Ÿฆ‹.

Note that this discussion is about the transfer encoding of the CMS object, the "outside" MIME entity. It's completely separate from, and unrelated to, the transfer encoding of the MIME entity secured by the CMS object, the "inside" object, which is described in section 3.1 โœจ.

Because there are several types of application/pkcs7-mime objects, a sending agent SHOULD do as much as it can to help a receiving agent know what's in the object, without forcing the receiving agent to decode the ASN.1 for the object ๐Ÿ•ต๏ธโ€โ™€๏ธ. The MIME headers of all application/pkcs7-mime objects SHOULD include the optional "smime-type" parameter, as described in the following sections.

3.2.1. The name and filename Parameters ๐ŸŽ€

For application/pkcs7-mime, sending agents SHOULD emit the optional "name" parameter in the Content-Type field for compatibility with older systems. Sending agents SHOULD also emit the optional Content-Disposition field [CONTDISP] with the "filename" parameter. If a sending agent emits the above parameters, the value of those parameters SHOULD be a file name with the appropriate extension ๐Ÿ“:

MIME Type                                            File Extension

application/pkcs7-mime (SignedData, EnvelopedData)      .p7m

application/pkcs7-mime (degenerate SignedData           .p7c
  certificate management message)

application/pkcs7-mime (CompressedData)                 .p7z

application/pkcs7-signature (SignedData)                .p7s

In addition, the file name SHOULD be limited to eight characters followed by a three-letter extension. The eight-character filename base can be any distinct name, but using the filename base "smime" SHOULD be used to show that the MIME entity is associated with S/MIME ๐ŸŒˆ.

Including a file name does two jobs. It makes S/MIME objects easier to use as files on disk, and it can carry type information across gateways ๐Ÿงš. When a MIME entity of type application/pkcs7-mime (for example) arrives at a gateway with no special knowledge of S/MIME, it defaults the entity's MIME type to application/octet-stream and treats it as a generic attachment, so the type information gets lost ๐Ÿ˜ญ. But the suggested filename for an attachment often survives the trip across a gateway. That often lets the receiving systems figure out which app to hand the attachment to, in this case a stand-alone S/MIME processing application ๐Ÿ’…. This mechanism is a convenience for implementations in certain environments, not the main event. A proper S/MIME implementation MUST use the MIME types and MUST NOT rely on the file extensions ๐Ÿ™…โ€โ™€๏ธ.

3.2.2. The smime-type parameter โœจ

The application/pkcs7-mime content type has an optional "smime-type" parameter, and it's the best hint ๐Ÿ’ก about what happened to a message. It tells you whether the content was signed or enveloped, plus a bit about what's inside. This spec defines these smime-types:

Name                   CMS type                Inner Content

enveloped-data         EnvelopedData           id-data

signed-data            SignedData              id-data

certs-only             SignedData              none

compressed-data        CompressedData          id-data

If you're making up a new smime-type later, these guidelines SHOULD be followed so everything stays consistent with future specs ๐ŸŽ€:

  1. If both signing and encryption can be applied to the content, then two values for smime-type SHOULD be assigned "signed-" and "encrypted-". If only one operation can be assigned, that prefix can be left out. So since "certs-only" can only be signed, "signed-" gets dropped.
  2. A common string for a content OID SHOULD be assigned. We use "data" for the id-data content OID when MIME is the inner content.
  3. If no common string is assigned, then the common string of "OID.<oid>" is recommended. For example, "OID.1.3.6.1.5.5.7.6.1" would be DES40.

The whole point is that a mail client can tell if a message is "signed" or "encrypted" without tunneling into the CMS payload ๐Ÿ”โœจ


3.3. Creating an Enveloped-only Message ๐Ÿฆ‹

This section walks you through enveloping a MIME entity without signing it. Here's the tea โ˜•: enveloped-but-not-signed messages do not give you data integrity.

โš ๏ธ Bestie, read this part twice: someone could swap out the ciphertext so the message still processes fine, but what it means could be totally altered ๐Ÿ˜ญ

Step 1. The MIME entity to be enveloped is prepared according to section 3.1.

Step 2. The MIME entity and other required data get processed into a CMS object of type EnvelopedData. On top of encrypting a copy of the content-encryption key for each recipient, a copy of the content-encryption key SHOULD be encrypted for the originator and included in the EnvelopedData (see [CMS] Section 6) ๐Ÿ”

Step 3. The EnvelopedData object gets wrapped in a CMS ContentInfo object.

Step 4. The ContentInfo object gets inserted into an application/pkcs7-mime MIME entity.

For enveloped-only messages, the smime-type parameter is "enveloped-data", and the file extension is ".p7m" ๐Ÿ’Œ

A sample message would be:

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

    rfvbnj756tbBghyHhHUujhJhjH77n8HHGT9HG4VQpfyF467GhIGfHfYT6
    7n8HHGghyHhHUujhJh4VQpfyF467GhIGfHfYGTrfvbnjT6jH7756tbB9H
    f8HHGTrfvhJhjH776tbB9HG4VQbnj7567GhIGfHfYT6ghyHhHUujpfyF4
    0GhIGfHfQbnj756YT64V

3.4. Creating a Signed-only Message ๐ŸŒธ

There are two formats for signed messages in S/MIME: application/pkcs7-mime with SignedData, and multipart/signed. The multipart/signed form is generally the preferred one for sending, but receiving agents MUST be able to handle both ๐Ÿ’…

3.4.1. Choosing a Format for Signed-only Messages

There's no hard-and-fast rule for picking a signed-only format ๐Ÿคทโ€โ™€๏ธ It depends on the capabilities of every receiver, and on how much it matters that S/MIME-capable receivers can verify the signature versus how much it matters that receivers without S/MIME software can read the message at all.

Messages signed with the multipart/signed format can always be viewed by the receiver, whether or not they have S/MIME software. They can also be viewed by a MIME-native user agent or by someone whose messages got translated through a gateway. In this context, "be viewed" means the ability to process the message essentially as if it weren't signed at all, including any other MIME structure the message might have ๐Ÿ‘€

Messages signed with the SignedData format can't be viewed by a recipient unless they have S/MIME facilities. The upside is that SignedData protects the message content from being changed by benign intermediate agents. Those agents might do line wrapping or content-transfer encoding changes, which would break the signature ๐Ÿฅบ

3.4.2. Signing Using application/pkcs7-mime with SignedData

This signing format uses the application/pkcs7-mime MIME type. Here are the steps:

Step 1. The MIME entity is prepared according to section 3.1.

Step 2. The MIME entity and other required data get processed into a CMS object of type SignedData.

Step 3. The SignedData object gets wrapped in a CMS ContentInfo object.

Step 4. The ContentInfo object gets inserted into an application/pkcs7-mime MIME entity.

For messages using application/pkcs7-mime with SignedData, the smime-type parameter is "signed-data", and the file extension is ".p7m" ๐ŸŽ€

A sample message would be:

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

    567GhIGfHfYT6ghyHhHUujpfyF4f8HHGTrfvhJhjH776tbB9HG4VQbnj7
    77n8HHGT9HG4VQpfyF467GhIGfHfYT6rfvbnj756tbBghyHhHUujhJhjH
    HUujhJh4VQpfyF467GhIGfHfYGTrfvbnjT6jH7756tbB9H7n8HHGghyHh
    6YT64V0GhIGfHfQbnj75

3.4.3. Signing Using the multipart/signed Format ๐Ÿง

This is a clear-signing format, so recipients with zero S/MIME or CMS processing facilities can still read the message ๐Ÿ“– It uses the multipart/signed MIME type described in [MIME-SECURE]. The multipart/signed MIME type has two parts. The first part holds the MIME entity that gets signed. The second part holds the "detached signature" CMS SignedData object, and in that object the encapContentInfo eContent field is absent.

3.4.3.1. The application/pkcs7-signature MIME Type

This MIME type always contains a CMS ContentInfo wrapping a single CMS object of type SignedData. The SignedData encapContentInfo eContent field MUST be absent. The signerInfos field holds the signatures for the MIME entity.

For signed-only messages using application/pkcs7-signature, the file extension is ".p7s" ๐Ÿ“Ž

3.4.3.2. Creating a multipart/signed Message

Step 1. The MIME entity to be signed is prepared according to section 3.1, with extra special care for clear-signing ๐Ÿ’–

Step 2. The MIME entity gets presented to CMS processing so you end up with a SignedData object where the encapContentInfo eContent field is absent.

Step 3. The MIME entity gets inserted into the first part of a multipart/signed message, with no processing beyond what section 3.1 describes.

Step 4. Transfer encoding is applied to the "detached signature" CMS SignedData object, and it gets inserted into a MIME entity of type application/pkcs7-signature.

Step 5. The application/pkcs7-signature MIME entity gets inserted into the second part of the multipart/signed entity.

The multipart/signed Content type has two required parameters: the protocol parameter and the micalg parameter ๐Ÿ“‹

The protocol parameter MUST be "application/pkcs7-signature". Quotation marks are required around it, because MIME requires that the "/" character in the parameter value MUST be quoted. Yes, MUST shows up twice, and yes, it's serious ๐Ÿ˜ค

The micalg parameter allows for one-pass processing when the signature is being verified. Its value depends on the message digest algorithm(s) used in the calculation of the Message Integrity Check. If multiple message digest algorithms are used, they MUST be separated by commas per [MIME-SECURE]. The values to put in the micalg parameter SHOULD come from the following:

Algorithm   Value
used

MD5         md5
SHA-1       sha1
SHA-256     sha256
SHA-384     sha384
SHA-512     sha512
Any other   (defined separately in algorithm profile or "unknown"
             if not defined)

(Historical note: some early S/MIME implementations emitted and expected "rsa-md5" and "rsa-sha1" for the micalg parameter ๐Ÿ•ฐ๏ธ)

Receiving agents SHOULD be able to recover gracefully from a micalg parameter value they don't recognize ๐Ÿซถ

The SHA-256, SHA-384, and SHA-512 algorithms [FIPS180-2] are not currently recommended in S/MIME, but they're included here for completeness ๐Ÿค“

3.4.3.3. Sample multipart/signed Message

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

    --boundary42
    Content-Type: text/plain

    This is a clear-signed message.

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

    ghyHhHUujhJhjH77n8HHGTrfvbnj756tbB9HG4VQpfyF467GhIGfHfYT6
    4VQpfyF467GhIGfHfYT6jH77n8HHGghyHhHUujhJh756tbB9HGTrfvbnj
    n8HHGTrfvhJhjH776tbB9HG4VQbnj7567GhIGfHfYT6ghyHhHUujpfyF4
    7GhIGfHfYT64VQbnj756

    --boundary42--

The content that gets digested (the first part of the multipart/signed) is these bytes ๐Ÿ”ข

43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20 74 65 78 74 2f 70 6c 61 69
6e 0d 0a 0d 0a 54 68 69 73 20 69 73 20 61 20 63 6c 65 61 72 2d 73 69
67 6e 65 64 20 6d 65 73 73 61 67 65 2e 0d 0a

3.5. Creating an Compressed-only Message ๐Ÿ’œ

This section describes how to compress a MIME entity. Heads up: versions of S/MIME before 3.1 never specified any use of CompressedData, so they won't recognize it. The capability for indicating that you can receive CompressedData is described in [CMSCOMPR], and that's the preferred method for compatibility ๐ŸŒˆ

Step 1. The MIME entity to be compressed is prepared according to section 3.1.

Step 2. The MIME entity and other required data get processed into a CMS object of type CompressedData.

Step 3. The CompressedData object gets wrapped in a CMS ContentInfo object.

Step 4. The ContentInfo object gets inserted into an application/pkcs7-mime MIME entity.

For compressed-only messages, the smime-type parameter is "compressed-data", and the file extension is ".p7z" ๐Ÿ—œ๏ธโœจ

A sample message would be:

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

    rfvbnj756tbBghyHhHUujhJhjH77n8HHGT9HG4VQpfyF467GhIGfHfYT6
    7n8HHGghyHhHUujhJh4VQpfyF467GhIGfHfYGTrfvbnjT6jH7756tbB9H
    f8HHGTrfvhJhjH776tbB9HG4VQbnj7567GhIGfHfYT6ghyHhHUujpfyF4
    0GhIGfHfQbnj756YT64V

3.6. Multiple Operations ๐Ÿช†

okay so the signed-only, encrypted-only, and compressed-only formats can be nested bc they're ALL MIME entities that wrap other MIME entities. bestie-inside-bestie-inside-bestie energy ๐Ÿ’–

An S/MIME implementation MUST be able to receive and process arbitrarily nested S/MIME within reasonable resource limits of the recipient computer. ๐Ÿซถ

You can apply the signing, encrypting, and compressing operations in any order you like ๐Ÿ’…. It's up to the implementer and the user to choose. When you sign first, the signatories get securely hidden by the envelope ๐Ÿ™ˆ. When you envelope first, the signatories are exposed, BUT you can still verify the signatures without peeling off the envelope. that's lowkey useful in setups where automatic signature verification is wanted, bc no private key material is needed to verify a signature ๐Ÿ”‘.

there are security ramifications to whether you sign first or encrypt first ๐Ÿ‘€. if a recipient gets a message that's encrypted and then signed, they can check that the encrypted block wasn't altered, but they can't figure out any relationship between the signer and the unencrypted contents. if a recipient gets a message that's signed-then-encrypted, they can assume the signed message itself hasn't been messed with, but a careful attacker could have changed the unauthenticated parts of the encrypted message ๐Ÿ˜ฌ.

when you're using compression, keep these vibes in mind ๐Ÿ“:

  • compressing binary encoded encrypted data is discouraged, bc it won't yield much compression. base64 encrypted data could totally benefit tho โœจ
  • if a lossy compression algorithm is used with signing, you'll need to compress FIRST, then sign ๐Ÿ”ฅ

3.7. Creating a Certificate Management Message ๐ŸŽ€

the certificate management message (or MIME entity) is used to transport certificates and/or certificate revocation lists, like when you're responding to a registration request ๐Ÿ“œ.

Step 1. the certificates and/or certificate revocation lists get handed to the CMS generating process, which creates a CMS object of type SignedData. the SignedData encapContentInfo eContent field MUST be absent and the signerInfos field MUST be empty ๐Ÿ™…โ€โ™€๏ธ.

Step 2. the SignedData object gets wrapped in a CMS ContentInfo object ๐ŸŽ.

Step 3. the ContentInfo object gets enclosed in an application/pkcs7-mime MIME entity ๐Ÿ’Œ.

the smime-type parameter for a certificate management message is certs-only ๐Ÿ’…. the file extension for this type of message is .p7c ๐Ÿฆ‹.


3.8. Registration Requests ๐ŸŒธ

a sending agent that signs messages MUST have a certificate for the signature so that a receiving agent can verify the signature ๐Ÿชช. there are lots of ways to get certificates, like an exchange with a certificate authority, through a hardware token or diskette, and so on ๐Ÿ’พ.

S/MIME v2 [SMIMEV2] specified a method for "registering" public keys with certificate authorities using an application/pkcs10 body part. since then, the IETF PKIX Working Group has developed other ways to request certificates ๐Ÿงš. however, S/MIME v3.1 does not require a particular certificate request mechanism, so you do you ๐Ÿ’œ.


3.9. Identifying an S/MIME Message ๐Ÿ”

S/MIME works in non-MIME environments too, so it uses a few different ways to carry the type info, and that makes it kinda tricky to spot S/MIME messages ๐Ÿ˜ตโ€๐Ÿ’ซ. the table below lists the criteria for figuring out whether a message is an S/MIME message. a message counts as S/MIME if it matches ANY of the criteria listed below โœจ.

the file suffix in the table comes from the "name" parameter in the content-type header, or the "filename" parameter on the content-disposition header. the parameters that give the file suffix aren't listed below as part of the parameter section ๐Ÿ“Ž.

MIME type:   application/pkcs7-mime
parameters:  any
file suffix: any

MIME type:   multipart/signed
parameters:  protocol="application/pkcs7-signature"
file suffix: any

MIME type:   application/octet-stream
parameters:  any
file suffix: p7m, p7s, p7c, p7z

4. Certificate Processing ๐Ÿชช

a receiving agent MUST provide some certificate retrieval mechanism so it can get access to certificates for recipients of digital envelopes ๐Ÿ“ฌ. this spec doesn't cover how S/MIME agents handle certificates, only what they do AFTER a certificate has been validated or rejected. S/MIME certificate issues are covered in [CERT31] ๐Ÿ“–.

at a minimum, for initial S/MIME deployment, a user agent could automatically generate a message to an intended recipient asking for that recipient's certificate in a signed return message ๐Ÿ’Œ. receiving and sending agents SHOULD also provide a mechanism that lets a user "store and protect" certificates for correspondents, in a way that guarantees they can be retrieved later ๐Ÿซถ.

4.1. Key Pair Generation ๐Ÿ”

all generated key pairs MUST be generated from a good source of non-deterministic random input [RANDOM], and the private key MUST be protected in a secure fashion ๐Ÿ”’.

if an S/MIME agent needs to generate an RSA key pair, then the S/MIME agent or some related administrative utility or function SHOULD generate RSA key pairs using the following guidelines ๐Ÿงฎ. a user agent SHOULD generate RSA key pairs at a minimum key size of 768 bits. a user agent MUST NOT generate RSA key pairs less than 512 bits long ๐Ÿšซ. creating keys longer than 1024 bits can cause some older S/MIME receiving agents to not be able to verify signatures, BUT it gives better security and is therefore valuable ๐Ÿ’ช. a receiving agent SHOULD be able to verify signatures with keys of any size over 512 bits.

some agents created in the United States have chosen to create 512 bit keys to get more advantageous export licenses. however, 512 bit keys are considered by many to be cryptographically insecure ๐Ÿ’€. implementers SHOULD be aware that multiple (active) key pairs can be associated with a single individual ๐Ÿ‘ฏ. for example, one key pair can support confidentiality, while a different key pair is used for authentication ๐Ÿ”‘.


5. Security Considerations ๐Ÿ’€

okay this section is SERIOUS, bestie, so read it all ๐Ÿซฃ.

40-bit encryption is considered weak by most cryptographers ๐Ÿ™…โ€โ™€๏ธ. using weak cryptography in S/MIME offers little actual security over sending plaintext. HOWEVER, other features of S/MIME, like the specification of tripleDES and the ability to announce stronger cryptographic capabilities to the parties you talk to, let senders create messages that use strong encryption ๐Ÿ’ช. using weak cryptography is never recommended unless the only alternative is no cryptography at all. when it's feasible, sending and receiving agents SHOULD inform senders and recipients of the relative cryptographic strength of messages ๐Ÿ”ฅ.

it's impossible for most software or people to estimate the value of a message ๐Ÿคทโ€โ™€๏ธ. it's also impossible for most software or people to estimate the actual cost of decrypting a message encrypted with a key of a particular size. and it's quite difficult to determine the cost of a failed decryption if a recipient can't decode a message. so choosing between different key sizes (or choosing whether to just use plaintext) is also impossible ๐Ÿ˜ญ. BUT decisions based on these criteria get made all the time, so this specification gives a framework for using those estimates when choosing algorithms ๐Ÿง .

if a sending agent is sending the same message using different strengths of cryptography, an attacker watching the communications channel might be able to figure out the contents of the strongly-encrypted message by decrypting the weakly-encrypted version ๐Ÿ‘€. in other words, a sender SHOULD NOT send a copy of a message using weaker cryptography than they'd use for the original โœ‹.

modification of the ciphertext can go undetected if authentication isn't also used, which is the case when sending EnvelopedData without wrapping it in SignedData or enclosing SignedData within it ๐Ÿšจ.

see RFC 3218 [MMA] for more info about thwarting the adaptive chosen ciphertext vulnerability in PKCS #1 Version 1.5 implementations ๐Ÿง.

in some circumstances, the use of the Diffie-Hellman key agreement scheme in a prime order subgroup of a large prime p is vulnerable to certain attacks known as "small-subgroup" attacks ๐Ÿ˜ฑ. methods exist, however, to prevent these attacks. these methods are described in RFC 2785 [DHSUB] ๐Ÿ›ก๏ธ.


A. ASN.1 Module ๐Ÿงฉ

SecureMimeMessageV3dot1
  { iso(1) member-body(2) us(840) rsadsi(113549)
         pkcs(1) pkcs-9(9) smime(16) modules(0) msg-v3dot1(21) }

DEFINITIONS IMPLICIT TAGS ::=
BEGIN

IMPORTS
-- Cryptographic Message Syntax
    SubjectKeyIdentifier, IssuerAndSerialNumber,
    RecipientKeyIdentifier
        FROM    CryptographicMessageSyntax
               { iso(1) member-body(2) us(840) rsadsi(113549)
                 pkcs(1) pkcs-9(9) smime(16) modules(0) cms-2001(14) };


--  id-aa is the arc with all new authenticated and unauthenticated
--  attributes produced the by S/MIME Working Group

id-aa OBJECT IDENTIFIER ::= {iso(1) member-body(2) usa(840)
        rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) attributes(2)}

-- S/MIME Capabilities provides a method of broadcasting the symmetric
-- capabilities understood.  Algorithms SHOULD be ordered by
-- preference and grouped by type

smimeCapabilities OBJECT IDENTIFIER ::=
   {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9) 15}

SMIMECapability ::= SEQUENCE {
   capabilityID OBJECT IDENTIFIER,
   parameters ANY DEFINED BY capabilityID OPTIONAL }

SMIMECapabilities ::= SEQUENCE OF SMIMECapability

-- Encryption Key Preference provides a method of broadcasting the
-- preferred encryption certificate.

id-aa-encrypKeyPref OBJECT IDENTIFIER ::= {id-aa 11}

SMIMEEncryptionKeyPreference ::= CHOICE {
   issuerAndSerialNumber   [0] IssuerAndSerialNumber,
   receipentKeyId          [1] RecipientKeyIdentifier,
   subjectAltKeyIdentifier [2] SubjectKeyIdentifier
}
id-smime OBJECT IDENTIFIER ::= { iso(1) member-body(2)
   us(840) rsadsi(113549) pkcs(1) pkcs9(9) 16 }

id-cap  OBJECT IDENTIFIER ::= { id-smime 11 }

-- The preferBinaryInside indicates an ability to receive messages
-- with binary encoding inside the CMS wrapper

id-cap-preferBinaryInside  OBJECT IDENTIFIER ::= { id-cap 1 }

--  The following list the OIDs to be used with S/MIME V3

-- Signature Algorithms Not Found in [CMSALG]
--
-- md2WithRSAEncryption OBJECT IDENTIFIER ::=
--    {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-1(1)
--     2}
--
-- Other Signed Attributes
--
-- signingTime OBJECT IDENTIFIER ::=
--    {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9)
--     5}
--    See [CMS] for a description of how to encode the attribute
--    value.

SMIMECapabilitiesParametersForRC2CBC ::= INTEGER
--        (RC2 Key Length (number of bits))

END

B. References ๐Ÿ“š

B.1. Normative References ๐Ÿ’–

okay so these are the docs this spec literally can't work without, bestie ๐Ÿ“š

  • [CERT31] Ramsdell, B., Ed., "S/MIME Version 3.1 Certificate Handling", RFC 3850, July 2004.
  • [CHARSETS] Character sets assigned by IANA. See http://www.iana.org/assignments/character-sets
  • [CMS] Housley, R., "Cryptographic Message Syntax (CMS)", RFC 3852, July 2004.
  • [CMSAES] Schaad, J., "Use of the Advanced Encryption Standard (AES) Encryption Algorithm in Cryptographic Message Syntax (CMS)", RFC 3565, July 2003.
  • [CMSALG] Housley, R., "Cryptographic Message Syntax (CMS) Algorithms", RFC 3370, August 2002.
  • [CMSCOMPR] Gutmann, P., "Compressed Data Content Type for Cryptographic Message Syntax (CMS)", RFC 3274, June 2002.
  • [CONTDISP] Troost, R., Dorner, S., and K. Moore, "Communicating Presentation Information in Internet Messages: The Content-Disposition Header Field", RFC 2183, August 1997.
  • [ESS] Hoffman, P., "Enhanced Security Services for S/MIME", RFC 2634, June 1999.
  • [FIPS180-2] "Secure Hash Signature Standard (SHS)", National Institute of Standards and Technology (NIST). FIPS Publication 180-2.
  • [MIME-SPEC] This one's a whole bundle of five RFCs, so get comfy ๐Ÿงš
    • Freed, N. and N. Borenstein, "Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies", RFC 2045, November 1996.
    • Freed, N. and N. Borenstein, "Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types", RFC 2046, November 1996.
    • Moore, K., "MIME (Multipurpose Internet Mail Extensions) Part Three: Message Header Extensions for Non-ASCII Text", RFC 2047, November 1996.
    • Freed, N., Klensin, J., and J. Postel, "Multipurpose Internet Mail Extensions (MIME) Part Four: Registration Procedures", BCP 13, RFC 2048, November 1996.
    • Freed, N. and N. Borenstein, "Multipurpose Internet Mail Extensions (MIME) Part Five: Conformance Criteria and Examples", RFC 2049, November 1996.
  • [MIME-SECURE] Galvin, J., Murphy, S., Crocker, S., and N. Freed, "Security Multiparts for MIME: Multipart/Signed and Multipart/Encrypted", RFC 1847, October 1995.
  • [MUSTSHOULD] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
  • [X.208-88] CCITT. Recommendation X.208: Specification of Abstract Syntax Notation One (ASN.1). 1988.
  • [X.209-88] CCITT. Recommendation X.209: Specification of Basic Encoding Rules for Abstract Syntax Notation One (ASN.1). 1988.
  • [X.509-88] CCITT. Recommendation X.509: The Directory - Authentication Framework. 1988.

B.2. Informative References ๐ŸŒธ

these ones are the extra-helpful reading, not required to implement, but so worth a peek ๐Ÿ‘€

  • [DHSUB] Zuccherato, R., "Methods for Avoiding the "Small-Subgroup" Attacks on the Diffie-Hellman Key Agreement Method for S/MIME", RFC 2785, March 2000.
  • [MMA] Rescorla, E., "Preventing the Million Message Attack on Cryptographic Message Syntax", RFC 3218, January 2002.
  • [PKCS-7] Kaliski, B., "PKCS #7: Cryptographic Message Syntax Version 1.5", RFC 2315, March 1998.
  • [RANDOM] Eastlake 3rd, D., Crocker, S., and J. Schiller, "Randomness Recommendations for Security", RFC 1750, December 1994.
  • [SMIMEV2] Dusse, S., Hoffman, P., Ramsdell, B., Lundblade, L., and L. Repka, "S/MIME Version 2 Message Specification", RFC 2311, March 1998.

C. Acknowledgements โœจ

big thank-yous to the other authors of the S/MIME Version 2 Message Specification RFC: Steve Dusse, Paul Hoffman, Laurence Lundblade and Lisa Repka ๐Ÿซถ

a bunch of the S/MIME Working Group folks also worked super hard on this doc. Any list of people is doomed to leave someone out, and the author apologizes for that ๐Ÿ™ˆ In alphabetical order, these people stand out because they made direct contributions to this document:

  • Tony Capel
  • Piers Chivers
  • Dave Crocker
  • Bill Flanigan
  • Peter Gutmann
  • Paul Hoffman
  • Russ Housley
  • William Ottaway
  • John Pawling
  • Jim Schaad

D. Editor's Address ๐ŸŽ€

the editor who put it all together can be reached here:

Blake Ramsdell
Sendmail, Inc.
704 228th Ave NE #775
Sammamish, WA  98074

EMail: blake@sendmail.com

Copyright (C) The Internet Society (2004). This document is subject to the rights, licenses and restrictions contained in BCP 78, and except as set forth therein, the authors retain all their rights.

This document and the information contained herein are provided on an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

Intellectual Property ๐Ÿฆ‹

The IETF takes no position regarding the validity or scope of any Intellectual Property Rights or other rights that might be claimed to pertain to the implementation or use of the technology described in this document, or the extent to which any license under such rights might or might not be available. It also doesn't represent that it has made any independent effort to identify any such rights. Information on the procedures with respect to rights in RFC documents can be found in BCP 78 and BCP 79.

Copies of IPR disclosures made to the IETF Secretariat, any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementers or users of this specification can be obtained from the IETF on-line IPR repository at http://www.ietf.org/ipr.

The IETF invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights that may cover technology that may be required to implement this standard. Please address the information to the IETF at ietf-ipr@ietf.org.

Acknowledgement ๐ŸŒธ

Funding for the RFC Editor function is currently provided by the Internet Society. ๐Ÿ’œ

๐Ÿ“ฆ where this page comes from