RFC 8551

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

๐Ÿ“… published April 2019, from ietf

RFC 8551: S/MIME Version 4.0 Message Specification ๐Ÿ’Œ

okay bestie, here's the tea โ˜• This one is from April 2019, and it's a Standards Track doc, so it's an actual official Internet spec and not just a vibe. It was written by J. Schaad (August Cellars), B. Ramsdell (Brute Squad Labs, Inc.), S. Turner, and sn3rd. Its ISSN is 2070-1721. It obsoletes RFC 5751, which means the older spec is retired and this one takes over. Main character energy ๐Ÿ‘‘

Abstract โœจ

okay so this doc defines S/MIME version 4.0 ๐Ÿ’– S/MIME gives you one consistent way to send and receive secure MIME data. Digital signatures handle authentication, message integrity, and non-repudiation with proof of origin (so nobody can deny they sent it, iconic ๐Ÿ’…). Encryption keeps your data confidential ๐Ÿ”’ and compression can shrink the data size ๐Ÿ—œ๏ธ. This document obsoletes RFC 5751.

Status of This Memo โœจ

this is an Internet Standards Track document ๐Ÿฆ‹

it's a product of the Internet Engineering Task Force (IETF), and it represents the consensus of the IETF community. it got public review and was approved for publication by the Internet Engineering Steering Group (IESG). if you want more info on Internet Standards, check out Section 2 of RFC 7841 ๐ŸŽ€

for the current status of this doc, any errata, and how to give feedback, go to https://www.rfc-editor.org/info/rfc8551 ๐ŸŒธ

Copyright (c) 2019 IETF Trust and the persons identified as the document authors. All rights reserved. ๐Ÿ’œ

this document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) as they're in effect on the date of publication. please read these carefully, bestie, because they describe your rights and restrictions for this doc. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions, and they're provided without warranty as described in the Simplified BSD License ๐Ÿงš

this document may contain material from IETF Documents or IETF Contributions published or made publicly available before November 10, 2008. the people who control the copyright in some of that material may not have given the IETF Trust permission to allow modifications outside the IETF Standards Process. so unless you get an adequate license from those copyright holders, this document may not be modified outside the IETF Standards Process, and derivative works of it may not be created outside the IETF Standards Process. the only exceptions are formatting it for publication as an RFC or translating it into languages other than English ๐Ÿ™ˆ

Table of Contents ๐Ÿ—‚๏ธ

1.  Introduction  . . . . . . . . . . . . . . . . . . . . . . . .   5
  1.1.  Specification Overview  . . . . . . . . . . . . . . . . .   5
  1.2.  Definitions . . . . . . . . . . . . . . . . . . . . . . .   6
  1.3.  Conventions Used in This Document . . . . . . . . . . . .   7
  1.4.  Compatibility with Prior Practice of S/MIME . . . . . . .   8
  1.5.  Changes from S/MIME v3 to S/MIME v3.1 . . . . . . . . . .   9
  1.6.  Changes from S/MIME v3.1 to S/MIME v3.2 . . . . . . . . .   9
  1.7.  Changes for S/MIME v4.0 . . . . . . . . . . . . . . . . .  11
2.  CMS Options . . . . . . . . . . . . . . . . . . . . . . . . .  12
  2.1.  DigestAlgorithmIdentifier . . . . . . . . . . . . . . . .  12
  2.2.  SignatureAlgorithmIdentifier  . . . . . . . . . . . . . .  12
  2.3.  KeyEncryptionAlgorithmIdentifier  . . . . . . . . . . . .  13
  2.4.  General Syntax  . . . . . . . . . . . . . . . . . . . . .  13
    2.4.1.  Data Content Type . . . . . . . . . . . . . . . . . .  14
    2.4.2.  SignedData Content Type . . . . . . . . . . . . . . .  14
    2.4.3.  EnvelopedData Content Type  . . . . . . . . . . . . .  14
    2.4.4.  AuthEnvelopedData Content Type  . . . . . . . . . . .  14
    2.4.5.  CompressedData Content Type . . . . . . . . . . . . .  14
  2.5.  Attributes and the SignerInfo Type  . . . . . . . . . . .  15
    2.5.1.  Signing Time Attribute  . . . . . . . . . . . . . . .  15
    2.5.2.  SMIMECapabilities Attribute . . . . . . . . . . . . .  16
    2.5.3.  Encryption Key Preference Attribute . . . . . . . . .  17
  2.6.  SignerIdentifier SignerInfo Type  . . . . . . . . . . . .  19
  2.7.  ContentEncryptionAlgorithmIdentifier  . . . . . . . . . .  19
    2.7.1.  Deciding Which Encryption Method to Use . . . . . . .  19
    2.7.2.  Choosing Weak Encryption  . . . . . . . . . . . . . .  21
    2.7.3.  Multiple Recipients . . . . . . . . . . . . . . . . .  21
3.  Creating S/MIME Messages  . . . . . . . . . . . . . . . . . .  21
  3.1.  Preparing the MIME Entity for Signing, Enveloping, or
        Compressing . . . . . . . . . . . . . . . . . . . . . . .  22
    3.1.1.  Canonicalization  . . . . . . . . . . . . . . . . . .  23
    3.1.2.  Transfer Encoding . . . . . . . . . . . . . . . . . .  24
    3.1.3.  Transfer Encoding for Signing Using multipart/signed   25
    3.1.4.  Sample Canonical MIME Entity  . . . . . . . . . . . .  25
  3.2.  The application/pkcs7-mime Media Type . . . . . . . . . .  26
    3.2.1.  The name and filename Parameters  . . . . . . . . . .  27
    3.2.2.  The smime-type Parameter  . . . . . . . . . . . . . .  28
  3.3.  Creating an Enveloped-Only Message  . . . . . . . . . . .  29
  3.4.  Creating an Authenticated Enveloped-Only Message  . . . .  30
  3.5.  Creating a Signed-Only Message  . . . . . . . . . . . . .  31
    3.5.1.  Choosing a Format for Signed-Only Messages  . . . . .  32
    3.5.2.  Signing Using application/pkcs7-mime with SignedData   32
    3.5.3.  Signing Using the multipart/signed Format . . . . . .  33
  3.6.  Creating a Compressed-Only Message  . . . . . . . . . . .  36
  3.7.  Multiple Operations . . . . . . . . . . . . . . . . . . .  37
  3.8.  Creating a Certificate Management Message . . . . . . . .  38
  3.9.  Registration Requests . . . . . . . . . . . . . . . . . .  38
  3.10. Identifying an S/MIME Message . . . . . . . . . . . . . .  39
4.  Certificate Processing  . . . . . . . . . . . . . . . . . . .  39
  4.1.  Key Pair Generation . . . . . . . . . . . . . . . . . . .  40
  4.2.  Signature Generation  . . . . . . . . . . . . . . . . . .  40
  4.3.  Signature Verification  . . . . . . . . . . . . . . . . .  40
  4.4.  Encryption  . . . . . . . . . . . . . . . . . . . . . . .  41
  4.5.  Decryption  . . . . . . . . . . . . . . . . . . . . . . .  41
5.  IANA Considerations . . . . . . . . . . . . . . . . . . . . .  41
  5.1.  Media Type for application/pkcs7-mime . . . . . . . . . .  42
  5.2.  Media Type for application/pkcs7-signature  . . . . . . .  43
  5.3.  authEnveloped-data smime-type . . . . . . . . . . . . . .  44
  5.4.  Reference Updates . . . . . . . . . . . . . . . . . . . .  44
6.  Security Considerations . . . . . . . . . . . . . . . . . . .  44
7.  References  . . . . . . . . . . . . . . . . . . . . . . . . .  48
  7.1.  Reference Conventions . . . . . . . . . . . . . . . . . .  48
  7.2.  Normative References  . . . . . . . . . . . . . . . . . .  49
  7.3.  Informative References  . . . . . . . . . . . . . . . . .  52
Appendix A.  ASN.1 Module . . . . . . . . . . . . . . . . . . . .  57
Appendix B.  Historic Mail Considerations . . . . . . . . . . . .  59
  B.1.  DigestAlgorithmIdentifier . . . . . . . . . . . . . . . .  59
  B.2.  Signature Algorithms  . . . . . . . . . . . . . . . . . .  59
  B.3.  ContentEncryptionAlgorithmIdentifier  . . . . . . . . . .  61
  B.4.  KeyEncryptionAlgorithmIdentifier  . . . . . . . . . . . .  62
Appendix C.  Moving S/MIME v2 Message Specification to Historic
             Status . . . . . . . . . . . . . . . . . . . . . . .  62
Acknowledgements  . . . . . . . . . . . . . . . . . . . . . . . .  62
Authors' Addresses  . . . . . . . . . . . . . . . . . . . . . . .  63

1. Introduction ๐ŸŒท

okay, S/MIME (Secure/Multipurpose Internet Mail Extensions) gives you one consistent way to send and receive secure MIME data ๐Ÿ’Œ It's built on the popular Internet MIME standard, and it gives you these cryptographic security services for electronic messaging apps: authentication, message integrity, and non-repudiation of origin (that's the digital signatures part โœ๏ธ), plus data confidentiality (that's encryption ๐Ÿ”). As a bonus perk, S/MIME also does message compression ๐Ÿ—œ๏ธ

S/MIME can be used by traditional mail user agents (MUAs) to add cryptographic security to the mail you send, and to interpret those protections in the mail you receive. but it's not limited to mail, bestie! it works with any transport mechanism that carries MIME data, like HTTP or SIP ๐Ÿฆ‹ That means S/MIME takes advantage of MIME's object-based features and lets secure messages get exchanged across mixed-transport systems. so iconic, right? ๐Ÿ‘‘

it can also 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 ๐Ÿ“ 

this document defines version 4.0 of the S/MIME Message Specification, so it obsoletes version 3.2 of that spec [RFC5751] ๐Ÿ’…

ngl, this spec has a bunch of references to documents that have been obsoleted or replaced, and that's on purpose ๐Ÿ™ˆ The updated docs often don't have the same info or protocol requirements in them, so we keep the references as they are ๐Ÿง

1.1. Specification Overview

okay bestie, this doc is all about giving MIME data cryptographic signature and encryption powers ๐Ÿ”โœจ MIME [MIME-SPEC] already gives Internet messages a general structure and lets new applications plug in based on content-type ๐Ÿ’Œ

this spec explains how to make a MIME body part that's been cryptographically enhanced under the Cryptographic Message Syntax (CMS) [CMS], which is basically the glow-up of PKCS #7 [RFC2315] ๐Ÿ’… it also defines the application/pkcs7-mime media type, which is what carries those body parts around ๐ŸŽ€

it also talks about using the multipart/signed media type from [RFC1847] to carry S/MIME signed messages ๐Ÿฆ‹ multipart/signed works together with the application/pkcs7-signature media type, which transports a detached S/MIME signature ๐Ÿซถ

if you want to create S/MIME messages, an S/MIME agent MUST follow this document, plus the specs listed in [CMS], [RFC3370], [RFC4056], [RFC3560], and [RFC5754] ๐Ÿ‘‘

there are requirements and recommendations for how receiving agents handle incoming messages, and separate ones for how sending agents build outgoing messages ๐ŸŒธ the big-picture move is to follow the Robustness Principle: be liberal in what you receive and conservative in what you send ๐Ÿ’– most of the requirements land on handling incoming messages, and most of the recommendations land on creating outgoing ones ๐Ÿงš

the receiving and sending agents get their own sections because S/MIME isn't just for traditional Internet mail clients anymore ๐Ÿค– S/MIME can be used with any system that moves MIME data, and an automated process that sends an encrypted message might not be able to receive one at all ๐Ÿ˜ญ so the requirements and recommendations for each kind of agent are listed separately when that makes sense ๐Ÿ“

1.2. Definitions

for this spec, the following definitions apply ๐Ÿ“–

  • ASN.1: Abstract Syntax Notation One, as defined in ITU-T Recommendations X.680, X.681, X.682, and X.683 [ASN.1].
  • BER: Basic Encoding Rules for ASN.1, as defined in ITU-T Recommendation X.690 [X.690].
  • 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 ITU-T Recommendation X.690 [X.690].
  • 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.
  • 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.
  • Data integrity service: A security service that protects against unauthorized changes to data by ensuring that changes to the data are detectable [RFC4949].
  • Data confidentiality: The property that data is not disclosed to system entities unless they have been authorized to know the data [RFC4949].

1.3. Conventions Used in This Document

here's the key-word situation ๐Ÿ—๏ธ the words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here ๐Ÿ’ฏ

we also define some extra requirement levels ๐ŸŽ€

  • SHOULD+: This term means the same as SHOULD. However, the authors expect that a requirement marked as SHOULD+ will be promoted at some future time to be a MUST.
  • SHOULD-: This term means the same as SHOULD. However, the authors expect that a requirement marked as SHOULD- will be demoted to a MAY in a future version of this document.
  • MUST-: This term means the same as MUST. However, the authors expect that this requirement will no longer be a MUST in a future document. Although its status will be determined at a later time, it is reasonable to expect that if a future revision of a document alters the status of a MUST- requirement, it will remain at least a SHOULD or a SHOULD-.

the term "RSA" in this document almost always means the PKCS #1 v1.5 RSA [RFC2313] signature or encryption algorithms, even when it isn't labeled that way ๐Ÿงฎ there are a couple of places where it means the general RSA cryptographic operation, and you can tell those apart from the context ๐Ÿ”

1.4. Compatibility with Prior Practice of S/MIME

S/MIME version 4.0 agents ought to try their hardest to be as interoperable as possible with agents for prior versions of S/MIME ๐Ÿค

1.5. Changes from S/MIME v3 to S/MIME v3.1

this section is the tea on what changed between S/MIME v3 and S/MIME v3.1 โ˜• heads up that the requirement levels in capitalized key words ("MUST", "SHOULD", etc.) may have shifted in later versions of S/MIME ๐Ÿ‘€

  • The RSA public key algorithm was changed to a MUST implement. The key wrap algorithm and the Diffie-Hellman (DH) algorithm [RFC2631] were 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 the use of "empty" SignedData messages to transmit certificates was clarified to reflect that transmission of 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 media type has been added. ๐Ÿ›ก๏ธ
  • Use of the CompressedData CMS type is allowed, along with required media type and file extension additions. ๐Ÿ—œ๏ธ

1.6. Changes from S/MIME v3.1 to S/MIME v3.2

this section covers the changes between S/MIME v3.1 and S/MIME v3.2 ๐Ÿ’ซ same heads up as before: the capitalized key words ("MUST", "SHOULD", etc.) may have changed in later versions of S/MIME ๐Ÿ™ˆ also, the section numbers listed here (e.g., 3.4.3.2) come from [RFC5751] ๐Ÿ“Ž

  • Made editorial changes, e.g., replaced "MIME type" with "media type", "content-type" with "Content-Type". ๐Ÿ’…
  • Moved "Conventions Used in This Document" to Section 1.3. Added definitions for SHOULD+, SHOULD-, and MUST-. ๐ŸŽ€
  • Section 1.1 and Appendix A: Added references to RFCs for RSASSA-PSS, RSAES-OAEP, and SHA2 CMS algorithms. Added CMS Multiple Signers Clarification to CMS reference. ๐Ÿ“š
  • Section 1.2: Updated references to ASN.1 to X.680, and BER and DER to X.690. ๐Ÿ”ค
  • Section 1.4: Added references to S/MIME v3.1 RFCs. ๐Ÿ”—
  • Section 2.1 (digest algorithm): SHA-256 added as MUST, SHA-1 and MD5 made SHOULD-. ๐Ÿ”
  • Section 2.2 (signature algorithms): RSA with SHA-256 added as MUST; DSA with SHA-256 added as SHOULD+; RSA with SHA-1, DSA with SHA-1, and RSA with MD5 changed to SHOULD-; and RSASSA-PSS with SHA-256 added as SHOULD+. Also added note about what S/MIME v3.1 clients support. โœ๏ธ
  • Section 2.3 (key encryption): DH changed to SHOULD-, and RSAES-OAEP added as SHOULD+. Elaborated on requirements for key wrap algorithm. ๐Ÿ—๏ธ
  • Section 2.5.1: Added requirement that receiving agents MUST support both GeneralizedTime and UTCTime. โฐ
  • Section 2.5.2: Replaced reference "sha1WithRSAEncryption" with "sha256WithRSAEncryption", replaced "DES-3EDE-CBC" with "AES-128 CBC", and deleted the RC5 example. ๐Ÿงน
  • Section 2.5.2.1: Deleted entire section (discussed deprecated RC2). ๐Ÿ—‘๏ธ
  • Section 2.7, Section 2.7.1, and Appendix A: References to RC2/40 removed. ๐Ÿ‘‹
  • Section 2.7 (content encryption): AES-128 CBC added as MUST, AES-192 and AES-256 CBC SHOULD+, and tripleDES now SHOULD-. ๐Ÿ”’
  • Section 2.7.1: Updated pointers from 2.7.2.1 through 2.7.2.4 to 2.7.1.1 and 2.7.1.2. ๐Ÿ‘‰
  • Section 3.1.1: Removed text about MIME character sets. โœ‚๏ธ
  • Sections 3.2.2 and 3.6: Replaced "encrypted" with "enveloped". Updated OID example to use AES-128 CBC OID. ๐Ÿ”
  • Section 3.4.3.2: Replaced "micalg" parameter for "SHA-1" with "sha-1". ๐Ÿ”ค
  • Section 4: Updated reference to CERT v3.2. ๐Ÿ“Œ
  • Section 4.1: Updated RSA and DSA key size discussion. Moved last four sentences to security considerations. Updated reference to randomness requirements for security. ๐ŸŽฒ
  • Section 5: Added IANA registration templates to update media type registry to point to this document as opposed to RFC 2311. ๐Ÿ—‚๏ธ
  • Section 6: Updated security considerations. ๐Ÿ›ก๏ธ
  • Section 7: Moved references from Appendix B to this section. Updated references. Added informative references to SMIMEv2, SMIMEv3, and SMIMEv3.1. ๐Ÿ“š
  • Appendix B: Added Appendix B to move S/MIME v2 to Historic status. ๐Ÿ›๏ธ

1.7. Changes for S/MIME v4.0

this one covers what changed between S/MIME v3.2 and S/MIME v4.0 ๐ŸŒˆ

  • Added the use of AuthEnvelopedData, including defining and registering an smime-type value (Sections 2.4.4 and 3.4). ๐Ÿ†•
  • Updated the content-encryption algorithms (Sections 2.7 and 2.7.1.2): added AES-256 Galois/Counter Mode (GCM), added ChaCha20-Poly1305, removed mention of AES-192 Cipher Block Chaining (CBC), and marked tripleDES as historic. ๐Ÿ”
  • Updated the set of signature algorithms (Section 2.2): added the Edwards-curve Digital Signature Algorithm (EdDSA), added the Elliptic Curve Digital Signature Algorithm (ECDSA), and marked DSA as historic. โœ๏ธ
  • Updated the set of digest algorithms (Section 2.1): added SHA-512, and marked SHA-1 as historic. ๐Ÿงพ
  • Updated the size of keys to be used for RSA encryption and RSA signing (Section 4). ๐Ÿ“
  • Created Appendix B, which discusses considerations for dealing with historic email messages. ๐Ÿ“จ

2. CMS Options โœจ

okay so CMS is giving options, and I mean a wild amount of them: content types, attributes, algorithms, the whole buffet ๐Ÿ’…. This section picks out a bunch of support requirements and recommendations so every S/MIME implementation has a shared baseline and can actually talk to each other ๐Ÿซถ. [RFC3370] and [RFC5754] have the extra details on the crypto algorithms, and [ESS] covers the extra attributes.

2.1. DigestAlgorithmIdentifier

these algorithms digest the body of the message, and they are NOT the same as the digest algorithms inside the signature algorithms ๐Ÿ™ˆ. The result goes into the message-digest attribute of the signed attributes. It is RECOMMENDED that the algorithm digesting the message body be of similar strength to, or greater strength than, the signature algorithm ๐Ÿ’ช.

Sending and receiving agents:

  • MUST support SHA-256.
  • MUST support SHA-512.

[RFC5754] has the details for using these with S/MIME ๐ŸŒธ.

2.2. SignatureAlgorithmIdentifier

receiving and sending agents have different requirements, and that's on purpose ๐Ÿฆ‹. Splitting it up gets you the most interoperability, because agents can lock down their private key material while still validating signatures as widely as possible ๐Ÿ”.

Receiving agents:

  • MUST support ECDSA with curve P-256 and SHA-256.
  • MUST support EdDSA with curve25519 using PureEdDSA mode [RFC8419].
  • MUST- support RSA PKCS #1 v1.5 with SHA-256.
  • SHOULD support the RSA Probabilistic Signature Scheme (RSASSA-PSS) with SHA-256.

Sending agents:

  • MUST support at least one of the following algorithms: ECDSA with curve P-256 and SHA-256, or EdDSA with curve25519 using PureEdDSA mode.
  • MUST- support RSA PKCS #1 v1.5 with SHA-256.
  • SHOULD support RSASSA-PSS with SHA-256.

see Section 4.1 for info on key size and algorithm references ๐Ÿ‘€.

2.3. KeyEncryptionAlgorithmIdentifier

both receiving and sending agents get a list here ๐Ÿ“:

  • MUST support Elliptic Curve Diffie-Hellman (ECDH) ephemeral-static mode for P-256, as specified in [RFC5753].
  • MUST support ECDH ephemeral-static mode for X25519 using HKDF-256 ("HKDF" stands for "HMAC-based Key Derivation Function") for the KDF, as specified in [RFC8418].
  • MUST- support RSA encryption, as specified in [RFC3370].
  • SHOULD+ support RSA Encryption Scheme - Optimal Asymmetric Encryption Padding (RSAES-OAEP), as specified in [RFC3560].

when ECDH ephemeral-static is used, a key wrap algorithm also gets specified in the KeyEncryptionAlgorithmIdentifier [RFC5652] ๐ŸŽ€. The encryption functions under the key wrap and content-encryption algorithms [RFC3370] [RFC3565], plus the key sizes for those two algorithms, MUST be the same. Think AES-128 key wrap paired with AES-128 content encryption, no mix-and-match ๐Ÿ“. Since both 128-bit and 256-bit AES modes are mandatory to implement as content-encryption algorithms (Section 2.7), both the AES-128 and AES-256 key wrap algorithms MUST be supported when ECDH ephemeral-static is used ๐Ÿ˜ญ. Recipients MAY enforce this, but they MUST use the weaker of the two as part of any cryptographic strength computations they might do ๐Ÿงš.

Appendix B has info on algorithm support in older versions of S/MIME ๐Ÿ“œ.

2.4. General Syntax

there are a bunch of CMS content types, but only five are actually used for S/MIME: Data, SignedData, EnvelopedData, AuthEnvelopedData, and CompressedData ๐ŸŒˆ.

2.4.1. Data Content Type

sending agents MUST use the id-data content type identifier to identify the "inner" MIME message content ๐ŸŽ€. For example, when you sign MIME data, the CMS SignedData encapContentInfo eContentType MUST include the id-data object identifier (OID), and the media type MUST be stored in the SignedData encapContentInfo eContent OCTET STRING. The one exception is when the sending agent is using multipart/signed, because then eContent is absent (see Section 3.5.3 of this document) ๐Ÿ™ƒ. Another example: when you encrypt MIME data, the CMS EnvelopedData encryptedContentInfo contentType MUST include the id-data OID, 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. Or, in the degenerate case with no signature info, to convey certificates ๐Ÿ“จ. Signing a message gives you authentication, message integrity, and non-repudiation of origin, so it's a whole vibe ๐Ÿ’….

2.4.3. EnvelopedData Content Type

this one is for data confidentiality ๐Ÿคซ. To get the symmetric key to recipients, a sender needs access to a public key for every intended recipient ๐Ÿ—๏ธ.

2.4.4. AuthEnvelopedData Content Type

this one gives you data confidentiality AND message integrity ๐Ÿ›ก๏ธ. It does NOT provide authentication or non-repudiation, so keep that in mind ๐Ÿ‘€. Same deal as before: to distribute the symmetric key, a sender needs a public key for each intended recipient ๐Ÿ”‘.

2.4.5. CompressedData Content Type

this one is for compressing a message to make it smaller ๐Ÿ“ฆ. It does NOT give you authentication, message integrity, non-repudiation, or data confidentiality. It's only there to shrink the message's size ๐Ÿค.

See Section 3.7 for more 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 ๐Ÿ–Š๏ธ. Some attributes are required to process the message (like message digest), some are info the signer supplied that should still get processed (like SMIME capabilities), and some are just not relevant to the current situation (like mlExpansionHistory [RFC2634] for mail viewers) ๐Ÿ™ˆ.

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 ๐Ÿ’–:

  • Signing time (Section 2.5.1 in this document)
  • SMIME capabilities (Section 2.5.2 in this document)
  • Encryption key Preference (Section 2.5.3 in this document)
  • Message digest (Section 11.2 in [RFC5652])
  • Content type (Section 11.1 in [RFC5652])

also, receiving agents SHOULD be able to handle zero or one instance of the signingCertificate and signingCertificateV2 signed attributes, as defined in Section 5 of RFC 2634 [ESS] and Section 3 of RFC 5035 [ESS], respectively ๐ŸŽ€.

sending agents SHOULD generate one instance of the signingCertificate or signingCertificateV2 signed attribute in each SignerInfo structure โœจ.

more attributes and values might be defined in the future ๐Ÿ”ฎ. So receiving agents SHOULD handle attributes or values they don't recognize in a graceful manner, no drama ๐Ÿซถ.

interactive sending agents that include signed attributes NOT listed here SHOULD display those attributes to the user, so the user knows exactly what data is getting signed ๐Ÿ‘€๐Ÿ’….

2.5.1. Signing Time Attribute

the signingTime attribute conveys when a message was signed โฐ. The signer usually creates that time, so it's only as trustworthy as the signer ๐Ÿซ .

Sending agents MUST encode signing time through the year 2049 as UTCTime. 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.

Receiving agents MUST be able to process signingTime attributes encoded in either UTCTime or GeneralizedTime ๐Ÿงš.

2.5.2. SMIMECapabilities Attribute โœจ

okay so the SMIMECapabilities attribute is basically your bestie list of what you can handle ๐Ÿ’… It can name signature algorithms (like sha256WithRSAEncryption), symmetric algorithms (like AES-128 CBC), authenticated symmetric algorithms (like AES-128 GCM), and key encipherment algorithms (like rsaEncryption). If you show up with a capability on the list, that means you can actually use the algorithm AND you understand the ASN.1 structures that go with it. ๐Ÿงš It also has identifiers for extra perks like binary encoding and compression. The best part is that it was built to be flexible and extensible, so later on we can add stuff like certificate preferences without breaking the older clients. Not me being dramatic when I say that's iconic ๐Ÿ˜ญ๐Ÿซถ

If it's there, the SMIMECapabilities attribute MUST be a SignedAttribute. CMS defines SignedAttributes as a SET OF Attribute. The SignedAttributes in a signerInfo MUST include a single instance of the SMIMECapabilities attribute. CMS defines the ASN.1 syntax for Attribute with attrValues SET OF AttributeValue, and an SMIMECapabilities attribute MUST only include a single instance of AttributeValue. If a signature breaks any of these rules, the signature SHOULD be treated as failing. ๐Ÿšซ

The SMIMECapabilities list is a partial list of what the announcing client can support, so you don't have to list everything you can do ๐ŸŒธ You also don't need to dump every capability just to make the list super long, because nobody wants that. The OIDs go in order of preference, but they SHOULD be grouped logically by category (signature algorithms, symmetric algorithms, key encipherment algorithms, and so on) ๐Ÿ“

The whole structure is built so you can do simple table lookups and binary comparisons to figure out matches. For example, the encoding for the sha256WithRSAEncryption capability includes the NULL parameter rather than omitting it ๐Ÿ™ˆ Since the encoding has to be identical for a match, people writing up algorithms for the SMIMECapabilities attribute SHOULD explicitly document the correct byte sequence for the common cases. Be the person who writes it down, bestie ๐Ÿ’–

For any capability, the parameters attached to the OID MUST specify everything needed to tell apart two instances of the same algorithm ๐Ÿฆ‹

The OID you use to name an algorithm SHOULD also be the one you use in the SMIMECapability for that algorithm. Sometimes one OID can point to multiple algorithms, and that's where it gets messy ๐ŸŒˆ In those cases, a single algorithm MUST be assigned to the SMIMECapability using that OID, and the other algorithm usages get their own additional OIDs from the smimeCapabilities OID tree. An earlier spec had rsaEncryption being ambiguous, since it could mean a signature algorithm OR a key encipherment algorithm (the main character of confusion, honestly ๐Ÿ’€). If an OID turns out to be ambiguous, the maintainer of the registered SMIMECapabilities list gets to arbitrate which type of algorithm uses it, and a new OID MUST be allocated under smimeCapabilities to cover the other use. โญ

The registered SMIMECapabilities list is where the parameters for OIDs that need them get specified, most notably key lengths for variable-length symmetric ciphers ๐Ÿ”ฅ If there are no differentiating parameters for an OID, the parameters MUST be omitted and MUST NOT be encoded as NULL. More values for the SMIMECapabilities attribute might be defined in the future, and receiving agents MUST handle a SMIMECapabilities object with values they don't recognize in a graceful way. No drama, just grace ๐ŸŽ€

Section 2.7.1 explains a strategy for caching capabilities ๐Ÿง 

2.5.3. Encryption Key Preference Attribute ๐Ÿ’œ

The encryption key preference attribute lets the signer clearly say which of their certificates has their preferred encryption key ๐Ÿ”‘ It's designed to play nicely with those clients that use separate keys for encryption and signing. Basically, it tells anyone looking which listed certificate is the right one to use for encrypting a session key for future encrypted messages. Clarity is everything, periodt โœจ

If it's there, the SMIMEEncryptionKeyPreference attribute MUST be a SignedAttribute. CMS defines SignedAttributes as a SET OF Attribute. The SignedAttributes in a signerInfo MUST include a single instance of the SMIMEEncryptionKeyPreference attribute. CMS defines the ASN.1 syntax for Attribute with attrValues SET OF AttributeValue, and an SMIMEEncryptionKeyPreference attribute MUST only include a single instance of AttributeValue. If a signature breaks these requirements, the signature SHOULD be treated as failing ๐Ÿ™…โ€โ™€๏ธ

If this attribute is used, the sending agent SHOULD include the referenced certificate in the set of certificates included in the signed message ๐ŸŽ The certificate MAY be omitted if it was already 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. (Just like with 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. Here's the tea though: this is only a preference, so the receiving agent can use any valid certificate 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 ๐Ÿ”

When you're figuring out which key management certificate to use for 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, it identifies the X.509 certificate that SHOULD be used as the X.509 key management certificate for that 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 signer of an X.509 certificate that can be used for key management ๐Ÿ”Ž
  • Or, use some other method of determining the user's key management key. If no X.509 key management certificate is 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 v4.0 implementations MUST support both issuerAndSerialNumber and subjectKeyIdentifier. Messages that use the subjectKeyIdentifier choice cannot be read by S/MIME v2 clients ๐Ÿ‘ต (the vibe check is that old clients are just not it)

It's really important to get this one: some certificates use a subjectKeyIdentifier value that is NOT suitable for uniquely identifying a certificate ๐Ÿšจ Implementations MUST be prepared for multiple certificates, possibly for different entities, to have the same subjectKeyIdentifier value. They MUST also be prepared to try each matching certificate during signature verification before reporting an error condition. Patience is a virtue, bestie ๐Ÿง˜โ€โ™€๏ธ

2.7. ContentEncryptionAlgorithmIdentifier ๐Ÿ”

Sending and receiving agents have a few must-haves:

  • MUST support encryption and decryption with AES-128 GCM and AES-256 GCM [RFC5084].
  • MUST- support encryption and decryption with AES-128 CBC [RFC3565].
  • SHOULD+ support encryption and decryption with ChaCha20-Poly1305 [RFC7905] ๐Ÿฆ‹

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 ๐Ÿค” That decision pulls from the capabilities lists included in messages received from the recipient, plus out-of-band info like private agreements, user preferences, legal restrictions, and so on. It's giving strategy, honestly โœจ

Section 2.5.2 defines a method where a sending agent can optionally announce, among other things, its decrypting capabilities in 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 hasn't created a list of capabilities for the sender's public key yet, 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 the capabilities in the list. Signing time values that lie far in the future (meaning a greater discrepancy than any reasonable clock skew), or a capabilities list from messages whose signature could not be verified, MUST NOT be accepted ๐Ÿšซ๐Ÿ™…โ€โ™€๏ธ

The list of capabilities SHOULD be stored for future use when creating messages ๐Ÿ’พ

Before sending a message, the sending agent MUST decide whether it's willing to use weak encryption for the particular data in that message ๐Ÿ›ก๏ธ If the sending agent decides weak encryption is unacceptable for this data, then the sending agent MUST NOT use a weak algorithm. That decision overrides any other decision in this section about which encryption algorithm to use. Safety first, slay forever ๐Ÿ’…

Sections 2.7.1.1 and 2.7.1.2 describe the decisions a sending agent SHOULD use when choosing 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 (the one 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 ๐Ÿ•ต๏ธโ€โ™€๏ธ

okay so this is the fallback for when the sending agent is totally in the dark ๐ŸŒ‘. If BOTH of these conditions are true, the sending agent SHOULD use AES-256 GCM, because it's the stronger option and S/MIME v4.0 says it's required ๐Ÿ’…:

  • The sending agent has no knowledge of the encryption capabilities of the recipient.
  • The sending agent has no knowledge of the version of S/MIME used or supported by the recipient.

If the sending agent decides NOT to go with AES-256 GCM in this step, it SHOULD use AES-128 CBC instead. The reasoning is that a client implementing AES-GCM is presumed to do both AES-256 and AES-128, so it's a safe bet ๐ŸŽ€โœจ.

2.7.2. Choosing Weak Encryption ๐Ÿฅ€

Algorithms like RC2 are considered weak encryption algorithms, and TripleDES is not state of the art and is considered weaker than AES ๐Ÿ˜ฌ. A sending agent that is controlled by a human SHOULD let the human sender understand the risks of sending data with a weaker encryption algorithm BEFORE it goes out ๐Ÿšจ. It can also let the human pick a stronger algorithm, such as AES GCM or AES CBC, even if the recipient might not be able to process it. The human is in charge here, bestie ๐Ÿ‘‘.

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

If a sending agent is composing an encrypted message for a group of recipients whose encryption capabilities don't all overlap, the sending agent is forced to send more than one message ๐Ÿ˜ฉ. Heads up though: if the sending agent sends a message with a strong algorithm and then sends the SAME message with a weak algorithm, anyone watching the communications channel could learn the contents of the strongly encrypted message just by decrypting the weakly encrypted one ๐Ÿ’€. Not okay, so be careful!

3. Creating S/MIME Messages ๐Ÿฆ‹

This section is all about the S/MIME message formats and how they get made โœจ. S/MIME messages are a combo of MIME bodies and CMS content types, and several media types and several CMS content types are used. The data being secured is always a canonical MIME entity. That MIME entity, plus other stuff like certificates and algorithm identifiers, gets handed to CMS processing facilities, which produce a CMS object. Last step: the CMS object gets wrapped in MIME ๐ŸŽ. The "Enhanced Security Services for S/MIME" documents [ESS] describe how nested, secured S/MIME messages are formatted. ESS also explains how a triple-wrapped S/MIME message is formatted, using multipart/signed and application/pkcs7-mime for the signatures ๐ŸŒธ.

S/MIME gives you one format for enveloped-only data, several formats for signed-only data, and several formats for signed and enveloped data. Having several formats is necessary to cover different environments, especially for signed messages ๐ŸŒˆ. The criteria for picking among them are described here too.

Anyone reading this section is expected to understand MIME as described in [MIME-SPEC] and [RFC1847] ๐Ÿ“š.

3.1. Preparing the MIME Entity for Signing, Enveloping, or Compressing ๐ŸŽ€

S/MIME is used to secure MIME entities ๐Ÿ’–. A MIME message is made of a MIME header and a MIME body. The body can be a single MIME entity or a tree of MIME entities (rooted with a multipart). S/MIME can secure either a single MIME entity or a whole tree of them, and those entities can live somewhere other than the root. S/MIME can even be applied multiple times to different entities in one message ๐Ÿช†. A MIME entity that IS the whole message includes only the MIME message headers and MIME body, and does NOT include the rfc822 header. Also, S/MIME can secure MIME entities used in applications other than Internet mail ๐Ÿงš. When you need to protect the rfc822 header, the use of the message/rfc822 media type is explained later in this section.

The MIME entity that gets secured here can be thought of as the "inside" MIME entity. It's the "innermost" object in what might be a bigger MIME message ๐Ÿชบ. Processing "outside" MIME entities into CMS EnvelopedData, CompressedData, and AuthEnvelopedData content types is covered in Sections 3.2 and 3.5. Other documents define additional CMS content types, and those documents are the place to look for how to process those ๐Ÿ“–.

The procedure for preparing a MIME entity is given in [MIME-SPEC]. The same procedure is used here, with some extra restrictions when signing. The procedure from [MIME-SPEC] gets repeated here, but the reader is encouraged to check those documents for the exact details ๐Ÿ”. This section also describes additional requirements ๐Ÿ’….

A single procedure is used for creating MIME entities that are going to have any combo of signing, enveloping, and compressing applied ๐ŸŒ€. Some additional steps are recommended to guard against known corruptions that can happen during mail transport. These matter MOST for clear-signing with the multipart/signed format ๐Ÿงผ. Those additional steps are recommended for enveloped messages, or signed and enveloped messages, so the messages can be forwarded to any environment without being modified ๐Ÿš€.

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 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, its security services are processed and the result is the MIME entity ๐ŸŽ‰. That MIME entity is typically passed to a MIME-capable user agent, where it's further decoded and presented to the user or receiving application.

To protect outer, non-content-related header fields (like Subject, To, From, and Cc), the sending client MAY wrap a full MIME message in a message/rfc822 wrapper so it can apply S/MIME security services to those header fields ๐Ÿซถ. It's up to the receiving client to decide how to show this "inner" header alongside the unprotected "outer" header. Because the headers have different security levels, it is RECOMMENDED that the receiving client make a visible distinction between header fields based on where they are located ๐Ÿ‘€.

When an S/MIME message is received and 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 the header-merging issues discussed earlier.

3.1.1. Canonicalization ๐Ÿงฝ

Each MIME entity MUST be converted to a canonical form that is uniquely and unambiguously representable in both the environment where the signature is created and the environment where it will be verified ๐Ÿ’Ž. MIME entities MUST be canonicalized for enveloping and compressing as well as for signing.

The exact details of canonicalization depend on the media type and subtype of an entity, and they are not described here ๐Ÿ—‚๏ธ. Instead, the standard for that particular media type SHOULD be consulted. For example, canonicalizing text/plain is different from canonicalizing audio/basic. Apart from text types, most types have just one representation, regardless of computing platform or environment, and that can be considered their canonical representation โœจ.

In general, canonicalization is performed by the non-security part of the sending agent, not by the S/MIME implementation ๐Ÿง‘โ€๐Ÿ’ป.

The most common and important canonicalization is for text, which is often represented differently in different 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] ๐Ÿ’œ.

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, transfer encoding is not required at all, EXCEPT when signing with the multipart/signed format ๐Ÿ™…โ€โ™€๏ธ. S/MIME implementations MUST be able to deal with binary MIME objects. If no Content-Transfer-Encoding header field is present, the transfer encoding is presumed to be 7BIT ๐Ÿ”ข.

As a rule, S/MIME implementations SHOULD use transfer encoding as described in Section 3.1.3 for all MIME entities they secure. The reason for securing only 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 and 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 on 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 ๐Ÿ˜ฑ.

If S/MIME implementations can determine that ALL intended recipients can handle inner (all but the outermost) binary MIME objects, implementations SHOULD use binary encoding instead of a 7-bit-safe transfer encoding for the inner entities ๐Ÿ‹๏ธ. A 7-bit-safe encoding, such as base64, unnecessarily expands the message size, so binary is the way to go when it's possible ๐Ÿ’ช. Implementations MAY determine that recipient implementations can handle inner binary MIME entities by (1) interpreting the id-cap-preferBinaryInside SMIMECapabilities attribute, (2) prior agreement, or (3) other means ๐Ÿ”Ž.

If one or more intended recipients can't handle inner binary MIME objects, or if that capability is unknown for ANY of the intended recipients, S/MIME implementations SHOULD use transfer encoding as described in Section 3.1.3 for all MIME entities they secure ๐Ÿซง.

3.1.3. Transfer Encoding for Signing Using multipart/signed โœจ

Okay so, if a multipart/signed entity is ever going over regular Internet SMTP or any other transport that's stuck on 7-bit text, it MUST get transfer encoding applied so it's represented as 7-bit text ๐Ÿ’…. Entities that are already 7-bit don't need any encoding ๐ŸŒธ. 8-bit text and binary data can be encoded with quoted-printable or base64 ๐Ÿซถ.

The big reason for the 7-bit rule is that the Internet mail transport infrastructure can't guarantee it'll carry 8-bit or binary data ๐Ÿ˜ญ. Lots of parts of the transport now handle 8-bit and even binary data, but sometimes you just can't tell whether the path is 8-bit clean ๐Ÿ™ˆ. If a message with 8-bit data hits a message transfer agent that can't move 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. That would invalidate the signature.
  • The agent could send the data anyway, which would most likely corrupt the 8th bit. That would also invalidate the signature.
  • The agent could return the message to the sender.

[RFC1847] says an agent isn't allowed to change the transfer encoding of the first part of a multipart/signed message ๐Ÿ”’. So if a compliant agent that can't handle 8-bit or binary data ran 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 is a multipart/mixed message with full transfer encoding. It has a text part and an attachment. The sample text has characters that aren't ASCII, so they need to be transfer encoded ๐Ÿ“. You can't see it here, but the end of each line is <CR><LF>. The line endings of the MIME headers, the text, and the transfer-encoded parts all MUST be <CR><LF> ๐Ÿฉท.

Note that this example is not 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 Media Type ๐Ÿฆ‹

The application/pkcs7-mime media type carries CMS content types, including EnvelopedData, SignedData, and CompressedData ๐ŸŽ. The details for building these entities come in the next sections, and this one covers the general vibe of application/pkcs7-mime ๐Ÿ’œ.

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

CMS content types are binary data, so base64 transfer encoding is usually the right move, especially with SMTP transport ๐Ÿ”ฅ. Which transfer encoding you use depends on the transport the object is going through, so it's not a trait of the media type itself ๐Ÿšš.

Quick distinction, because it's easy to mix up: this part is about the transfer encoding of the CMS object, the "outside" MIME entity ๐Ÿ“ฆ. That's totally separate from, and unrelated to, the transfer encoding of the MIME entity that's secured by the CMS object, the "inside" object described in Section 3.1 ๐Ÿง .

Since there are several kinds of application/pkcs7-mime objects, a sending agent SHOULD do as much as it can to help the receiving agent know what's inside, without making the receiver decode the ASN.1 for the object ๐Ÿ‘€. The Content-Type header field 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 so older systems don't get confused ๐Ÿ•ฐ๏ธ. Sending agents SHOULD also emit the optional Content-Disposition field [RFC2183] with the "filename" parameter ๐Ÿ“Ž. If a sending agent emits those parameters, the value SHOULD be a filename with the right extension:

File
Media Type                                                Extension
-------------------------------------------------------------------
application/pkcs7-mime (SignedData, EnvelopedData,           .p7m
   AuthEnvelopedData)
application/pkcs7-mime (degenerate SignedData certificate    .p7c
   management message)
application/pkcs7-mime (CompressedData)                      .p7z
application/pkcs7-signature (SignedData)                     .p7s

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

Including a filename does two jobs ๐Ÿ’–. It makes S/MIME objects easier to use as files on disk ๐Ÿ’พ. It can also carry type information across gateways ๐ŸŒ‰. When a MIME entity of type application/pkcs7-mime (for example) arrives at a gateway with no special S/MIME knowledge, the gateway defaults the media type to application/octet-stream and treats it as a generic attachment, so the type info gets lost ๐Ÿ˜ฉ. But the suggested filename for an attachment often survives the trip across a gateway, and that often helps the receiving system pick the right app to hand the attachment to, in this case a standalone S/MIME processing app ๐ŸŽฏ. This mechanism is only a convenience for implementations in certain environments โญ. A proper S/MIME implementation MUST use the media types and MUST NOT rely on the file extensions ๐Ÿšซ.

3.2.2. The smime-type Parameter ๐ŸŒˆ

The application/pkcs7-mime content type defines the optional "smime-type" parameter ๐Ÿช„. Its job is to tell you about the security applied (signed or enveloped) and what kind of content is inside ๐Ÿ”. This spec defines the following smime-types:

    Name                   CMS Type              Inner Content
    ----------------------------------------------------------
    enveloped-data         EnvelopedData         id-data
    signed-data            SignedData            id-data
    certs-only             SignedData            id-data
    compressed-data        CompressedData        id-data
    authEnveloped-data     AuthEnvelopedData     id-data

To keep things consistent with future specs, the following guidelines SHOULD be followed when assigning a new smime-type parameter ๐Ÿ“:

  1. If both signing and encryption can be applied to the content, then three values for smime-type SHOULD be assigned: "signed-", "authEnv-", and "enveloped-*". If only one operation can be assigned, the prefix can be left off. So since "certs-only" can only be signed, "signed-" gets omitted ๐Ÿงฉ.
  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.2.16.840.1.101.3.4.1.2" would be AES-128 CBC) ๐Ÿ”ข.

This field is explicitly meant to be a handy hint for mail client apps, so they can tell whether a message is "signed", "authEnveloped", or "enveloped" without digging into the CMS payload ๐Ÿ‘‘.

A registry for additional smime-type parameter values has been defined in [RFC7114] ๐Ÿ—‚๏ธ.

3.3. Creating an Enveloped-Only Message ๐Ÿ’Œ

This section describes the format for enveloping a MIME entity without signing it ๐Ÿซง. Heads up: sending enveloped but unsigned messages does not provide data integrity โš ๏ธ. The "enveloped-only" structure doesn't support authenticated symmetric algorithms, so for those you use the "authenticated enveloped" structure instead ๐Ÿ”. That's because it's possible to replace ciphertext so the processed message is still valid, while the meaning gets 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 are processed into a CMS object of type EnvelopedData. In addition to encrypting a copy of the content-encryption key (CEK) for each recipient, a copy of the CEK SHOULD be encrypted for the originator and included in the EnvelopedData (see [RFC5652], 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 ๐Ÿ.

The smime-type parameter for enveloped-only messages is "enveloped-data" โœจ. The file extension for this type of message is ".p7m" ๐Ÿ“‚.

Here's a sample message:

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

MIIBHgYJKoZIhvcNAQcDoIIBDzCCAQsCAQAxgcAwgb0CAQAwJjASMRAwDgYDVQQDEw
dDYXJsUlNBAhBGNGvHgABWvBHTbi7NXXHQMA0GCSqGSIb3DQEBAQUABIGAC3EN5nGI
iJi2lsGPcP2iJ97a4e8kbKQz36zg6Z2i0yx6zYC4mZ7mX7FBs3IWg+f6KgCLx3M1eC
bWx8+MDFbbpXadCDgO8/nUkUNYeNxJtuzubGgzoyEd8Ch4H/dd9gdzTd+taTEgS0ip
dSJuNnkVY4/M652jKKHRLFf02hosdR8wQwYJKoZIhvcNAQcBMBQGCCqGSIb3DQMHBA
gtaMXpRwZRNYAgDsiSf8Z9P43LrY4OxUk660cu1lXeCSFOSOpOJ7FuVyU=

3.4. Creating an Authenticated Enveloped-Only Message โœจ

okay so this section is all about wrapping up a MIME entity in an envelope WITHOUT signing it ๐ŸŽ€ authenticated enveloped messages give you confidentiality AND data integrity, which is so good ๐Ÿ’– BUT bestie, sending one does NOT give you proof of origination when you're using S/MIME ๐Ÿ˜ญ a third party could swap out the ciphertext so the processed message still looks valid, and the meaning could get altered. it's substantially harder than with a plain enveloped-only message though, because the algorithm does give you a level of authentication ๐Ÿ” still, any recipient the message is encrypted for can replace it without anyone noticing ๐Ÿ’€ so yeah, not a full forgery-proof situation, just vibes-with-a-lock ๐Ÿ™ˆ

Step 1. The MIME entity to be enveloped is prepared according to Section 3.1. ๐Ÿง

Step 2. The MIME entity and other required data are processed into a CMS object of type AuthEnvelopedData. In addition to encrypting a copy of the CEK for each recipient, a copy of the CEK SHOULD be encrypted for the originator and included in the AuthEnvelopedData (see [RFC5083]). โœจ

Step 3. The AuthEnvelopedData object is wrapped in a CMS ContentInfo object. ๐ŸŒธ

Step 4. The ContentInfo object is inserted into an application/pkcs7-mime MIME entity. ๐Ÿฆ‹

The smime-type parameter for authenticated enveloped-only messages is "authEnveloped-data". The file extension for this type of message is ".p7m". ๐Ÿ’œ

A sample message would be:

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

MIIDWQYLKoZIhvcNAQkQARegggNIMIIDRAIBADGBvjCBuwIBADAmMBIxEDAO
BgNVBAMTB0NhcmxSU0ECEEY0a8eAAFa8EdNuLs1dcdAwCwYJKoZIhvcNAQEB
BIGAgyZJo0ERTxA4xdTri5P5tVMyh0RARepTUCORZvlUbcUlaI8IpJZH3/J1
Fv6MxTRS4O/K+ZcTlQmYeWLQvwdltQdOIP3mhpqXzTnOYhTK1IDtF2zx75Lg
vE+ilpcLIzXfJB4RCBPtBWaHAof4Wb+VMQvLkk9OolX4mRSH1LPktgAwggJq
BgkqhkiG9w0BBwEwGwYJYIZIAWUDBAEGMA4EDGPizioC9OHSsnNx4oCCAj7Y
Cb8rOy8+55106newEJohC/aDgWbJhrMKzSOwa7JraXOV3HXD3NvKbl665dRx
vmDwSCNaLCRU5q8/AxQx2SvnAbM+JKcEfC/VFdd4SiHNiUECAApLku2rMi5B
WrhW/FXmx9d+cjum2BRwB3wj0q1wajdB0/kVRbQwg697dnlYyUog4vpJERjr
7KAkawZx1RMHaM18wgZjUNpCBXFS3chQi9mTBp2i2Hf5iZ8OOtTx+rCQUmI6
Jhy03vdcPCCARBjn3v0d3upZYDZddMA41CB9fKnnWFjadV1KpYwv80tqsEfx
Vo0lJQ5VtJ8MHJiBpLVKadRIZ4iH2ULC0JtN5mXE1SrFKh7cqbJ4+7nqSRL3
oBTud3rX41DGshOjpqcYHT4sqYlgZkc6dp0g1+hF1p3cGmjHdpysV2NVSUev
ghHbvSqhIsXFzRSWKiZOigmlkv3R5LnjpYyP4brM62Jl7y0qborvV4dNMz7m
D+5YxSlH0KAe8z6TT3LHuQdN7QCkFoiUSCaNhpAFaakkGIpqcqLhpOK4lXxt
kptCG93eUwNCcTxtx6bXufPR5TUHohvZvfeqMp42kL37FJC/A8ZHoOxXy8+X
X5QYxCQNuofWlvnIWv0Nr8w65x6lgVjPYmd/cHwzQKBTBMXN6pBud/PZL5zF
tw3QHlQkBR+UflMWZKeN9L0KdQ27mQlCo5gQS85aifxoiiA2v9+0hxZw91rP
IW4D+GS7oMMoKj8ZNyCJJsyf5smRZ+WxeBoolb3+TiGcBBCsRnfe6noLZiFO
6Zeu2ZwE

3.5. Creating a Signed-Only Message ๐Ÿ–Š๏ธ

there are two formats for signed messages in S/MIME, bestie ๐Ÿ‘‘

  • application/pkcs7-mime with SignedData.
  • multipart/signed.

in general, the multipart/signed form is preferred for sending, and receiving agents MUST be able to handle both ๐Ÿซถ

3.5.1. Choosing a Format for Signed-Only Messages ๐Ÿค”

there are no hard-and-fast rules for when you pick a particular signed-only format ๐Ÿ’… it depends on the capabilities of all the receivers, and on how important it is that receivers with S/MIME facilities can verify the signature compared to how important it is that receivers without S/MIME software can view the message.

messages signed using the multipart/signed format can always be viewed by the receiver, whether or not they have S/MIME software ๐Ÿฆ‹ they can also be viewed whether the receiver uses a MIME-native user agent or has their messages translated by a gateway. in this context, "be viewed" means the ability to process the message essentially as if it were not a signed message, including any other MIME structure the message might have โœจ

messages signed using the SignedData format cannot be viewed by a recipient unless they have S/MIME facilities ๐Ÿ˜ญ however, the SignedData format protects the message content from being changed by benign intermediate agents. those agents might do line wrapping or content-transfer encoding changes that would break the signature ๐ŸŒˆ

3.5.2. Signing Using application/pkcs7-mime with SignedData ๐ŸŽ€

this signing format uses the application/pkcs7-mime media type. the steps to create this format are as follows:

Step 1. The MIME entity is prepared according to Section 3.1. ๐Ÿง

Step 2. The MIME entity and other required data are processed into a CMS object of type SignedData. ๐ŸŒธ

Step 3. The SignedData object is wrapped in a CMS ContentInfo object. ๐Ÿฆ‹

Step 4. The ContentInfo object is inserted into an application/pkcs7-mime MIME entity. ๐Ÿ’œ

The smime-type parameter for messages using application/pkcs7-mime with SignedData is "signed-data". The file extension for this type of message 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

MIIDmQYJKoZIhvcNAQcCoIIDijCCA4YCAQExCTAHBgUrDgMCGjAtBgkqhkiG9w0BBw
GgIAQeDQpUaGlzIGlzIHNvbWUgc2FtcGxlIGNvbnRlbnQuoIIC4DCCAtwwggKboAMC
AQICAgDIMAkGByqGSM44BAMwEjEQMA4GA1UEAxMHQ2FybERTUzAeFw05OTA4MTcwMT
EwNDlaFw0zOTEyMzEyMzU5NTlaMBMxETAPBgNVBAMTCEFsaWNlRFNTMIIBtjCCASsG
ByqGSM44BAEwggEeAoGBAIGNze2D6gqeOT7CSCij5EeT3Q7XqA7sU8WrhAhP/5Thc0
h+DNbzREjR/p+vpKGJL+HZMMg23j+bv7dM3F9piuR10DcMkQiVm96nXvn89J8v3UOo
i1TxP7AHCEdNXYjDw7Wz41UIddU5dhDEeL3/nbCElzfy5FEbteQJllzzflvbAhUA4k
emGkVmuBPG2o+4NyErYov3k80CgYAmONAUiTKqOfs+bdlLWWpMdiM5BAI1XPLLGjDD
HlBd3ZtZ4s2qBT1YwHuiNrhuB699ikIlp/R1z0oIXks+kPht6pzJIYo7dhTpzi5dow
fNI4W4LzABfG1JiRGJNkS9+MiVSlNWteL5c+waYTYfEX/Cve3RUP+YdMLRgUpgObo2
OQOBhAACgYBc47ladRSWC6l63eM/qeysXty9txMRNKYWiSgRI9k0hmd1dRMSPUNbb+
VRv/qJ8qIbPiR9PQeNW2PIu0WloErjhdbOBoA/6CN+GvIkq1MauCcNHu8Iv2YUgFxi
rGX6FYvxuzTU0pY39mFHssQyhPB+QUD9RqdjTjPypeL08oPluKOBgTB/MAwGA1UdEw
EB/wQCMAAwDgYDVR0PAQH/BAQDAgbAMB8GA1UdIwQYMBaAFHBEPoIub4feStN14z0g
vEMrk/EfMB0GA1UdDgQWBBS+bKGz48H37UNwpM4TAeL945f+zTAfBgNVHREEGDAWgR
RBbGljZURTU0BleGFtcGxlLmNvbTAJBgcqhkjOOAQDAzAAMC0CFFUMpBkfQiuJcSIz
jYNqtT1na79FAhUAn2FTUlQLXLLd2ud2HeIQUltDXr0xYzBhAgEBMBgwEjEQMA4GA1
UEAxMHQ2FybERTUwICAMgwBwYFKw4DAhowCQYHKoZIzjgEAwQuMCwCFD1cSW6LIUFz
eXle3YI5SKSBer/sAhQmCq7s/CTFHOEjgASeUjbMpx5g6A==

3.5.3. Signing Using the multipart/signed Format ๐Ÿช„

this format is a clear-signing format ๐Ÿ‘€ recipients without any S/MIME or CMS processing facilities are still able to view the message ๐Ÿ’– it makes use of the multipart/signed media type described in [RFC1847]. the multipart/signed media type has two parts. the first part contains the MIME entity that is signed; the second part contains the "detached signature" CMS SignedData object in which the encapContentInfo eContent field is absent.

3.5.3.1. The application/pkcs7-signature Media Type ๐ŸŒท

this media type always contains a CMS ContentInfo containing a single CMS object of type SignedData. the SignedData encapContentInfo eContent field MUST be absent. the signerInfos field contains the signatures for the MIME entity.

the file extension for signed-only messages using application/pkcs7-signature is ".p7s". ๐Ÿงš

3.5.3.2. Creating a multipart/signed Message ๐Ÿ’Œ

Step 1. The MIME entity to be signed is prepared according to Section 3.1, taking special care for clear-signing. ๐Ÿง

Step 2. The MIME entity is presented to CMS processing in order to obtain an object of type SignedData in which the encapContentInfo eContent field is absent. ๐ŸŒธ

Step 3. The MIME entity is inserted into the first part of a multipart/signed message with no processing other than that described in Section 3.1. ๐Ÿฆ‹

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

Step 5. The MIME entity of the application/pkcs7-signature is 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". note that quotation marks are required around the protocol parameter, because MIME requires that the "/" character in the parameter value MUST be quoted ๐ŸŽ€

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 [RFC1847]. the values to be placed in the micalg parameter SHOULD be from the following:

     Algorithm      Value Used
     -----------------------------------------------------------
     MD5*           md5
     SHA-1*         sha-1
     SHA-224        sha-224
     SHA-256        sha-256
     SHA-384        sha-384
     SHA-512        sha-512
     Any other      (defined separately in the algorithm profile
                     or "unknown" if not defined)

*Note: MD5 and SHA-1 are historical and no longer considered secure.
See Appendix B for details.

(historical note: some early implementations of S/MIME emitted and expected "rsa-md5", "rsa-sha1", and "sha1" for the micalg parameter ๐Ÿ•ฐ๏ธ) receiving agents SHOULD be able to recover gracefully from a micalg parameter value that they do not recognize ๐Ÿซถ future values for this parameter will be taken from the IANA "Hash Function Textual Names" registry ๐Ÿ“œ

3.5.3.3. Sample multipart/signed Message ๐Ÿงพ

Content-Type: multipart/signed;
    micalg=sha-256;
    boundary="----=_NextBoundary____Fri,_06_Sep_2002_00:25:21";
    protocol="application/pkcs7-signature"

This is a multipart message in MIME format.

------=_NextBoundary____Fri,_06_Sep_2002_00:25:21

This is some sample content.
------=_NextBoundary____Fri,_06_Sep_2002_00:25:21
Content-Type: application/pkcs7-signature; name=smime.p7s
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename=smime.p7s

MIIBJgYJKoZIhvcNAQcCoIIBFzCCARMCAQExADALBgkqhkiG9w0BBwExgf4w
gfsCAQIwJjASMRAwDgYDVQQDEwdDYXJsUlNBAhBGNGvHgABWvBHTbi7EELOw
MAsGCWCGSAFlAwQCAaAxMC8GCSqGSIb3DQEJBDEiBCCxwpZGNZzTSsugsn+f
lEidzQK4mf/ozKqfmbxhcIkKqjALBgkqhkiG9w0BAQsEgYB0XJV7fjPa5Nuh
oth5msDfP8A5urYUMjhNpWgXG8ae3XpppqVrPi2nVO41onHnkByjkeD/wc31
A9WH8MzFQgSTsrJ65JvffTTXkOpRPxsSHn3wJFwP/atWHkh8YK/jR9bULhUl
Mv5jQEDiwVX5DRasxu6Ld8zv9u5/TsdBNiufGw==

------=_NextBoundary____Fri,_06_Sep_2002_00:25:21--

the content that is digested (the first part of the multipart/signed) consists of the bytes:

54 68 69 73 20 69 73 20 73 6f 6d 65 20 73 61 6d 70 6c 65 20 63 6f 6e
74 65 6e 74 2e 0d 0a

3.6. Creating a Compressed-Only Message ๐Ÿ—œ๏ธ

okay so this section is about squishing a MIME entity down with compression ๐Ÿงƒ heads up: versions of S/MIME before 3.1 didn't know about CompressedData at all, so they won't recognize it ๐Ÿ’€ the way to check if someone can receive it is the capability in [RFC3274], and that's the preferred move for compatibility โœจ

Step 1. The MIME entity to be compressed gets prepared according to Section 3.1. ๐Ÿ’…

Step 2. The MIME entity and any 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 goes inside an application/pkcs7-mime MIME entity ๐Ÿ’Œ

The smime-type parameter for compressed-only messages is "compressed-data", and the file extension for this type is ".p7z" ๐Ÿฆ‹

here's a sample message bc examples slap:

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

eNoLycgsVgCi4vzcVIXixNyCnFSF5Py8ktS8Ej0AlCkKVA==

3.7. Multiple Operations ๐Ÿช†

the signed-only, enveloped-only, and compressed-only formats can all be nested, and that works bc they're all MIME entities that wrap other MIME entities ๐Ÿงธ it's giving Russian nesting doll energy fr fr

an S/MIME implementation MUST be able to receive and process arbitrarily nested S/MIME within reasonable resource limits of the recipient computer. no skipping this one bestie ๐Ÿซถ

you can apply the signing, encrypting, and compressing operations in any order ๐Ÿ”€ that choice is up to the implementer and the user. if you sign first, the signers get securely hidden by the enveloping ๐Ÿซฃ if you envelope first, the signers are visible, but you can verify signatures without taking the envelope off. that's super useful when you want automatic signature checks, bc no private key material is needed to verify a signature ๐Ÿ”‘

ok this part is a lil serious, so be careful ๐Ÿฅบ the sign-first vs encrypt-first choice has real security ramifications. if a message is encrypted and then signed, the recipient can confirm the encrypted block wasn't altered, but they can't figure out any relationship between the signer and the unencrypted contents ๐Ÿšจ if a message is signed and then encrypted, the recipient can assume the signed message itself hasn't been changed, but a careful attacker could have altered the unauthenticated parts of the encrypted message ๐Ÿ‘€ not a vibe to ignore!!

when you're using compression, keep these in mind:

  • compressing encrypted data that gets transferred as binary data is discouraged, since it won't really shrink much ๐Ÿ“‰ encrypted data sent as base64-encoded data could benefit though ๐ŸŒˆ
  • if you use a lossy compression algorithm together with signing, you need to compress first and then sign ๐Ÿ”ฅ

3.8. Creating a Certificate Management Message ๐Ÿ“œ

the certificate management message (or MIME entity) carries certificates and/or Certificate Revocation Lists (CRLs), like when you're responding to a registration request ๐Ÿ“ฌ

Step 1. The certificates and/or CRLs get made available 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 ๐Ÿซ™ no content, no signers, just vibes ๐ŸงŠ

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 ๐Ÿ’–

for this message type, the smime-type parameter is "certs-only", and the file extension is ".p7c" ๐Ÿฆ‹


3.9. Registration Requests ๐Ÿ“

a sending agent that signs messages MUST have a certificate for the signature so the receiving agent can verify it ๐Ÿ” there are lots of ways to get certificates, like exchanging stuff with a certification authority, using a hardware token or diskette, and so on ๐Ÿ’พ

S/MIME v2 [SMIMEv2] specified a way to "register" public keys with certificate authorities using an application/pkcs10 body part ๐Ÿ—‚๏ธ since then, the IETF PKIX Working Group has come up with other ways to request certificates โœจ but S/MIME v4.0 does not require a particular certificate request mechanism, so you get to pick your fave ๐Ÿ’…


3.10. Identifying an S/MIME Message ๐Ÿ•ต๏ธโ€โ™€๏ธ

S/MIME works in non-MIME environments too, so it uses a few different ways to carry type info, and that makes it kinda tricky to spot S/MIME messages ๐Ÿ™ˆ the table below lists the criteria for telling whether a message is an S/MIME message. if a message matches any one of these criteria, it counts as S/MIME ๐ŸŽฏ

the file suffix in the table comes from the "name" parameter in the Content-Type header field or the "filename" parameter in the Content-Disposition header field. the MIME parameters that carry the file suffix aren't listed in the table ๐Ÿ“Ž

Media Type                 Parameters                     File Suffix
---------------------------------------------------------------------
application/pkcs7-mime     N/A                            N/A

multipart/signed           protocol=                      N/A
                           "application/pkcs7-signature"

application/octet-stream   N/A                            p7m, p7s,
                                                          p7c, p7z

4. Certificate Processing ๐ŸŽ€

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

for initial S/MIME deployment, a user agent could automatically send a message to an intended recipient asking for their certificate, with the reply signed ๐Ÿ’Œ receiving and sending agents SHOULD also provide a way for users to "store and protect" certificates for correspondents, so they can be retrieved later on ๐Ÿ”

4.1. Key Pair Generation ๐Ÿ—๏ธ

all key pairs MUST be generated from a good source of non-deterministic random input [RFC4086], and the private key MUST be protected in a secure fashion ๐Ÿ›ก๏ธ

an S/MIME user agent MUST NOT generate asymmetric keys smaller than 2048 bits for use with an RSA signature algorithm ๐Ÿšซ no tiny keys, please and thank you ๐Ÿ™…โ€โ™€๏ธ

for 2048-bit through 4096-bit RSA with SHA-256, check out [RFC5754] and [FIPS186-4]. the first one gives you the signature algorithm's OID, and the second one defines the algorithm itself ๐Ÿง 

for RSASSA-PSS with SHA-256, see [RFC4056]. for RSAES-OAEP, see [RFC3560] ๐ŸŒธ

4.2. Signature Generation โœ๏ธ

here are the requirements for an S/MIME agent when it's generating RSA and RSASSA-PSS signatures:

        key size <= 2047 : SHOULD NOT (Note 2)
2048 <= key size <= 4096 : SHOULD     (Note 1)
4096 <  key size         : MAY        (Note 1)

Note 1: See Security Considerations in Section 6.
Note 2: See Historical Mail Considerations in Appendix B.

key sizes for ECDSA and EdDSA are fixed by the curve ๐ŸŒˆ

4.3. Signature Verification โœ…

here are the requirements for S/MIME receiving agents when they're verifying RSA and RSASSA-PSS signatures:

        key size <= 2047 : SHOULD NOT (Note 2)
2048 <= key size <= 4096 : MUST       (Note 1)
4096 <  key size         : MAY        (Note 1)

Note 1: See Security Considerations in Section 6.
Note 2: See Historical Mail Considerations in Appendix B.

key sizes for ECDSA and EdDSA are fixed by the curve ๐Ÿงš

4.4. Encryption ๐Ÿ”’

here are the requirements for an S/MIME agent when it's setting up keys for content encryption with the RSA and RSA-OAEP algorithms:

        key size <= 2047 : SHOULD NOT (Note 2)
2048 <= key size <= 4096 : SHOULD     (Note 1)
4096 <  key size         : MAY        (Note 1)

Note 1: See Security Considerations in Section 6.
Note 2: See Historical Mail Considerations in Appendix B.

key sizes for ECDH are fixed by the curve ๐Ÿ’œ

4.5. Decryption ๐Ÿ”“

here are the requirements for an S/MIME agent when it's setting up keys for content decryption with the RSA and RSAES-OAEP algorithms:

        key size <= 2047 : MAY        (Note 2)
2048 <= key size <= 4096 : MUST       (Note 1)
4096 <  key size         : MAY        (Note 1)

Note 1: See Security Considerations in Section 6.
Note 2: See Historical Mail Considerations in Appendix B.

key sizes for ECDH are fixed by the curve ๐Ÿ“


5. IANA Considerations ๐Ÿ—‚๏ธ

this section does three things ๐Ÿ’โ€โ™€๏ธ (1) it updates the media type registrations for application/pkcs7-mime and application/pkcs7-signature so they point to this document instead of RFC 5751, (2) it adds authEnveloped-data to the list of values for smime-type, and (3) it updates references from RFC 5751 to this document in general ๐Ÿซถ

other documents can define additional media types for S/MIME too, so this isn't the only one ๐ŸŒŸ

5.1. Media Type for application/pkcs7-mime ๐Ÿ“จ

Type name: application

Subtype Name: pkcs7-mime

Required Parameters: NONE

Optional Parameters: smime-type
                     name

Encoding Considerations: See Section 3 of this document

Security Considerations: See Section 6 of this document

Interoperability Considerations: See Sections 1-6 of this document

Published Specification: RFC 2311, RFC 2633, RFC 5751,
                         and this document

Applications that use this media type: Security applications

Fragment identifier considerations: N/A

Additional information:
    Deprecated alias names for this type: N/A
    Magic number(s): N/A
    File extensions(s): See Section 3.2.1 of this document
    Macintosh file type code(s): N/A

Person & email address to contact for further information:
   The IESG <iesg@ietf.org>

Intended usage: COMMON

Restrictions on usage: NONE

Author: Sean Turner

Change Controller: LAMPS working group delegated from the IESG

5.2. Media Type for application/pkcs7-signature โœ๏ธ

Type name: application

Subtype Name: pkcs7-signature

Required Parameters: N/A

Optional Parameters: N/A

Encoding Considerations: See Section 3 of this document

Security Considerations: See Section 6 of this document

Interoperability Considerations: See Sections 1-6 of this document

Published Specification: RFC 2311, RFC 2633, RFC 5751,
                         and this document

Applications that use this media type: Security applications

Fragment identifier considerations: N/A

Additional information:
    Deprecated alias names for this type: N/A
    Magic number(s): N/A
    File extensions(s): See Section 3.2.1 of this document
    Macintosh file type code(s): N/A

Person & email address to contact for further information:
   The IESG <iesg@ietf.org>

Intended usage: COMMON

Restrictions on usage: N/A

Author: Sean Turner

Change Controller: LAMPS working group delegated from the IESG

5.3. authEnveloped-data smime-type ๐Ÿ†•

IANA has registered the following value in the "Parameter Values for the smime-type Parameter" registry ๐ŸŽ‰

smime-type value: authEnveloped-data

Reference: RFC 8551, Section 3.2.2

5.4. Reference Updates ๐Ÿ”„

IANA is to update all references to RFC 5751 to this document. the known registries to be updated are "CoAP Content-Formats" and "media-types" ๐Ÿ’–

6. Security Considerations โœจ

okay bestie, this is the security section and it is SERIOUS, so let's gooo ๐Ÿ”’๐Ÿ’… Cryptographic algorithms get broken or weakened over time, so implementers and users need to keep checking that the algorithms in this document still give the security level they're supposed to ๐Ÿ•ฐ๏ธ. The IETF will drop documents about the current state of the art from time to time, and the examples are:

  • The Million Message Attack described in RFC 3218 [RFC3218]. ๐Ÿ˜ฑ
  • The Diffie-Hellman "small-subgroup" attacks described in RFC 2785 [RFC2785]. ๐Ÿ™ˆ
  • The attacks against hash algorithms described in RFC 4270 [RFC4270]. ๐Ÿ’€

This spec uses Public-Key Cryptography, so it's assumed the private key is protected so nobody unauthorized can access or change it ๐Ÿ”. Protect that key like it's your diary, periodt ๐Ÿ“”.

Okay, now the vibe check on value. It's basically impossible for most people or software to figure out how valuable a message's content is ๐Ÿคทโ€โ™€๏ธ. It's also impossible for most people or software to estimate what it actually costs to crack an encrypted message that uses a key of a particular size ๐Ÿ’ธ. And figuring out the cost of a failed decryption, when the recipient can't process the content, is pretty hard too ๐Ÿ˜ตโ€๐Ÿ’ซ. So picking between key sizes (or deciding to just send plaintext) is also impossible for most people or software. BUT people make these calls all the time anyway, so this spec gives a framework for using those estimates when choosing algorithms ๐Ÿ“Šโœจ.

The 2048-bit RSA key size in this spec is picked to give at least 100 bits of security ๐ŸŒˆ๐Ÿ’–. The key sizes you MUST support to conform seem good for the Internet, based on [RFC3766]. Of course, some environments, like financial and medical systems, might pick different key sizes ๐Ÿฆ๐Ÿฅ. So an implementation MAY support key sizes bigger than the ones recommended here ๐ŸŽ€.

Receiving agents that validate signatures and sending agents that encrypt messages need to be careful about how much crypto processing they're doing when they use keys bigger than the ones this spec mandates โš ๏ธ. An attacker could send certificates with keys that cause excessive processing, for example keys bigger than this spec mandates, because those keys could swamp the processing element ๐ŸŒŠ. Agents that use such keys without first validating the certificate to a trust anchor are advised to have some kind of cryptographic resource management system to stop these attacks ๐Ÿ›ก๏ธ.

Some algorithms, like RC2, give you basically no real security over just sending plaintext ๐Ÿ’€. Others, like TripleDES, do provide security but aren't considered state of the art anymore ๐Ÿ“‰. S/MIME REQUIRES current state-of-the-art algorithms like AES, and it lets you announce your crypto capabilities to the people you talk to ๐Ÿ“ฃ. That way the sender can use the strongest encryption algorithm you both support ๐Ÿ’ช. Using algorithms like RC2 is NOT RECOMMENDED unless the only other option is no cryptography at all ๐Ÿ™…โ€โ™€๏ธ.

RSA and DSA keys under 2048 bits are now considered insecure by lots of experts, thanks to advances in computing power ๐Ÿ–ฅ๏ธ๐Ÿ’ฅ, and they SHOULD NOT be used to protect messages anymore ๐Ÿšซ. These keys used to be considered secure, so processing old signed and encrypted mail will often mean using weak keys ๐Ÿ“ฌ. Implementations that want to support previous S/MIME versions or process old messages need to weigh the security risks of smaller keys (like spoofed messages) against the costs of denial of service โš–๏ธ. If an implementation supports verifying digital signatures made with RSA and DSA keys under 1024 bits, it MUST warn the user ๐Ÿšจ. Implementers SHOULD give different warnings for newly received messages versus previously stored ones ๐Ÿ—‚๏ธ. Server implementations, like secure mail list servers, where warning users isn't appropriate, SHOULD reject messages with weak signatures ๐Ÿ™….

Implementers SHOULD know that one person can have multiple active key pairs at the same time ๐Ÿ”‘๐Ÿ”‘. For example, one key pair can handle confidentiality while a different one handles digital signatures โœ๏ธ.

If a sending agent sends the same message using different strengths of cryptography, an attacker watching the channel might be able to read 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 used for the original ๐Ÿ™…โ€โ™€๏ธ.

Modification of the ciphertext in EnvelopedData can go undetected if authentication isn't also used, which is what happens when you send EnvelopedData without wrapping it in SignedData or putting SignedData inside it ๐Ÿซฃ. This is one of the reasons we're moving from EnvelopedData to AuthEnvelopedData, since the authenticated encryption algorithms provide authentication without needing the SignedData layer ๐Ÿง.

If an implementation cares about compliance with the National Institute of Standards and Technology (NIST) key size recommendations, check out [SP800-57] ๐Ÿ“š.

If messaging environments use the fact that a message is signed to change how it's processed (like running rules or UI display hints) without first verifying the signature and knowing its state, that can lead to incorrect handling ๐Ÿ™ƒ. Visual indicators on messages may need to have the signature validation code checked periodically if the indicator is supposed to show the current status of a message ๐Ÿ”.

Lots of people assume that using an authenticated encryption algorithm is all you need to authenticate the sender. In almost all cases, that is NOT a correct statement ๐Ÿ™…โ€โ™€๏ธ. A few preconditions have to hold for an authenticated encryption algorithm to provide this service:

  • The starting key MUST be bound to a single entity. Using a group key only would let you say a message was sent by one of the entities that held the key, but it won't identify a specific entity ๐Ÿ‘ฅโŒ.
  • The message MUST have exactly one sender and one recipient. With more than one recipient, the second recipient could strip the first recipient off and make a message the first recipient would believe came from the sender ๐ŸŽญ.
  • A direct path MUST exist from the starting key to the key used as the CEK. That path needs to guarantee that no third party could have seen the resulting CEK. This means you need an algorithm called a "Direct Encryption" or a "Direct Key Agreement" algorithm in other contexts. So the starting key is either (1) used directly as the CEK or (2) used to create a secret that then gets turned into the CEK via a KDF step ๐Ÿ”.

S/MIME implementations almost universally use ephemeral-static rather than static-static key agreement, and they don't use a shared secret for encryption, so the first precondition isn't met ๐Ÿ™…โ€โ™€๏ธ. [RFC6278] defines how to use static-static key agreement with CMS, so the first precondition CAN be met ๐ŸŽ‰. Right now, all S/MIME key agreement methods derive a key-encryption key (KEK) and wrap a CEK, which violates the third precondition above ๐Ÿ˜ฌ. New key agreement algorithms that directly create the CEK without an intervening KEK would need to be defined ๐Ÿ› ๏ธ.

Even when all the preconditions are met and the origin of a message is established by an authenticated encryption algorithm, users need to know there's NO WAY to prove this to a third party ๐Ÿ™ˆ. That's because either party can create the message (or just alter the content), since the CEK is known to both of them ๐Ÿ‘ฏ. So the origin is always built on a presumption that "I did not send this message to myself." ๐Ÿชž

All of the authenticated encryption algorithms in this document use counter mode for the encryption part ๐Ÿ”ข. That means the plaintext length is always known, because the ciphertext length and plaintext length are always the same ๐Ÿ“. This info can let passive observers infer things just from the message length ๐Ÿ‘€. Applications where this matters need to add some kind of padding so the message length doesn't give that away ๐Ÿงธ.

When compression is used with encryption, it can add an extra layer of security ๐Ÿ—œ๏ธ. But you have to be careful when designing a protocol that relies on compression, so you don't create a compression oracle โš ๏ธ. Compression oracle attacks need adaptive input to the process and attack the unknown content of a message based on the length of the compressed output ๐Ÿ•ต๏ธโ€โ™€๏ธ. This means no attack on the encryption key is necessarily required ๐Ÿ”“.

A recent paper on S/MIME and OpenPGP email security [Efail] pointed out a bunch of problems with the current S/MIME specs and how people have implemented mail clients ๐Ÿ“„๐Ÿ˜ฌ. Because of how CBC mode works, its modes allow plaintexts to be malleable ๐Ÿงˆ. That malleability lets attackers change the ciphertext and, if parts of the plaintext are known, create arbitrary blocks of plaintext ๐Ÿช„. These changes can happen without tripping the weak integrity check in CBC mode ๐Ÿ™€. This type of attack can be prevented by using an Authenticated Encryption with Associated Data (AEAD) algorithm with a more robust integrity check during decryption ๐Ÿ›ก๏ธ. So it is RECOMMENDED that mail systems migrate to AES-GCM as quickly as possible, and that decrypted content is not acted on before the integrity check finishes ๐Ÿƒโ€โ™€๏ธ๐Ÿ’จ.

The other attack highlighted in [Efail] comes from how mail clients handle HTML and multipart/mixed messages ๐Ÿงฉ. Clients MUST require that a text/html content type be a complete HTML document (per [RFC1866]) ๐Ÿ“‘. Clients SHOULD treat each piece of the multipart/mixed construct as having a different origin ๐ŸŒ. Clients MUST treat each encrypted or signed piece of a MIME message as having a different origin, both from unprotected content and from each other ๐Ÿ”๐Ÿ”’.


7. References ๐Ÿ“š

7.1. Reference Conventions ๐ŸŽ€

[ASN.1] refers to [X.680], [X.681], [X.682], and [X.683].

[CMS] refers to [RFC5083] and [RFC5652].

[ESS] refers to [RFC2634] and [RFC5035].

[MIME-SPEC] refers to [RFC2045], [RFC2046], [RFC2047], [RFC2049], [RFC6838], and [RFC4289].

[SMIMEv2] refers to [RFC2311], [RFC2312], [RFC2313], [RFC2314], and [RFC2315].

[SMIMEv3] refers to [RFC2630], [RFC2631], [RFC2632], [RFC2633], [RFC2634], and [RFC5035].

[SMIMEv3.1] refers to [RFC2634], [RFC5035], [RFC5652], [RFC5750], and [RFC5751].

[SMIMEv3.2] refers to [RFC2634], [RFC3850], [RFC3851], [RFC3852], and [RFC5035].

[SMIMEv4] refers to [RFC2634], [RFC5035], [RFC5652], [RFC8550], and this document. ๐Ÿ’–

7.2. Normative References โœจ

Okay bestie, this is the normative reference list, so it's where all the building blocks live ๐Ÿงฑ๐Ÿ’– Every entry is a doc the spec leans on, so I'm keeping every single detail, no cap ๐Ÿ’…

[CHARSETS] IANA, "Character sets assigned by IANA", <http://www.iana.org/assignments/character-sets>.

[FIPS186-4] National Institute of Standards and Technology (NIST), "Digital Signature Standard (DSS)", Federal Information Processing Standards Publication 186-4, DOI 10.6028/NIST.FIPS.186-4, July 2013, <https://nvlpubs.nist.gov/nistpubs/fips/ nist.fips.186-4.pdf>.

[RFC1847] Galvin, J., Murphy, S., Crocker, S., and N. Freed, "Security Multiparts for MIME: Multipart/Signed and Multipart/Encrypted", RFC 1847, DOI 10.17487/RFC1847, October 1995, <https://www.rfc-editor.org/info/rfc1847>.

[RFC2045] Freed, N. and N. Borenstein, "Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies", RFC 2045, DOI 10.17487/RFC2045, November 1996, <https://www.rfc-editor.org/info/rfc2045>.

[RFC2046] Freed, N. and N. Borenstein, "Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types", RFC 2046, DOI 10.17487/RFC2046, November 1996, <https://www.rfc-editor.org/info/rfc2046>.

[RFC2047] Moore, K., "MIME (Multipurpose Internet Mail Extensions) Part Three: Message Header Extensions for Non-ASCII Text", RFC 2047, DOI 10.17487/RFC2047, November 1996, <https://www.rfc-editor.org/info/rfc2047>.

[RFC2049] Freed, N. and N. Borenstein, "Multipurpose Internet Mail Extensions (MIME) Part Five: Conformance Criteria and Examples", RFC 2049, DOI 10.17487/RFC2049, November 1996, <https://www.rfc-editor.org/info/rfc2049>.

[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, <https://www.rfc-editor.org/info/rfc2119>.

[RFC2183] Troost, R., Dorner, S., and K. Moore, Ed., "Communicating Presentation Information in Internet Messages: The Content-Disposition Header Field", RFC 2183, DOI 10.17487/RFC2183, August 1997, <https://www.rfc-editor.org/info/rfc2183>.

[RFC2634] Hoffman, P., Ed., "Enhanced Security Services for S/MIME", RFC 2634, DOI 10.17487/RFC2634, June 1999, <https://www.rfc-editor.org/info/rfc2634>.

[RFC3274] Gutmann, P., "Compressed Data Content Type for Cryptographic Message Syntax (CMS)", RFC 3274, DOI 10.17487/RFC3274, June 2002, <https://www.rfc-editor.org/info/rfc3274>.

[RFC3370] Housley, R., "Cryptographic Message Syntax (CMS) Algorithms", RFC 3370, DOI 10.17487/RFC3370, August 2002, <https://www.rfc-editor.org/info/rfc3370>.

[RFC3560] Housley, R., "Use of the RSAES-OAEP Key Transport Algorithm in Cryptographic Message Syntax (CMS)", RFC 3560, DOI 10.17487/RFC3560, July 2003, <https://www.rfc-editor.org/info/rfc3560>.

[RFC3565] Schaad, J., "Use of the Advanced Encryption Standard (AES) Encryption Algorithm in Cryptographic Message Syntax (CMS)", RFC 3565, DOI 10.17487/RFC3565, July 2003, <https://www.rfc-editor.org/info/rfc3565>.

[RFC4289] Freed, N. and J. Klensin, "Multipurpose Internet Mail Extensions (MIME) Part Four: Registration Procedures", BCP 13, RFC 4289, DOI 10.17487/RFC4289, December 2005, <https://www.rfc-editor.org/info/rfc4289>.

[RFC4056] Schaad, J., "Use of the RSASSA-PSS Signature Algorithm in Cryptographic Message Syntax (CMS)", RFC 4056, DOI 10.17487/RFC4056, June 2005, <https://www.rfc-editor.org/info/rfc4056>.

[RFC4086] Eastlake 3rd, D., Schiller, J., and S. Crocker, "Randomness Requirements for Security", BCP 106, RFC 4086, DOI 10.17487/RFC4086, June 2005, <https://www.rfc-editor.org/info/rfc4086>.

[RFC5083] Housley, R., "Cryptographic Message Syntax (CMS) Authenticated-Enveloped-Data Content Type", RFC 5083, DOI 10.17487/RFC5083, November 2007, <https://www.rfc-editor.org/info/rfc5083>.

[RFC5084] Housley, R., "Using AES-CCM and AES-GCM Authenticated Encryption in the Cryptographic Message Syntax (CMS)", RFC 5084, DOI 10.17487/RFC5084, November 2007, <https://www.rfc-editor.org/info/rfc5084>.

[RFC5652] Housley, R., "Cryptographic Message Syntax (CMS)", STD 70, RFC 5652, DOI 10.17487/RFC5652, September 2009, <https://www.rfc-editor.org/info/rfc5652>.

[RFC5753] Turner, S. and D. Brown, "Use of Elliptic Curve Cryptography (ECC) Algorithms in Cryptographic Message Syntax (CMS)", RFC 5753, DOI 10.17487/RFC5753, January 2010, <https://www.rfc-editor.org/info/rfc5753>.

[RFC5754] Turner, S., "Using SHA2 Algorithms with Cryptographic Message Syntax", RFC 5754, DOI 10.17487/RFC5754, January 2010, <https://www.rfc-editor.org/info/rfc5754>.

[RFC6838] Freed, N., Klensin, J., and T. Hansen, "Media Type Specifications and Registration Procedures", BCP 13, RFC 6838, DOI 10.17487/RFC6838, January 2013, <https://www.rfc-editor.org/info/rfc6838>.

[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, <https://www.rfc-editor.org/info/rfc8174>.

[RFC8418] Housley, R., "Use of the Elliptic Curve Diffie-Hellman Key Agreement Algorithm with X25519 and X448 in the Cryptographic Message Syntax (CMS)", RFC 8418, DOI 10.17487/RFC8418, August 2018, <https://www.rfc-editor.org/info/rfc8418>.

[RFC8419] Housley, R., "Use of Edwards-Curve Digital Signature Algorithm (EdDSA) Signatures in the Cryptographic Message Syntax (CMS)", RFC 8419, DOI 10.17487/RFC8419, August 2018, <https://www.rfc-editor.org/info/rfc8419>.

[RFC8550] Schaad, J., Ramsdell, B., and S. Turner, "Secure/Multipurpose Internet Mail Extensions (S/MIME) Version 4.0 Certificate Handling", RFC 8550, DOI 10.17487/RFC8550, April 2019, <https://www.rfc-editor.org/info/rfc8550>.

[X.680] "Information Technology - Abstract Syntax Notation One (ASN.1): Specification of basic notation", ITU-T Recommendation X.680, ISO/IEC 8824-1:2015, August 2015, <https://www.itu.int/rec/T-REC-X.680>.

[X.681] "Information Technology - Abstract Syntax Notation One (ASN.1): Information object specification", ITU-T Recommendation X.681, ISO/IEC 8824-2:2015, August 2015, <https://www.itu.int/rec/T-REC-X.681>.

[X.682] "Information Technology - Abstract Syntax Notation One (ASN.1): Constraint specification", ITU-T Recommendation X.682, ISO/IEC 8824-3:2015, August 2015, <https://www.itu.int/rec/T-REC-X.682>.

[X.683] "Information Technology - Abstract Syntax Notation One (ASN.1): Parameterization of ASN.1 specifications", ITU-T Recommendation X.683, ISO/IEC 8824-4:2015, August 2015, <https://www.itu.int/rec/T-REC-X.683>.

[X.690] "Information Technology - ASN.1 encoding rules: Specification of Basic Encoding Rules (BER), Canonical Encoding Rules (CER) and Distinguished Encoding Rules (DER)", ITU-T Recommendation X.690, ISO/IEC 8825-1:2015, August 2015, <https://www.itu.int/rec/T-REC-X.690>.

7.3. Informative References ๐Ÿฆ‹

okay so these are the bonus reads, bestie ๐Ÿ“š they aren't strictly required to build this, but they're the receipts for everything else. the big ones are the S/MIME and CMS lineage, plus some crypto and security background that's lowkey essential if you want the whole picture ๐Ÿ’…


Appendix A. ASN.1 Module โœจ

Note time! The ASN.1 module below is the same as the one in RFC 5751 [SMIMEv2] and RFC 3851 [SMIMEv3.1], with one exception: the preferBinaryInside ASN.1 comment got changed in RFC 3851 [SMIMEv3.1]. If you need a module that works with current ASN.1 standards, check out [RFC6268]. This module uses the 1988 version of ASN.1. ๐Ÿ’…

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 [CMS]
   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 by the 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
}

-- "receipentKeyId" is spelled incorrectly but is kept for
-- historical reasons.

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

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

-- The preferBinaryInside OID indicates an ability to receive
-- messages with binary encoding inside the CMS wrapper.
-- The preferBinaryInside attribute's value field is ABSENT.

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

-- The following is a list of OIDs to be used with S/MIME v3.

-- Signature Algorithms Not Found in [RFC3370], [RFC5754], [RFC4056],
-- and [RFC3560]

--
-- 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

Appendix B. Historic Mail Considerations โœจ

okay bestie, this appendix is the "what about my old emails?" section and it's lowkey so important ๐Ÿฅบ๐Ÿซถ over the years the recommended algorithms kept changing with every update, so if your user agent only speaks the current set, some of your older emails might just... stop opening ๐Ÿ’€ it is strongly suggested that user agents implement some of the algorithms below so historic mail stays readable ๐ŸŽ€

heads up: this appendix references a bunch of documents that have been obsoleted or replaced. that's on purpose ๐Ÿ’… the newer docs often don't have the same info in them, so the old ones are still needed ๐Ÿฆ‹

B.1. DigestAlgorithmIdentifier ๐ŸŒธ

these algorithms got some level of support in previous S/MIME specs:

  • SHA-1 was dropped in [SMIMEv4]. it's no longer considered secure bc it's no longer collision resistant ๐Ÿ˜ญ the IETF statement on SHA-1 is in [RFC6194], but it's kinda outdated compared to the latest advances ๐Ÿ•ฐ๏ธ
  • MD5 was dropped in [SMIMEv4]. same deal, no longer secure because it's no longer collision resistant ๐Ÿ’€ details are in [RFC6151] ๐Ÿงš

B.2. Signature Algorithms ๐Ÿ”

okay so validating signatures on really historic messages is a whole thing ๐Ÿ™ˆ that's why it's strongly suggested that user agents treat these signatures differently from signatures on current messages. the problems include:

  • certification authorities don't have to keep certificates on a CRL beyond one update after a certificate has expired. so unless CRLs get cached as part of the message, it's not always possible to check whether a certificate was revoked ๐Ÿ˜ฌ the same problems exist with Online Certificate Status Protocol (OCSP) responses, since they might be based on a CRL instead of the certificate database ๐Ÿซ 
  • RSA and DSA keys under 2048 bits are now considered by lots of experts to be cryptographically insecure (thanks, advances in computing power ๐Ÿ–ฅ๏ธ๐Ÿ’ฅ). smaller keys used to be considered secure, so processing historic signed messages will often mean using weak keys. implementations that want to support previous versions of S/MIME or process old messages need to weigh the security risks from smaller key sizes (like spoofed messages) against the costs of denial of service ๐Ÿ›ก๏ธ

[SMIMEv3.1] set the lower limit on suggested key sizes for creating and validation at 1024 bits. before that, the lower bound was 512 bits ๐ŸŽ€

  • hash functions used to validate signatures on historic messages may no longer be considered secure (see below). there aren't any known practical pre-image or second pre-image attacks against MD5 or SHA-1 right now, BUT they're no longer considered collision resistant, which means the security levels of those signatures are generally considered suspect ๐Ÿคจ if a message is known to be historic and it's been in the client's possession for a while, it might still be considered secure ๐Ÿคทโ€โ™€๏ธ
  • the previous two issues apply to the certificates used to validate the binding of the public key to the identity that signed the message too ๐Ÿ’…

the following algorithms have been called out for some level of support by previous S/MIME specs:

  • RSA with MD5 was dropped in [SMIMEv4]. MD5 is no longer considered secure, bc it's no longer collision resistant. details in [RFC6151] ๐ŸŒˆ
  • RSA and DSA with SHA-1 were dropped in [SMIMEv4]. SHA-1 is no longer considered secure, bc it's no longer collision resistant ๐Ÿ˜ญ the IETF statement on SHA-1 is in [RFC6194], but it's outdated relative to the most recent advances ๐Ÿ•ฐ๏ธ
  • DSA with SHA-256 was dropped in [SMIMEv4]. DSA has been replaced by elliptic curve versions โœจ

as "mandatory to implement" requirements changed over time, some interoperability problems showed up ๐Ÿซฃ

  • 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 ๐Ÿ’€
  • S/MIME v3 clients might only implement signing or signature verification using id-dsa-with-sha1, and they might also use id-dsa as an AlgorithmIdentifier in this field ๐Ÿ™ƒ
  • note that S/MIME v3.1 clients support verifying id-dsa-with-sha1 and rsaEncryption, and they might not implement sha256WithRSAEncryption ๐Ÿฅด

NOTE: Receiving clients SHOULD recognize id-dsa as equivalent to id-dsa-with-sha1. ๐Ÿซถ

for 512-bit RSA with SHA-1, see [RFC3370] and [FIPS186-2] without Change Notice 1. for 512-bit RSA with SHA-256, see [RFC5754] and [FIPS186-2] without Change Notice 1. and for 1024-bit through 2048-bit RSA with SHA-256, see [RFC5754] and [FIPS186-2] with Change Notice 1. the first reference gives the signature algorithm's OID, and the second gives the signature algorithm's definition ๐Ÿ“šโœจ

for 512-bit DSA with SHA-1, see [RFC3370] and [FIPS186-2] without Change Notice 1. for 512-bit DSA with SHA-256, see [RFC5754] and [FIPS186-2] without Change Notice 1. for 1024-bit DSA with SHA-1, see [RFC3370] and [FIPS186-2] with Change Notice 1. and for 1024-bit and above DSA with SHA-256, see [RFC5754] and [FIPS186-4]. the first reference gives the signature algorithm's OID, and the second gives the signature algorithm's definition ๐ŸŽ€

B.3. ContentEncryptionAlgorithmIdentifier ๐Ÿ”’

these algorithms got some level of support in previous S/MIME specs:

  • RC2/40 [RFC2268] was dropped in [SMIMEv3.2]. it's known to be insecure, and if you support it, only use it to decrypt existing email ๐Ÿ™…โ€โ™€๏ธ
  • DES EDE3 CBC [TripleDES], also known as "tripleDES", was dropped in [SMIMEv4]. it's removed from the supported list bc (1) it has a 64-bit block size and (2) it offers less than 128 bits of security ๐Ÿ˜ญ it should only be supported to decrypt existing email, and it should NOT be used to encrypt new emails ๐Ÿšซ

B.4. KeyEncryptionAlgorithmIdentifier ๐Ÿ—๏ธ

these algorithms got some level of support in previous S/MIME specs:

  • DH ephemeral-static mode, as specified in [RFC3370] and [SP800-57], was dropped in [SMIMEv4] ๐Ÿฅ€
  • RSA key sizes have been increased over time. decrypting old mail with smaller key sizes is reasonable, but new mail should use the updated key sizes ๐Ÿ’–

for 1024-bit DH, see [RFC3370]. for 1024-bit and larger DH, see [SP800-56A]. regardless, use the KDF, which is from X9.42 and specified in [RFC3370] ๐Ÿงš

Appendix C. Moving S/MIME v2 Message Specification to Historic Status ๐Ÿ“œ

the S/MIME v3 [SMIMEv3], v3.1 [SMIMEv3.1], and v3.2 [SMIMEv3.2] specs are backward compatible with the S/MIME v2 Message Specification [SMIMEv2], except for the algorithms (dropped RC2/40 requirement and added DSA and RSASSA-PSS requirements). so RFC 2311 [SMIMEv2] was moved to Historic status ๐Ÿฆ‹

Acknowledgements ๐Ÿซถ

many thanks to the other authors of the S/MIME version 2 Message Specification RFC: Steve Dusse, Paul Hoffman, Laurence Lundblade, and Lisa Repka ๐Ÿ’œ without v2, there wouldn't be a v3, v3.1, v3.2, or v4.0 ๐ŸŒˆ

some of the examples in this document were copied from [RFC4134]. thanks to the people who wrote and verified the examples in that document ๐Ÿ™Œ

a bunch of S/MIME Working Group members also worked super hard and contributed to this document ๐Ÿ’ช any list of people is doomed to omission, and for that I apologize ๐Ÿฅน 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, Alfred Hoenes, Paul Hoffman, Russ Housley, William Ottaway, and John Pawling โœจ

the version 4 update to the S/MIME documents was done under the auspices of the LAMPS Working Group ๐ŸŽ€

Authors' Addresses ๐Ÿ’Œ

Jim Schaad August Cellars

Email: ietf@augustcellars.com

Blake Ramsdell Brute Squad Labs, Inc.

Email: blaker@gmail.com

Sean Turner sn3rd

Email: sean@sn3rd.com

๐Ÿ“ฆ where this page comes from