RFC 7468

Textual Encodings of PKIX, PKCS, and CMS Structures

πŸ“… published April 2015, from ietf

RFC 7468: Textual Encodings of PKIX, PKCS, and CMS Structures πŸŽ€

okay bestie, this is RFC 7468 πŸ’– It's from April 2015, it's on the Standards Track (ISSN 2070-1721), and the authors are S. Josefsson (SJD AB) and S. Leonard (Penango, Inc.). The header doesn't list anything it obsoletes or updates, so there's no drama there 🫢

Abstract ✨

so this doc describes and discusses the textual encodings of PKIX (the Public-Key Infrastructure X.509 stuff), PKCS (Public-Key Cryptography Standards), and CMS (Cryptographic Message Syntax) πŸ” these encodings are already well-known, a bunch of apps and libraries use them, and they're everywhere 😭 the doc writes down the de facto rules that existing implementations already follow, and then defines them so future implementations can actually interoperate πŸ’…

Status of This Memo πŸ“œ

this is an Internet Standards Track document πŸ”₯

it's a product of the Internet Engineering Task Force (IETF), so 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 Section 2 of RFC 5741.

for the current status, any errata, and how to give feedback, go to http://www.rfc-editor.org/info/rfc7468 🌸

Copyright (c) 2015 IETF Trust and the persons identified as the document authors. All rights reserved. ✨

this doc is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) as they stand on the publication date. please read these carefully, because they're the ones that spell out your rights and restrictions for this doc πŸ‘€ also, any Code Components pulled out of this doc have to include the Simplified BSD License text (see Section 4.e of the Trust Legal Provisions), and they come with no warranty, as the Simplified BSD License describes.

Table of Contents πŸ—‚οΈ

1.  Introduction  . . . . . . . . . . . . . . . . . . . . . . . .   2
2.  General Considerations  . . . . . . . . . . . . . . . . . . .   3
3.  ABNF  . . . . . . . . . . . . . . . . . . . . . . . . . . . .   5
4.  Guide . . . . . . . . . . . . . . . . . . . . . . . . . . . .   7
5.  Textual Encoding of Certificates  . . . . . . . . . . . . . .   8
  5.1.  Encoding  . . . . . . . . . . . . . . . . . . . . . . . .   8
  5.2.  Explanatory Text  . . . . . . . . . . . . . . . . . . . .   9
  5.3.  File Extension  . . . . . . . . . . . . . . . . . . . . .   9
6.  Textual Encoding of Certificate Revocation Lists  . . . . . .  10
7.  Textual Encoding of PKCS #10 Certification Request Syntax . .  11
8.  Textual Encoding of PKCS #7 Cryptographic Message Syntax  . .  11
9.  Textual Encoding of Cryptographic Message Syntax  . . . . . .  12
10. One Asymmetric Key and the Textual Encoding of PKCS #8
    Private Key Info  . . . . . . . . . . . . . . . . . . . . . .  12
11. Textual Encoding of PKCS #8 Encrypted Private Key Info  . . .  13
12. Textual Encoding of Attribute Certificates  . . . . . . . . .  13
13. Textual Encoding of Subject Public Key Info . . . . . . . . .  14
14. Security Considerations . . . . . . . . . . . . . . . . . . .  14
15. References  . . . . . . . . . . . . . . . . . . . . . . . . .  14
  15.1.  Normative References . . . . . . . . . . . . . . . . . .  14
  15.2.  Informative References . . . . . . . . . . . . . . . . .  15
Appendix A.  Non-conforming Examples  . . . . . . . . . . . . . .  17
Appendix B.  DER Expectations . . . . . . . . . . . . . . . . . .  18
Acknowledgements  . . . . . . . . . . . . . . . . . . . . . . . .  19
Authors' Addresses  . . . . . . . . . . . . . . . . . . . . . . .  20

1. Introduction πŸ¦‹

so a bunch of security standards on the Internet define ASN.1 data formats 🧠 they're usually encoded with the Basic Encoding Rules (BER) or the Distinguished Encoding Rules (DER) [X.690], and those are binary, octet-oriented encodings. this doc is all about the textual encodings of these formats:

  1. Certificates, Certificate Revocation Lists (CRLs), and Subject Public Key Info structures from the Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile [RFC5280] πŸ”‘
  2. PKCS #10: Certification Request Syntax [RFC2986] πŸ“
  3. PKCS #7: Cryptographic Message Syntax [RFC2315] πŸ“¦
  4. Cryptographic Message Syntax [RFC5652] πŸ’Œ
  5. PKCS #8: Private-Key Information Syntax [RFC5208], which got renamed to One Asymmetric Key in Asymmetric Key Package [RFC5958], plus the Encrypted Private-Key Information Syntax in those same docs πŸ—οΈ
  6. Attribute Certificates from An Internet Attribute Certificate Profile for Authorization [RFC5755] 🎟️

the big downside of binary formats is that they can't be passed around over text transports like email or plain text docs 😩 the upside of text encodings is that they're easy to edit in regular text editors. for example, you can stick a few certificates together into a certificate chain with copy and paste, which is literally so iconic πŸ’…

the tradition here goes all the way back to Privacy-Enhanced Mail (PEM) [RFC1421], which was based on Marshall Rose's proposal in Message Encapsulation [RFC934]. it's been called the "PEM encapsulation mechanism", "encapsulated PEM message", or (arguably) "PEM printable encoding" 🌷 these days people often just say "PEM encoding". other variations include OpenPGP ASCII armor [RFC4880] and the OpenSSH key file format [RFC4716] 🌈

so basically because of non-coordination or just not paying attention πŸ™ˆ lots of PKIX, PKCS, and CMS libraries ended up with a text-based encoding that looks a lot like PEM but isn't exactly the same. this doc specifies the textual encoding format, writes down the de facto rules most implementations follow, and gives recommendations that will help interoperability going forward πŸ’– it also sets up common names for syntax elements, which reflects how this de facto format has evolved. Peter Gutmann's "X.509 Style Guide" [X.509SG] has a "base64 Encoding" section that describes these formats and has suggestions similar to this doc's. and all the figures are real, working examples, with key lengths and inner contents kept as small as practicable ✨

the key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this doc are to be interpreted as described in RFC 2119 [RFC2119] πŸŽ€

2. General Considerations 🧁

textual encoding starts with a line that has -----BEGIN , a label, and -----. it ends with a line that has -----END , a label, and -----. the stuff in between those lines (the "encapsulation boundaries") is base64-encoded data, following Section 4 of [RFC4648] 🫧 (PEM [RFC1421] called this data the "encapsulated text portion".) stuff before the encapsulation boundaries is allowed, and parsers MUST NOT malfunction when they process it πŸ’€ also, parsers SHOULD ignore whitespace and other non-base64 characters, and they MUST handle different newline conventions πŸ™Œ

the type of data is labeled by the type label in the -----BEGIN line (the pre-encapsulation boundary). for example, the line could be -----BEGIN CERTIFICATE-----, which means the content is a PKIX certificate (more on that below) πŸ“œ generators MUST put the same label on the -----END line (the post-encapsulation boundary) as they put on the matching -----BEGIN line. labels are formally case-sensitive, uppercase, and made up of zero or more characters. they can't have consecutive spaces or hyphen-minuses, and they can't have spaces or hyphen-minuses at either end. parsers MAY disregard the label in the post-encapsulation boundary instead of throwing an error if the labels don't match, because some existing implementations require the labels to match and others don't πŸ€·β€β™€οΈ

there's exactly one space character (SP) between "BEGIN" or "END" and the label. there are exactly five hyphen-minus (aka dash) characters ("-") on both ends of the encapsulation boundaries. no more, no less πŸ”₯

the label type implies that the encoded data follows the specified syntax. parsers MUST handle non-conforming data gracefully 🫢 but not every parser or generator from before this doc behaved consistently. a conforming parser MAY read the contents as another label type, but it ought to be aware of the security implications covered in the Security Considerations section πŸ‘€ the labels in this doc name container formats that aren't tied to any one cryptographic algorithm, which matches algorithm agility. these formats use the ASN.1 AlgorithmIdentifier structure described in Section 4.1.1.2 of [RFC5280].

unlike legacy PEM encoding [RFC1421], OpenPGP ASCII armor, and the OpenSSH key file format, textual encoding does not define or permit headers to be encoded alongside the data 🚫 empty space can show up between the pre-encapsulation boundary and the base64, but generators SHOULD NOT emit that spacing. (that empty area is a throwback to PEM, which had an "encapsulated header portion".) πŸ•°οΈ

implementers need to know that existing parsers differ a LOT on how they handle whitespace 😭 in this doc, "whitespace" means any character or series of characters that represents horizontal or vertical space in typography. in US-ASCII, whitespace is HT (0x09), VT (0x0B), FF (0x0C), SP (0x20), CR (0x0D), and LF (0x0A). "blank" means HT and SP. lines are split by CRLF, CR, or LF. the common ABNF production WSP lines up with "blank", and there's a new production called W for "whitespace". the ABNF in Section 3 is specific to US-ASCII. these encodings can be used on tons of different systems, and also on long-term archival storage like paper or engravings, so implementers ought to follow the spirit rather than the letter of the rules when they generate or parse these formats in environments that aren't strictly US-ASCII 🌍

most existing parsers ignore blanks at the ends of lines. blanks at the beginnings of lines or in the middle of the base64-encoded data are way less compatible πŸ’… these observations are codified in Figure 1. the most lax parser implementations aren't line-oriented at all, and they'll accept any mixture of whitespace outside the encapsulation boundaries (see Figure 2). that kind of lax parsing can accept text that was never meant to be accepted in the first place (for example, because the text was just a snippet or a sample) 😬

generators MUST wrap the base64-encoded lines so each line is exactly 64 characters, except the final line, which holds whatever's left of the data (within the 64-character line boundary). they MUST NOT emit extraneous whitespace. parsers MAY handle other line sizes. these requirements are consistent with PEM [RFC1421] 🌸

files MAY contain multiple textual encoding instances. this happens, for example, when a file has several certificates in it πŸ“‚ whether the instances are ordered or unordered depends on the context 🧚

3. ABNF ✨

okay so the grammar for the textual encoding is written in ABNF [RFC5234], and it is extremely precise bestie πŸ’… Here's the main one, the Standard version πŸŽ€

textualmsg = preeb *WSP eol
             *eolWSP
             base64text
             posteb *WSP [eol]

preeb      = "-----BEGIN " label "-----" ; unlike [RFC1421] (A)BNF,
                                         ; eol is not required (but
posteb     = "-----END " label "-----"   ; see [RFC1421], Section 4.4)

base64char = ALPHA / DIGIT / "+" / "/"

base64pad  = "="

base64line = 1*base64char *WSP eol
base64finl = *base64char (base64pad *WSP eol base64pad /
                          *2base64pad) *WSP eol
                     ; ...AB= <EOL> = <EOL> is not good, but is valid

base64text = *base64line base64finl
       ; we could also use <encbinbody> from RFC 1421, which requires
       ; 16 groups of 4 chars, which means exactly 64 chars per
       ; line, except the final line, but this is more accurate

labelchar  = %x21-2C / %x2E-7E    ; any printable character,
                                  ; except hyphen-minus

label      = [ labelchar *( ["-" / SP] labelchar ) ]       ; empty ok

eol        = CRLF / CR / LF

eolWSP     = WSP / CR / LF                        ; compare with LWSP

Figure 1: ABNF (Standard)

Next up is the Lax version, which is way more chill about what it accepts πŸ¦‹

laxtextualmsg    = *W preeb
                   laxbase64text
                   posteb *W

W                = WSP / CR / LF / %x0B / %x0C           ; whitespace

laxbase64text    = *(W / base64char) [base64pad *W [base64pad *W]]

Figure 2: ABNF (Lax)

And last but not least, the Strict one, which is the most picky and honestly iconic πŸ‘‘

stricttextualmsg = preeb eol
                   strictbase64text
                   posteb eol

strictbase64finl = *15(4base64char) (4base64char / 3base64char
                     base64pad / 2base64char 2base64pad) eol

base64fullline   = 64base64char eol

strictbase64text = *base64fullline strictbase64finl

Figure 3: ABNF (Strict)

New implementations SHOULD emit the strict format (Figure 3) specified above. The parsing strategy you pick depends on what you're using it for ✨

4. Guide 🧚

So these figures are basically your cheat sheet πŸ“ They sum up the structures, encodings, and references you'll see in the sections coming up 🌸

Sec. Label                  ASN.1 Type              Reference Module
----+----------------------+-----------------------+---------+----------
  5  CERTIFICATE            Certificate             [RFC5280] id-pkix1-e
  6  X509 CRL               CertificateList         [RFC5280] id-pkix1-e
  7  CERTIFICATE REQUEST    CertificationRequest    [RFC2986] id-pkcs10
  8  PKCS7                  ContentInfo             [RFC2315] id-pkcs7*
  9  CMS                    ContentInfo             [RFC5652] id-cms2004
 10  PRIVATE KEY            PrivateKeyInfo ::=      [RFC5208] id-pkcs8
                            OneAsymmetricKey        [RFC5958] id-aKPV1
 11  ENCRYPTED PRIVATE KEY  EncryptedPrivateKeyInfo [RFC5958] id-aKPV1
 12  ATTRIBUTE CERTIFICATE  AttributeCertificate    [RFC5755] id-acv2
 13  PUBLIC KEY             SubjectPublicKeyInfo    [RFC5280] id-pkix1-e

Figure 4: Convenience Guide

Now the OID lineup, which is giving pure ASN.1 energy πŸ”₯

-----------------------------------------------------------------------
id-pkixmod OBJECT IDENTIFIER ::= {iso(1) identified-organization(3)
           dod(6) internet(1) security(5) mechanisms(5) pkix(7) mod(0)}
id-pkix1-e OBJECT IDENTIFIER ::= {id-pkixmod pkix1-explicit(18)}
id-acv2    OBJECT IDENTIFIER ::= {id-pkixmod mod-attribute-cert-v2(61)}
id-pkcs    OBJECT IDENTIFIER ::= {iso(1) member-body(2) us(840)
                                  rsadsi(113549) pkcs(1)}
id-pkcs10  OBJECT IDENTIFIER ::= {id-pkcs 10 modules(1) pkcs-10(1)}
id-pkcs7   OBJECT IDENTIFIER ::= {id-pkcs 7 modules(0) pkcs-7(1)}
id-pkcs8   OBJECT IDENTIFIER ::= {id-pkcs 8 modules(1) pkcs-8(1)}
id-sm-mod  OBJECT IDENTIFIER ::= {id-pkcs 9 smime(16) modules(0)}
id-aKPV1   OBJECT IDENTIFIER ::= {id-sm-mod mod-asymmetricKeyPkgV1(50)}
id-cms2004 OBJECT IDENTIFIER ::= {id-sm-mod cms-2004(24)}
  • This OID does not actually appear in PKCS #7 v1.5 [RFC2315]. It was defined in the ASN.1 module to PKCS #7 v1.6 [P7v1.6], and has been carried forward through PKCS #12 [RFC7292].

Figure 5: ASN.1 Module Object Identifier Value Assignments

5. Textual Encoding of Certificates πŸŽ€

5.1. Encoding

Public-key certificates use the "CERTIFICATE" label, bestie πŸ’– The encoded data MUST be a BER (DER strongly preferred; see Appendix B) encoded ASN.1 Certificate structure as described in Section 4 of [RFC5280]. Here's what a certificate looks like in the wild πŸ‘€

-----BEGIN CERTIFICATE-----
MIICLDCCAdKgAwIBAgIBADAKBggqhkjOPQQDAjB9MQswCQYDVQQGEwJCRTEPMA0G
A1UEChMGR251VExTMSUwIwYDVQQLExxHbnVUTFMgY2VydGlmaWNhdGUgYXV0aG9y
aXR5MQ8wDQYDVQQIEwZMZXV2ZW4xJTAjBgNVBAMTHEdudVRMUyBjZXJ0aWZpY2F0
ZSBhdXRob3JpdHkwHhcNMTEwNTIzMjAzODIxWhcNMTIxMjIyMDc0MTUxWjB9MQsw
CQYDVQQGEwJCRTEPMA0GA1UEChMGR251VExTMSUwIwYDVQQLExxHbnVUTFMgY2Vy
dGlmaWNhdGUgYXV0aG9yaXR5MQ8wDQYDVQQIEwZMZXV2ZW4xJTAjBgNVBAMTHEdu
dVRMUyBjZXJ0aWZpY2F0ZSBhdXRob3JpdHkwWTATBgcqhkjOPQIBBggqhkjOPQMB
BwNCAARS2I0jiuNn14Y2sSALCX3IybqiIJUvxUpj+oNfzngvj/Niyv2394BWnW4X
uQ4RTEiywK87WRcWMGgJB5kX/t2no0MwQTAPBgNVHRMBAf8EBTADAQH/MA8GA1Ud
DwEB/wQFAwMHBgAwHQYDVR0OBBYEFPC0gf6YEr+1KLlkQAPLzB9mTigDMAoGCCqG
SM49BAMCA0gAMEUCIDGuwD1KPyG+hRf88MeyMQcqOFZD0TbVleF+UsAGQ4enAiEA
l4wOuDwKQa+upc8GftXE2C//4mKANBC6It01gUaTIpo=
-----END CERTIFICATE-----

Figure 6: Certificate Example

Now the lowkey messy part πŸ™ˆ Historically, people used the label "X509 CERTIFICATE" and, less commonly, "X.509 CERTIFICATE". Generators conforming to this document MUST generate "CERTIFICATE" labels and MUST NOT generate "X509 CERTIFICATE" or "X.509 CERTIFICATE" labels. Parsers SHOULD NOT treat "X509 CERTIFICATE" or "X.509 CERTIFICATE" as equivalent to "CERTIFICATE", but a valid exception may be for backwards compatibility (potentially together with a warning) 🫢

5.2. Explanatory Text

Okay so lots of tools like to add explanatory text before the BEGIN line and after the END line for PKIX certificates, more than for any other type πŸ“ If they do, that text SHOULD be related to the certificate, such as providing a textual representation of key data elements in the certificate ✨

Subject: CN=Atlantis
Issuer: CN=Atlantis
Validity: from 7/9/2012 3:10:38 AM UTC to 7/9/2013 3:10:37 AM UTC
-----BEGIN CERTIFICATE-----
MIIBmTCCAUegAwIBAgIBKjAJBgUrDgMCHQUAMBMxETAPBgNVBAMTCEF0bGFudGlz
MB4XDTEyMDcwOTAzMTAzOFoXDTEzMDcwOTAzMTAzN1owEzERMA8GA1UEAxMIQXRs
YW50aXMwXDANBgkqhkiG9w0BAQEFAANLADBIAkEAu+BXo+miabDIHHx+yquqzqNh
Ryn/XtkJIIHVcYtHvIX+S1x5ErgMoHehycpoxbErZmVR4GCq1S2diNmRFZCRtQID
AQABo4GJMIGGMAwGA1UdEwEB/wQCMAAwIAYDVR0EAQH/BBYwFDAOMAwGCisGAQQB
gjcCARUDAgeAMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDAzA1BgNVHQEE
LjAsgBA0jOnSSuIHYmnVryHAdywMoRUwEzERMA8GA1UEAxMIQXRsYW50aXOCASow
CQYFKw4DAh0FAANBAKi6HRBaNEL5R0n56nvfclQNaXiDT174uf+lojzA4lhVInc0
ILwpnZ1izL4MlI9eCSHhVQBHEp2uQdXJB+d5Byg=
-----END CERTIFICATE-----

Figure 7: Certificate Example with Explanatory Text

5.3. File Extension

Textual encodings of PKIX structures can show up pretty much anywhere πŸ¦‹ Lots of tools have an option to output this encoding when they serialize PKIX structures. To promote interoperability and to separate DER encodings from textual encodings, the extension ".crt" SHOULD be used for the textual encoding of a certificate. Implementations should be aware that in spite of this recommendation, many tools still default to encode certificates in this textual encoding with the extension ".cer".

This doesn't mess with the official application/pkix-cert registration [RFC2585] at all (which says that "each '.cer' file contains exactly one certificate, encoded in DER format"). It just describes a widespread, de facto alternative πŸ’…

6. Textual Encoding of Certificate Revocation Lists πŸ’œ

Certificate Revocation Lists (CRLs) use the "X509 CRL" label 🌈 The encoded data MUST be a BER (DER strongly preferred; see Appendix B) encoded ASN.1 CertificateList structure as described in Section 5 of [RFC5280].

-----BEGIN X509 CRL-----
MIIB9DCCAV8CAQEwCwYJKoZIhvcNAQEFMIIBCDEXMBUGA1UEChMOVmVyaVNpZ24s
IEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxRjBEBgNVBAsT
PXd3dy52ZXJpc2lnbi5jb20vcmVwb3NpdG9yeS9SUEEgSW5jb3JwLiBieSBSZWYu
LExJQUIuTFREKGMpOTgxHjAcBgNVBAsTFVBlcnNvbmEgTm90IFZhbGlkYXRlZDEm
MCQGA1UECxMdRGlnaXRhbCBJRCBDbGFzcyAxIC0gTmV0c2NhcGUxGDAWBgNVBAMU
D1NpbW9uIEpvc2Vmc3NvbjEiMCAGCSqGSIb3DQEJARYTc2ltb25Aam9zZWZzc29u
Lm9yZxcNMDYxMjI3MDgwMjM0WhcNMDcwMjA3MDgwMjM1WjAjMCECEC4QNwPfRoWd
elUNpllhhTgXDTA2MTIyNzA4MDIzNFowCwYJKoZIhvcNAQEFA4GBAD0zX+J2hkcc
Nbrq1Dn5IKL8nXLgPGcHv1I/le1MNo9t1ohGQxB5HnFUkRPAY82fR6Epor4aHgVy
b+5y+neKN9Kn2mPF4iiun+a4o26CjJ0pArojCL1p8T0yyi9Xxvyc/ezaZ98HiIyP
c3DGMNR+oUmSjKZ0jIhAYmeLxaPHfQwR
-----END X509 CRL-----

Figure 8: CRL Example

Historically, the label "CRL" has rarely been used. Today it's not common, and lots of popular tools don't understand it at all 😭 So this document standardizes "X509 CRL" to promote interoperability and backwards-compatibility. Generators conforming to this document MUST generate "X509 CRL" labels and MUST NOT generate "CRL" labels. Parsers SHOULD NOT treat "CRL" as equivalent to "X509 CRL" πŸ“

7. Textual Encoding of PKCS #10 Certification Request Syntax πŸ¦‹

PKCS #10 Certification Requests use the "CERTIFICATE REQUEST" label πŸŽ€ The encoded data MUST be a BER (DER strongly preferred; see Appendix B) encoded ASN.1 CertificationRequest structure as described in [RFC2986].

-----BEGIN CERTIFICATE REQUEST-----
MIIBWDCCAQcCAQAwTjELMAkGA1UEBhMCU0UxJzAlBgNVBAoTHlNpbW9uIEpvc2Vm
c3NvbiBEYXRha29uc3VsdCBBQjEWMBQGA1UEAxMNam9zZWZzc29uLm9yZzBOMBAG
ByqGSM49AgEGBSuBBAAhAzoABLLPSkuXY0l66MbxVJ3Mot5FCFuqQfn6dTs+9/CM
EOlSwVej77tj56kj9R/j9Q+LfysX8FO9I5p3oGIwYAYJKoZIhvcNAQkOMVMwUTAY
BgNVHREEETAPgg1qb3NlZnNzb24ub3JnMAwGA1UdEwEB/wQCMAAwDwYDVR0PAQH/
BAUDAwegADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDATAKBggqhkjOPQQDAgM/ADA8
AhxBvfhxPFfbBbsE1NoFmCUczOFApEuQVUw3ZP69AhwWXk3dgSUsKnuwL5g/ftAY
dEQc8B8jAcnuOrfU
-----END CERTIFICATE REQUEST-----

Figure 9: PKCS #10 Example

The label "NEW CERTIFICATE REQUEST" is also in wide use πŸ‘€ Generators conforming to this document MUST generate "CERTIFICATE REQUEST" labels. Parsers MAY treat "NEW CERTIFICATE REQUEST" as equivalent to "CERTIFICATE REQUEST" ✨

8. Textual Encoding of PKCS #7 Cryptographic Message Syntax 🌸

PKCS #7 Cryptographic Message Syntax structures use the "PKCS7" label πŸ’– The encoded data MUST be a BER-encoded ASN.1 ContentInfo structure as described in [RFC2315].

-----BEGIN PKCS7-----
MIHjBgsqhkiG9w0BCRABF6CB0zCB0AIBADFho18CAQCgGwYJKoZIhvcNAQUMMA4E
CLfrI6dr0gUWAgITiDAjBgsqhkiG9w0BCRADCTAUBggqhkiG9w0DBwQIZpECRWtz
u5kEGDCjerXY8odQ7EEEromZJvAurk/j81IrozBSBgkqhkiG9w0BBwEwMwYLKoZI
hvcNAQkQAw8wJDAUBggqhkiG9w0DBwQI0tCBcU09nxEwDAYIKwYBBQUIAQIFAIAQ
OsYGYUFdAH0RNc1p4VbKEAQUM2Xo8PMHBoYdqEcsbTodlCFAZH4=
-----END PKCS7-----

Figure 10: PKCS #7 Example

The label "CERTIFICATE CHAIN" has been used for a degenerate PKCS #7 structure that only holds a list of certificates (see Section 9 of [RFC2315]). Several modern tools don't support this label πŸ™ˆ Generators MUST NOT generate the "CERTIFICATE CHAIN" label. Parsers SHOULD NOT treat "CERTIFICATE CHAIN" as equivalent to "PKCS7".

PKCS #7 is an old spec that has long been superseded by CMS [RFC5652] πŸ₯€ Implementations SHOULD NOT generate PKCS #7 when CMS is an alternative.

9. Textual Encoding of Cryptographic Message Syntax 🧚

Cryptographic Message Syntax structures use the "CMS" label πŸ’œ The encoded data MUST be a BER-encoded ASN.1 ContentInfo structure as described in [RFC5652].

-----BEGIN CMS-----
MIGDBgsqhkiG9w0BCRABCaB0MHICAQAwDQYLKoZIhvcNAQkQAwgwXgYJKoZIhvcN

AQcBoFEET3icc87PK0nNK9ENqSxItVIoSa0o0S/ISczMs1ZIzkgsKk4tsQ0N1nUM dvb05OXi5XLPLEtViMwvLVLwSE0sKlFIVHAqSk3MBkkBAJv0Fx0= -----END CMS-----


<mint>Figure 11: CMS Example</mint> πŸŽ€

CMS is the IETF's successor to PKCS #7 πŸ’–. Section 1.1.1 of [RFC5652] describes the changes since PKCS #7 v1.5. Implementations SHOULD generate CMS when it is an alternative, promoting interoperability and forwards-compatibility ✨.

# 10. One Asymmetric Key and the Textual Encoding of PKCS #8 Private Key Info 🧚

Okay so, unencrypted PKCS #8 Private Key Information Syntax structures (PrivateKeyInfo) got a glow-up and are now called Asymmetric Key Packages (OneAsymmetricKey) πŸ’…. They're encoded using the "PRIVATE KEY" label. The encoded data MUST be a BER (DER preferred; see Appendix B) encoded ASN.1 PrivateKeyInfo structure as described in PKCS #8 [RFC5208], or a OneAsymmetricKey structure as described in [RFC5958]. The two are semantically identical and can be distinguished by version number πŸ”₯.

-----BEGIN PRIVATE KEY----- MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgVcB/UNPxalR9zDYAjQIf jojUDiQuGnSJrFEEzZPT/92hRANCAASc7UJtgnF/abqWM60T3XNJEzBv5ez9TdwK H0M6xpM2q+53wmsN/eYLdgtjgBd3DBmHtPilCkiFICXyaA8z9LkJ -----END PRIVATE KEY-----


<mint>Figure 12: PKCS #8 PrivateKeyInfo (OneAsymmetricKey) Example</mint> 🌸

# 11. Textual Encoding of PKCS #8 Encrypted Private Key Info πŸ”

Encrypted PKCS #8 Private Key Information Syntax structures (EncryptedPrivateKeyInfo) are still called the same thing in [RFC5958] 🫢. They're encoded using the "ENCRYPTED PRIVATE KEY" label. The encoded data MUST be a BER (DER preferred; see Appendix B) encoded ASN.1 EncryptedPrivateKeyInfo structure as described in PKCS #8 [RFC5208] and [RFC5958] πŸ’œ.

-----BEGIN ENCRYPTED PRIVATE KEY----- MIHNMEAGCSqGSIb3DQEFDTAzMBsGCSqGSIb3DQEFDDAOBAghhICA6T/51QICCAAw FAYIKoZIhvcNAwcECBCxDgvI59i9BIGIY3CAqlMNBgaSI5QiiWVNJ3IpfLnEiEsW Z0JIoHyRmKK/+cr9QPLnzxImm0TR9s4JrG3CilzTWvb0jIvbG3hu0zyFPraoMkap 8eRzWsIvC5SVel+CSjoS2mVS87cyjlD+txrmrXOVYDE+eTgMLbrLmsWh3QkCTRtF QC7k0NNzUHTV9yGDwfqMbw== -----END ENCRYPTED PRIVATE KEY-----


<mint>Figure 13: PKCS #8 EncryptedPrivateKeyInfo Example</mint> πŸ“

# 12. Textual Encoding of Attribute Certificates πŸ¦‹

Attribute certificates are encoded using the "ATTRIBUTE CERTIFICATE" label πŸ“œ. The encoded data MUST be a BER (DER strongly preferred; see Appendix B) encoded ASN.1 AttributeCertificate structure as described in [RFC5755] πŸ‘‘.

-----BEGIN ATTRIBUTE CERTIFICATE----- MIICKzCCAZQCAQEwgZeggZQwgYmkgYYwgYMxCzAJBgNVBAYTAlVTMREwDwYDVQQI DAhOZXcgWW9yazEUMBIGA1UEBwwLU3RvbnkgQnJvb2sxDzANBgNVBAoMBkNTRTU5 MjE6MDgGA1UEAwwxU2NvdHQgU3RhbGxlci9lbWFpbEFkZHJlc3M9c3N0YWxsZXJA aWMuc3VueXNiLmVkdQIGARWrgUUSoIGMMIGJpIGGMIGDMQswCQYDVQQGEwJVUzER MA8GA1UECAwITmV3IFlvcmsxFDASBgNVBAcMC1N0b255IEJyb29rMQ8wDQYDVQQK DAZDU0U1OTIxOjA4BgNVBAMMMVNjb3R0IFN0YWxsZXIvZW1haWxBZGRyZXNzPXNz dGFsbGVyQGljLnN1bnlzYi5lZHUwDQYJKoZIhvcNAQEFBQACBgEVq4FFSjAiGA8z OTA3MDIwMTA1MDAwMFoYDzM5MTEwMTMxMDUwMDAwWjArMCkGA1UYSDEiMCCGHmh0 dHA6Ly9pZGVyYXNobi5vcmcvaW5kZXguaHRtbDANBgkqhkiG9w0BAQUFAAOBgQAV M9axFPXXozEFcer06bj9MCBBCQLtAM7ZXcZjcxyva7xCBDmtZXPYUluHf5OcWPJz 5XPus/xS9wBgtlM3fldIKNyNO8RsMp6Ocx+PGlICc7zpZiGmCYLl64lAEGPO/bsw Smluak1aZIttePeTAHeJJs8izNJ5aR3Wcd3A5gLztQ== -----END ATTRIBUTE CERTIFICATE-----


<mint>Figure 14: Attribute Certificate Example</mint> ✨

# 13. Textual Encoding of Subject Public Key Info 🌈

Public keys are encoded using the "PUBLIC KEY" label πŸ—οΈ. The encoded data MUST be a BER (DER preferred; see Appendix B) encoded ASN.1 SubjectPublicKeyInfo structure as described in Section 4.1.2.7 of [RFC5280] πŸ’–.

-----BEGIN PUBLIC KEY----- MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEn1LlwLN/KBYQRVH6HfIMTzfEqJOVztLe kLchp2hi78cCaMY81FBlYs8J9l7krc+M4aBeCGYFjba+hiXttJWPL7ydlE+5UG4U Nkn3Eos8EiZByi9DVsyfy9eejh+8AXgp -----END PUBLIC KEY-----


<mint>Figure 15: Subject Public Key Info Example</mint> πŸ¦‹

# 14. Security Considerations 🚨

Okay, bestie, this part is SERIOUS 😭. Data in this format often comes from untrusted sources, so parsers must be prepared to handle unexpected data without causing security vulnerabilities πŸ’€.

Implementers who build stuff that relies on canonical representation, or on being able to fingerprint a particular data object, need to understand that this document does not define canonical encodings πŸ™ˆ. The first ambiguity shows up when text-encoded representations are allowed instead of the binary BER or DER encodings. Further ambiguities arise when multiple labels get treated as similar. Variations of whitespace and non-base64 alphabetic characters can create even more ambiguities πŸŒ€. Data encoding ambiguities also open the door to side channels πŸ‘€. If you want canonical encodings, the encoded structure must be decoded and processed into a canonical form (namely, DER encoding) 🫢.

> Main character warning: skipping the canonical step is how sneaky bugs slip in. Decode first, then compare. πŸ’…

# 15. References πŸ“š

## 15.1. Normative References

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

[RFC2315] Kaliski, B., "PKCS #7: Cryptographic Message Syntax Version 1.5", RFC 2315, March 1998, <http://www.rfc-editor.org/info/rfc2315>.

[RFC2986] Nystrom, M. and B. Kaliski, "PKCS #10: Certification Request Syntax Specification Version 1.7", RFC 2986, November 2000, <http://www.rfc-editor.org/info/rfc2986>.

[RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data Encodings", RFC 4648, October 2006, <http://www.rfc-editor.org/info/rfc4648>.

[RFC5280] Cooper, D., Santesson, S., Farrell, S., Boeyen, S., Housley, R., and W. Polk, "Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile", RFC 5280, May 2008, <http://www.rfc-editor.org/info/rfc5280>.

[RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax Specifications: ABNF", STD 68, RFC 5234, January 2008, <http://www.rfc-editor.org/info/rfc5234>.

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

[RFC5755] Farrell, S., Housley, R., and S. Turner, "An Internet Attribute Certificate Profile for Authorization", RFC 5755, January 2010, <http://www.rfc-editor.org/info/rfc5755>.

[RFC5958] Turner, S., "Asymmetric Key Packages", RFC 5958, August 2010, <http://www.rfc-editor.org/info/rfc5958>.

[X.690] International Telecommunications Union, "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:2008, November 2008.


## 15.2. Informative References

[RFC934] Rose, M. and E. Stefferud, "Proposed standard for message encapsulation", RFC 934, January 1985, <http://www.rfc-editor.org/info/rfc934>.

[RFC1421] Linn, J., "Privacy Enhancement for Internet Electronic Mail: Part I: Message Encryption and Authentication Procedures", RFC 1421, February 1993, <http://www.rfc-editor.org/info/rfc1421>.

[RFC2585] Housley, R. and P. Hoffman, "Internet X.509 Public Key Infrastructure Operational Protocols: FTP and HTTP", RFC 2585, May 1999, <http://www.rfc-editor.org/info/rfc2585>.

[RFC4716] Galbraith, J. and R. Thayer, "The Secure Shell (SSH) Public Key File Format", RFC 4716, November 2006, <http://www.rfc-editor.org/info/rfc4716>.

[RFC4880] Callas, J., Donnerhacke, L., Finney, H., Shaw, D., and R. Thayer, "OpenPGP Message Format", RFC 4880, November 2007, <http://www.rfc-editor.org/info/rfc4880>.

[RFC5208] Kaliski, B., "Public-Key Cryptography Standards (PKCS) #8: Private-Key Information Syntax Specification Version 1.2", RFC 5208, May 2008, <http://www.rfc-editor.org/info/rfc5208>.

[RFC7292] Moriarty, K., Ed., Nystrom, M., Parkinson, S., Rusch, A., and M. Scott, "PKCS #12: Personal Information Exchange Syntax v1.1", RFC 7292, July 2014, <http://www.rfc-editor.org/info/rfc7292>.

[P7v1.6] Kaliski, B. and K. Kingdon, "Extensions and Revisions to PKCS #7 (Version 1.6 Bulletin)", May 1997, <http://www.emc.com/emc-plus/rsa-labs/ standards-initiatives/pkcs-7-cryptographic-message- syntax-standar.htm>.

[X.509SG] Gutmann, P., "X.509 Style Guide", October 2000, <http://www.cs.auckland.ac.nz/~pgut001/pubs/ x509guide.txt>.


# Appendix A. Non-conforming Examples πŸ™ˆ

This appendix has examples for the non-recommended label variants we covered earlier in the doc 🧁. As discussed earlier, supporting these is not required, and it's sometimes discouraged 😬. Still, they can be super useful for interoperability testing and for easy reference πŸ’œ.

-----BEGIN X509 CERTIFICATE----- MIIBHDCBxaADAgECAgIcxzAJBgcqhkjOPQQBMBAxDjAMBgNVBAMUBVBLSVghMB4X DTE0MDkxNDA2MTU1MFoXDTI0MDkxNDA2MTU1MFowEDEOMAwGA1UEAxQFUEtJWCEw WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATwoQSr863QrR0PoRIYQ96H7WykDePH Wa0eVAE24bth43wCNc+U5aZ761dhGhSSJkVWRgVH5+prLIr+nzfIq+X4oxAwDjAM BgNVHRMBAf8EAjAAMAkGByqGSM49BAEDRwAwRAIfMdKS5F63lMnWVhi7uaKJzKCs NnY/OKgBex6MIEAv2AIhAI2GdvfL+mGvhyPZE+JxRxWChmggb5/9eHdUcmW/jkOH -----END X509 CERTIFICATE-----


<mint>Figure 16: Non-standard 'X509' Certificate Example</mint> 🌸

-----BEGIN X.509 CERTIFICATE----- MIIBHDCBxaADAgECAgIcxzAJBgcqhkjOPQQBMBAxDjAMBgNVBAMUBVBLSVghMB4X DTE0MDkxNDA2MTU1MFoXDTI0MDkxNDA2MTU1MFowEDEOMAwGA1UEAxQFUEtJWCEw WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATwoQSr863QrR0PoRIYQ96H7WykDePH Wa0eVAE24bth43wCNc+U5aZ761dhGhSSJkVWRgVH5+prLIr+nzfIq+X4oxAwDjAM BgNVHRMBAf8EAjAAMAkGByqGSM49BAEDRwAwRAIfMdKS5F63lMnWVhi7uaKJzKCs NnY/OKgBex6MIEAv2AIhAI2GdvfL+mGvhyPZE+JxRxWChmggb5/9eHdUcmW/jkOH -----END X.509 CERTIFICATE-----


<mint>Figure 17: Non-standard 'X.509' Certificate Example</mint> πŸ¦‹

-----BEGIN NEW CERTIFICATE REQUEST----- MIIBWDCCAQcCAQAwTjELMAkGA1UEBhMCU0UxJzAlBgNVBAoTHlNpbW9uIEpvc2Vm c3NvbiBEYXRha29uc3VsdCBBQjEWMBQGA1UEAxMNam9zZWZzc29uLm9yZzBOMBAG ByqGSM49AgEGBSuBBAAhAzoABLLPSkuXY0l66MbxVJ3Mot5FCFuqQfn6dTs+9/CM EOlSwVej77tj56kj9R/j9Q+LfysX8FO9I5p3oGIwYAYJKoZIhvcNAQkOMVMwUTAY BgNVHREEETAPgg1qb3NlZnNzb24ub3JnMAwGA1UdEwEB/wQCMAAwDwYDVR0PAQH/ BAUDAwegADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDATAKBggqhkjOPQQDAgM/ADA8 AhxBvfhxPFfbBbsE1NoFmCUczOFApEuQVUw3ZP69AhwWXk3dgSUsKnuwL5g/ftAY dEQc8B8jAcnuOrfU -----END NEW CERTIFICATE REQUEST-----


<mint>Figure 18: Non-standard 'NEW' PKCS #10 Example</mint> πŸ’…

-----BEGIN CERTIFICATE CHAIN----- MIHjBgsqhkiG9w0BCRABF6CB0zCB0AIBADFho18CAQCgGwYJKoZIhvcNAQUMMA4E CLfrI6dr0gUWAgITiDAjBgsqhkiG9w0BCRADCTAUBggqhkiG9w0DBwQIZpECRWtz u5kEGDCjerXY8odQ7EEEromZJvAurk/j81IrozBSBgkqhkiG9w0BBwEwMwYLKoZI hvcNAQkQAw8wJDAUBggqhkiG9w0DBwQI0tCBcU09nxEwDAYIKwYBBQUIAQIFAIAQ OsYGYUFdAH0RNc1p4VbKEAQUM2Xo8PMHBoYdqEcsbTodlCFAZH4= -----END CERTIFICATE CHAIN-----


<mint>Figure 19: Non-standard 'CERTIFICATE CHAIN' Example</mint> 🌈

# Appendix B. DER Expectations πŸ’…

This appendix is informative. Consult the respective standards for the normative rules. πŸŽ€

okay so DER is a restricted profile of BER [X.690] 🧠. That means every DER encoding is a BER encoding, but only one of the BER encodings is *the* DER encoding for a given data value. Canonical encoding matters a LOT when you're doing cryptographic operations, and it also has efficiency perks for parsers ✨. There are three principal reasons to encode with DER, and I'm obsessed with all of them:

1. A digital signature is (supposed to be) computed over the DER encoding of the semantic content, so providing anything other than the DER encoding is senseless πŸ’€. (In practice, an implementer might choose to parse and digest the data as is, but that practice amounts to guesswork πŸ™ˆ.)

2. In practice, cryptographic hashes are computed over the DER encoding for identification πŸ”‘.

3. In practice, the content is small. DER always encodes data values in definite-length form, meaning the length is stated at the beginning of the encoding πŸ“. So a parser can anticipate memory or resource usage up front 🧚.

Figure 20 matches the structures in this document with the particular reasons for DER encoding. Here's the tea 🍡:

Sec. Label Reasons ----+----------------------+------- 5 CERTIFICATE 1 2 ~3 6 X509 CRL 1 7 CERTIFICATE REQUEST 1 ~3 8 PKCS7 * 9 CMS * 10 PRIVATE KEY 3 11 ENCRYPTED PRIVATE KEY 3 12 ATTRIBUTE CERTIFICATE 1 ~3 13 PUBLIC KEY 2 3

Figure 20: Guide for DER Encoding


And the notes that go with those symbols πŸ“:

* Cryptographic Message Syntax is designed for content of any length 🌊. Indefinite-length encoding enables one-pass processing (streaming) when generating the encoding πŸ¦‹. Only certain parts, namely signed and authenticated attributes, need to be DER encoded πŸ’œ.

~ Although not always "small," these encoded structures should not be particularly "large" (e.g., more than 16 kilobytes) πŸ“. The parser ought to be informed of large things up front in any event πŸ‘‘. This is yet another reason to DER encode these things in the first place 😭.

Figure 20: Guide for DER Encoding


---

# Acknowledgements 🫢

Peter Gutmann suggested documenting labels for Attribute Certificates and PKCS #7 messages, and adding examples for the non-standard variants 🌸. Dr. Stephen Henson suggested distinguishing when BER versus DER is appropriate or necessary πŸ”₯. Iconic contributions, honestly ✨.

# Authors' Addresses πŸ’Œ

Simon Josefsson SJD AB Johan Olof Wallins Vaeg 13 Solna 171 64 Sweden

EMail: simon@josefsson.org URI: http://josefsson.org/

Sean Leonard Penango, Inc. 5900 Wilshire Boulevard 21st Floor Los Angeles, CA 90036 United States

EMail: dev+ietf@seantek.com URI: http://www.penango.com/

πŸ“¦ where this page comes from