RFC 5280

Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile

๐Ÿ“… published May 2008, from ietf

RFC 5280 ๐ŸŽ€ Part 1 of 34

Okay bestie, let's get into it ๐Ÿ’… This one is RFC 5280, titled Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile ๐Ÿ”. It's from the Network Working Group and it's a Standards Track doc, so it's the real deal, not just a vibe ๐Ÿ‘‘

It was written by six people. D. Cooper (NIST), S. Santesson (Microsoft), S. Farrell (Trinity College Dublin), S. Boeyen (Entrust), R. Housley (Vigil Security), and W. Polk (NIST) ๐Ÿซถ It's dated May 2008.

It obsoletes RFC 3280, RFC 4325, and RFC 4630, so those older versions are officially retired ๐Ÿ™ˆ It doesn't update anything else.

Status of This Memo โœจ

This doc specifies an Internet standards track protocol for the Internet community, and it's literally asking you for discussion and suggestions for improvements ๐Ÿ’– If you want to know where this protocol stands officially, check the current edition of "Internet Official Protocol Standards" (STD 1) ๐Ÿ“œ Distribution of this memo is unlimited, so share it freely ๐Ÿฆ‹

Abstract ๐ŸŒธ

So this memo sets the profile for the X.509 v3 certificate and the X.509 v2 certificate revocation list (CRL) so they work on the Internet ๐ŸŒ It starts with a big-picture overview, then gets detailed about the v3 certificate format, including how Internet name forms are formatted and what they mean โœจ

It covers the standard certificate extensions and defines two Internet-specific extensions ๐Ÿ”ฅ It also specifies a set of required certificate extensions ๐Ÿ’… The v2 CRL format gets the same deep dive, with its standard and Internet-specific extensions ๐Ÿงš

Last but not least, it describes an algorithm for X.509 certification path validation ๐Ÿ‘‘ The ASN.1 module and the examples are in the appendices ๐Ÿ“

Table of Contents ๐Ÿงš

Here's the whole table of contents, copied exactly so you can find everything ๐Ÿ—‚๏ธ

1. Introduction ....................................................4
   2. Requirements and Assumptions ....................................6
      2.1. Communication and Topology .................................7
      2.2. Acceptability Criteria .....................................7
      2.3. User Expectations ..........................................7
      2.4. Administrator Expectations .................................8
   3. Overview of Approach ............................................8
      3.1. X.509 Version 3 Certificate ................................9
      3.2. Certification Paths and Trust .............................10
      3.3. Revocation ................................................13
      3.4. Operational Protocols .....................................14
      3.5. Management Protocols ......................................14
   4. Certificate and Certificate Extensions Profile .................16
      4.1. Basic Certificate Fields ..................................16
           4.1.1. Certificate Fields .................................17
                  4.1.1.1. tbsCertificate ............................18
                  4.1.1.2. signatureAlgorithm ........................18
                  4.1.1.3. signatureValue ............................18
           4.1.2. TBSCertificate .....................................18
                  4.1.2.1. Version ...................................19
                  4.1.2.2. Serial Number .............................19
                  4.1.2.3. Signature .................................19
                  4.1.2.4. Issuer ....................................20
                  4.1.2.5. Validity ..................................22
                           4.1.2.5.1. UTCTime ........................23
                           4.1.2.5.2. GeneralizedTime ................23
                  4.1.2.6. Subject ...................................23
                  4.1.2.7. Subject Public Key Info ...................25
                  4.1.2.8. Unique Identifiers ........................25
                  4.1.2.9. Extensions ................................26
      4.2. Certificate Extensions ....................................26
           4.2.1. Standard Extensions ................................27
                  4.2.1.1. Authority Key Identifier ..................27
                  4.2.1.2. Subject Key Identifier ....................28
                  4.2.1.3. Key Usage .................................29
                  4.2.1.4. Certificate Policies ......................32
                  4.2.1.5. Policy Mappings ...........................35
                  4.2.1.6. Subject Alternative Name ..................35
                  4.2.1.7. Issuer Alternative Name ...................38
                  4.2.1.8. Subject Directory Attributes ..............39
                  4.2.1.9. Basic Constraints .........................39
                  4.2.1.10. Name Constraints .........................40
                  4.2.1.11. Policy Constraints .......................43
                  4.2.1.12. Extended Key Usage .......................44
                  4.2.1.13. CRL Distribution Points ..................45
                  4.2.1.14. Inhibit anyPolicy ........................48
                  4.2.1.15. Freshest CRL (a.k.a. Delta CRL
                            Distribution Point) ......................48
           4.2.2. Private Internet Extensions ........................49
                  4.2.2.1. Authority Information Access ..............49
                  4.2.2.2. Subject Information Access ................51
   5. CRL and CRL Extensions Profile .................................54
      5.1. CRL Fields ................................................55
           5.1.1. CertificateList Fields .............................56
                  5.1.1.1. tbsCertList ...............................56
                  5.1.1.2. signatureAlgorithm ........................57
                  5.1.1.3. signatureValue ............................57
           5.1.2. Certificate List "To Be Signed" ....................58
                  5.1.2.1. Version ...................................58
                  5.1.2.2. Signature .................................58
                  5.1.2.3. Issuer Name ...............................58
                  5.1.2.4. This Update ...............................58
                  5.1.2.5. Next Update ...............................59
                  5.1.2.6. Revoked Certificates ......................59
                  5.1.2.7. Extensions ................................60
      5.2. CRL Extensions ............................................60
           5.2.1. Authority Key Identifier ...........................60
           5.2.2. Issuer Alternative Name ............................60
           5.2.3. CRL Number .........................................61
           5.2.4. Delta CRL Indicator ................................62
           5.2.5. Issuing Distribution Point .........................65
           5.2.6. Freshest CRL (a.k.a. Delta CRL Distribution
                  Point) .............................................67
           5.2.7. Authority Information Access .......................67
      5.3. CRL Entry Extensions ......................................69
           5.3.1. Reason Code ........................................69
           5.3.2. Invalidity Date ....................................70
           5.3.3. Certificate Issuer .................................70
   6. Certification Path Validation ..................................71
      6.1. Basic Path Validation .....................................72
           6.1.1. Inputs .............................................75
           6.1.2. Initialization .....................................77
           6.1.3. Basic Certificate Processing .......................80
           6.1.4. Preparation for Certificate i+1 ....................84
           6.1.5. Wrap-Up Procedure ..................................87
           6.1.6. Outputs ............................................89
      6.2. Using the Path Validation Algorithm .......................89
      6.3. CRL Validation ............................................90
           6.3.1. Revocation Inputs ..................................91
           6.3.2. Initialization and Revocation State Variables ......91
           6.3.3. CRL Processing .....................................92
   7. Processing Rules for Internationalized Names ...................95
      7.1. Internationalized Names in Distinguished Names ............96
      7.2. Internationalized Domain Names in GeneralName .............97
      7.3. Internationalized Domain Names in Distinguished Names .....98
      7.4. Internationalized Resource Identifiers ....................98
      7.5. Internationalized Electronic Mail Addresses ..............100
   8. Security Considerations .......................................100
   9. IANA Considerations ...........................................105
   10. Acknowledgments ..............................................105
   11. References ...................................................105
      11.1. Normative References ....................................105
      11.2. Informative References ..................................107
   Appendix A.  Pseudo-ASN.1 Structures and OIDs ....................110
      A.1. Explicitly Tagged Module, 1988 Syntax ....................110
      A.2. Implicitly Tagged Module, 1988 Syntax ....................125
   Appendix B. ASN.1 Notes ..........................................133
   Appendix C. Examples .............................................136
      C.1. RSA Self-Signed Certificate ..............................137
      C.2. End Entity Certificate Using RSA .........................140
      C.3. End Entity Certificate Using DSA .........................143
      C.4. Certificate Revocation List ..............................147

Part 2 is coming up next, bestie, and it starts with Section 1 ๐Ÿฆ‹๐Ÿ’œ

1. Introduction โœจ

okay so this spec is ONE piece of a whole family of standards for the X.509 Public Key Infrastructure (PKI) for the Internet ๐ŸŽ€

it profiles the format and semantics of certificates and certificate revocation lists (CRLs) for the Internet PKI. it also describes procedures for processing certification paths in the Internet environment, and the appendices have ASN.1 modules for every data structure it defines or references ๐Ÿ’œ

here's the map ๐Ÿ—บ๏ธ Section 2 covers Internet PKI requirements and the assumptions that affect the scope of this doc. Section 3 shows an architectural model and how it connects to older IETF and ISO/IEC/ITU-T standards, especially how this doc relates to the IETF PEM specs and the ISO/IEC/ITU-T X.509 docs ๐Ÿฆ‹

Section 4 profiles the X.509 version 3 certificate, and Section 5 profiles the X.509 version 2 CRL. these profiles name the ISO/IEC/ITU-T and ANSI extensions that may be useful in the Internet PKI ๐ŸŒธ the profiles are written in the 1988 Abstract Syntax Notation One (ASN.1), not the 1997 ASN.1 syntax that the newest ISO/IEC/ITU-T standards use, so that's the vibe here ๐Ÿงš

Section 6 has the certification path validation procedures, which are based on the ISO/IEC/ITU-T definition. implementations are REQUIRED to get the same results, but they're not required to use the specific procedures in here. no cap, that's a very healthy amount of flexibility ๐Ÿซถ

the procedures for identifying and encoding public key materials and digital signatures live in [RFC3279], [RFC4055], and [RFC4491]. implementations of this spec are not required to use any particular cryptographic algorithms. however, conforming implementations that use the algorithms identified in [RFC3279], [RFC4055], and [RFC4491] MUST identify and encode the public key materials and digital signatures the way those specs describe ๐Ÿ’…

lastly, there are three appendices to help implementers ๐Ÿ“ Appendix A has every ASN.1 structure defined or referenced in this spec, again in 1988 ASN.1. Appendix B has notes on the less familiar features of the ASN.1 notation used here. Appendix C has examples of conforming certificates and a conforming CRL ๐ŸŒˆ

this specification obsoletes [RFC3280]. here's what's different from RFC 3280, bestie ๐Ÿ‘‘

  • Better internationalized names. Section 7 is upgraded with rules for encoding and comparing Internationalized Domain Names, Internationalized Resource Identifiers (IRIs), and distinguished names. these rules line up with comparison rules in current RFCs, including [RFC3490], [RFC3987], and [RFC4518] ๐ŸŒ
  • Legacy text encodings. Sections 4.1.2.4 and 4.1.2.6 bring in the conditions for continued use of legacy text encoding schemes that were specified in [RFC4630]. where an established PKI is already using them, moving to UTF8String could cause a denial of service through name chaining failures or incorrect processing of name constraints. yikes, so be careful ๐Ÿ˜ญ
  • privateKeyUsagePeriod is gone. Section 4.2.1.4 in RFC 3280 specified the privateKeyUsagePeriod certificate extension but deprecated its use, and it was removed here. use of this ISO standard extension is neither deprecated nor recommended for use in the Internet PKI ๐Ÿ™ˆ
  • Policy mappings should be critical. Section 4.2.1.5 recommends marking the policy mappings extension as critical. RFC 3280 required that the policy mappings extension be marked as non-critical, so this is a big flip โœจ
  • Policy constraints must be critical. Section 4.2.1.11 requires marking the policy constraints extension as critical. RFC 3280 let the policy constraints extension be critical or non-critical, so now it's locked in ๐Ÿ”’
  • AIA for CRLs. the Authority Information Access (AIA) CRL extension, as specified in [RFC4325], was added as Section 5.2.7 ๐Ÿฆ‹
  • Unrecognized extensions are clearer. Sections 5.2 and 5.3 clarify the rules for handling unrecognized CRL extensions and CRL entry extensions, respectively ๐Ÿ’–
  • holdInstructionCode is gone. Section 5.3.2 in RFC 3280, which specified the holdInstructionCode CRL entry extension, was removed ๐Ÿ’€
  • No more criticality tracking in path validation. the path validation algorithm in Section 6 no longer tracks the criticality of the certificate policies extensions in a chain of certificates. in RFC 3280, that info was handed back to a relying party ๐Ÿงฉ
  • Security is glowing up. the Security Considerations section now covers the risk of circular dependencies from using https or similar schemes in the CRL distribution points, authority information access, or subject information access extensions ๐Ÿ”ฅ
  • Name ambiguity got a whole section. the Security Considerations section now addresses risks tied to name ambiguity ๐Ÿซฃ
  • Signaling CA changes. the Security Considerations section references RFC 4210 for procedures to signal changes in CA operations ๐Ÿ“ฃ

the ASN.1 modules in Appendix A are unchanged from RFC 3280, with ONE exception: ub-emailaddress-length went from 128 to 255 so it lines up with PKCS #9 [RFC2985] ๐ŸŽ€

the key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119]. these are the official rule words, so read them carefully ๐Ÿ’œ

2. Requirements and Assumptions โœจ

the goal here is to create a profile that makes it easier to use X.509 certificates in Internet applications, for the communities that want to use X.509 tech. these applications can include WWW, electronic mail, user authentication, and IPsec ๐ŸŒ to make the obstacles to using X.509 certificates less painful, this doc defines a profile that helps build certificate management systems, application tools, and interoperability that's decided by policy ๐Ÿงš

some communities will need to add to this profile, or maybe replace it, to meet the needs of specialized application domains or environments with extra authorization, assurance, or operational requirements ๐ŸŒธ but for basic applications, there are common representations of frequently used attributes, so app developers can get the info they need without caring which issuer made a particular certificate or certificate revocation list (CRL) ๐Ÿ’…

a certificate user should review the certificate policy generated by the certification authority (CA) before relying on the authentication or non-repudiation services tied to the public key in a particular certificate. so this standard doesn't prescribe legally binding rules or duties. not a legal document, babe โš–๏ธ

as supplemental authorization and attribute management tools show up, like attribute certificates, it may make sense to limit which authenticated attributes go into a certificate. these other management tools may do a better job of carrying many authenticated attributes ๐Ÿฆ‹

2.1. Communication and Topology ๐ŸŒ

the users of certificates will be operating in all kinds of environments when it comes to communication topology, especially users of secure electronic mail. this profile supports users who don't have high bandwidth, real-time IP connectivity, or high connection availability. the profile also allows for firewalls or other filtered communication ๐Ÿงฑ

this profile does not assume a deployment of an X.500 directory system [X.500] or a Lightweight Directory Access Protocol (LDAP) directory system [RFC4510]. it doesn't prohibit using an X.500 directory or an LDAP directory either. any means of distributing certificates and certificate revocation lists (CRLs) may be used ๐ŸŽ€

2.2. Acceptability Criteria ๐ŸŽฏ

the goal of the Internet Public Key Infrastructure (PKI) is to meet the needs of deterministic, automated identification, authentication, access control, and authorization functions. the services it supports decide which attributes go in the certificate, plus the ancillary control info like policy data and certification path constraints ๐Ÿ’–

2.3. User Expectations ๐Ÿ™‹โ€โ™€๏ธ

users of the Internet PKI are people and processes that use client software, and they're the subjects named in certificates. this covers readers and writers of electronic mail, clients for WWW browsers, WWW servers, and the key manager for IPsec inside a router ๐Ÿ–ฅ๏ธ this profile knows that the platforms users rely on have limits, and so do the users' sophistication and attentiveness ๐Ÿ˜… that shows up as minimal user configuration responsibility (e.g., trusted CA keys, rules), explicit platform usage constraints inside the certificate, certification path constraints that shield the user from a lot of malicious actions, and applications that sensibly automate validation functions ๐Ÿซถ

2.4. Administrator Expectations ๐Ÿ› ๏ธ

same energy as the user expectations: the Internet PKI profile is built to support the individuals who usually run CAs. giving administrators unbounded choices makes it more likely that one subtle CA administrator mistake turns into a broad compromise ๐Ÿ’€ unbounded choices also make the software that processes and validates the certificates CAs create way more complicated ๐Ÿง 

3. Overview of Approach โœจ

okay so bestie, before we get into the nitty gritty, let's look at the big picture ๐Ÿฆ‹ this is a simplified model of the architecture that the Public-Key Infrastructure using X.509 (PKIX) specs assume. it's giving blueprint energy ๐Ÿ’…

the cast of characters:

  • end entity: a user of PKI certificates and/or an end user system that is the subject of a certificate ๐Ÿงš
  • CA: certification authority ๐Ÿ‘‘
  • RA: registration authority, which is an optional system that a CA can hand certain management functions off to ๐Ÿซถ
  • CRL issuer: a system that generates and signs CRLs ๐Ÿ”ฅ
  • repository: a system (or a collection of distributed systems) that stores certificates and CRLs and acts as the way these certificates and CRLs get distributed to end entities ๐Ÿ“ฆ

CAs are responsible for indicating the revocation status of the certificates they issue, no cap ๐Ÿ™ˆ that status info can come through the Online Certificate Status Protocol (OCSP) [RFC2560], through certificate revocation lists (CRLs), or through some other mechanism. generally, when revocation info is delivered with CRLs, the CA is also the CRL issuer. BUT a CA can totally delegate the job of issuing CRLs to a different entity ๐ŸŒธ

also, an Attribute Authority (AA) might choose to delegate publishing CRLs to a CRL issuer. the way that delegation works is giving me main character energy โœจ

here's the whole picture in diagram form, bestie ๐Ÿ’–

                      +---+
                      | C |                       +------------+
                      | e | <-------------------->| End entity |
                      | r |       Operational     +------------+
                      | t |       transactions          ^
                      | i |      and management         |  Management
                      | f |       transactions          |  transactions        PKI
                      | i |                             |                     users
                      | c |                             v
                      | a | =======================  +--+------------+  ==============
                      | t |                          ^               ^
                      | e |                          |               |         PKI
                      |   |                          v               |      management
                      | & |                       +------+           |       entities
                      |   | <---------------------|  RA  |<----+     |
                      | C |  Publish certificate  +------+     |     |
                      | R |                                    |     |
                      | L |                                    |     |
                      |   |                                    v     v
                      | R |                                +------------+
                      | e | <------------------------------|     CA     |
                      | p |   Publish certificate          +------------+
                      | o |   Publish CRL                     ^      ^
                      | s |                                   |      |  Management
                      | i |                +------------+     |      |  transactions
                      | t | <--------------| CRL Issuer |<----+      |
                      | o |   Publish CRL  +------------+            v
                      | r |                                      +------+
                      | y |                                      |  CA  |
                      +---+                                      +------+

                      Figure 1. PKI Entities

3.1. X.509 Version 3 Certificate

okay so the core vibe here: users of a public key need confidence that the matching private key is owned by the correct remote subject (a person or a system) that they'll be using encryption or digital signatures with ๐ŸŽ€ that confidence comes from public key certificates, which are data structures that bind public key values to subjects ๐Ÿ’œ the binding is asserted by a trusted CA digitally signing each certificate. the CA can base that assertion on technical means (a.k.a., proof of possession through a challenge-response protocol), on presentation of the private key, or on an assertion by the subject ๐Ÿ”ฅ

certificates have a limited valid lifetime, and that lifetime is indicated in the signed contents โณ and here's the iconic part: because a certificate's signature and timeliness can be checked independently by a certificate-using client, certificates can be distributed over untrusted communications and server systems, and they can be cached in unsecured storage in certificate-using systems. the signature does the protecting, not the pipe ๐Ÿฆ‹ literally so cool

now the history lesson, but make it fun ๐ŸŒˆ ITU-T X.509 (formerly CCITT X.509) or ISO/IEC 9594-8 was first published in 1988 as part of the X.500 directory recommendations, and it defines a standard certificate format [X.509]. that 1988 format is called version 1 (v1). then when X.500 got revised in 1993, two more fields were added, and that's the version 2 (v2) format ๐Ÿ“

the Internet Privacy Enhanced Mail (PEM) RFCs, published in 1993, included specs for a public key infrastructure based on X.509 v1 certificates [RFC1422]. but the experience of trying to deploy RFC 1422 made it super clear that the v1 and v2 formats were deficient in several respects ๐Ÿ’€ the biggest issue: more fields were needed to carry information that PEM design and implementation experience had proven necessary. so the ISO/IEC, ITU-T, and ANSI X9 folks developed the X.509 version 3 (v3) certificate format ๐Ÿ‘‘ the v3 format extends v2 by adding provision for additional extension fields. particular extension field types may be specified in standards or may be defined and registered by any organization or community. in June 1996, standardization of the basic v3 format was completed [X.509] โœจ

ISO/IEC, ITU-T, and ANSI X9 have also developed standard extensions for use in the v3 extensions field [X.509][X9.55] ๐Ÿงš these can carry stuff like additional subject identification info, key attribute info, policy info, and certification path constraints.

BUT (the plot twist ๐Ÿ˜ญ) those ISO/IEC, ITU-T, and ANSI X9 standard extensions are very broad in their applicability. so if you want interoperable X.509 v3 implementations for Internet use, you need to specify a profile for using the X.509 v3 extensions that's tailored for the Internet ๐Ÿซถ it is one goal of this document to specify exactly that, a profile for Internet WWW, electronic mail, and IPsec applications ๐ŸŒธ and if an environment has extra requirements, it can build on this profile or replace it entirely. no drama, just options ๐Ÿ’…

3.2. Certification Paths and Trust โœจ

okay so bestie, if you need someone's public key, you usually have to grab a certificate that holds it and then validate that certificate ๐Ÿ” But if you don't already have a trusted copy of the public key of the CA that signed it, the CA's name, and stuff like the validity period or name constraints, you might need another certificate just to get that CA key ๐Ÿ’… Honestly, you could end up needing a whole chain: the end entity's certificate signed by one CA, plus zero or more CA certificates signed by other CAs. These chains are called certification paths, and they're needed because a public key user only starts out with a limited number of assured CA public keys ๐Ÿซถ

There are different ways CAs can be set up so public key users can actually find certification paths. For PEM, RFC 1422 laid out a strict hierarchy of CAs ๐ŸŒธ There are three types of PEM certification authority:

  • (a) Internet Policy Registration Authority (IPRA): This authority, operated under the auspices of the Internet Society, is the root of the PEM certification hierarchy at level 1. It only issues certificates for the next level of authorities, PCAs. All certification paths start with the IPRA. ๐Ÿ‘‘
  • (b) Policy Certification Authorities (PCAs): PCAs sit at level 2 of the hierarchy, and each PCA is certified by the IPRA. A PCA shall establish and publish a statement of its policy with respect to certifying users or subordinate certification authorities. Different PCAs aim to meet different user needs. For example, one PCA (an organizational PCA) might support the general electronic mail needs of commercial organizations, and another PCA (a high-assurance PCA) might have a stricter policy built for legally binding digital signature requirements. ๐ŸŽ€
  • (c) Certification Authorities (CAs): CAs are at level 3 of the hierarchy, and they can also be at lower levels. The ones at level 3 are certified by PCAs. CAs can represent things like particular organizations, particular organizational units (e.g., departments, groups, sections), or particular geographical areas. ๐Ÿงš

RFC 1422 also has a name subordination rule, which says that a CA can only issue certificates for entities whose names are subordinate (in the X.500 naming tree) to the name of the CA itself ๐Ÿ™ˆ The trust tied to a PEM certification path is implied by the PCA name. The name subordination rule keeps the CAs below the PCA sensibly constrained in terms of which subordinate entities they can certify (e.g., a CA for an organization can only certify entities in that organization's name tree). Certificate user systems can mechanically check that the name subordination rule was followed. Iconic for automation ๐Ÿค–

RFC 1422 uses the X.509 v1 certificate format. X.509 v1 had limitations, so it needed several structural restrictions to clearly associate policy information or limit how certificates could be used. These restrictions included:

  • (a) a pure top-down hierarchy, with all certification paths starting from IPRA;
  • (b) a naming subordination rule restricting the names of a CA's subjects; and
  • (c) use of the PCA concept, which requires knowledge of individual PCAs to be built into certificate chain verification logic. Knowledge of individual PCAs was required to determine if a chain could be accepted.

With X.509 v3, most of the requirements addressed by RFC 1422 can be handled using certificate extensions, without needing to restrict the CA structures used ๐Ÿ’– Specifically, the certificate extensions relating to certificate policies make PCAs unnecessary, and the constraint extensions make the name subordination rule unnecessary. So this document supports a more flexible architecture, including:

  • (a) Certification paths start with a public key of a CA in a user's own domain, or with the public key of the top of a hierarchy. Starting with the public key of a CA in a user's own domain has certain advantages. In some environments, the local domain is the most trusted. ๐Ÿ 
  • (b) Name constraints may be imposed through explicit inclusion of a name constraints extension in a certificate, but they are not required.
  • (c) Policy extensions and policy mappings replace the PCA concept, which permits a greater degree of automation. The application can determine if the certification path is acceptable based on the contents of the certificates, instead of a priori knowledge of PCAs. This permits automation of certification path processing. โš™๏ธ

X.509 v3 also includes an extension that identifies the subject of a certificate as either a CA or an end entity, which reduces the reliance on out-of-band information that PEM demanded โœจ

This specification covers two classes of certificates: CA certificates and end entity certificates. CA certificates can be further divided into three classes: cross-certificates, self-issued certificates, and self-signed certificates. Cross-certificates are CA certificates in which the issuer and subject are different entities, and they describe a trust relationship between the two CAs ๐Ÿฆ‹ Self-issued certificates are CA certificates in which the issuer and subject are the same entity, and they're generated to support changes in policy or operations. Self-signed certificates are self-issued certificates where the digital signature can be verified by the public key bound into the certificate. Self-signed certificates are used to convey a public key for use to begin certification paths. End entity certificates are issued to subjects that are not authorized to issue certificates. ๐Ÿ’œ

3.3. Revocation ๐Ÿšซ

When a certificate is issued, it's expected to be in use for its entire validity period. Still, various circumstances can make a certificate invalid before the validity period ends ๐Ÿ˜ญ Those circumstances include a change of name, a change of association between subject and CA (e.g., an employee terminates employment with an organization), and compromise or suspected compromise of the corresponding private key. In those situations, the CA needs to revoke the certificate.

X.509 defines one method of certificate revocation. In this method, each CA periodically issues a signed data structure called a certificate revocation list (CRL) ๐Ÿ“œ A CRL is a time-stamped list that identifies revoked certificates, is signed by a CA or CRL issuer, and is made freely available in a public repository. Each revoked certificate is identified in a CRL by its certificate serial number. When a certificate-using system uses a certificate (e.g., for verifying a remote user's digital signature), it doesn't just check the certificate signature and validity. It also acquires a suitably recent CRL and checks that the certificate serial number is not on that CRL ๐Ÿ” The meaning of "suitably recent" may vary with local policy, but it usually means the most recently issued CRL. A new CRL is issued on a regular periodic basis (e.g., hourly, daily, or weekly). An entry is added to the CRL as part of the next update following notification of revocation. An entry MUST NOT be removed from the CRL until it appears on one regularly scheduled CRL issued beyond the revoked certificate's validity period. This rule is non-negotiable, bestie ๐Ÿ™…โ€โ™€๏ธ

A big advantage of this revocation method is that CRLs can be distributed by exactly the same means as certificates themselves, namely, via untrusted servers and untrusted communications. ๐Ÿ™Œ

One limitation of the CRL method, when using untrusted communications and servers, is that the time granularity of revocation is limited to the CRL issue period. For example, if a revocation is reported now, that revocation won't be reliably notified to certificate-using systems until all currently issued CRLs are scheduled to be updated. That could be up to one hour, one day, or one week, depending on how often CRLs are issued ๐Ÿข

Just like with the X.509 v3 certificate format, the X.509 v2 CRL format needs to be profiled for Internet use so that implementations from multiple vendors can interoperate. Making that profile is one goal of this document. However, this profile does not require the issuance of CRLs. Message formats and protocols that support on-line revocation notification are defined in other PKIX specifications. On-line methods of revocation notification may be applicable in some environments as an alternative to the X.509 CRL. On-line revocation checking can significantly reduce the latency between a revocation report and the distribution of that information to relying parties โšก Once the CA accepts a revocation report as authentic and valid, any query to the on-line service will correctly reflect the certificate validation impacts of the revocation. But these methods come with new security requirements: the certificate validator needs to trust the on-line validation service, while the repository does not need to be trusted. ๐Ÿ”

3.4. Operational Protocols ๐Ÿ“ฎ

Operational protocols are required to deliver certificates and CRLs (or status information) to certificate-using client systems. Provisions are needed for a variety of different means of certificate and CRL delivery, including distribution procedures based on LDAP, HTTP, FTP, and X.500. Operational protocols that support these functions are defined in other PKIX specifications. Those specifications may include definitions of message formats and procedures for supporting all of the above operational environments, including definitions of or references to appropriate MIME content types ๐ŸŽ€

3.5. Management Protocols ๐Ÿ’Œ

Okay so management protocols are the online chats that keep a PKI running ๐Ÿ’ฌ. They cover conversations between a PKI user and management entities, like a CA and a client system holding a key pair, or two CAs that cross-certify each other ๐Ÿค. These are the functions the protocols might need to support:

  • (a) registration: This is how a user first introduces themselves to a CA (directly, or through an RA) before that CA issues any certificates for them ๐Ÿชช.
  • (b) initialization: Before a client system can operate securely, it needs key materials that have the right relationship with keys stored elsewhere in the infrastructure ๐Ÿ”. For example, the client needs to be securely initialized with the public key and other assured information of the trusted CA(s), so it can validate certificate paths.

Furthermore, a client typically needs to be initialized with its own key pair(s) ๐ŸŽ€.

  • (c) certification: This is where a CA issues a certificate for a user's public key, then returns that certificate to the user's client system and/or posts it in a repository ๐Ÿ“ฎ.
  • (d) key pair recovery: As an option, user client key materials (e.g., a user's private key used for encryption purposes) may be backed up by a CA or a key backup system ๐Ÿ—๏ธ. If a user needs to recover that backed-up material (e.g., after a forgotten password or a lost key chain file), an online protocol exchange may be needed to make that happen ๐Ÿ˜ญ.
  • (e) key pair update: All key pairs need to be updated regularly, i.e., replaced with a new key pair, with new certificates issued ๐Ÿ”„.
  • (f) revocation request: An authorized person tells a CA about an abnormal situation that requires certificate revocation ๐Ÿšจ.
  • (g) cross-certification: Two CAs exchange the information used to establish a cross-certificate. A cross-certificate is a certificate issued by one CA to another CA that contains a CA signature key used for issuing certificates ๐Ÿฆ‹.

Note that online protocols aren't the only way to do any of this ๐Ÿ™ˆ. For all functions, there are offline methods that get the same result, and this specification does not mandate use of online protocols. For example, when hardware tokens are used, many of these functions can happen as part of the physical token delivery ๐Ÿ“ฆ. Some of the functions can also be combined into one protocol exchange. In particular, two or more of the registration, initialization, and certification functions can be combined into one protocol exchange โœจ.

The PKIX series of specifications defines a set of standard message formats that support all of this. The protocols for carrying these messages in different environments (e.g., email, file transfer, and WWW) are described in those specifications ๐Ÿ’œ.


4. Certificate and Certificate Extensions Profile ๐Ÿ‘‘

This section presents a profile for public key certificates that fosters interoperability and a reusable PKI ๐Ÿซถ. It's based on the X.509 v3 certificate format and the standard certificate extensions defined in [X.509]. The ISO/IEC and ITU-T documents use the 1997 version of ASN.1, while this document uses the 1988 ASN.1 syntax. The encoded certificate and standard extensions are equivalent, so no stress ๐Ÿงš. This section also defines private extensions needed to support a PKI for the Internet community ๐ŸŒˆ.

Certificates can show up in a wide range of applications and environments, with all kinds of interoperability goals and even more operational and assurance requirements ๐Ÿคฏ. The goal of this document is to set a common baseline for generic applications that need broad interoperability and have limited special purpose requirements ๐Ÿ’…. Specifically, the emphasis is on supporting X.509 v3 certificates for informal Internet electronic mail, IPsec, and WWW applications ๐Ÿ“.

4.1. Basic Certificate Fields ๐ŸŽ€

The X.509 v3 certificate basic syntax looks like this. For signature calculation, the data to be signed is encoded using the ASN.1 distinguished encoding rules (DER) [X.690]. ASN.1 DER encoding is a tag, length, value encoding system for each element ๐Ÿงฉ.

Certificate  ::=  SEQUENCE  {
     tbsCertificate       TBSCertificate,
     signatureAlgorithm   AlgorithmIdentifier,
     signatureValue       BIT STRING  }

TBSCertificate  ::=  SEQUENCE  {
     version         [0]  EXPLICIT Version DEFAULT v1,
     serialNumber         CertificateSerialNumber,
     signature            AlgorithmIdentifier,
     issuer               Name,
     validity             Validity,
     subject              Name,
     subjectPublicKeyInfo SubjectPublicKeyInfo,
     issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
                          -- If present, version MUST be v2 or v3

     subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
                          -- If present, version MUST be v2 or v3
     extensions      [3]  EXPLICIT Extensions OPTIONAL
                          -- If present, version MUST be v3
     }

Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }

CertificateSerialNumber  ::=  INTEGER

Validity ::= SEQUENCE {
     notBefore      Time,
     notAfter       Time }

Time ::= CHOICE {
     utcTime        UTCTime,
     generalTime    GeneralizedTime }

UniqueIdentifier  ::=  BIT STRING

SubjectPublicKeyInfo  ::=  SEQUENCE  {
     algorithm            AlgorithmIdentifier,
     subjectPublicKey     BIT STRING  }

Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension

Extension  ::=  SEQUENCE  {
     extnID      OBJECT IDENTIFIER,
     critical    BOOLEAN DEFAULT FALSE,
     extnValue   OCTET STRING
                 -- contains the DER encoding of an ASN.1 value
                 -- corresponding to the extension type identified
                 -- by extnID
     }

The following items describe the X.509 v3 certificate for use on the Internet ๐ŸŒธ.

4.1.1. Certificate Fields ๐Ÿ“œ

The Certificate is a SEQUENCE of three required fields. Each field is described in detail in the subsections below ๐Ÿ’–.

4.1.1.1. tbsCertificate ๐Ÿงพ

This field contains the names of the subject and issuer, a public key associated with the subject, a validity period, and other associated information. The fields are described in detail in Section 4.1.2. The tbsCertificate usually includes extensions, which are described in Section 4.2 โœจ.

4.1.1.2. signatureAlgorithm ๐Ÿ”

The signatureAlgorithm field contains the identifier for the cryptographic algorithm the CA used to sign this certificate. [RFC3279], [RFC4055], and [RFC4491] list supported signature algorithms, but other signature algorithms MAY also be supported ๐Ÿฆ„.

An algorithm identifier is defined by the following ASN.1 structure:

AlgorithmIdentifier  ::=  SEQUENCE  {
     algorithm               OBJECT IDENTIFIER,
     parameters              ANY DEFINED BY algorithm OPTIONAL  }

The algorithm identifier is used to identify a cryptographic algorithm. The OBJECT IDENTIFIER component identifies the algorithm (such as DSA with SHA-1). The contents of the optional parameters field vary according to the algorithm identified ๐Ÿ”ข.

This field MUST contain the same algorithm identifier as the signature field in the sequence tbsCertificate (Section 4.1.2.3). No mixing it up, bestie ๐Ÿ™…โ€โ™€๏ธ.

4.1.1.3. signatureValue โœ๏ธ

The signatureValue field contains a digital signature computed over the ASN.1 DER encoded tbsCertificate. That encoded tbsCertificate is the input to the signature function. The signature value is encoded as a BIT STRING and included in the signature field. The details of this process are specified for each of the algorithms listed in [RFC3279], [RFC4055], and [RFC4491] ๐Ÿ–‹๏ธ.

By generating this signature, a CA certifies the validity of the information in the tbsCertificate field. In particular, the CA certifies the binding between the public key material and the subject of the certificate. That's the whole vibe ๐Ÿ’•.

4.1.2. TBSCertificate ๐Ÿ’Ž

The sequence TBSCertificate contains information about the subject of the certificate and the CA that issued it ๐Ÿง . Every TBSCertificate contains the names of the subject and issuer, a public key associated with the subject, a validity period, a version number, and a serial number. Some MAY contain optional unique identifier fields ๐Ÿ”‘. The rest of this section covers the syntax and semantics of these fields. A TBSCertificate usually includes extensions, and extensions for the Internet PKI are described in Section 4.2 ๐ŸŒท.

4.1.2.1. Version ๐Ÿ”ข

This field describes the version of the encoded certificate. When extensions are used, as expected in this profile, version MUST be 3 (value is 2). If no extensions are present, but a UniqueIdentifier is present, the version SHOULD be 2 (value is 1); however, the version MAY be 3. If only basic fields are present, the version SHOULD be 1 (the value is omitted from the certificate as the default value); however, the version MAY be 2 or 3 ๐ŸŒ™.

Implementations SHOULD be prepared to accept any version certificate. At a minimum, conforming implementations MUST recognize version 3 certificates ๐Ÿ™Œ.

Generation of version 2 certificates is not expected by implementations based on this profile ๐Ÿ™…โ€โ™€๏ธ.

4.1.2.2. Serial Number ๐Ÿ”Ÿ

The serial number MUST be a positive integer assigned by the CA to each certificate. It MUST be unique for each certificate issued by a given CA (i.e., the issuer name and serial number identify a unique certificate). CAs MUST force the serialNumber to be a non-negative integer ๐Ÿ”.

Given the uniqueness requirements above, serial numbers can be expected to contain long integers. Certificate users MUST be able to handle serialNumber values up to 20 octets. Conforming CAs MUST NOT use serialNumber values longer than 20 octets ๐Ÿ“.

Note: Non-conforming CAs may issue certificates with serial numbers that are negative or zero. Certificate users SHOULD be prepared to gracefully handle such certificates ๐Ÿ˜ญ๐Ÿซถ.

4.1.2.3. Signature ๐Ÿ–Š๏ธ

This field contains the algorithm identifier for the algorithm the CA used to sign the certificate ๐Ÿ’ซ.

This field MUST contain the same algorithm identifier as the signatureAlgorithm field in the sequence Certificate (Section 4.1.1.2). The contents of the optional parameters field vary according to the algorithm identified. [RFC3279], [RFC4055], and [RFC4491] list supported signature algorithms, but other signature algorithms MAY also be supported ๐Ÿฆ‹.

4.1.2.4. Issuer

The issuer field is the entity that signed and issued the certificate. ๐Ÿ•ต๏ธโ€โ™€๏ธ It MUST contain a non-empty distinguished name (DN). The issuer field is defined as the X.501 type Name [X.501], and Name is built from these ASN.1 structures:

Name ::= CHOICE { -- only one possibility for now --
  rdnSequence  RDNSequence }

RDNSequence ::= SEQUENCE OF RelativeDistinguishedName

RelativeDistinguishedName ::=
  SET SIZE (1..MAX) OF AttributeTypeAndValue

AttributeTypeAndValue ::= SEQUENCE {
  type     AttributeType,
  value    AttributeValue }

AttributeType ::= OBJECT IDENTIFIER

AttributeValue ::= ANY -- DEFINED BY AttributeType

DirectoryString ::= CHOICE {
      teletexString           TeletexString (SIZE (1..MAX)),
      printableString         PrintableString (SIZE (1..MAX)),
      universalString         UniversalString (SIZE (1..MAX)),
      utf8String              UTF8String (SIZE (1..MAX)),
      bmpString               BMPString (SIZE (1..MAX)) }

So a Name is a hierarchy of attributes, like country name โžก๏ธ US. โœจ The type of each AttributeValue depends on its AttributeType, and it's usually a DirectoryString. ๐Ÿ’…

DirectoryString is a choice between PrintableString, TeletexString, BMPString, UTF8String, and UniversalString. Now here's the important bit ๐Ÿšจ: CAs following this profile MUST use either PrintableString or UTF8String for DirectoryString, with two exceptions. First, if a CA already issued certificates with issuer attributes encoded as TeletexString, BMPString, or UniversalString, it MAY keep using those encodings for backward compatibility. Second, new CAs joining a domain where existing CAs use TeletexString, BMPString, or UniversalString in their issuer attributes MAY encode the attributes they share with those existing CAs using the same encodings the existing CAs use. Iconic consistency energy ๐ŸŽ€

Distinguished names are made of attributes, and this spec doesn't restrict which attribute types can show up in names. ๐Ÿ™Œ Still, conforming implementations MUST be prepared to receive certificates whose issuer names contain the attribute types listed below. This specification RECOMMENDS support for additional attribute types too ๐ŸŒˆ

The X.500 series [X.520] defines standard attribute sets. Implementations of this spec MUST be prepared to receive these standard attribute types in issuer and subject (Section 4.1.2.6) names:

  • country,
  • organization,
  • organizational unit,
  • distinguished name qualifier,
  • state or province name,
  • common name (e.g., "Susan Housley"), and
  • serial number.

Implementations of this spec SHOULD also be prepared to receive these standard attribute types in issuer and subject names:

  • locality,
  • title,
  • surname,
  • given name,
  • initials,
  • pseudonym, and
  • generation qualifier (e.g., "Jr.", "3rd", or "IV").

The syntax and OIDs (object identifiers) for these attribute types are in the ASN.1 modules in Appendix A. ๐Ÿงพ

Implementations of this spec MUST also be prepared to receive the domainComponent attribute, defined in [RFC4519]. DNS is a hierarchical labeling system for resources ๐ŸŒ, and this attribute is a handy way for organizations to make DNs that mirror their DNS names. ๐Ÿชž It is not a replacement for the dNSName component of the alternative name extensions. Implementations are not required to convert these names into DNS names. The syntax and OID for this attribute are in the ASN.1 modules in Appendix A. Rules for encoding internationalized domain names with the domainComponent attribute type are in Section 7.3. ๐ŸŒ

Certificate users MUST be prepared to process the issuer distinguished name and the subject distinguished name (Section 4.1.2.6) fields so they can do name chaining for certification path validation (Section 6). ๐Ÿ”— Name chaining works by matching the issuer DN in one certificate against the subject name in a CA certificate. Rules for comparing distinguished names are in Section 7.1. If the issuer and subject names in a certificate match under the rules in Section 7.1, the certificate is self-issued. ๐Ÿชžโœจ


4.1.2.5. Validity

The validity period is the time window during which the CA promises it will keep information about the certificate's status. โณ It's a SEQUENCE of two dates: notBefore (when the window starts) and notAfter (when it ends). Both can be encoded as UTCTime or GeneralizedTime.

CAs following this profile MUST always encode validity dates through the year 2049 as UTCTime, and validity dates in 2050 or later MUST be encoded as GeneralizedTime. ๐Ÿ“… Conforming applications MUST be able to process validity dates encoded as either UTCTime or GeneralizedTime. ๐Ÿซถ

A certificate's validity period runs from notBefore through notAfter, inclusive. ๐Ÿ’œ

Some devices get certificates that don't have a good expiration date ๐Ÿค–. For example, a device might get a certificate that binds its model and serial number to its public key. That kind of certificate is meant to last for the device's entire life. ๐Ÿ”ง

To say a certificate has no well-defined expiration date, the notAfter SHOULD be set to the GeneralizedTime value 99991231235959Z. โ™พ๏ธ

If the issuer won't be able to maintain status information until the notAfter date (including when notAfter is 99991231235959Z), the issuer MUST make sure no valid certification path exists for the certificate once status maintenance stops. ๐Ÿ’€ This can happen by expiring or revoking all CA certificates that contain the public key used to verify the signature on the certificate, and by no longer using that public key as a trust anchor.

4.1.2.5.1. UTCTime

UTCTime is a standard ASN.1 type for dates and times. โฐ It stores the year as its two lowest-order digits, and the time can be given to the precision of one minute or one second. UTCTime includes either Z (for Zulu, meaning Greenwich Mean Time) or a time differential.

For this profile, UTCTime values MUST be expressed in Greenwich Mean Time (Zulu) and MUST include seconds (so times look like YYMMDDHHMMSSZ), even when the seconds are zero. ๐Ÿ•ฐ๏ธ Conforming systems MUST read the year field (YY) like this:

  • Where YY is greater than or equal to 50, the year SHALL be interpreted as 19YY; and
  • Where YY is less than 50, the year SHALL be interpreted as 20YY.

4.1.2.5.2. GeneralizedTime

GeneralizedTime is a standard ASN.1 type for representing time with variable precision. ๐ŸŒ™ It can optionally include the time differential between local time and Greenwich Mean Time.

For this profile, GeneralizedTime values MUST be expressed in Greenwich Mean Time (Zulu) and MUST include seconds (so times look like YYYYMMDDHHMMSSZ), even when the seconds are zero. GeneralizedTime values MUST NOT include fractional seconds. ๐Ÿšซโœจ

Okay that's the issuer and validity stuff! ๐Ÿ’– Next up we get into the subject field ๐Ÿงš

4.1.2.6. Subject ๐Ÿซถ

okay so the subject field is basically how we say who this cert belongs to ๐ŸŽ€ it names the entity tied to the public key in the subject public key field ๐Ÿ”‘ the subject name MAY be carried in the subject field and/or the subjectAltName extension, so you've got options โœจ but if the subject is a CA (like when basic constraints from Section 4.2.1.9 is there and cA is TRUE), then the subject field MUST be populated with a non-empty distinguished name that matches the issuer field (Section 4.1.2.4) in every cert that CA issues ๐Ÿ’… same energy for a CRL issuer (key usage from Section 4.2.1.3 with cRLSign set to TRUE): the subject field MUST be populated with a non-empty DN matching the issuer field (Section 5.1.2.3) in all CRLs that CRL issuer puts out ๐Ÿ“œ and if the subject naming info only lives in subjectAltName (like a key tied to just an email or URI), then the subject name MUST be an empty sequence and the subjectAltName extension MUST be critical ๐Ÿฆ‹

when the subject name isn't empty, the subject field MUST contain an X.500 distinguished name (DN) ๐Ÿ’– the DN MUST be unique for each subject entity certified by the one CA, as defined by the issuer field ๐Ÿ‘‘ a CA MAY issue more than one certificate with the same DN to the same subject entity, which is totally fine ๐ŸŒธ

the subject field is defined as the X.501 type Name, and the implementation rules are the same ones as the issuer field (Section 4.1.2.4) ๐Ÿงš implementations MUST be prepared to receive subject names with the attribute types required for the issuer field, and they SHOULD be prepared for the recommended attribute types too ๐Ÿ“ the syntax and OIDs for those attribute types are in the ASN.1 modules in Appendix A ๐Ÿ“š implementations MAY use the comparison rules in Section 7.1 to handle unfamiliar attribute types (for name chaining) whose values use one of the DirectoryString encoding options ๐Ÿ” binary comparison should be used when unfamiliar attribute types have values with encoding options that aren't in DirectoryString ๐Ÿค– this way, implementations can process certs with unfamiliar attributes in the subject name ๐Ÿซถ

now, when you encode DirectoryString attribute values, conforming CAs MUST use PrintableString or UTF8String, with these exceptions ๐Ÿ’…

  • (a) When the subject of the certificate is a CA, the subject field MUST be encoded the same way it's encoded in the issuer field (Section 4.1.2.4) in all certificates that CA issues. So if the subject CA uses TeletexString, BMPString, or UniversalString in its issuer fields, the subject field of certs issued to that CA MUST use the same encoding ๐ŸŒˆ
  • (b) When the subject of the certificate is a CRL issuer, the subject field MUST be encoded the same way it's encoded in the issuer field (Section 5.1.2.3) in all CRLs that CRL issuer puts out ๐Ÿ“œ
  • (c) TeletexString, BMPString, and UniversalString are only here for backward compatibility ๐Ÿ˜ญ they SHOULD NOT be used for certificates for new subjects. They MAY be used where the name was already established, like a new cert for an existing subject, or a cert for a new subject where the attributes were already set up in certs for other subjects ๐Ÿ•ฐ๏ธ certificate users SHOULD be prepared to receive certs with these types ๐Ÿซถ

legacy implementations exist where an email address gets stuffed into the subject DN as an emailAddress attribute [RFC2985] ๐Ÿ™ˆ its value is an IA5String, because IA5String lets you include the @ character, which PrintableString doesn't allow โœจ also, emailAddress values aren't case-sensitive (so "subscriber@example.com" is the same as "SUBSCRIBER@EXAMPLE.COM") ๐Ÿฆ‹

conforming implementations that generate new certs with email addresses MUST use the rfc822Name in the subject alternative name extension (Section 4.2.1.6) to describe those identities ๐Ÿ’œ putting the emailAddress attribute in the subject DN too, to support legacy implementations, is deprecated but still permitted ๐Ÿ˜ญ

4.1.2.7. Subject Public Key Info ๐Ÿ”‘

this field carries the public key and says which algorithm the key is used with (like RSA, DSA, or Diffie-Hellman) ๐Ÿง the algorithm is identified with the AlgorithmIdentifier structure from Section 4.1.1.2 ๐Ÿ’… the OIDs for the supported algorithms, and how to encode the public key material (the key and its parameters), are specified in [RFC3279], [RFC4055], and [RFC4491] ๐Ÿ“–

4.1.2.8. Unique Identifiers ๐Ÿชช

these fields MUST only appear if the version is 2 or 3 (Section 4.1.2.1) ๐ŸŒธ they MUST NOT appear if the version is 1 ๐Ÿ™…โ€โ™€๏ธ the subject and issuer unique identifiers are in the cert to handle the chance that subject and/or issuer names get reused over time ๐Ÿ•ฐ๏ธ this profile RECOMMENDS that names not be reused for different entities, and that Internet certificates not make use of unique identifiers ๐Ÿ’… CAs conforming to this profile MUST NOT generate certificates with unique identifiers ๐Ÿšซ applications conforming to this profile SHOULD be capable of parsing certs that include unique identifiers, but there are no processing requirements tied to them ๐Ÿฆ‹

4.1.2.9. Extensions ๐ŸŽ€

this field MUST only appear if the version is 3 (Section 4.1.2.1) ๐Ÿ‘‘ if it's there, it's a SEQUENCE of one or more certificate extensions โœจ the format and content of certificate extensions in the Internet PKI are defined in Section 4.2 ๐Ÿงš

4.2. Certificate Extensions ๐Ÿ’œ

the extensions for X.509 v3 certs give you ways to attach extra attributes to users or public keys, and to manage the relationships between CAs ๐Ÿซถ the X.509 v3 format also lets communities define private extensions for info that's unique to them ๐ŸŒˆ every extension in a cert is marked either critical or non-critical ๐Ÿ”ฅ a certificate-using system MUST reject the certificate if it runs into a critical extension it doesn't recognize, or a critical extension with info it can't process ๐Ÿ›‘ a non-critical extension MAY be ignored if it isn't recognized, but it MUST be processed if it is recognized โœจ the next sections present the recommended extensions for Internet certs and the standard places to put info ๐Ÿ“š communities can pick extra extensions too, but be careful about adopting critical extensions that might stop the cert from being used in a general context โš ๏ธ

each extension has an OID and an ASN.1 structure ๐Ÿ’… when an extension shows up in a cert, the OID appears as the field extnID, and the matching ASN.1 DER encoded structure is the value of the octet string extnValue ๐ŸŽ€ a certificate MUST NOT include more than one instance of a particular extension ๐Ÿ™ˆ for example, a certificate may contain only one authority key identifier extension (Section 4.2.1.1) ๐Ÿ™…โ€โ™€๏ธ the extension has a boolean critical, with a default value of FALSE ๐Ÿซถ the text for each extension says which values of the critical field are acceptable for CAs conforming to this profile ๐Ÿ”

conforming CAs MUST support the key identifier (Sections 4.2.1.1 and 4.2.1.2), basic constraints (Section 4.2.1.9), key usage (Section 4.2.1.3), and certificate policies (Section 4.2.1.4) extensions ๐Ÿ’– if the CA issues certs with an empty sequence for the subject field, the CA MUST support the subject alternative name extension (Section 4.2.1.6) ๐Ÿฆ‹ support for the remaining extensions is OPTIONAL ๐ŸŒธ conforming CAs MAY support extensions that aren't identified in this specification, but cert issuers are warned that marking those as critical may hurt interoperability โš ๏ธ

at a minimum, applications conforming to this profile MUST recognize these extensions: key usage (Section 4.2.1.3), certificate policies (Section 4.2.1.4), subject alternative name (Section 4.2.1.6), basic constraints (Section 4.2.1.9), name constraints (Section 4.2.1.10), policy constraints (Section 4.2.1.11), extended key usage (Section 4.2.1.12), and inhibit anyPolicy (Section 4.2.1.14) ๐Ÿ“œ

on top of that, applications conforming to this profile SHOULD recognize the authority and subject key identifier (Sections 4.2.1.1 and 4.2.1.2) and the policy mappings (Section 4.2.1.5) extensions ๐Ÿงš

4.2.1. Standard Extensions ๐ŸŒˆ

this section identifies the standard certificate extensions defined in [X.509] for use in the Internet PKI ๐Ÿ” each extension is linked to an OID defined in [X.509] ๐Ÿซถ these OIDs live in the id-ce arc, defined like this ๐Ÿ‘‡

id-ce   OBJECT IDENTIFIER ::=  { joint-iso-ccitt(2) ds(5) 29 }

4.2.1.1. Authority Key Identifier โœจ

okay so the authority key identifier extension is basically how a cert says "this is the key that signed me" ๐Ÿ”‘ it's giving receipts. ๐Ÿ’… It's used when an issuer has multiple signing keys (either because they have multiple key pairs running at once or because they're switching keys over). The identification MAY be based on either the key identifier (the subject key identifier in the issuer's certificate) or the issuer name and serial number. ๐Ÿฆ‹

The keyIdentifier field of this extension MUST be included in all certificates generated by conforming CAs so that certification path construction works smoothly ๐Ÿ›ค๏ธ there's one exception tho: if a CA hands out its public key as a "self-signed" certificate, the authority key identifier MAY be omitted. ๐Ÿ™ˆ A self-signed cert is signed with the private key that goes with the certificate's own subject public key. (That proves the issuer has both the public and private keys ๐Ÿ”) In that case the subject and authority key identifiers would be identical, but only the subject key identifier is actually needed for building the certification path.

The value of the keyIdentifier field SHOULD be derived from the public key used to verify the certificate's signature, or from a method that generates unique values. โœจ Two common methods for generating key identifiers from the public key are described in Section 4.2.1.2. If no key identifier has been set up yet, this specification RECOMMENDS using one of those methods, or a similar method that uses a different hash algorithm. If a key identifier has already been established, the CA SHOULD keep using that previously established identifier. ๐Ÿ’œ

This profile RECOMMENDS that all certificate users support the key identifier method. ๐ŸŒธ

Conforming CAs MUST mark this extension as non-critical. ๐Ÿซถ

id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::=  { id-ce 35 }

AuthorityKeyIdentifier ::= SEQUENCE {
   keyIdentifier             [0] KeyIdentifier           OPTIONAL,
   authorityCertIssuer       [1] GeneralNames            OPTIONAL,
   authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL  }

KeyIdentifier ::= OCTET STRING

4.2.1.2. Subject Key Identifier ๐ŸŽ€

the subject key identifier extension is the flip side: it's how you identify certificates that contain a particular public key. ๐Ÿ” main character energy for keys, bestie.

To make certification path construction work, this extension MUST appear in all conforming CA certificates. That means all certificates that include the basic constraints extension (Section 4.2.1.9) where the value of cA is TRUE. ๐Ÿ‘‘ In conforming CA certificates, the subject key identifier MUST be the value that goes in the key identifier field of the authority key identifier extension (Section 4.2.1.1) of certificates issued by the subject of that certificate. Applications are not required to verify that key identifiers match when they're doing certification path validation. ๐Ÿคทโ€โ™€๏ธ

For CA certificates, subject key identifiers SHOULD be derived from the public key or from a method that generates unique values. Two common methods for generating key identifiers from the public key are:

  • (1) The keyIdentifier is composed of the 160-bit SHA-1 hash of the value of the BIT STRING subjectPublicKey (excluding the tag, length, and number of unused bits). ๐Ÿงฎ
  • (2) The keyIdentifier is composed of a four-bit type field with the value 0100 followed by the least significant 60 bits of the SHA-1 hash of the value of the BIT STRING subjectPublicKey (excluding the tag, length, and number of unused bits). ๐Ÿงฎโœจ

Other methods of generating unique numbers are also acceptable. ๐Ÿ’–

For end entity certificates, the subject key identifier extension gives a way to identify the certificates containing the particular public key an application uses. ๐Ÿ“ฑ If an end entity has gotten multiple certificates, especially from multiple CAs, the subject key identifier lets you quickly find the set of certificates that share one public key. To help applications pick the right end entity certificate, this extension SHOULD be included in all end entity certificates. ๐ŸŒˆ

For end entity certificates, subject key identifiers SHOULD be derived from the public key. The two common methods for generating key identifiers from the public key are the ones listed above. ๐Ÿ”

If no key identifier has been established yet, this specification RECOMMENDS using one of these methods, or a similar method that uses a different hash algorithm. If a key identifier has already been established, the CA SHOULD use that previously established identifier. ๐Ÿ“

Conforming CAs MUST mark this extension as non-critical. ๐Ÿ™Œ

id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::=  { id-ce 14 }

SubjectKeyIdentifier ::= KeyIdentifier

4.2.1.3. Key Usage ๐Ÿ”

the key usage extension says what the key in the certificate is for, like encipherment, signatures, or signing certificates. ๐Ÿ–Š๏ธ It's super useful when a key could do a bunch of things but you want to restrict it to just one. For example, if an RSA key should only be used to verify signatures on objects other than public key certificates and CRLs, then the digitalSignature and/or nonRepudiation bits would be asserted. ๐Ÿงพ And if an RSA key should only be used for key management, the keyEncipherment bit would be asserted. ๐Ÿ—๏ธ

Conforming CAs MUST include this extension in certificates that contain public keys used to validate digital signatures on other public key certificates or CRLs. ๐Ÿซก When it's present, conforming CAs SHOULD mark this extension as critical. โญ

   id-ce-keyUsage OBJECT IDENTIFIER ::=  { id-ce 15 }

   KeyUsage ::= BIT STRING {
        digitalSignature        (0),
        nonRepudiation          (1), -- recent editions of X.509 have
                             -- renamed this bit to contentCommitment
        keyEncipherment         (2),
        dataEncipherment        (3),
        keyAgreement            (4),
        keyCertSign             (5),
        cRLSign                 (6),
        encipherOnly            (7),
        decipherOnly            (8) }

Here's how the bits in the KeyUsage type work: ๐Ÿงฉ

  • The digitalSignature bit is asserted when the subject public key is used for verifying digital signatures, other than signatures on certificates (bit 5) and CRLs (bit 6). Think entity authentication, data origin authentication, and/or integrity service. โœ๏ธ
  • The nonRepudiation bit is asserted when the subject public key is used to verify digital signatures, other than signatures on certificates (bit 5) and CRLs (bit 6), to provide a non-repudiation service that protects against the signing entity falsely denying some action. If things go sideways later, a reliable third party may determine the authenticity of the signed data. (Note that recent editions of X.509 have renamed the nonRepudiation bit to contentCommitment.) ๐Ÿง
  • The keyEncipherment bit is asserted when the subject public key is used for enciphering private or secret keys, i.e., for key transport. For example, this bit shall be set when an RSA public key is to be used for encrypting a symmetric content-decryption key or an asymmetric private key. ๐Ÿ”‘๐Ÿ”’
  • The dataEncipherment bit is asserted when the subject public key is used for directly enciphering raw user data without an intermediate symmetric cipher. Heads up: this bit is extremely uncommon. Almost all applications use key transport or key agreement to set up a symmetric key instead. ๐Ÿ™ƒ
  • The keyAgreement bit is asserted when the subject public key is used for key agreement. For example, when a Diffie-Hellman key is to be used for key management, this bit gets set. ๐Ÿค
  • The keyCertSign bit is asserted when the subject public key is used for verifying signatures on public key certificates. If keyCertSign is asserted, then the cA bit in the basic constraints extension (Section 4.2.1.9) MUST also be asserted. ๐Ÿ“œ
  • The cRLSign bit is asserted when the subject public key is used for verifying signatures on certificate revocation lists (e.g., CRLs, delta CRLs, or ARLs). ๐Ÿ—’๏ธ
  • The meaning of the encipherOnly bit is undefined when the keyAgreement bit is absent. When encipherOnly is asserted and keyAgreement is also set, the subject public key may be used only for enciphering data while performing key agreement. ๐ŸŒ™
  • The meaning of the decipherOnly bit is undefined when the keyAgreement bit is absent. When decipherOnly is asserted and keyAgreement is also set, the subject public key may be used only for deciphering data while performing key agreement. โ˜€๏ธ

So, if the keyUsage extension is present, the subject public key MUST NOT be used to verify signatures on certificates or CRLs unless the corresponding keyCertSign or cRLSign bit is set. ๐Ÿšซ If the subject public key is only going to be used for verifying signatures on certificates and/or CRLs, then the digitalSignature and nonRepudiation bits SHOULD NOT be set. However, the digitalSignature and/or nonRepudiation bits MAY be set in addition to the keyCertSign and/or cRLSign bits if the subject public key is used to verify signatures on certificates and/or CRLs as well as other objects. ๐Ÿง 

โš ๏ธ bestie, combining the nonRepudiation bit in the keyUsage certificate extension with other keyUsage bits may have security implications depending on the context the certificate is used in. Further distinctions between the digitalSignature and nonRepudiation bits may be provided in specific certificate policies. ๐Ÿ’€

This profile doesn't restrict which combinations of bits can be set in a keyUsage extension. ๐ŸŽ‰ However, appropriate keyUsage values for particular algorithms are specified in [RFC3279], [RFC4055], and [RFC4491]. When the keyUsage extension appears in a certificate, at least one of the bits MUST be set to 1. ๐Ÿ’–

4.2.1.4. Certificate Policies ๐Ÿ“œโœจ

Okay bestie, so the certificate policies extension is a list of one or more policy information terms ๐Ÿ“œ. Each term has an object identifier (OID) and optional qualifiers. The qualifiers MAY be present, but they aren't supposed to change what the policy means ๐Ÿ’…. And a certificate policy OID MUST NOT show up more than once in the same certificate policies extension. No duplicates, periodt ๐Ÿ™…

In an end entity certificate, these terms tell you which policy the cert was issued under and what it's allowed to be used for ๐ŸŽ€. In a CA certificate, they limit which policies are okay for certification paths that go through that cert ๐Ÿ›ค๏ธ. If a CA doesn't want to limit anything, it MAY assert the special policy anyPolicy, with a value of { 2 5 29 32 0 } ๐ŸŒˆ.

Apps with specific policy needs are expected to keep a list of the policies they'll accept, then compare the policy OIDs in the cert to that list ๐Ÿ“‹. If this extension is critical, the path validation software MUST be able to interpret it (including the optional qualifier), or MUST reject the certificate ๐Ÿšซ. Strict but fair, honestly ๐Ÿ’€.

To keep things interoperable, this profile RECOMMENDS that policy information terms consist of only an OID ๐Ÿซถ. When an OID alone isn't enough, this profile strongly recommends keeping qualifiers limited to the ones in this section ๐Ÿงš. When qualifiers are used with the special policy anyPolicy, they MUST be limited to the qualifiers identified in this section too. Only the qualifiers returned as a result of path validation are considered โœจ.

This spec defines two policy qualifier types for policy writers and certificate issuers: the CPS Pointer and User Notice qualifiers ๐Ÿ’–.

The CPS Pointer qualifier is a pointer to a Certification Practice Statement (CPS) that the CA published. It's in the form of a URI ๐Ÿ”—. How you process it is a local matter, and no action is mandated by this spec, no matter what criticality value the extension has ๐Ÿคท

User notice is meant for display to a relying party when a cert is used ๐Ÿ‘€. Only user notices returned as a result of path validation are intended for display. If a notice gets duplicated, only one copy needs to be shown. To prevent that duplication, this qualifier SHOULD only be present in end entity certificates and in CA certificates issued to other organizations ๐Ÿ™ˆ.

The user notice has two optional fields: the noticeRef field and the explicitText field. Conforming CAs SHOULD NOT use the noticeRef option ๐Ÿ™…โ€โ™€๏ธ.

The noticeRef field, if used, names an organization and identifies, by number, a particular textual statement that organization prepared. For example, it might identify the organization "CertsRUs" and notice number 1. In a typical implementation, the application software has a notice file with the current set of notices for CertsRUs. The application extracts the notice text from that file and displays it. Messages MAY be multilingual, so the software can pick the message in its own language ๐ŸŒธ.

The explicitText field includes the textual statement directly in the certificate ๐Ÿ“. It's a string with a maximum size of 200 characters. Conforming CAs SHOULD use the UTF8String encoding for explicitText, but MAY use IA5String. Conforming CAs MUST NOT encode explicitText as VisibleString or BMPString. The explicitText string SHOULD NOT include any control characters (e.g., U+0000 to U+001F and U+007F to U+009F). When the UTF8String encoding is used, all character sequences SHOULD be normalized according to Unicode normalization form C (NFC) [NFC] ๐Ÿ’….

If both the noticeRef and explicitText options are included in the one qualifier, and the application software can locate the notice text the noticeRef option points to, then that text SHOULD be displayed. Otherwise, the explicitText string SHOULD be displayed ๐Ÿง .

Note: While explicitText has a maximum size of 200 characters, some non-conforming CAs exceed that limit ๐Ÿ˜ญ. So certificate users SHOULD gracefully handle explicitText with more than 200 characters ๐Ÿซถ.

id-ce-certificatePolicies OBJECT IDENTIFIER ::=  { id-ce 32 }

anyPolicy OBJECT IDENTIFIER ::= { id-ce-certificatePolicies 0 }

certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation

PolicyInformation ::= SEQUENCE {
     policyIdentifier   CertPolicyId,
     policyQualifiers   SEQUENCE SIZE (1..MAX) OF
                             PolicyQualifierInfo OPTIONAL }

CertPolicyId ::= OBJECT IDENTIFIER

PolicyQualifierInfo ::= SEQUENCE {
     policyQualifierId  PolicyQualifierId,
     qualifier          ANY DEFINED BY policyQualifierId }

-- policyQualifierIds for Internet policy qualifiers

id-qt          OBJECT IDENTIFIER ::=  { id-pkix 2 }
id-qt-cps      OBJECT IDENTIFIER ::=  { id-qt 1 }
id-qt-unotice  OBJECT IDENTIFIER ::=  { id-qt 2 }

PolicyQualifierId ::= OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice )

Qualifier ::= CHOICE {
     cPSuri           CPSuri,
     userNotice       UserNotice }

CPSuri ::= IA5String

UserNotice ::= SEQUENCE {
     noticeRef        NoticeReference OPTIONAL,
     explicitText     DisplayText OPTIONAL }

NoticeReference ::= SEQUENCE {
     organization     DisplayText,
     noticeNumbers    SEQUENCE OF INTEGER }

DisplayText ::= CHOICE {
     ia5String        IA5String      (SIZE (1..200)),
     visibleString    VisibleString  (SIZE (1..200)),
     bmpString        BMPString      (SIZE (1..200)),
     utf8String       UTF8String     (SIZE (1..200)) }

4.2.1.5. Policy Mappings ๐Ÿฆ‹

This extension is used in CA certificates ๐Ÿ›๏ธ. It lists one or more pairs of OIDs. Each pair includes an issuerDomainPolicy and a subjectDomainPolicy. The pairing means the issuing CA considers its issuerDomainPolicy equivalent to the subject CA's subjectDomainPolicy ๐Ÿค.

The issuing CA's users might accept an issuerDomainPolicy for certain applications. The policy mapping defines the list of policies associated with the subject CA that may be accepted as comparable to the issuerDomainPolicy ๐Ÿ‘‘.

Each issuerDomainPolicy named in the policy mappings extension SHOULD also be asserted in a certificate policies extension in the same certificate. Policies MUST NOT be mapped either to or from the special value anyPolicy (Section 4.2.1.4) ๐Ÿšซ.

In general, certificate policies that appear in the issuerDomainPolicy field of the policy mappings extension aren't considered acceptable for inclusion in subsequent certificates in the certification path ๐Ÿ™ƒ. But sometimes a CA wants to map from one policy (p1) to another (p2) and still wants p1 to count as acceptable for subsequent certificates. This can happen, for example, when the CA is transitioning from p1 to p2 and has valid certificates issued under each policy ๐Ÿ”„. A CA can do this by including two policy mappings in the CA certificates it issues. Each mapping has an issuerDomainPolicy of p1. One mapping has a subjectDomainPolicy of p1, and the other has a subjectDomainPolicy of p2 ๐Ÿ’œ.

This extension MAY be supported by CAs and/or applications. Conforming CAs SHOULD mark this extension as critical ๐Ÿ”ฅ.

id-ce-policyMappings OBJECT IDENTIFIER ::=  { id-ce 33 }

PolicyMappings ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE {
     issuerDomainPolicy      CertPolicyId,
     subjectDomainPolicy     CertPolicyId }

4.2.1.6. Subject Alternative Name โœจ

Okay so the subject alternative name extension is how you bind identities to the subject of a certificate, bestie ๐ŸŽ€ These identities can come along in addition to the identity in the subject field, or they can be used in place of it ๐Ÿ’… The defined options are an Internet electronic mail address, a DNS name, an IP address, and a Uniform Resource Identifier (URI) ๐Ÿฆ‹ There are other options too, including completely local definitions ๐ŸŒˆ Multiple name forms, and multiple instances of each name form, MAY be included โœจ Whenever identities are getting bound into a certificate, the subject alternative name (or issuer alternative name) extension MUST be used ๐Ÿซถ A DNS name MAY also show up in the subject field through the domainComponent attribute, as described in Section 4.1.2.4 ๐Ÿงš Just know that implementations are not required to turn those names into DNS names when they're sitting in the subject field ๐Ÿ™ˆ

Because the subject alternative name is considered definitively bound to the public key, all parts of the subject alternative name MUST be verified by the CA ๐Ÿ’œ

Now here's the tea ๐Ÿต If the only subject identity in the certificate is an alternative name form (like an email address), then the subject distinguished name MUST be empty (an empty sequence), and the subjectAltName extension MUST be present ๐Ÿ’€ If the subject field contains an empty sequence, the issuing CA MUST include a subjectAltName extension that is marked as critical ๐Ÿ”ฅ When you include the subjectAltName extension in a certificate that has a non-empty subject distinguished name, conforming CAs SHOULD mark the subjectAltName extension as non-critical ๐Ÿ“

Quick vibe check: an empty subject plus a critical SAN is the only combo that works here, so don't mix up the two cases ๐Ÿ‘€

When the subjectAltName extension contains an Internet mail address, the address MUST be stored in the rfc822Name ๐Ÿ“ง The format of an rfc822Name is a "Mailbox" as defined in Section 4.1.2 of [RFC2821]. A Mailbox looks like "Local-part@Domain" โœจ A Mailbox has no phrase (like a common name) in front of it, no comment (text in parentheses) after it, and it's not wrapped in "<" and ">" ๐Ÿ™…โ€โ™€๏ธ Rules for encoding mail addresses with internationalized domain names are in Section 7.5 ๐ŸŒธ

When the subjectAltName extension contains an iPAddress, the address MUST be stored in the octet string in "network byte order", as specified in [RFC791] ๐Ÿฆ‹ The least significant bit (LSB) of each octet is the LSB of the corresponding byte in the network address. For IP version 4, as specified in [RFC791], the octet string MUST contain exactly four octets. For IP version 6, as specified in [RFC2460], the octet string MUST contain exactly sixteen octets ๐Ÿ”ข

When the subjectAltName extension contains a domain name system label, the domain name MUST be stored in the dNSName (an IA5String) ๐ŸŒ The name MUST be in the "preferred name syntax", as specified by Section 3.5 of [RFC1034] and as modified by Section 2.1 of [RFC1123]. Uppercase and lowercase letters are allowed in domain names, but no significance is attached to the case ๐Ÿ”ค Also, while the string " " is a legal domain name, subjectAltName extensions with a dNSName of " " MUST NOT be used ๐Ÿšซ Finally, the DNS representation for Internet mail addresses (subscriber.example.com instead of subscriber@example.com) MUST NOT be used. Those identities are to be encoded as rfc822Name instead ๐Ÿ“ฌ Rules for encoding internationalized domain names are in Section 7.2 ๐ŸŒ

When the subjectAltName extension contains a URI, the name MUST be stored in the uniformResourceIdentifier (an IA5String) ๐Ÿ”— The name MUST NOT be a relative URI, and it MUST follow the URI syntax and encoding rules in [RFC3986]. The name MUST include both a scheme (like "http" or "ftp") and a scheme-specific-part ๐Ÿงฉ URIs that include an authority ([RFC3986], Section 3.2) MUST include a fully qualified domain name or IP address as the host ๐Ÿก Rules for encoding Internationalized Resource Identifiers (IRIs) are in Section 7.4 ๐Ÿ’–

As specified in [RFC3986], the scheme name is not case-sensitive (so "http" is equivalent to "HTTP") ๐Ÿค“ The host part, if present, is also not case-sensitive, but other components of the scheme-specific-part may be case-sensitive ๐Ÿ‘€ Rules for comparing URIs are in Section 7.4 โœจ

When the subjectAltName extension contains a DN in the directoryName, the encoding rules are the same as those for the issuer field in Section 4.1.2.4 ๐Ÿ“š The DN MUST be unique for each subject entity certified by the one CA, as defined by the issuer field. A CA MAY issue more than one certificate with the same DN to the same subject entity ๐Ÿซง

The subjectAltName MAY carry additional name types through the otherName field ๐ŸŽ The format and semantics of the name are indicated through the OBJECT IDENTIFIER in the type-id field. The name itself is conveyed in the value field of otherName. For example, Kerberos [RFC4120] format names can be encoded into the otherName, using a Kerberos 5 principal name OID and a SEQUENCE of the Realm and the PrincipalName ๐Ÿงšโ€โ™€๏ธ

Subject alternative names MAY be constrained in the same manner as subject distinguished names, using the name constraints extension described in Section 4.2.1.10 ๐Ÿ”’

If the subjectAltName extension is present, the sequence MUST contain at least one entry ๐Ÿ“ Unlike the subject field, conforming CAs MUST NOT issue certificates with subjectAltNames containing empty GeneralName fields. For example, an rfc822Name is represented as an IA5String. While an empty string is a valid IA5String, such an rfc822Name is not permitted by this profile ๐Ÿ™… The behavior of clients that encounter such a certificate when processing a certification path is not defined by this profile ๐Ÿคทโ€โ™€๏ธ

Finally, the semantics of subject alternative names that include wildcard characters (like a placeholder for a set of names) are not addressed by this specification ๐Ÿƒ Applications with specific requirements MAY use such names, but they must define the semantics ๐Ÿ’…

id-ce-subjectAltName OBJECT IDENTIFIER ::=  { id-ce 17 }

SubjectAltName ::= GeneralNames

GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName

GeneralName ::= CHOICE {
     otherName                       [0]     OtherName,
     rfc822Name                      [1]     IA5String,
     dNSName                         [2]     IA5String,
     x400Address                     [3]     ORAddress,
     directoryName                   [4]     Name,
     ediPartyName                    [5]     EDIPartyName,
     uniformResourceIdentifier       [6]     IA5String,
     iPAddress                       [7]     OCTET STRING,
     registeredID                    [8]     OBJECT IDENTIFIER }

OtherName ::= SEQUENCE {
     type-id    OBJECT IDENTIFIER,
     value      [0] EXPLICIT ANY DEFINED BY type-id }

EDIPartyName ::= SEQUENCE {
     nameAssigner            [0]     DirectoryString OPTIONAL,
     partyName               [1]     DirectoryString }

4.2.1.7. Issuer Alternative Name โœจ

Same energy as the last section, but this time it's for the certificate issuer ๐Ÿ›๏ธ As with Section 4.2.1.6, this extension is used to associate Internet style identities with the certificate issuer. Issuer alternative names MUST be encoded as in 4.2.1.6 ๐Ÿ’• Issuer alternative names are NOT processed as part of the certification path validation algorithm in Section 6. (Translation: issuer alternative names aren't used in name chaining, and name constraints aren't enforced on them ๐Ÿ™ƒ)

Where present, conforming CAs SHOULD mark this extension as non-critical ๐ŸŒฟ

id-ce-issuerAltName OBJECT IDENTIFIER ::=  { id-ce 18 }

IssuerAltName ::= GeneralNames

4.2.1.8. Subject Directory Attributes ๐Ÿ—‚๏ธ

The subject directory attributes extension is used to convey identification attributes (like nationality) of the subject ๐ŸŒ The extension is defined as a sequence of one or more attributes. Conforming CAs MUST mark this extension as non-critical ๐Ÿ™Œ

id-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::=  { id-ce 9 }

SubjectDirectoryAttributes ::= SEQUENCE SIZE (1..MAX) OF Attribute

4.2.1.9. Basic Constraints ๐Ÿ‘‘

The basic constraints extension says whether the subject of the certificate is a CA, plus the maximum depth of valid certification paths that include this certificate ๐Ÿง 

The cA boolean indicates whether the certified public key may be used to verify certificate signatures. If the cA boolean is not asserted, then the keyCertSign bit in the key usage extension MUST NOT be asserted ๐Ÿšซ If the basic constraints extension is not present in a version 3 certificate, or the extension is present but the cA boolean is not asserted, then the certified public key MUST NOT be used to verify certificate signatures ๐Ÿ”

The pathLenConstraint field only matters if the cA boolean is asserted and the key usage extension, if present, asserts the keyCertSign bit (Section 4.2.1.3) ๐ŸŽฏ In that case, it gives the maximum number of non-self-issued intermediate certificates that may follow this certificate in a valid certification path. (Note: the last certificate in the certification path is not an intermediate certificate, and is not included in this limit. Usually the last certificate is an end entity certificate, but it can be a CA certificate ๐Ÿ’โ€โ™€๏ธ) A pathLenConstraint of zero means that no non-self-issued intermediate CA certificates may follow in a valid certification path 0๏ธโƒฃ Where it appears, the pathLenConstraint field MUST be greater than or equal to zero. Where pathLenConstraint does not appear, no limit is imposed โ™พ๏ธ

Conforming CAs MUST include this extension in all CA certificates that contain public keys used to validate digital signatures on certificates, and MUST mark the extension as critical in such certificates ๐Ÿ›ก๏ธ This extension MAY appear as a critical or non-critical extension in CA certificates that contain public keys used exclusively for purposes other than validating digital signatures on certificates. Such CA certificates include ones with public keys used exclusively for validating digital signatures on CRLs, and ones with key management public keys used with certificate enrollment protocols ๐Ÿ“œ This extension MAY appear as a critical or non-critical extension in end entity certificates ๐Ÿชช

CAs MUST NOT include the pathLenConstraint field unless the cA boolean is asserted and the key usage extension asserts the keyCertSign bit ๐Ÿ™…โ€โ™€๏ธ

id-ce-basicConstraints OBJECT IDENTIFIER ::=  { id-ce 19 }

BasicConstraints ::= SEQUENCE {
     cA                      BOOLEAN DEFAULT FALSE,
     pathLenConstraint       INTEGER (0..MAX) OPTIONAL }

4.2.1.10. Name Constraints โœจ

okay bestie, the name constraints extension is giving serious gatekeeper energy ๐Ÿ’… It MUST be used only in a CA certificate, and it lays out a name space where all subject names in later certificates on a certification path MUST be located. The restrictions hit the subject distinguished name AND subject alternative names, but only when that name form is actually there. If the certificate has no name of that type, it's totally fine ๐Ÿฆ‹

Name constraints are not applied to self-issued certificates (unless the certificate is the final one in the path). (ngl this could stop CAs that use name constraints from using self-issued certificates for key rollover ๐Ÿฅบ)

Restrictions are written as permitted or excluded name subtrees. Any name that matches something in excludedSubtrees is invalid, no matter what permittedSubtrees says ๐Ÿšซ Conforming CAs MUST mark this extension as critical and SHOULD NOT impose name constraints on the x400Address, ediPartyName, or registeredID name forms. Conforming CAs MUST NOT issue certificates where name constraints is an empty sequence. So either the permittedSubtrees field or the excludedSubtrees field MUST be present, no empty vibes allowed โœจ

Applications following this profile MUST be able to process name constraints on the directoryName name form, and they SHOULD be able to process them on the rfc822Name, uniformResourceIdentifier, dNSName, and iPAddress name forms. If a critical name constraints extension puts constraints on a name form, and that name form shows up in the subject field or subjectAltName extension of a later certificate, then the application MUST either process the constraint or reject the certificate. No skipping allowed ๐Ÿ™…โ€โ™€๏ธ

Within this profile, the minimum and maximum fields aren't used with any name forms. So the minimum MUST be zero, and the maximum MUST be absent ๐ŸŒธ If an application runs into a critical name constraints extension with other minimum or maximum values for a name form in a later certificate, it MUST either process those fields or reject the certificate.

For URIs, the constraint applies to the host part of the name. The constraint MUST be specified as a fully qualified domain name, and it MAY specify a host or a domain. For example, host.example.com or .example.com. When the constraint starts with a period, it MAY be expanded with one or more labels. So .example.com is satisfied by both host.example.com and my.host.example.com, but NOT by example.com ๐Ÿ‘€ When the constraint doesn't start with a period, it names a specific host. If a constraint is applied to the uniformResourceIdentifier name form and a later certificate has a subjectAltName uniformResourceIdentifier with no authority component, or with an authority host written as an IP address (so no fully qualified domain name), then the application MUST reject the certificate ๐Ÿ’€

Heads up: a URI that doesn't have a fully qualified domain name as its host is an automatic reject once a URI constraint is in play.

A name constraint for Internet mail addresses MAY specify a particular mailbox, all addresses at a particular host, or all mailboxes in a domain. For one mailbox, the constraint is the full mail address, like root@example.com for the root mailbox on the host example.com ๐Ÿ“ฌ For every Internet mail address at a host, the constraint is just the host name. So example.com is satisfied by any mail address at the host example.com. For a whole domain, add a leading period (same as URIs). .example.com covers all the Internet mail addresses in the domain example.com, but NOT the addresses on the host example.com itself ๐Ÿงš

DNS name restrictions look like host.example.com. Any DNS name you can make by adding zero or more labels to the left side of the name satisfies the constraint. So www.host.example.com would pass, but host1.example.com would not ๐Ÿ“

Some legacy setups stick an email address into the subject distinguished name, in an attribute of type emailAddress (Section 4.1.2.6). When constraints are put on the rfc822Name name form, but the certificate doesn't have a subject alternative name, the rfc822Name constraint MUST be applied to that emailAddress attribute in the subject distinguished name. The ASN.1 syntax for emailAddress and its OID are in Appendix A ๐ŸŽ€

Restrictions of the form directoryName MUST be applied to the subject field in the certificate (when the subject field isn't empty) and to any directoryName names in the subjectAltName extension. Restrictions of the form x400Address MUST be applied to any x400Address names in the subjectAltName extension ๐Ÿ’–

When applying directoryName restrictions, an implementation MUST compare DN attributes. At the very least, implementations MUST perform the DN comparison rules in Section 7.1. CAs that issue certificates with a directoryName restriction SHOULD NOT rely on the implementation of the full ISO DN name comparison algorithm. That means name restrictions MUST be written exactly the same way as they're encoded in the subject field or subjectAltName extension ๐Ÿซถ

The syntax of iPAddress MUST be as described in Section 4.2.1.6, plus the following additions for name constraints. For IPv4 addresses, the iPAddress field of GeneralName MUST contain eight (8) octets, encoded in the CIDR style of RFC 4632 to represent an address range [RFC4632]. For IPv6 addresses, the iPAddress field MUST contain 32 octets, encoded the same way. For example, a name constraint for the "class C" subnet 192.0.2.0 is written as the octets C0 00 02 00 FF FF FF 00, which is CIDR notation 192.0.2.0/24 (mask 255.255.255.0) ๐ŸŒˆ

Extra rules for encoding and processing name constraints are in Section 7 ๐Ÿ“š

The syntax and semantics for name constraints on otherName, ediPartyName, and registeredID aren't defined by this specification. However, syntax and semantics for name constraints on other name forms may be specified in other documents โœจ

   id-ce-nameConstraints OBJECT IDENTIFIER ::=  { id-ce 30 }

   NameConstraints ::= SEQUENCE {
        permittedSubtrees       [0]     GeneralSubtrees OPTIONAL,
        excludedSubtrees        [1]     GeneralSubtrees OPTIONAL }

   GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
   GeneralSubtree ::= SEQUENCE {
        base                    GeneralName,
        minimum         [0]     BaseDistance DEFAULT 0,
        maximum         [1]     BaseDistance OPTIONAL }

   BaseDistance ::= INTEGER (0..MAX)

4.2.1.11. Policy Constraints โœจ

the policy constraints extension can be used in certificates issued to CAs, and it's all about controlling path validation in two ways ๐Ÿฆ‹ It can stop policy mapping, or it can require that every certificate in a path has an acceptable policy identifier. Very main character energy for the chain ๐Ÿ‘‘

If the inhibitPolicyMapping field is there, its value is the number of additional certificates that may appear in the path before policy mapping isn't allowed anymore. For example, a value of one means policy mapping may be processed in certificates issued by the subject of this certificate, but not in any additional certificates in the path ๐ŸŒธ

If the requireExplicitPolicy field is there, its value is the number of additional certificates that may appear in the path before an explicit policy is required for the whole path. When an explicit policy is required, every certificate in the path has to contain an acceptable policy identifier in the certificate policies extension. An acceptable policy identifier is either the identifier of a policy the user of the certification path asked for, or the identifier of a policy that's been declared equivalent through policy mapping ๐Ÿง

Conforming applications MUST be able to process the requireExplicitPolicy field and SHOULD be able to process the inhibitPolicyMapping field. Applications that support the inhibitPolicyMapping field MUST also implement support for the policyMappings extension. If the policyConstraints extension is marked as critical and the inhibitPolicyMapping field is present, applications that don't implement support for inhibitPolicyMapping MUST reject the certificate ๐Ÿ’…

Conforming CAs MUST NOT issue certificates where policy constraints is an empty sequence. So either the inhibitPolicyMapping field or the requireExplicitPolicy field MUST be present. How clients handle an empty policy constraints field isn't covered in this profile ๐Ÿ™ˆ

Conforming CAs MUST mark this extension as critical ๐Ÿ”ฅ

   id-ce-policyConstraints OBJECT IDENTIFIER ::=  { id-ce 36 }

   PolicyConstraints ::= SEQUENCE {
        requireExplicitPolicy           [0] SkipCerts OPTIONAL,
        inhibitPolicyMapping            [1] SkipCerts OPTIONAL }

   SkipCerts ::= INTEGER (0..MAX)

4.2.1.12. Extended Key Usage ๐ŸŽ€

okay so this extension lists one or more purposes the certified public key can be used for ๐Ÿ’–, on top of or instead of the basic purposes in the key usage extension. It's usually only on end entity certificates ๐Ÿงš. It's defined like this:

id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 }

ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId

KeyPurposeId ::= OBJECT IDENTIFIER

Any organization with a need can define key purposes ๐ŸŒธ. Object identifiers used to identify key purposes MUST be assigned in accordance with IANA or ITU-T Recommendation X.660 [X.660].

This extension MAY, at the option of the certificate issuer, be either critical or non-critical ๐Ÿฆ‹.

If the extension is present, then the certificate MUST only be used for one of the purposes indicated ๐Ÿ”ฅ. If there are multiple purposes, the application doesn't have to recognize all of them, as long as the intended purpose is in the list ๐Ÿ’…. Certificate using applications MAY require that the extended key usage extension be present and that a particular purpose be indicated in order for the certificate to be acceptable to that application ๐Ÿ‘‘.

If a CA includes extended key usages to satisfy those applications but doesn't want to restrict how the key is used, the CA can include the special KeyPurposeId anyExtendedKeyUsage alongside the specific purposes the applications need โœจ. Conforming CAs SHOULD NOT mark this extension as critical if the anyExtendedKeyUsage KeyPurposeId is present ๐Ÿ™ˆ. Applications that require the presence of a particular purpose MAY reject certificates that include the anyExtendedKeyUsage OID but not the particular OID expected for the application ๐Ÿ’€.

If a certificate contains both a key usage extension and an extended key usage extension, then both extensions MUST be processed independently and the certificate MUST only be used for a purpose consistent with both extensions ๐Ÿซถ. If there's no purpose consistent with both extensions, then the certificate MUST NOT be used for any purpose ๐Ÿ˜ญ.

The following key usage purposes are defined ๐ŸŒˆ:

anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 }

id-kp OBJECT IDENTIFIER ::= { id-pkix 3 }

id-kp-serverAuth             OBJECT IDENTIFIER ::= { id-kp 1 }
-- TLS WWW server authentication
-- Key usage bits that may be consistent: digitalSignature,
-- keyEncipherment or keyAgreement

id-kp-clientAuth             OBJECT IDENTIFIER ::= { id-kp 2 }
-- TLS WWW client authentication
-- Key usage bits that may be consistent: digitalSignature
-- and/or keyAgreement

id-kp-codeSigning             OBJECT IDENTIFIER ::= { id-kp 3 }
-- Signing of downloadable executable code
-- Key usage bits that may be consistent: digitalSignature

id-kp-emailProtection         OBJECT IDENTIFIER ::= { id-kp 4 }
-- Email protection
-- Key usage bits that may be consistent: digitalSignature,
-- nonRepudiation, and/or (keyEncipherment or keyAgreement)

id-kp-timeStamping            OBJECT IDENTIFIER ::= { id-kp 8 }
-- Binding the hash of an object to a time
-- Key usage bits that may be consistent: digitalSignature
-- and/or nonRepudiation

id-kp-OCSPSigning            OBJECT IDENTIFIER ::= { id-kp 9 }
-- Signing OCSP responses
-- Key usage bits that may be consistent: digitalSignature
-- and/or nonRepudiation

4.2.1.13. CRL Distribution Points ๐Ÿฆ‹

this extension is how you figure out where to get CRL info ๐Ÿ—บ๏ธ. It SHOULD be non-critical, but this profile RECOMMENDS that CAs and applications support it ๐Ÿ’œ. More CRL management drama is in Section 5 ๐Ÿ“š.

The cRLDistributionPoints extension is a SEQUENCE of DistributionPoint ๐ŸŽ€. Each DistributionPoint has three fields that are all optional: distributionPoint, reasons, and cRLIssuer ๐ŸŒธ. Even though they're optional, a DistributionPoint MUST NOT consist of only the reasons field ๐Ÿ™…โ€โ™€๏ธ. Either distributionPoint or cRLIssuer MUST be present. If the certificate issuer isn't the CRL issuer, then the cRLIssuer field MUST be present and contain the Name of the CRL issuer ๐Ÿ”ฅ. If the certificate issuer is also the CRL issuer, then conforming CAs MUST omit the cRLIssuer field and MUST include the distributionPoint field โœจ.

When the distributionPoint field is there, it holds either a SEQUENCE of general names or one single value, nameRelativeToCRLIssuer ๐Ÿ’…. If the DistributionPointName has multiple values, each name is a different way to grab the same CRL ๐Ÿงš. For example, the same CRL could be fetched through both LDAP and HTTP ๐Ÿซถ.

If the distributionPoint field has a directoryName, the entry for that directoryName holds the current CRL for the associated reasons, and that CRL is issued by the associated cRLIssuer ๐Ÿ‘‘. The CRL might be stored in the certificateRevocationList or authorityRevocationList attribute ๐ŸŒˆ. The application grabs the CRL from whatever directory server is locally configured ๐Ÿ’–. Which protocol the app uses to reach the directory (like DAP or LDAP) is a local matter ๐Ÿ“.

If the DistributionPointName has a general name of type URI, the following semantics MUST be assumed: the URI points to the current CRL for the associated reasons, and it will be issued by the associated cRLIssuer ๐Ÿ”ฎ. When the HTTP or FTP URI scheme is used, the URI MUST point to a single DER encoded CRL as specified in [RFC2585]. HTTP server implementations accessed via the URI SHOULD specify the media type application/pkix-crl in the content-type header field of the response ๐Ÿ“จ. When the LDAP URI scheme [RFC4516] is used, the URI MUST include a <dn> field with the distinguished name of the entry holding the CRL, MUST include a single <attrdesc> with an appropriate attribute description for the attribute that holds the CRL [RFC4523], and SHOULD include a <host> ๐Ÿซง. Here's an example: <ldap://ldap.example.com/cn=example%20CA,dc=example,dc=com?certificateRevocationList;binary>. Leaving out the <host>, like <ldap:///cn=CA,dc=example,dc=com?authorityRevocationList;binary>, means the client relies on whatever a priori knowledge it has to contact the right server ๐Ÿงญ. When it's present, DistributionPointName SHOULD include at least one LDAP or HTTP URI ๐ŸŒท.

If the DistributionPointName is the single value nameRelativeToCRLIssuer, that value is a distinguished name fragment ๐Ÿฌ. The fragment gets appended to the X.500 distinguished name of the CRL issuer to get the distribution point name ๐Ÿ’ซ. If the cRLIssuer field in the DistributionPoint is there, the name fragment gets appended to the distinguished name it contains; otherwise, it gets appended to the certificate issuer distinguished name ๐ŸŽ€. Conforming CAs SHOULD NOT use nameRelativeToCRLIssuer to specify distribution point names ๐Ÿ™ˆ. The DistributionPointName MUST NOT use the nameRelativeToCRLIssuer alternative when cRLIssuer contains more than one distinguished name ๐Ÿšซ.

If the DistributionPoint leaves out the reasons field, the CRL MUST include revocation information for all reasons ๐Ÿ’ฏ. This profile RECOMMENDS against splitting CRLs up by reason code ๐Ÿ™…โ€โ™€๏ธ. When a conforming CA includes a cRLDistributionPoints extension in a certificate, it MUST include at least one DistributionPoint that points to a CRL covering the certificate for all reasons ๐Ÿซถ.

The cRLIssuer is the entity that signs and issues the CRL ๐Ÿ–‹๏ธ. If it's present, the cRLIssuer MUST only contain the distinguished name (DN) from the issuer field of the CRL that the DistributionPoint points to ๐Ÿ’œ. The encoding of the name in the cRLIssuer field MUST be exactly the same as the encoding in the issuer field of the CRL ๐Ÿ”. If the cRLIssuer field is included and the DN in it doesn't match an X.500 or LDAP directory entry where the CRL lives, then conforming CAs MUST include the distributionPoint field ๐Ÿซถ.

id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::=  { id-ce 31 }

CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint

DistributionPoint ::= SEQUENCE {
     distributionPoint       [0]     DistributionPointName OPTIONAL,
     reasons                 [1]     ReasonFlags OPTIONAL,
     cRLIssuer               [2]     GeneralNames OPTIONAL }

DistributionPointName ::= CHOICE {
     fullName                [0]     GeneralNames,
     nameRelativeToCRLIssuer [1]     RelativeDistinguishedName }

ReasonFlags ::= BIT STRING {
     unused                  (0),
     keyCompromise           (1),
     cACompromise            (2),
     affiliationChanged      (3),
     superseded              (4),
     cessationOfOperation    (5),
     certificateHold         (6),
     privilegeWithdrawn      (7),
     aACompromise            (8) }

4.2.1.14. Inhibit anyPolicy โณ

the inhibit anyPolicy extension can be used in certificates issued to CAs ๐Ÿง. It says the special anyPolicy OID, { 2 5 29 32 0 }, doesn't count as an explicit match for other certificate policies, unless it shows up in an intermediate self-issued CA certificate ๐Ÿ™…โ€โ™€๏ธ. The value is how many more non-self-issued certificates can show up in the path before anyPolicy is no longer allowed ๐Ÿ”ข. For example, a value of one means anyPolicy can be processed in certificates issued by the subject of this certificate, but not in any additional certificates in the path ๐ŸŒธ.

Conforming CAs MUST mark this extension as critical ๐Ÿ”ฅ.

id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::=  { id-ce 54 }

InhibitAnyPolicy ::= SkipCerts

SkipCerts ::= INTEGER (0..MAX)

4.2.1.15. Freshest CRL (a.k.a. Delta CRL Distribution Point) ๐Ÿญ

the freshest CRL extension is how you find out where to get delta CRL info ๐Ÿงญ. The extension MUST be marked as non-critical by conforming CAs ๐Ÿ’•. More CRL management is in Section 5 ๐Ÿ“–.

This extension uses the same syntax as the cRLDistributionPoints extension, described in Section 4.2.1.13 ๐Ÿชž. The same conventions apply to both extensions ๐Ÿซถ.

id-ce-freshestCRL OBJECT IDENTIFIER ::=  { id-ce 46 }

FreshestCRL ::= CRLDistributionPoints

4.2.2. Private Internet Extensions ๐ŸŒˆ

this section defines two extensions for the Internet Public Key Infrastructure ๐ŸŒ. They can point applications to online info about the issuer or the subject ๐Ÿ”. Each extension holds a sequence of access methods and access locations ๐Ÿ—‚๏ธ. The access method is an object identifier that says what kind of info is available ๐Ÿงฉ. The access location is a GeneralName that implicitly specifies where the info lives, what format it's in, and how to get it ๐Ÿช„.

Object identifiers for the private extensions are defined under the arc id-pe within the arc id-pkix ๐Ÿ’œ. Any future extensions defined for the Internet PKI are also expected to go under the arc id-pe ๐Ÿ”ฎ.

id-pkix  OBJECT IDENTIFIER  ::=
         { iso(1) identified-organization(3) dod(6) internet(1)
                 security(5) mechanisms(5) pkix(7) }

id-pe  OBJECT IDENTIFIER  ::=  { id-pkix 1 }

4.2.2.1. Authority Information Access โœจ

okay bestie, the authority information access extension is how a certificate says "hey, here's where to find the people who issued me" ๐Ÿฆ‹ It tells you how to get information and services belonging to the issuer of the certificate it lives in, like online validation services and CA policy data ๐Ÿ’… The location of CRLs is NOT in here, though (that's the cRLDistributionPoints extension's job, so don't go hunting for it here ๐Ÿ™ˆ). This extension may be included in end entity or CA certificates. Conforming CAs MUST mark this extension as non-critical. ๐Ÿ’–

id-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pe 1 }

AuthorityInfoAccessSyntax  ::=
        SEQUENCE SIZE (1..MAX) OF AccessDescription

AccessDescription  ::=  SEQUENCE {
        accessMethod          OBJECT IDENTIFIER,
        accessLocation        GeneralName  }

id-ad OBJECT IDENTIFIER ::= { id-pkix 48 }

id-ad-caIssuers OBJECT IDENTIFIER ::= { id-ad 2 }

id-ad-ocsp OBJECT IDENTIFIER ::= { id-ad 1 }

Each entry in the AuthorityInfoAccessSyntax sequence describes the format and location of extra info provided by the issuer of the certificate ๐Ÿงš The accessMethod field tells you the type and format of that info, and the accessLocation field tells you where to find it. The retrieval mechanism can be implied by the accessMethod or spelled out in accessLocation. โœจ

This profile defines two accessMethod OIDs: id-ad-caIssuers and id-ad-ocsp. ๐ŸŒธ

In a public key certificate, the id-ad-caIssuers OID gets used when the extra info lists certificates that were issued TO the CA that issued the certificate with this extension. The CA issuers description exists to help certificate users pick a certification path that ends at a point they trust. It's giving "find your way home" energy ๐Ÿ 

When id-ad-caIssuers shows up as accessMethod, the accessLocation field describes the referenced description server and the access protocol used to get that description. accessLocation is defined as a GeneralName, which can take several forms. ๐Ÿ’…

When the accessLocation is a directoryName, the application gets the info from whatever directory server is locally configured. The entry for that directoryName holds CA certificates in the crossCertificatePair and/or cACertificate attributes, as specified in [RFC4523]. Which protocol the application uses to reach the directory (like DAP or LDAP) is a local matter ๐Ÿซถ

Where the info is available via LDAP, the accessLocation SHOULD be a uniformResourceIdentifier. The LDAP URI [RFC4516] MUST include a <dn> field with the distinguished name of the entry holding the certificates. It MUST include an <attributes> field listing the right attribute descriptions for the attributes that hold the DER encoded certificates or cross-certificate pairs [RFC4523]. It SHOULD also include a <host>, like ldap://ldap.example.com/cn=CA,dc=example,dc=com?cACertificate;binary,crossCertificatePair;binary. Leaving out the <host> (like ldap:///cn=exampleCA,dc=example,dc=com?cACertificate;binary) means the client relies on whatever a priori knowledge it has to find a suitable server. Main character energy for the client, honestly ๐Ÿ‘‘

Where the info is available via HTTP or FTP, the accessLocation MUST be a uniformResourceIdentifier, and the URI MUST point to either a single DER encoded certificate as specified in [RFC2585], or a collection of certificates in a BER or DER encoded "certs-only" CMS message as specified in [RFC2797]. ๐ŸŽ€

Conforming applications that support HTTP or FTP for getting certificates MUST be able to accept individual DER encoded certificates, and they SHOULD be able to accept "certs-only" CMS messages. โœจ

HTTP server implementations accessed via the URI SHOULD specify the media type application/pkix-cert [RFC2585] in the content-type header field of the response for a single DER encoded certificate. They SHOULD specify the media type application/pkcs7-mime [RFC2797] in the content-type header field of the response for "certs-only" CMS messages. For FTP, a file holding a single DER encoded certificate SHOULD have a suffix of .cer [RFC2585], and a file holding a "certs-only" CMS message SHOULD have a suffix of .p7c [RFC2797]. Consuming clients may use the media type or file extension as a hint about the content, but they should not depend solely on the correct media type or file extension showing up in the server response. ๐Ÿฆ‹

The semantics of other id-ad-caIssuers accessLocation name forms are not defined. ๐Ÿ™ˆ

An authorityInfoAccess extension may include multiple instances of the id-ad-caIssuers accessMethod. The different instances may specify different methods for accessing the same information, or they may point to different information. When the id-ad-caIssuers accessMethod is used, at least one instance SHOULD specify an accessLocation that is an HTTP [RFC2616] or LDAP [RFC4516] URI. ๐Ÿ’œ

The id-ad-ocsp OID is used when revocation info for the certificate with this extension is available using the Online Certificate Status Protocol (OCSP) [RFC2560]. ๐Ÿ”ฅ

When id-ad-ocsp appears as accessMethod, the accessLocation field is the location of the OCSP responder, using the conventions defined in [RFC2560]. ๐ŸŒˆ

Additional access descriptors may be defined in other PKIX specifications. โญ

4.2.2.2. Subject Information Access โœจ

the subject information access extension is the mirror image of the last one ๐Ÿชž It tells you how to access info and services for the SUBJECT of the certificate it lives in. When the subject is a CA, that can include certificate validation services and CA policy data. When the subject is an end entity, the info describes the types of services offered and how to reach them. In that case, the contents of this extension are defined in the protocol specs for the supported services. This extension may be included in end entity or CA certificates. Conforming CAs MUST mark this extension as non-critical. ๐Ÿ’–

id-pe-subjectInfoAccess OBJECT IDENTIFIER ::= { id-pe 11 }

SubjectInfoAccessSyntax  ::=
        SEQUENCE SIZE (1..MAX) OF AccessDescription

AccessDescription  ::=  SEQUENCE {
        accessMethod          OBJECT IDENTIFIER,
        accessLocation        GeneralName  }

Each entry in the SubjectInfoAccessSyntax sequence describes the format and location of extra info provided by the subject of the certificate with this extension. The accessMethod field gives the type and format of the info, and the accessLocation field gives the location. The retrieval mechanism can be implied by the accessMethod or spelled out in accessLocation. ๐Ÿงš

This profile defines one access method for when the subject is a CA, and one access method for when the subject is an end entity. Additional access methods may be defined in the future in the protocol specs for other services. ๐ŸŒธ

The id-ad-caRepository OID is used when the subject is a CA that publishes the certificates it issues in a repository. The accessLocation field is defined as a GeneralName, which can take several forms. ๐Ÿ’…

When the accessLocation is a directoryName, the application gets the info from whatever directory server is locally configured. When the extension is used to point to CA certificates, the entry for the directoryName holds CA certificates in the crossCertificatePair and/or cACertificate attributes, as specified in [RFC4523]. The protocol the application uses to reach the directory (like DAP or LDAP) is a local matter. ๐Ÿซถ

Where the info is available via LDAP, the accessLocation SHOULD be a uniformResourceIdentifier. The LDAP URI [RFC4516] MUST include a <dn> field with the distinguished name of the entry holding the certificates. It MUST include an <attributes> field listing the right attribute descriptions for the attributes that hold the DER encoded certificates or cross-certificate pairs [RFC4523]. It SHOULD also include a <host>, like ldap://ldap.example.com/cn=CA,dc=example,dc=com?cACertificate;binary,crossCertificatePair;binary.

Leaving out the <host> (like ldap:///cn=exampleCA,dc=example,dc=com?cACertificate;binary) means the client relies on whatever a priori knowledge it has to find an appropriate server. ๐Ÿ‘‘

Where the info is available via HTTP or FTP, the accessLocation MUST be a uniformResourceIdentifier, and the URI MUST point to either a single DER encoded certificate as specified in [RFC2585], or a collection of certificates in a BER or DER encoded "certs-only" CMS message as specified in [RFC2797]. ๐ŸŽ€

Conforming applications that support HTTP or FTP for getting certificates MUST be able to accept individual DER encoded certificates, and they SHOULD be able to accept "certs-only" CMS messages. โœจ

HTTP server implementations accessed via the URI SHOULD specify the media type application/pkix-cert [RFC2585] in the content-type header field of the response for a single DER encoded certificate. They SHOULD specify the media type application/pkcs7-mime [RFC2797] in the content-type header field of the response for "certs-only" CMS messages. For FTP, a file holding a single DER encoded certificate SHOULD have a suffix of .cer [RFC2585], and a file holding a "certs-only" CMS message SHOULD have a suffix of .p7c [RFC2797]. Consuming clients may use the media type or file extension as a hint about the content, but they should not depend solely on the correct media type or file extension showing up in the server response. ๐Ÿฆ‹

The semantics of other id-ad-caRepository accessLocation name forms are not defined. ๐Ÿ™ˆ

A subjectInfoAccess extension may include multiple instances of the id-ad-caRepository accessMethod. The different instances may specify different methods for accessing the same information, or they may point to different information. When the id-ad-caRepository accessMethod is used, at least one instance SHOULD specify an accessLocation that is an HTTP [RFC2616] or LDAP [RFC4516] URI. ๐Ÿ’œ

The id-ad-timeStamping OID is used when the subject offers timestamping services using the Time Stamp Protocol defined in [RFC3161]. Where those timestamping services are available via HTTP or FTP, the accessLocation MUST be a uniformResourceIdentifier. Where they are available via electronic mail, the accessLocation MUST be an rfc822Name. Where timestamping services are available using TCP/IP, the dNSName or iPAddress name forms may be used. The semantics of other name forms of accessLocation (when accessMethod is id-ad-timeStamping) are not defined by this specification. โฐ

Additional access descriptors may be defined in other PKIX specifications. ๐ŸŒˆ

id-ad OBJECT IDENTIFIER ::= { id-pkix 48 }

id-ad-caRepository OBJECT IDENTIFIER ::= { id-ad 5 }

id-ad-timeStamping OBJECT IDENTIFIER ::= { id-ad 3 }

5. CRL and CRL Extensions Profile ๐Ÿ“œ๐Ÿ’–

Okay bestie, so the whole point of this X.509 v2 CRL profile is to make an interoperable and reusable Internet PKI, and that's giving main character energy ๐Ÿ‘‘. To get there, it lays down guidelines for using extensions and makes some assumptions about what info goes inside a CRL ๐ŸŽ€.

CRLs can show up in a huge range of apps and environments with all kinds of interoperability goals and even more operational and assurance needs ๐ŸŒˆ. This profile sets a common baseline for generic apps that need broad interoperability โœจ. It defines a set of info you can expect in every CRL, plus common spots inside the CRL for the attributes people use most, and common ways to represent those attributes ๐Ÿงš.

CRL issuers are the ones who issue CRLs ๐Ÿ’…. The CRL issuer is either the CA or an entity the CA has authorized to issue CRLs. CAs publish CRLs to share status info about the certificates they issued, but a CA can hand that job off to another trusted authority ๐Ÿซถ.

Every CRL has a particular scope, which is the set of certificates that could show up on it ๐Ÿฆ‹. For example, the scope could be "all certificates issued by CA X", "all CA certificates issued by CA X", "all certificates issued by CA X that have been revoked for reasons of key compromise and CA compromise", or a set of certificates based on arbitrary local info, such as "all certificates issued to the NIST employees located in Boulder" ๐Ÿ”ฅ.

A complete CRL lists all unexpired certificates within its scope that have been revoked for one of the revocation reasons covered by the CRL scope ๐Ÿ’œ. A full and complete CRL lists all unexpired certificates issued by a CA that have been revoked for any reason ๐Ÿ˜ญ. (Note that since CAs and CRL issuers are identified by name, the scope of a CRL is not affected by the key used to sign the CRL or the key(s) used to sign certificates. Iykyk ๐Ÿ™ˆ.)

If the scope of the CRL includes one or more certificates issued by an entity other than the CRL issuer, then it's an indirect CRL ๐Ÿ“. The scope of an indirect CRL may be limited to certificates issued by a single CA, or it may include certificates issued by multiple CAs ๐ŸŒธ. If the issuer of the indirect CRL is a CA, then the scope of the indirect CRL MAY also include certificates issued by the issuer of the CRL โœจ.

The CRL issuer MAY also generate delta CRLs ๐Ÿฆ‹. A delta CRL only lists those certificates within its scope whose revocation status has changed since a referenced complete CRL was issued. That referenced complete CRL is called a base CRL ๐ŸŽ€. The scope of a delta CRL MUST be the same as the base CRL that it references ๐Ÿ’….

This profile defines one private Internet CRL extension, but it does not define any private CRL entry extensions ๐ŸŒˆ.

Environments with additional or special purpose requirements may build on this profile or replace it entirely ๐Ÿงš.

Conforming CAs are not required to issue CRLs if other revocation or certificate status mechanisms are provided ๐Ÿซถ. When CRLs are issued, the CRLs MUST be version 2 CRLs, include the date by which the next CRL will be issued in the nextUpdate field (Section 5.1.2.5), include the CRL number extension (Section 5.2.3), and include the authority key identifier extension (Section 5.2.1) ๐Ÿ‘‘. Conforming applications that support CRLs are REQUIRED to process both version 1 and version 2 complete CRLs that provide revocation info for all certificates issued by one CA โœจ. Conforming applications are not required to support processing delta CRLs, indirect CRLs, or CRLs with a scope other than all certificates issued by one CA ๐ŸŒธ.

5.1. CRL Fields ๐Ÿ“

The X.509 v2 CRL syntax looks like this ๐Ÿ’–. For signature calculation, the data that's going to be signed is ASN.1 DER encoded. ASN.1 DER encoding is a tag, length, value encoding system for each element ๐Ÿ”ฅ.

CertificateList  ::=  SEQUENCE  {
     tbsCertList          TBSCertList,
     signatureAlgorithm   AlgorithmIdentifier,
     signatureValue       BIT STRING  }

TBSCertList  ::=  SEQUENCE  {
     version                 Version OPTIONAL,
                                  -- if present, MUST be v2
     signature               AlgorithmIdentifier,
     issuer                  Name,
     thisUpdate              Time,
     nextUpdate              Time OPTIONAL,
     revokedCertificates     SEQUENCE OF SEQUENCE  {
          userCertificate         CertificateSerialNumber,
          revocationDate          Time,
          crlEntryExtensions      Extensions OPTIONAL
                                   -- if present, version MUST be v2
                               }  OPTIONAL,
     crlExtensions           [0]  EXPLICIT Extensions OPTIONAL
                                   -- if present, version MUST be v2
                               }

-- Version, Time, CertificateSerialNumber, and Extensions
-- are all defined in the ASN.1 in Section 4.1

-- AlgorithmIdentifier is defined in Section 4.1.1.2

The following items describe how the X.509 v2 CRL gets used in the Internet PKI ๐Ÿฆ‹.

5.1.1. CertificateList Fields ๐ŸŽ€

The CertificateList is a SEQUENCE of three required fields ๐Ÿ’…. Each one gets a closer look in the subsections below ๐ŸŒˆ.

5.1.1.1. tbsCertList ๐Ÿงš

The first field in the sequence is the tbsCertList ๐Ÿซถ. It's its own sequence that holds the issuer's name, the issue date, the issue date of the next list, the optional list of revoked certificates, and optional CRL extensions ๐Ÿ‘‘. When there are no revoked certificates, the revoked certificates list is absent โœจ. When one or more certificates are revoked, each entry on that list is a sequence of user certificate serial number, revocation date, and optional CRL entry extensions ๐ŸŒธ.

5.1.1.2. signatureAlgorithm ๐Ÿ“

The signatureAlgorithm field holds the algorithm identifier for the algorithm the CRL issuer used to sign the CertificateList ๐Ÿ’–. It's of type AlgorithmIdentifier, which is defined in Section 4.1.1.2 ๐Ÿ”ฅ. [RFC3279], [RFC4055], and [RFC4491] list supported algorithms for this spec, but other signature algorithms MAY also be supported ๐Ÿฆ‹.

This field MUST contain the same algorithm identifier as the signature field in the sequence tbsCertList (Section 5.1.2.2) ๐Ÿ’….

5.1.1.3. signatureValue ๐Ÿ’œ

The signatureValue field holds a digital signature that's computed over the ASN.1 DER encoded tbsCertList ๐Ÿ˜ญ. That ASN.1 DER encoded tbsCertList is the input to the signature function ๐Ÿ™ˆ. The signature value is encoded as a BIT STRING and goes into the CRL signatureValue field ๐ŸŽ€. The details of this process are specified for each supported algorithm in [RFC3279], [RFC4055], and [RFC4491] โœจ.

CAs that are also CRL issuers MAY use one private key to digitally sign certificates and CRLs, or they MAY use separate private keys to digitally sign certificates and CRLs ๐ŸŒˆ. When separate private keys are used, each of the public keys tied to those private keys goes into a separate certificate: one with the keyCertSign bit set in the key usage extension, and one with the cRLSign bit set in the key usage extension (Section 4.2.1.3) ๐Ÿ‘‘. When separate private keys are used, certificates issued by the CA contain one authority key identifier, and the matching CRLs contain a different authority key identifier ๐Ÿงš. Using separate CA certificates for validating certificate signatures and CRL signatures can offer improved security characteristics ๐Ÿ”ฅ. However, it adds a burden on applications, and it might limit interoperability ๐Ÿ˜ญ.

Many applications build a certification path and then validate that path (Section 6) ๐ŸŒธ. CRL checking, in turn, requires a separate certification path to be built and validated for the CA's CRL signature validation certificate ๐Ÿ“.

Applications that perform CRL checking MUST support certification path validation when certificates and CRLs are digitally signed with the same CA private key ๐Ÿ’–. These applications SHOULD support certification path validation when certificates and CRLs are digitally signed with different CA private keys ๐Ÿซถ.

5.1.2. Certificate List "To Be Signed" ๐Ÿฆ‹

The certificate list to be signed, or TBSCertList, is a sequence of required and optional fields ๐Ÿ’…. The required fields identify the CRL issuer, the algorithm used to sign the CRL, and the date and time the CRL was issued ๐ŸŒˆ.

The optional fields include the date and time by which the CRL issuer will issue the next CRL, lists of revoked certificates, and CRL extensions ๐ŸŽ€. The revoked certificate list is optional to support the case where a CA hasn't revoked any unexpired certificates it has issued ๐Ÿงš. This profile requires conforming CRL issuers to include the nextUpdate field and the CRL number and authority key identifier CRL extensions in all CRLs they issue ๐Ÿ‘‘.

5.1.2.1. Version โœจ

This optional field describes the version of the encoded CRL ๐ŸŒธ. When extensions are used, as this profile requires, this field MUST be present and MUST specify version 2 (the integer value is 1) ๐Ÿ’–.

5.1.2.2. Signature ๐Ÿ“

This field holds the algorithm identifier for the algorithm used to sign the CRL ๐Ÿ”ฅ. [RFC3279], [RFC4055], and [RFC4491] list OIDs for the most popular signature algorithms used in the Internet PKI ๐Ÿฆ‹.

This field MUST contain the same algorithm identifier as the signatureAlgorithm field in the sequence CertificateList (Section 5.1.1.2) ๐Ÿ’….

5.1.2.3. Issuer Name ๐ŸŽ€

The issuer name identifies the entity that signed and issued the CRL ๐Ÿ˜ญ. The issuer identity is carried in the issuer field ๐Ÿ™ˆ. Alternative name forms may also appear in the issuerAltName extension (Section 5.2.2) โœจ. The issuer field MUST contain a non-empty X.500 distinguished name (DN) ๐ŸŒˆ. The issuer field is defined as the X.501 type Name, and it MUST follow the encoding rules for the issuer name field in the certificate (Section 4.1.2.4) ๐Ÿ‘‘.

5.1.2.4. This Update ๐Ÿ’œ

This field indicates the issue date of this CRL ๐Ÿงš. thisUpdate may be encoded as UTCTime or GeneralizedTime ๐Ÿซถ.

CRL issuers conforming to this profile MUST encode thisUpdate as UTCTime for dates through the year 2049 ๐Ÿ”ฅ. CRL issuers conforming to this profile MUST encode thisUpdate as GeneralizedTime for dates in the year 2050 or later ๐ŸŒธ. Conforming applications MUST be able to process dates encoded in either UTCTime or GeneralizedTime ๐Ÿ’–.

Where encoded as UTCTime, thisUpdate MUST be specified and interpreted as defined in Section 4.1.2.5.1 ๐Ÿ“. Where encoded as GeneralizedTime, thisUpdate MUST be specified and interpreted as defined in Section 4.1.2.5.2 ๐Ÿฆ‹.

5.1.2.5. Next Update โฐ

okay so this field tells you the date the next CRL is due ๐Ÿ—“๏ธ The next CRL could drop before that date, but it will NOT show up any later than that date, no exceptions ๐Ÿ’€ CRL issuers SHOULD issue CRLs with a nextUpdate time equal to or later than all previous CRLs, so the timeline only moves forward ๐Ÿซถ nextUpdate can be encoded as UTCTime or GeneralizedTime, so you've got options ๐ŸŽ€

Conforming CRL issuers MUST include the nextUpdate field in all CRLs ๐Ÿ’… Here's the tea: the ASN.1 syntax of TBSCertList calls this field OPTIONAL, and that matches the ASN.1 structure in [X.509] ๐Ÿค“ But how clients handle CRLs that leave out nextUpdate is not specified by this profile, so that's a whole mystery ๐Ÿ™ˆ

CRL issuers conforming to this profile MUST encode nextUpdate as UTCTime for dates through the year 2049 ๐Ÿ•ฐ๏ธ and MUST encode it as GeneralizedTime for dates in the year 2050 or later โœจ Conforming applications MUST be able to process dates encoded in either UTCTime or GeneralizedTime, so everyone can read both formats, periodt ๐Ÿ’–

When it's UTCTime, nextUpdate MUST be specified and interpreted as defined in Section 4.1.2.5.1. When it's GeneralizedTime, nextUpdate MUST be specified and interpreted as defined in Section 4.1.2.5.2. Know your formats, bestie ๐Ÿงš

5.1.2.6. Revoked Certificates ๐Ÿšซ

When there are no revoked certificates, the revoked certificates list MUST be absent ๐Ÿซฅ Otherwise, revoked certificates get listed by their serial numbers, since each certificate revoked by the CA is uniquely identified by its certificate serial number ๐Ÿ”ข The date the revocation happened is specified too ๐Ÿ“… The time for revocationDate MUST be expressed as described in Section 5.1.2.4, same vibes as the rest of the CRL timestamps ๐Ÿฆ‹ Extra info can ride along in CRL entry extensions, which get covered in Section 5.3 ๐ŸŒธ

5.1.2.7. Extensions ๐Ÿงฉ

This field may only appear if the version is 2 (Section 5.1.2.1) ๐Ÿ’œ If it's there, it's a sequence of one or more CRL extensions. CRL extensions are discussed in Section 5.2 โœจ


5.2. CRL Extensions ๐ŸŽ€

Okay, the extensions defined by ANSI X9, ISO/IEC, and ITU-T for X.509 v2 CRLs [X.509] [X9.55] are how you attach extra attributes to CRLs ๐ŸŒˆ The X.509 v2 CRL format also lets communities make their own private extensions for info that only they care about ๐Ÿงš Every extension in a CRL can be marked as critical or non-critical ๐Ÿ”ฅ

Here's the big rule: if a CRL has a critical extension the application can't process, the application MUST NOT use that CRL to determine the status of certificates ๐Ÿ›‘ Applications MAY ignore unrecognized non-critical extensions, though ๐Ÿซถ The subsections below cover the extensions used within Internet CRLs ๐Ÿ’… Communities can include extensions that aren't defined in this specification if they want, but caution should be exercised before adopting any critical extensions in CRLs that might be used in a general context โš ๏ธ

Conforming CRL issuers are REQUIRED to include the authority key identifier (Section 5.2.1) and the CRL number (Section 5.2.3) extensions in all CRLs they issue ๐Ÿ‘‘

5.2.1. Authority Key Identifier ๐Ÿ”‘

The authority key identifier extension is how you figure out which public key goes with the private key that signed a CRL ๐Ÿ•ต๏ธโ€โ™€๏ธ You can identify it by the key identifier (the subject key identifier in the CRL signer's certificate) or by the issuer name and serial number ๐Ÿชช This extension is super useful when an issuer has more than one signing key, whether from multiple concurrent key pairs or a changeover ๐Ÿ”„

Conforming CRL issuers MUST use the key identifier method, and MUST include this extension in all CRLs issued ๐Ÿ™Œ

The syntax for this CRL extension is defined in Section 4.2.1.1 ๐Ÿ“œ

5.2.2. Issuer Alternative Name ๐ŸŒ

The issuer alternative name extension lets you attach additional identities to the CRL issuer ๐Ÿ’– Defined options include an electronic mail address (rfc822Name), a DNS name, an IP address, and a URI ๐Ÿ“ฌ You can include multiple instances of one name form, or multiple name forms โœจ Whenever those identities are used, the issuer alternative name extension MUST be used ๐Ÿ’… A DNS name MAY be represented in the issuer field using the domainComponent attribute, as described in Section 4.1.2.4, so that's an option too ๐Ÿ“

Conforming CRL issuers SHOULD mark the issuerAltName extension as non-critical ๐Ÿซง

The OID and syntax for this CRL extension are defined in Section 4.2.1.7 ๐Ÿงพ

5.2.3. CRL Number ๐Ÿ”ข

The CRL number is a non-critical CRL extension that carries a monotonically increasing sequence number for a given CRL scope and CRL issuer ๐Ÿ“ˆ It's how users easily tell when one CRL supersedes another ๐Ÿ‘€ CRL numbers also help you spot complementary complete CRLs and delta CRLs ๐Ÿฆ‹ CRL issuers conforming to this profile MUST include this extension in all CRLs and MUST mark it as non-critical ๐Ÿ’œ

If a CRL issuer generates delta CRLs alongside complete CRLs for a given scope, the complete CRLs and delta CRLs MUST share one numbering sequence ๐Ÿงต If a delta CRL and a complete CRL covering the same scope get issued at the same time, they MUST have the same CRL number and provide the same revocation information โœจ So the delta CRL plus an acceptable complete CRL MUST provide the same revocation info as the complete CRL issued at that moment ๐Ÿ’…

If a CRL issuer generates two CRLs for the same scope at different times (two complete CRLs, two delta CRLs, or a complete CRL and a delta CRL), the two CRLs MUST NOT have the same CRL number ๐Ÿšซ In other words, if the this update field (Section 5.1.2.4) in the two CRLs are not identical, the CRL numbers MUST be different ๐Ÿ™ƒ

With all that in mind, CRL numbers can be expected to get pretty long integers ๐Ÿงฎ CRL verifiers MUST be able to handle CRLNumber values up to 20 octets ๐Ÿ’ช Conforming CRL issuers MUST NOT use CRLNumber values longer than 20 octets ๐Ÿ›‘

id-ce-cRLNumber OBJECT IDENTIFIER ::= { id-ce 20 }

CRLNumber ::= INTEGER (0..MAX)

5.2.4. Delta CRL Indicator ๐Ÿฆ‹

okay so the delta CRL indicator is a critical CRL extension that tells you a CRL is a delta CRL ๐Ÿ’… Delta CRLs only carry updates to revocation info that was already handed out, instead of everything a complete CRL would have. that's a huge glow-up for network load and processing time in some setups ๐ŸŒธ They're usually way smaller than the CRLs they update, so apps grabbing deltas use less bandwidth than apps grabbing full CRLs. And if an app keeps revocation info in something that isn't a CRL structure, it can toss new info into its local database without reprocessing everything ๐Ÿซถ

The delta CRL indicator extension holds one single value, and it's of type BaseCRLNumber ๐Ÿงš The CRL number points to the complete CRL (for a given scope) that the delta was built on top of. A conforming CRL issuer MUST publish that referenced base CRL as a complete CRL ๐Ÿ’– The delta then has every update to revocation status for that same scope. Delta plus base equals a complete CRL for that scope, as of when the delta got published. it's giving puzzle pieces, bestie ๐Ÿงฉ

When a conforming CRL issuer makes a delta CRL, that delta MUST include a critical delta CRL indicator extension ๐Ÿ”ฅ

A delta CRL MUST cover the same set of reasons and the same set of certificates as the base CRL it references ๐Ÿ’œ Basically, the delta's scope MUST match the scope of the complete base CRL, no cap. The referenced base CRL and the delta MUST either leave out the issuing distribution point extension or have identical issuing distribution point extensions ๐ŸŽ€ And the CRL issuer MUST sign the delta and any complete CRL it can update with the same private key ๐Ÿ”‘

An app that supports delta CRLs can build a CRL that's complete for a given scope by mixing a delta for that scope with either an issued complete CRL for that scope or a locally constructed complete CRL for that scope โœจ

When you combine a delta CRL with a complete CRL or a locally constructed CRL, the result gets the CRL number from the CRL number extension on the delta ๐ŸŒˆ It also gets the thisUpdate and nextUpdate times from the matching fields on the delta. On top of that, the locally constructed CRL inherits the issuing distribution point from the delta ๐Ÿ’…

A complete CRL and a delta CRL MAY be combined if all four of these conditions are met ๐Ÿฆ‹

  • (a) The complete CRL and delta CRL have the same issuer. ๐Ÿ’โ€โ™€๏ธ
  • (b) The complete CRL and delta CRL have the same scope. The two CRLs count as having the same scope if either of these is true:
    • (1) The issuingDistributionPoint extension is left out of both the complete CRL and the delta CRL.
    • (2) The issuingDistributionPoint extension is in both the complete CRL and the delta CRL, and every field in the extension has the same value in both CRLs. ๐Ÿซถ
  • (c) The CRL number of the complete CRL is equal to or greater than the BaseCRLNumber in the delta CRL. Translation: the complete CRL has at least everything the base CRL had ๐Ÿ“š
  • (d) The CRL number of the complete CRL is less than the CRL number of the delta CRL. So the delta comes after the complete CRL in the numbering sequence ๐Ÿ”ข

CRL issuers MUST make sure that a delta CRL plus any appropriate complete CRL accurately shows the current revocation status ๐Ÿ˜ญ The CRL issuer MUST also include an entry in the delta CRL for every certificate in the delta's scope whose status changed since the referenced base CRL was made:

  • (a) If the certificate is revoked for a reason that's in the scope of the CRL, list it as revoked. ๐Ÿ’€
  • (b) If the certificate is valid, was on the referenced base CRL or a later CRL with reason code certificateHold, and certificateHold is in the scope of the CRL, list it with the reason code removeFromCRL. ๐Ÿ™ˆ
  • (c) If the certificate is revoked for a reason outside the scope of the CRL, but it was on the referenced base CRL or a later CRL with a reason code that IS in this CRL's scope, list it as revoked but leave out the reason code. ๐Ÿ“
  • (d) If the certificate is revoked for a reason outside the scope of the CRL, and it wasn't on the referenced base CRL or any later CRL with a reason code in this CRL's scope, don't list it on this CRL. ๐Ÿšซ

A certificate's status counts as changed if it's revoked (for any reason, certificateHold included), if it's released from hold, or if its revocation reason changes ๐Ÿฆ‹

It's totally fine to list a certificate with reason code removeFromCRL on a delta CRL even if it wasn't on hold in the referenced base CRL ๐Ÿ’œ But if a certificate got put on hold in any CRL issued after the base and before this delta, and then got released, it MUST be listed on the delta CRL with revocation reason removeFromCRL. No exceptions, iykyk ๐Ÿ˜ค

A CRL issuer MAY optionally list a certificate on a delta CRL with reason code removeFromCRL if the notAfter time in the certificate is earlier than the thisUpdate time in the delta CRL, and the certificate was listed on the referenced base CRL or on any CRL issued after the base but before this delta ๐ŸŒธ

If a certificate revocation notice shows up on a delta CRL for the first time, the certificate's validity period could end before the next complete CRL for that scope comes out ๐Ÿฅบ When that happens, the revocation notice MUST stay in every later delta CRL until it's been included on at least one explicitly issued complete CRL for that scope. main character rules, periodt ๐Ÿ‘‘

An app that supports delta CRLs MUST be able to build a current complete CRL by combining a previously issued complete CRL with the newest delta CRL ๐Ÿ”ฅ An app that supports delta CRLs MAY also be able to build a current complete CRL by combining a previously locally constructed complete CRL with the current delta CRL ๐ŸŒˆ A delta CRL counts as the current one when the current time falls between its thisUpdate and nextUpdate fields ๐Ÿ•ฐ๏ธ Sometimes the CRL issuer publishes one or more deltas before the nextUpdate time, so if you run into more than one current delta CRL for a scope, the app SHOULD treat the one with the latest thisUpdate value as the most current one โœจ

id-ce-deltaCRLIndicator OBJECT IDENTIFIER ::= { id-ce 27 }

BaseCRLNumber ::= CRLNumber

5.2.5. Issuing Distribution Point ๐ŸŽ€

okay bestie, this one is a whole vibe โœจ The issuing distribution point is a critical CRL extension that tells you which CRL distribution point and scope a particular CRL belongs to. It also says whether the CRL covers end entity certificates only, CA certificates only, attribute certificates only, or just a limited set of reason codes ๐Ÿ’… It's critical, but conforming implementations aren't required to support it ๐Ÿ™ˆ Still, if your implementation doesn't support it, it MUST either treat the status of any certificate not listed on this CRL as unknown, or go find another CRL that doesn't contain any unrecognized critical extensions ๐Ÿซถ

The CRL is signed with the CRL issuer's private key. CRL distribution points don't get their own key pairs, so no, they're not doing it solo ๐Ÿ”‘ If the CRL is stored in the X.500 directory, it lives in the directory entry for the CRL distribution point, which can be different from the directory entry of the CRL issuer ๐Ÿ—‚๏ธ

Now the reason codes. The reason codes tied to a distribution point MUST be specified in onlySomeReasons. If onlySomeReasons doesn't show up, the distribution point MUST contain revocations for all reason codes ๐Ÿ’€ CAs can use CRL distribution points to split up the CRL by compromise vs. routine revocation. In that setup, the revocations with reason code keyCompromise (1), cACompromise (2), and aACompromise (8) go in one distribution point, and everything with other reason codes goes in another one ๐ŸŒˆ

If a CRL has an issuingDistributionPoint extension with onlySomeReasons present, then every certificate in the scope of the CRL that's revoked MUST be assigned a revocation reason other than unspecified. The assigned reason decides which CRL(s) the revoked certificate gets listed on. Also, there's no requirement to include the reasonCode CRL entry extension in the matching CRL entry, so don't panic if it's missing โœจ

The syntax and semantics for the distributionPoint field are the same as for the distributionPoint field in the cRLDistributionPoints extension (Section 4.2.1.13). If distributionPoint is present, it MUST include at least one of the names from the corresponding distributionPoint field of the cRLDistributionPoints extension of every certificate that's within the scope of this CRL. The identical encoding MUST be used in the distributionPoint fields of the certificate and the CRL. Matching energy, obsessed ๐Ÿ˜ญ

If distributionPoint is absent, the CRL MUST contain entries for all revoked unexpired certificates issued by the CRL issuer, if any, within the scope of the CRL ๐Ÿ“

If the scope of the CRL only includes certificates issued by the CRL issuer, then the indirectCRL boolean MUST be set to FALSE. Otherwise, if the scope includes certificates issued by one or more authorities other than the CRL issuer, the indirectCRL boolean MUST be set to TRUE. The authority responsible for each entry is shown by the certificate issuer CRL entry extension (Section 5.3.3) ๐Ÿฆ‹

If the scope of the CRL only includes end entity public key certificates, then onlyContainsUserCerts MUST be set to TRUE. If the scope only includes CA certificates, then onlyContainsCACerts MUST be set to TRUE. If either onlyContainsUserCerts or onlyContainsCACerts is set to TRUE, then the scope of the CRL MUST NOT include any version 1 or version 2 certificates. Conforming CRL issuers MUST set the onlyContainsAttributeCerts boolean to FALSE ๐Ÿงš

Last rule, and it's a big one: conforming CRL issuers MUST NOT issue CRLs where the DER encoding of the issuing distribution point extension is an empty sequence. So if onlyContainsUserCerts, onlyContainsCACerts, indirectCRL, and onlyContainsAttributeCerts are all FALSE, then either the distributionPoint field or the onlySomeReasons field MUST be present ๐Ÿšซ

id-ce-issuingDistributionPoint OBJECT IDENTIFIER ::= { id-ce 28 }

IssuingDistributionPoint ::= SEQUENCE {
     distributionPoint          [0] DistributionPointName OPTIONAL,
     onlyContainsUserCerts      [1] BOOLEAN DEFAULT FALSE,
     onlyContainsCACerts        [2] BOOLEAN DEFAULT FALSE,
     onlySomeReasons            [3] ReasonFlags OPTIONAL,
     indirectCRL                [4] BOOLEAN DEFAULT FALSE,
     onlyContainsAttributeCerts [5] BOOLEAN DEFAULT FALSE }

     -- at most one of onlyContainsUserCerts, onlyContainsCACerts,
     -- and onlyContainsAttributeCerts may be set to TRUE.

5.2.6. Freshest CRL (a.k.a. Delta CRL Distribution Point) ๐ŸŒธ

The freshest CRL extension tells you how to get the delta CRL information for this complete CRL ๐Ÿง  Conforming CRL issuers MUST mark this extension as non-critical. This extension MUST NOT appear in delta CRLs. Not allowed, bestie ๐Ÿ™…โ€โ™€๏ธ

It uses the same syntax as the cRLDistributionPoints certificate extension, described in Section 4.2.1.13. The only thing that matters here is the distribution point field, though. The reasons and cRLIssuer fields MUST be omitted from this CRL extension ๐Ÿซ 

Each distribution point name gives the location where a delta CRL for this complete CRL can be found. The scope of these delta CRLs MUST be the same as the scope of this complete CRL. The contents of this CRL extension are only used to find delta CRLs. They aren't used to validate the CRL or the referenced delta CRLs, so don't get confused ๐Ÿ’… The encoding conventions defined for distribution points in Section 4.2.1.13 apply to this extension too ๐ŸŽ€

id-ce-freshestCRL OBJECT IDENTIFIER ::=  { id-ce 46 }

FreshestCRL ::= CRLDistributionPoints

5.2.7. Authority Information Access โœจ

This section explains how the Authority Information Access extension gets used in a CRL. The syntax and semantics defined in Section 4.2.2.1 for the certificate extension also apply to the CRL extension ๐Ÿฆ‹

This CRL extension MUST be marked as non-critical ๐Ÿ™…โ€โ™€๏ธ

When it's present in a CRL, this extension MUST include at least one AccessDescription that specifies id-ad-caIssuers as the accessMethod. The id-ad-caIssuers OID is used when the info available lists certificates that can verify the signature on the CRL. Those are certificates whose subject name matches the issuer name on the CRL and whose subject public key matches the private key used to sign the CRL ๐Ÿ” Access method types other than id-ad-caIssuers MUST NOT be included. At least one AccessDescription SHOULD specify an accessLocation that's an HTTP [RFC2616] or LDAP [RFC4516] URI ๐ŸŒˆ

If the info is available over HTTP or FTP, accessLocation MUST be a uniformResourceIdentifier, and the URI MUST point to either a single DER encoded certificate as specified in [RFC2585], or a collection of certificates in a BER or DER encoded "certs-only" CMS message as specified in [RFC2797] ๐Ÿ“

Conforming applications that support HTTP or FTP for getting certificates MUST be able to accept individual DER encoded certificates, and SHOULD be able to accept "certs-only" CMS messages ๐Ÿซถ

HTTP server implementations accessed via the URI SHOULD specify the media type application/pkix-cert [RFC2585] in the content-type header field of the response for a single DER encoded certificate. They SHOULD specify the media type application/pkcs7-mime [RFC2797] in the content-type header field of the response for "certs-only" CMS messages. For FTP, a file that contains a single DER encoded certificate SHOULD have a suffix of ".cer" [RFC2585], and a file that contains a "certs-only" CMS message SHOULD have a suffix of ".p7c" [RFC2797]. Consuming clients may use the media type or file extension as a hint to the content, but they should not depend solely on the correct media type or file extension being in the server response ๐Ÿ‘€

When the accessLocation is a directoryName, the application gets the info from whatever directory server is locally configured. When one CA public key is used to validate signatures on certificates and CRLs, the desired CA certificate is stored in the crossCertificatePair and/or cACertificate attributes, as specified in [RFC4523]. When different public keys are used to validate signatures on certificates and CRLs, the desired certificate is stored in the userCertificate attribute, as specified in [RFC4523]. So implementations that support the directoryName form of accessLocation MUST be prepared to find the needed certificate in any of these three attributes ๐Ÿ—‚๏ธ Which protocol the application uses to access the directory (e.g., DAP or LDAP) is a local matter ๐Ÿ’œ

When the info is available via LDAP, the accessLocation SHOULD be a uniformResourceIdentifier. The LDAP URI [RFC4516] MUST include a <dn> field with the distinguished name of the entry holding the certificates. It MUST include an <attributes> field that lists appropriate attribute descriptions for the attributes holding the DER encoded certificates or cross-certificate pairs [RFC4523]. It SHOULD include a <host>, for example <ldap://ldap.example.com/cn=CA,dc=example,dc=com?cACertificate;binary,crossCertificatePair;binary> ๐ŸŒธ

Leaving out the <host>, like <ldap:///cn=exampleCA,dc=example,dc=com?cACertificate;binary>, means the client relies on whatever a priori knowledge it has to contact an appropriate server ๐Ÿงš


5.3. CRL Entry Extensions ๐Ÿ’–

The CRL entry extensions defined by ISO/IEC, ITU-T, and ANSI X9 for X.509 v2 CRLs let you attach extra info to CRL entries [X.509] [X9.55]. The X.509 v2 CRL format also lets communities define private CRL entry extensions for their own special info ๐Ÿฆ‹ Each extension in a CRL entry can be marked as critical or non-critical. If a CRL has a critical CRL entry extension the application can't process, then the application MUST NOT use that CRL to determine the status of any certificates. But applications may ignore unrecognized non-critical CRL entry extensions ๐Ÿ™ˆ

The following subsections present recommended extensions used within Internet CRL entries, plus standard places to put info. Communities may use additional CRL entry extensions, but caution should be exercised before adopting any critical CRL entry extensions in CRLs that might be used in a general context โš ๏ธ

Support for the CRL entry extensions defined in this specification is optional for conforming CRL issuers and applications. However, CRL issuers SHOULD include reason codes (Section 5.3.1) and invalidity dates (Section 5.3.2) whenever this info is available ๐Ÿ‘‘

5.3.1. Reason Code

okay so the reasonCode is a non-critical CRL entry extension that tells you why a certificate got revoked ๐Ÿฅ€โœจ. CRL issuers are strongly encouraged to add meaningful reason codes to their entries, but if you don't have a real reason, the extension SHOULD be absent rather than using unspecified (0). ๐Ÿ™…โ€โ™€๏ธ don't just put "unspecified" and call it a day bestie ๐Ÿ’…

the removeFromCRL (8) value may only show up in delta CRLs ๐Ÿฆ‹. It means a certificate is being taken off a CRL because it either expired or got released from hold. Every other reason code can appear in any CRL and tells you the certificate should be treated as revoked ๐Ÿšซ.

id-ce-cRLReasons OBJECT IDENTIFIER ::= { id-ce 21 }

-- reasonCode ::= { CRLReason }

CRLReason ::= ENUMERATED {
     unspecified             (0),
     keyCompromise           (1),
     cACompromise            (2),
     affiliationChanged      (3),
     superseded              (4),
     cessationOfOperation    (5),
     certificateHold         (6),
          -- value 7 is not used
     removeFromCRL           (8),
     privilegeWithdrawn      (9),
     aACompromise           (10) }

5.3.2. Invalidity Date

the invalidity date is a non-critical CRL entry extension that says when the private key was (or is suspected to have been) compromised, or when the certificate otherwise stopped being valid ๐Ÿ’”. This date can be earlier than the revocation date in the entry, and that revocation date is when the CA actually processed the revocation ๐Ÿ•ฐ๏ธ. When a CRL issuer first posts a revocation, the invalidity date can come before the issue date of earlier CRLs, but the revocation date SHOULD NOT come before the issue date of earlier CRLs ๐Ÿ™ˆ. And whenever this info is available, CRL issuers are strongly encouraged to share it with CRL users ๐Ÿซถ.

the GeneralizedTime values in this field MUST be in Greenwich Mean Time (Zulu) ๐ŸŒ, and they MUST be specified and interpreted the way Section 4.1.2.5.2 says ๐ŸŽ€.

id-ce-invalidityDate OBJECT IDENTIFIER ::= { id-ce 24 }

InvalidityDate ::=  GeneralizedTime

5.3.3. Certificate Issuer

this CRL entry extension names the certificate issuer for an entry in an indirect CRL ๐Ÿงš. An indirect CRL is one that has the indirectCRL indicator set in its issuing distribution point extension. When it's present, the extension includes one or more names from the certificate's issuer field and/or its issuer alternative name extension, the ones that match the CRL entry ๐Ÿ“. If it's missing on the first entry of an indirect CRL, the certificate issuer defaults to the CRL issuer. On later entries, if it's missing, the certificate issuer is the same as the one from the entry before it ๐Ÿ”. Here's how it's defined:

id-ce-certificateIssuer   OBJECT IDENTIFIER ::= { id-ce 29 }

CertificateIssuer ::=     GeneralNames

conforming CRL issuers MUST include the distinguished name (DN) from the issuer field of the certificate that matches this CRL entry ๐Ÿ“›. The DN encoding MUST be identical to the encoding used in the certificate, byte for byte, no vibes-based re-encoding ๐Ÿ’….

CRL issuers MUST mark this extension as critical ๐Ÿšจ. The reason is that an implementation which ignored it couldn't correctly attribute CRL entries to certificates, and that would be chaos ๐Ÿ˜ญ. This specification RECOMMENDS that implementations recognize this extension ๐ŸŒธ.


6. Certification Path Validation โœจ

okay now we're getting into the main character arc ๐Ÿ‘‘. Certification path validation for the Internet PKI is based on the algorithm supplied in [X.509] ๐Ÿ“œ. Path processing checks that the binding between the subject distinguished name and/or subject alternative name and the subject public key is legit ๐Ÿ”. That binding is limited by constraints in the certificates along the path, plus any inputs the relying party provides ๐ŸŽฏ. The basic constraints and policy constraints extensions let the path processing logic automate the decision-making ๐Ÿค–.

this section describes an algorithm for validating certification paths ๐Ÿ’œ. Conforming implementations of this spec are not required to implement this algorithm, but they MUST provide functionality equivalent to the external behavior that comes out of this procedure ๐Ÿซถ. Any algorithm works for a particular implementation as long as it derives the correct result ๐Ÿง . Iykyk, the output is what matters, not the choreography ๐Ÿฉฐ.

in Section 6.1 the text covers basic path validation ๐ŸŒˆ. Valid paths begin with certificates issued by a trust anchor ๐Ÿชท. The algorithm needs the CA's public key, the CA's name, and any constraints on the set of paths that can be validated with that key ๐Ÿ—๏ธ.

picking a trust anchor is a matter of policy ๐Ÿ›๏ธ. It could be the top CA in a hierarchical PKI, the CA that issued the verifier's own certificate(s), or any other CA in a network PKI ๐Ÿ•ธ๏ธ. The validation procedure is the same no matter which trust anchor you pick โœจ. Different applications may rely on different trust anchors, or they may accept paths that start with any one of a set of trust anchors ๐Ÿ’–.

Section 6.2 describes methods for using the path validation algorithm in specific implementations ๐ŸŽ€.

Section 6.3 describes the steps needed to figure out whether a certificate is revoked when CRLs are the revocation mechanism the certificate issuer uses ๐Ÿšซ๐Ÿ“‹. Bestie, that's the whole arc, so go read it ๐Ÿ’…๐Ÿฆ‹.

6.1. Basic Path Validation โœจ

okay bestie, this part is about an algorithm for X.509 path processing ๐Ÿ”ฅ A conforming implementation MUST include an X.509 path processing procedure that is functionally equivalent to the external behavior of this algorithm ๐Ÿ’… But support for some of the certificate extensions processed in here is OPTIONAL for compliant implementations โœจ Clients that don't support those extensions MAY omit the matching steps in the path validation algorithm ๐Ÿฆ‹

For example, clients aren't required to support the policy mappings extension ๐ŸŒธ Clients that skip that extension MAY omit the path validation steps where policy mappings get processed. But ngl, clients MUST reject the certificate if it has an unsupported critical extension ๐Ÿ˜ญ That one's a hard rule, so don't sleep on it ๐Ÿ’€

Sections 4 and 5 of this document give values for certificate and CRL fields and extensions that are considered appropriate for the Internet PKI ๐Ÿงš but this algorithm isn't limited to accepting certificates and CRLs that follow those profiles. So the algorithm only checks that the certification path is valid according to X.509, and it doesn't check that the certificates and CRLs conform to the profile. It could be extended to check conformance with Sections 4 and 5, but this profile RECOMMENDS against including those checks ๐ŸŽ€

The algorithm in this section validates the certificate with respect to the current date and time โฐ A conforming implementation MAY also support validation with respect to some point in the past ๐Ÿ•ฐ๏ธ Just know that mechanisms are not available for validating a certificate at a time outside its validity period, so that's a no-go ๐Ÿ’€

The trust anchor is an input to the algorithm. There's no requirement that the same trust anchor be used for every certification path ๐ŸŒˆ Different trust anchors MAY be used to validate different paths, and we'll get into that more in Section 6.2 ๐Ÿซถ

The main goal of path validation is to verify the binding between a subject distinguished name or a subject alternative name and a subject public key, as represented in the target certificate, based on the public key of the trust anchor ๐Ÿ‘‘ Usually the target certificate is an end entity certificate, but it can be a CA certificate too, as long as the subject public key is going to be used for something other than verifying the signature on a public key certificate โœจ To verify that binding, you need a sequence of certificates that support it. How you go about getting that sequence is outside the scope of this specification, so that's not our problem here ๐Ÿ™ˆ

To meet that goal, path validation checks, among other things, that a prospective certification path (a sequence of n certificates) satisfies these conditions:

  • (a) for all x in {1, ..., n-1}, the subject of certificate x is the issuer of certificate x+1;
  • (b) certificate 1 is issued by the trust anchor;
  • (c) certificate n is the certificate to be validated (i.e., the target certificate); and
  • (d) for all x in {1, ..., n}, the certificate was valid at the time in question.

A certificate MUST NOT appear more than once in a prospective certification path ๐Ÿ™…โ€โ™€๏ธ Like, no repeats, period ๐Ÿ’–

When the trust anchor comes as a self-signed certificate, that self-signed certificate is NOT included as part of the prospective certification path ๐Ÿ“ Info about trust anchors goes in as inputs to the certification path validation algorithm instead (Section 6.1.1) ๐Ÿง

A particular certification path might not be right for every application ๐Ÿฆ‹ So an application MAY augment this algorithm to further limit the set of valid paths ๐Ÿ”ฅ The path validation process also figures out which certificate policies are valid for the path, based on the certificate policies extension, policy mappings extension, policy constraints extension, and inhibit anyPolicy extension โœจ To do that, the algorithm builds a valid policy tree. If the set of certificate policies valid for the path isn't empty, the result is a valid policy tree of depth n. Otherwise, the result is a null valid policy tree ๐ŸŒธ

A certificate is self-issued if the same DN shows up in both the subject and issuer fields. (The two DNs count as the same if they match under the rules in Section 7.1 ๐Ÿงš) Normally the issuer and subject are different for each certificate in a path ๐Ÿ’… But a CA can issue a certificate to itself to support key rollover or changes in certificate policies ๐Ÿ”„ Those self-issued certificates are NOT counted when evaluating path length or name constraints ๐Ÿซถ

This section lays the algorithm out in four basic steps: (1) initialization, (2) basic certificate processing, (3) preparation for the next certificate, and (4) wrap-up ๐Ÿ“‹ Steps (1) and (4) happen exactly once. Step (2) happens for every certificate in the path. Step (3) happens for every certificate in the path except the final one ๐ŸŽ€ Figure 2 is a high-level flowchart of the whole thing ๐Ÿ‘‘

                           +-------+
                           | START |
                           +-------+
                               |
                               V
                       +----------------+
                       | Initialization |
                       +----------------+
                               |
                               +<--------------------+
                               |                     |
                               V                     |
                       +----------------+            |
                       |  Process Cert  |            |
                       +----------------+            |
                               |                     |
                               V                     |
                       +================+            |
                       |  IF Last Cert  |            |
                       |    in Path     |            |
                       +================+            |
                         |            |              |
                    THEN |            | ELSE         |
                         V            V              |
              +----------------+ +----------------+  |
              |    Wrap up     | |  Prepare for   |  |
              +----------------+ |   Next Cert    |  |
                      |          +----------------+  |
                      V               |              |
                  +-------+           +--------------+
                  | STOP  |
                  +-------+

         Figure 2.  Certification Path Processing Flowchart

6.1.1. Inputs ๐Ÿงƒ

This algorithm assumes that the following nine inputs are provided to the path processing logic ๐Ÿ’–

  • (a) a prospective certification path of length n.
  • (b) the current date/time.
  • (c) user-initial-policy-set: A set of certificate policy identifiers naming the policies that are acceptable to the certificate user. The user-initial-policy-set contains the special value any-policy if the user isn't concerned about certificate policy ๐ŸŒˆ
  • (d) trust anchor information, describing a CA that serves as a trust anchor for the certification path. The trust anchor information includes:
    • (1) the trusted issuer name,
    • (2) the trusted public key algorithm,
    • (3) the trusted public key, and
    • (4) optionally, the trusted public key parameters associated with the public key.

The trust anchor information can be given to the path processing procedure as a self-signed certificate ๐Ÿ“ When it comes as a certificate, the name in the subject field is used as the trusted issuer name, and the contents of the subjectPublicKeyInfo field are used as the source of the trusted public key algorithm and the trusted public key ๐Ÿง The trust anchor information is trusted because it was delivered to the path processing procedure by some trustworthy out-of-band procedure ๐Ÿ” If the trusted public key algorithm needs parameters, those parameters are provided along with the trusted public key โœจ

  • (e) initial-policy-mapping-inhibit, which indicates if policy mapping is allowed in the certification path.
  • (f) initial-explicit-policy, which indicates if the path has to be valid for at least one of the certificate policies in the user-initial-policy-set ๐ŸŽฏ
  • (g) initial-any-policy-inhibit, which indicates whether the anyPolicy OID should be processed if it's included in a certificate ๐Ÿ™ˆ
  • (h) initial-permitted-subtrees, which indicates for each name type (e.g., X.500 distinguished names, email addresses, or IP addresses) a set of subtrees within which all subject names in every certificate in the certification path MUST fall ๐ŸŒธ The initial-permitted-subtrees input includes a set for each name type. For each name type, the set can be a single subtree that includes all names of that name type, or one or more subtrees that each specify a subset of the names of that name type, or the set can be empty. If the set for a name type is empty, then the certification path is considered invalid if any certificate in the path includes a name of that name type ๐Ÿ’€
  • (i) initial-excluded-subtrees, which indicates for each name type (e.g., X.500 distinguished names, email addresses, or IP addresses) a set of subtrees within which no subject name in any certificate in the certification path may fall ๐Ÿšซ The initial-excluded-subtrees input includes a set for each name type. For each name type, the set can be empty or can consist of one or more subtrees that each specify a subset of the names of that name type. If the set for a name type is empty, then no names of that name type are excluded ๐Ÿฆ‹

Conforming implementations are NOT required to support setting all of these inputs ๐Ÿซถ For example, a conforming implementation may be designed to validate all certification paths using a value of FALSE for initial-any-policy-inhibit ๐Ÿ’œ

6.1.2. Initialization ๐ŸŽ€

okay bestie, this is the setup phase ๐Ÿงš we're filling in eleven state variables using the nine inputs we just met in 6.1.1 ๐Ÿ’… let's go one by one!

  • (a) valid_policy_tree: this is a tree of certificate policies, with their optional qualifiers attached ๐ŸŒณ. Each leaf is a policy that counts as valid at this point in path validation. If valid policies exist right now, the tree's depth equals how many certificates in the chain have been processed so far. If there are no valid policies, the tree is set to NULL, and once it's NULL, policy processing is over ๐Ÿ™ˆ Every node holds three things: the valid policy, a set of associated policy qualifiers, and a set of one or more expected policy values โœจ For a node at depth x:
    • (1) The valid_policy is one policy OID that's valid for the path of length x.
    • (2) The qualifier_set is the policy qualifiers tied to that valid policy in certificate x.
    • (3) The expected_policy_set is one or more policy OIDs that would satisfy this policy in certificate x+1.

The starting point is a single node: valid_policy is anyPolicy, qualifier_set is empty, and expected_policy_set has just anyPolicy in it. This node sits at depth zero ๐ŸŒฑ

Figure 3 shows what the starting state looks like. Later figures will use this same format to show how the tree changes during path processing ๐Ÿ“Š

              +----------------+
              |   anyPolicy    |   <---- valid_policy
              +----------------+
              |       {}       |   <---- qualifier_set
              +----------------+
              |  {anyPolicy}   |   <---- expected_policy_set
              +----------------+

Figure 3. Initial Value of the valid_policy_tree State Variable ๐Ÿ–ผ๏ธ

  • (b) permitted_subtrees: this is a set of root names for each name type (like X.500 distinguished names, email addresses, or IP addresses) that defines subtrees. Every subject name in later certificates in the path MUST fall inside these subtrees ๐Ÿ”’ There's a set for each name type, and it starts out as initial-permitted-subtrees.
  • (c) excluded_subtrees: same deal as above, but flipped ๐Ÿ™…โ€โ™€๏ธ it's a set of root names for each name type that defines subtrees where no subject name in later certificates may fall. It also has a set per name type and starts as initial-excluded-subtrees.
  • (d) explicit_policy: this is an integer that tells us whether a non-NULL valid_policy_tree is required ๐Ÿ“œ The number says how many non-self-issued certificates get processed before that requirement kicks in. Once it's set, it can go down but never up, so if one certificate demands a non-NULL tree, a later certificate can't cancel that demand ๐Ÿ˜ค If initial-explicit-policy is set, the starting value is 0. Otherwise it's n+1.
  • (e) inhibit_anyPolicy: this integer tracks whether anyPolicy still counts as a match ๐Ÿšซ It's the number of non-self-issued certificates processed before any anyPolicy OID gets ignored, as long as it shows up in a certificate that isn't an intermediate self-issued one. Same rule: it can decrease but not increase, so if a certificate shuts anyPolicy down, a later one can't turn it back on. If initial-any-policy-inhibit is set, it starts at 0. Otherwise it's n+1.
  • (f) policy_mapping: this integer says whether policy mapping is allowed ๐Ÿ—บ๏ธ It counts the non-self-issued certificates processed before policy mapping gets shut off. It can go down but not up, and if a certificate says mapping isn't permitted, no later certificate can override that ๐Ÿ™… If initial-policy-mapping-inhibit is set, it starts at 0. Otherwise it's n+1.
  • (g) working_public_key_algorithm: this is the digital signature algorithm used to check a certificate's signature ๐Ÿ”‘ It starts from the trusted public key algorithm in the trust anchor information.
  • (h) working_public_key: this is the public key used to check a certificate's signature ๐Ÿ—๏ธ It starts from the trusted public key in the trust anchor information.
  • (i) working_public_key_parameters: these are the parameters that go with the current public key and may be needed to verify a signature, depending on the algorithm ๐Ÿงฉ It starts from the trusted public key parameters in the trust anchor information.
  • (j) working_issuer_name: this is the issuer distinguished name we expect to see in the next certificate in the chain ๐Ÿ‘€ It starts as the trusted issuer name from the trust anchor information.
  • (k) max_path_length: this integer starts at n, goes down by one for each non-self-issued certificate in the path, and can also be lowered to the value in the path length constraint field of the basic constraints extension in a CA certificate ๐Ÿ“‰ it's giving countdown ๐Ÿ’€

Once all of that is set up, we move on to the basic certificate processing steps in 6.1.3 ๐Ÿš€โœจ

6.1.3. Basic Certificate Processing โœจ

okay bestie, this is where the real path-checking happens ๐Ÿซถ For every certificate i (for all i in [1..n]), we run the basic path processing actions below. Let's go!! ๐Ÿ’…

  • (a) Verify the basic certificate information. The certificate MUST satisfy each of the following:
    • (1) The signature on the certificate can be verified using working_public_key_algorithm, the working_public_key, and the working_public_key_parameters. ๐Ÿ”
    • (2) The certificate validity period includes the current time. โฐ
    • (3) At the current time, the certificate is not revoked. This may be determined by obtaining the appropriate CRL (Section 6.3), by status information, or by out-of-band mechanisms. ๐Ÿšซ
    • (4) The certificate issuer name is the working_issuer_name. ๐ŸŽ€
  • (b) If certificate i is self-issued and it is not the final certificate in the path, skip this step for certificate i. Otherwise, verify that the subject name is within one of the permitted_subtrees for X.500 distinguished names, and verify that each of the alternative names in the subjectAltName extension (critical or non-critical) is within one of the permitted_subtrees for that name type. ๐ŸŒธ
  • (c) If certificate i is self-issued and it is not the final certificate in the path, skip this step for certificate i. Otherwise, verify that the subject name is not within any of the excluded_subtrees for X.500 distinguished names, and verify that each of the alternative names in the subjectAltName extension (critical or non-critical) is not within any of the excluded_subtrees for that name type. ๐Ÿ™…โ€โ™€๏ธ
  • (d) If the certificate policies extension is present in the certificate and the valid_policy_tree is not NULL, process the policy information by performing the following steps in order: ๐Ÿฆ‹
    • (1) For each policy P not equal to anyPolicy in the certificate policies extension, let P-OID denote the OID for policy P and P-Q denote the qualifier set for policy P. Perform the following steps in order:
      • (i) For each node of depth i-1 in the valid_policy_tree where P-OID is in the expected_policy_set, create a child node as follows: set the valid_policy to P-OID, set the qualifier_set to P-Q, and set the expected_policy_set to {P-OID}.
      • (ii) If there was no match in step (i) and the valid_policy_tree includes a node of depth i-1 with the valid_policy anyPolicy, generate a child node with the following values: set the valid_policy to P-OID, set the qualifier_set to P-Q, and set the expected_policy_set to {P-OID}.
    • (2) If the certificate policies extension includes the policy anyPolicy with the qualifier set AP-Q and either (a) inhibit_anyPolicy is greater than 0 or (b) i<n and the certificate is self-issued, then: For each node in the valid_policy_tree of depth i-1, for each value in the expected_policy_set (including anyPolicy) that does not appear in a child node, create a child node with the following values: set the valid_policy to the value from the expected_policy_set in the parent node, set the qualifier_set to AP-Q, and set the expected_policy_set to the value in the valid_policy from this node.
    • (3) If there is a node in the valid_policy_tree of depth i-1 or less without any child nodes, delete that node. Repeat this step until there are no nodes of depth i-1 or less without children.
  • (e) If the certificate policies extension is not present, set the valid_policy_tree to NULL. ๐Ÿซง
  • (f) Verify that either explicit_policy is greater than 0 or the valid_policy_tree is not equal to NULL;

Now for the policy examples, because the tree stuff is kinda wild ๐ŸŒณ For step (d)(1)(i), imagine a valid_policy_tree with a node of depth i-1 where the expected_policy_set is {Gold, White}. Say the certificate policies Gold and Silver show up in the certificate policies extension of certificate i. Gold matches, Silver doesn't, so this rule makes one child node of depth i for Gold. Here's how it looks, Figure 4 style ๐Ÿ’–:

                           +-----------------+
                           |       Red       |
                           +-----------------+
                           |       {}        |
                           +-----------------+   node of depth i-1
                           |  {Gold, White}  |
                           +-----------------+
                                    |
                                    |
                                    |
                                    V
                           +-----------------+
                           |      Gold       |
                           +-----------------+
                           |       {}        |
                           +-----------------+   node of depth i
                           |     {Gold}      |
                           +-----------------+

                  Figure 4.  Processing an Exact Match

For step (d)(1)(ii), imagine a valid_policy_tree with a node of depth i-1 where the valid_policy is anyPolicy. Say Gold and Silver are in the certificate policies extension of certificate i. Gold has no qualifier, but Silver has the qualifier Q-Silver. If Gold and Silver weren't matched in (i), this rule makes two child nodes of depth i, one for each policy ๐Ÿ“ Here's the picture, Figure 5 vibes:

                                 +-----------------+
                                 |    anyPolicy    |
                                 +-----------------+
                                 |       {}        |
                                 +-----------------+ node of depth i-1
                                 |   {anyPolicy}   |
                                 +-----------------+
                                    /           \
                                   /             \
                                  /               \
                                 /                 \
                   +-----------------+          +-----------------+
                   |      Gold       |          |     Silver      |
                   +-----------------+          +-----------------+
                   |       {}        |          |   {Q-Silver}    |
                   +-----------------+ nodes of +-----------------+
                   |     {Gold}      | depth i  |    {Silver}     |
                   +-----------------+          +-----------------+

                Figure 5.  Processing Unmatched Policies when a
                Leaf Node Specifies anyPolicy

For step (d)(2), imagine a valid_policy_tree with a node of depth i-1 where the expected_policy_set is {Gold, Silver}. Say anyPolicy shows up in the certificate policies extension of certificate i with no policy qualifiers, but Gold and Silver don't. This rule makes two child nodes of depth i, one per policy ๐ŸŒˆ Check out Figure 6 below:

                             +-----------------+
                             |      Red        |
                             +-----------------+
                             |       {}        |
                             +-----------------+ node of depth i-1
                             |  {Gold, Silver} |
                             +-----------------+
                                /           \
                               /             \
                              /               \
                             /                 \
               +-----------------+          +-----------------+
               |      Gold       |          |     Silver      |
               +-----------------+          +-----------------+
               |       {}        |          |       {}        |
               +-----------------+ nodes of +-----------------+
               |     {Gold}      | depth i  |    {Silver}     |
               +-----------------+          +-----------------+

            Figure 6.  Processing Unmatched Policies When the
            Certificate Policies Extension Specifies anyPolicy

For step (d)(3), take a look at the valid_policy_tree in Figure 7. The two nodes at depth i-1 marked with an 'X' have no children, so they get deleted. Applying the rule again to the resulting tree deletes the node at depth i-2 marked with a 'Y', because it's left childless too ๐Ÿงš Once the tree has no childless nodes of depth i-1 or less, this step is done. โœ…

                             +-----------+
                             |           | node of depth i-3
                             +-----------+
                             /     |     \
                            /      |      \
                           /       |       \
               +-----------+ +-----------+ +-----------+
               |           | |           | |     Y     | nodes of
               +-----------+ +-----------+ +-----------+ depth i-2
               /   \               |             |
              /     \              |             |
             /       \             |             |
  +-----------+ +-----------+ +-----------+ +-----------+ nodes of
  |           | |     X     | |           | |    X      |  depth
  +-----------+ +-----------+ +-----------+ +-----------+   i-1
        |                      /    |    \
        |                     /     |     \
        |                    /      |      \
  +-----------+ +-----------+ +-----------+ +-----------+ nodes of
  |           | |           | |           | |           |  depth
  +-----------+ +-----------+ +-----------+ +-----------+   i

         Figure 7.  Pruning the valid_policy_tree

If any of steps (a), (b), (c), or (f) fails, the procedure terminates, returning a failure indication and an appropriate reason. ๐Ÿšจ Big deal, so be careful there!!

If i is not equal to n, keep going with the preparatory steps in Section 6.1.4. If i is equal to n, do the wrap-up steps in Section 6.1.5 instead. ๐Ÿ’œ

6.1.4. Preparation for Certificate i+1 ๐Ÿ’…

okay bestie, before we can even think about certificate i+1, we gotta run through this checklist for certificate i ๐ŸŽ€

  • (a) If a policy mappings extension is present, verify that the special value anyPolicy does not appear as an issuerDomainPolicy or a subjectDomainPolicy. โœจ
  • (b) If a policy mappings extension is present, then for each issuerDomainPolicy ID-P in the policy mappings extension: ๐Ÿฆ‹
    • (1) If the policy_mapping variable is greater than 0, for each node in the valid_policy_tree of depth i where ID-P is the valid_policy, set expected_policy_set to the set of subjectDomainPolicy values that are specified as equivalent to ID-P by the policy mappings extension.
      • If no node of depth i in the valid_policy_tree has a valid_policy of ID-P but there is a node of depth i with a valid_policy of anyPolicy, then generate a child node of the node of depth i-1 that has a valid_policy of anyPolicy as follows:
        • (i) set the valid_policy to ID-P;
        • (ii) set the qualifier_set to the qualifier set of the policy anyPolicy in the certificate policies extension of certificate i; and
        • (iii) set the expected_policy_set to the set of subjectDomainPolicy values that are specified as equivalent to ID-P by the policy mappings extension.
    • (2) If the policy_mapping variable is equal to 0:
      • (i) delete each node of depth i in the valid_policy_tree where ID-P is the valid_policy.
      • (ii) If there is a node in the valid_policy_tree of depth i-1 or less without any child nodes, delete that node. Repeat this step until there are no nodes of depth i-1 or less without children.
  • (c) Assign the certificate subject name to working_issuer_name. ๐ŸŒธ
  • (d) Assign the certificate subjectPublicKey to working_public_key.
  • (e) If the subjectPublicKeyInfo field of the certificate contains an algorithm field with non-null parameters, assign the parameters to the working_public_key_parameters variable.

If the subjectPublicKeyInfo field of the certificate contains an algorithm field with null parameters or parameters are omitted, compare the certificate subjectPublicKey algorithm to the working_public_key_algorithm. If the certificate subjectPublicKey algorithm and the working_public_key_algorithm are different, set the working_public_key_parameters to null.

  • (f) Assign the certificate subjectPublicKey algorithm to the working_public_key_algorithm variable.
  • (g) If a name constraints extension is included in the certificate, modify the permitted_subtrees and excluded_subtrees state variables as follows: ๐Ÿงš
    • (1) If permittedSubtrees is present in the certificate, set the permitted_subtrees state variable to the intersection of its previous value and the value indicated in the extension field. If permittedSubtrees does not include a particular name type, the permitted_subtrees state variable is unchanged for that name type. For example, the intersection of example.com and foo.example.com is foo.example.com. And the intersection of example.com and example.net is the empty set.
    • (2) If excludedSubtrees is present in the certificate, set the excluded_subtrees state variable to the union of its previous value and the value indicated in the extension field. If excludedSubtrees does not include a particular name type, the excluded_subtrees state variable is unchanged for that name type. For example, the union of the name spaces example.com and foo.example.com is example.com. And the union of example.com and example.net is both name spaces.
  • (h) If certificate i is not self-issued:
    • (1) If explicit_policy is not 0, decrement explicit_policy by 1.
    • (2) If policy_mapping is not 0, decrement policy_mapping by 1.
    • (3) If inhibit_anyPolicy is not 0, decrement inhibit_anyPolicy by 1.
  • (i) If a policy constraints extension is included in the certificate, modify the explicit_policy and policy_mapping state variables as follows: ๐Ÿ‘‘
    • (1) If requireExplicitPolicy is present and is less than explicit_policy, set explicit_policy to the value of requireExplicitPolicy.
    • (2) If inhibitPolicyMapping is present and is less than policy_mapping, set policy_mapping to the value of inhibitPolicyMapping.
  • (j) If the inhibitAnyPolicy extension is included in the certificate and is less than inhibit_anyPolicy, set inhibit_anyPolicy to the value of inhibitAnyPolicy.
  • (k) If certificate i is a version 3 certificate, verify that the basicConstraints extension is present and that cA is set to TRUE. (If certificate i is a version 1 or version 2 certificate, then the application MUST either verify that certificate i is a CA certificate through out-of-band means or reject the certificate. Conforming implementations may choose to reject all version 1 and version 2 intermediate certificates.) ๐Ÿ™ˆ
  • (l) If the certificate was not self-issued, verify that max_path_length is greater than zero and decrement max_path_length by 1.
  • (m) If pathLenConstraint is present in the certificate and is less than max_path_length, set max_path_length to the value of pathLenConstraint.
  • (n) If a key usage extension is present, verify that the keyCertSign bit is set.
  • (o) Recognize and process any other critical extension present in the certificate. Process any other recognized non-critical extension present in the certificate that is relevant to path processing.

If check (a), (k), (l), (n), or (o) fails, the procedure terminates, returning a failure indication and an appropriate reason. ๐Ÿ’€

If (a), (k), (l), (n), and (o) have completed successfully, increment i and perform the basic certificate processing specified in Section 6.1.3. ๐Ÿซถ


6.1.5. Wrap-Up Procedure ๐ŸŒˆ

To complete the processing of the target certificate, perform the following steps for certificate n:

  • (a) If explicit_policy is not 0, decrement explicit_policy by 1.
  • (b) If a policy constraints extension is included in the certificate and requireExplicitPolicy is present and has a value of 0, set the explicit_policy state variable to 0.
  • (c) Assign the certificate subjectPublicKey to working_public_key.
  • (d) If the subjectPublicKeyInfo field of the certificate contains an algorithm field with non-null parameters, assign the parameters to the working_public_key_parameters variable.

If the subjectPublicKeyInfo field of the certificate contains an algorithm field with null parameters or parameters are omitted, compare the certificate subjectPublicKey algorithm to the working_public_key_algorithm. If the certificate subjectPublicKey algorithm and the working_public_key_algorithm are different, set the working_public_key_parameters to null.

  • (e) Assign the certificate subjectPublicKey algorithm to the working_public_key_algorithm variable.
  • (f) Recognize and process any other critical extension present in the certificate n. Process any other recognized non-critical extension present in certificate n that is relevant to path processing.
  • (g) Calculate the intersection of the valid_policy_tree and the user-initial-policy-set, as follows: โœจ
    • (i) If the valid_policy_tree is NULL, the intersection is NULL.
    • (ii) If the valid_policy_tree is not NULL and the user-initial-policy-set is any-policy, the intersection is the entire valid_policy_tree.
    • (iii) If the valid_policy_tree is not NULL and the user-initial-policy-set is not any-policy, calculate the intersection of the valid_policy_tree and the user-initial-policy-set as follows:
      • 1. Determine the set of policy nodes whose parent nodes have a valid_policy of anyPolicy. This is the valid_policy_node_set.
      • 2. If the valid_policy of any node in the valid_policy_node_set is not in the user-initial-policy-set and is not anyPolicy, delete this node and all its children.
      • 3. If the valid_policy_tree includes a node of depth n with the valid_policy anyPolicy and the user-initial-policy-set is not any-policy, perform the following steps:
        • a. Set P-Q to the qualifier_set in the node of depth n with valid_policy anyPolicy.
        • b. For each P-OID in the user-initial-policy-set that is not the valid_policy of a node in the valid_policy_node_set, create a child node whose parent is the node of depth n-1 with the valid_policy anyPolicy. Set the values in the child node as follows: set the valid_policy to P-OID, set the qualifier_set to P-Q, and set the expected_policy_set to {P-OID}.
        • c. Delete the node of depth n with the valid_policy anyPolicy.
      • 4. If there is a node in the valid_policy_tree of depth n-1 or less without any child nodes, delete that node. Repeat this step until there are no nodes of depth n-1 or less without children.

If either (1) the value of explicit_policy variable is greater than zero or (2) the valid_policy_tree is not NULL, then path processing has succeeded. ๐ŸŽ‰


6.1.6. Outputs ๐Ÿฆ‹

If path processing succeeds, the procedure terminates, returning a success indication together with final value of the valid_policy_tree, the working_public_key, the working_public_key_algorithm, and the working_public_key_parameters. and that's the whole vibe, bestie ๐Ÿ’œ

6.2. Using the Path Validation Algorithm โœจ

okay so the path validation algorithm is basically the recipe for checking ONE certification path ๐Ÿง. every path starts at a specific trust anchor, but there's no rule saying your whole system has to use the same trust anchor for everything ๐Ÿ™…โ€โ™€๏ธ. picking which trusted CAs you trust is a local decision, so your system gets to choose, and it can hand any one of its trusted CAs over as the trust anchor for a particular path ๐Ÿ’…. the inputs can even be different for each path! that's super useful because the inputs can reflect app-specific needs or limits on how much a certain trust anchor is trusted. like, a trusted CA might only be trusted for one particular certificate policy, and that restriction gets expressed right through the inputs ๐ŸŽ€

an implementation MAY augment the algorithm from Section 6.1 to limit the set of valid certification paths that start with a particular trust anchor ๐ŸŒธ for example, an implementation MAY tweak the algorithm to apply a path length constraint to one specific trust anchor during the initialization phase ๐Ÿ’–. or the application MAY require a particular alternative name form to show up in the target certificate, or the application MAY put requirements on application-specific extensions ๐Ÿซถ. so basically, the path validation algorithm in Section 6.1 only sets the minimum conditions for a path to count as valid ๐Ÿ‘‘

now, when a CA hands out self-signed certificates to describe trust anchor info, certificate extensions can be used to suggest recommended inputs to path validation ๐Ÿงš like, a policy constraints extension could sit in that self-signed certificate to say that paths starting from this trust anchor should only be trusted for the listed policies ๐Ÿ“. same vibe with a name constraints extension, which could say those paths should only be trusted for the specified name spaces ๐Ÿฆ‹. the Section 6.1 algorithm does NOT assume trust anchor info comes in self-signed certificates, and it doesn't spell out processing rules for any extra info in those certs ๐Ÿ™ˆ implementations that use self-signed certificates for trust anchor info are free to process that info or ignore it, totally their call ๐Ÿ’œ


6.3. CRL Validation ๐ŸŒˆ

this section walks through the steps for figuring out whether a certificate is revoked when CRLs are the revocation mechanism the certificate issuer uses ๐Ÿ“œ. conforming implementations that support CRLs are not required to implement this exact algorithm ๐Ÿคทโ€โ™€๏ธ, BUT they MUST be functionally equivalent to the external behavior this procedure gives when they're processing CRLs issued in line with this profile ๐Ÿ”ฅ. any algorithm is fine for a particular implementation as long as it gets the correct result โœจ

this algorithm assumes all the CRLs it needs are already sitting in a local cache ๐Ÿ—‚๏ธ. and if the next update time of a CRL has passed, the algorithm assumes there's a mechanism to fetch a current CRL and drop it into the local CRL cache ๐Ÿƒโ€โ™€๏ธ

this algorithm defines a set of inputs, a set of state variables, and processing steps that get run for each certificate in the path ๐Ÿ’…. the output is the revocation status of the certificate ๐ŸŽ€

6.3.1. Revocation Inputs ๐Ÿ”‘

to support revocation processing, the algorithm needs two inputs ๐Ÿ’œ

  • (a) certificate: the algorithm needs the certificate serial number and issuer name to figure out whether a certificate is on a particular CRL ๐Ÿ”. the basicConstraints extension tells you whether the supplied certificate belongs to a CA or an end entity ๐Ÿง‘โ€๐Ÿ’ป. if it's present, the algorithm uses the cRLDistributionPoints and freshestCRL extensions to determine revocation status ๐ŸŒธ
  • (b) use-deltas: this boolean input decides whether delta CRLs get applied to CRLs ๐Ÿฆ‹

6.3.2. Initialization and Revocation State Variables ๐Ÿง

to support CRL processing, the algorithm needs these state variables ๐Ÿซง

  • (a) reasons_mask: this holds the set of revocation reasons supported by the CRLs and delta CRLs processed so far ๐Ÿ’–. the legal members are the possible revocation reason values minus unspecified: keyCompromise, cACompromise, affiliationChanged, superseded, cessationOfOperation, certificateHold, privilegeWithdrawn, and aACompromise ๐Ÿ‘‘. the special value all-reasons is used to denote the set of all legal members ๐ŸŒˆ. this variable starts out as the empty set ๐Ÿ“
  • (b) cert_status: this holds the status of the certificate ๐ŸŽ€. it can be assigned one of these values: unspecified, keyCompromise, cACompromise, affiliationChanged, superseded, cessationOfOperation, certificateHold, removeFromCRL, privilegeWithdrawn, aACompromise, the special value UNREVOKED, or the special value UNDETERMINED ๐Ÿงš. this variable starts out as the special value UNREVOKED โœจ
  • (c) interim_reasons_mask: this contains the set of revocation reasons supported by the CRL or delta CRL currently being processed ๐Ÿ”ฅ
Note: some environments don't need to check every reason code ๐Ÿ‘€. for example, some environments only care about cACompromise and keyCompromise for CA certificates ๐Ÿ™ˆ. this algorithm checks ALL the reason codes, so if you want to limit the checking to a subset, you may need extra processing and state variables ๐Ÿ’…

6.3.3. CRL Processing โœจ

okay so we start by assuming the cert is NOT revoked ๐Ÿ’… ๐Ÿฆ‹ (innocent until proven guilty, bestie). Then we check one or more CRLs until either the cert status gets marked revoked, or we've checked enough CRLs to cover every reason code. iykyk ๐Ÿซถ

For each distribution point (DP) in the certificate's CRL distribution points extension, and for each matching CRL in the local CRL cache, we keep going while reasons_mask is not all-reasons AND cert_status is UNREVOKED. For each one, we do the following:

  • (a) Update the local CRL cache by grabbing a complete CRL, a delta CRL, or both, depending on what's needed ๐ŸŒธ
    • (1) If the current time is after the CRL's next update field, then do one of these:
      • (i) If use-deltas is set and either the cert or the CRL has the freshest CRL extension, get a delta CRL with a next update value that's after the current time, and use it to update the locally cached CRL as described in Section 5.2.4. ๐Ÿ“
      • (ii) Update the local CRL cache with a current complete CRL, and check that the current time is before the next update value in the new CRL. Then keep going with the new CRL. If use-deltas is set and either the cert or the CRL has the freshest CRL extension, also grab the current delta CRL that can update the new locally cached complete CRL as described in Section 5.2.4. ๐Ÿงš
    • (2) If the current time is still before the next update field, use-deltas is set, and either the cert or the CRL has the freshest CRL extension, then grab the current delta CRL that can update the locally cached complete CRL as described in Section 5.2.4. โœจ
  • (b) Verify the issuer and scope of the complete CRL, like this: ๐Ÿ”
    • (1) If the DP includes cRLIssuer, check that the issuer field in the complete CRL matches cRLIssuer in the DP, AND that the complete CRL has an issuing distribution point extension with the indirectCRL boolean asserted. Otherwise, check that the CRL issuer matches the cert issuer.
    • (2) If the complete CRL includes an issuing distribution point (IDP) CRL extension, check the following:
      • (i) If the distribution point name is in the IDP CRL extension AND the distribution field is in the DP, then check that at least one name in the IDP matches one name in the DP. If the distribution point name is in the IDP CRL extension but the distribution field is left out of the DP, then check that one of the names in the IDP matches one of the names in the DP's cRLIssuer field. ๐Ÿ’–
      • (ii) If the onlyContainsUserCerts boolean is asserted in the IDP CRL extension, check that the cert does NOT include the basic constraints extension with the cA boolean asserted. ๐Ÿ™ˆ
      • (iii) If the onlyContainsCACerts boolean is asserted in the IDP CRL extension, check that the cert DOES include the basic constraints extension with the cA boolean asserted. ๐Ÿ‘‘
      • (iv) Check that the onlyContainsAttributeCerts boolean is NOT asserted. ๐Ÿ’€
  • (c) If use-deltas is set, verify the issuer and scope of the delta CRL, like this: ๐ŸŽ€
    • (1) Check that the delta CRL issuer matches the complete CRL issuer.
    • (2) If the complete CRL includes an IDP CRL extension, check that the delta CRL has a matching IDP CRL extension. If the complete CRL leaves out an IDP CRL extension, check that the delta CRL also leaves one out. ๐ŸŒˆ
    • (3) Check that the delta CRL authority key identifier extension matches the complete CRL authority key identifier extension. ๐Ÿซถ
  • (d) Work out the interim_reasons_mask for this CRL, like this: ๐Ÿงฎ
    • (1) If the IDP CRL extension is present and includes onlySomeReasons, AND the DP includes reasons, then set interim_reasons_mask to the intersection of the reasons in the DP and onlySomeReasons in the IDP CRL extension.
    • (2) If the IDP CRL extension includes onlySomeReasons but the DP leaves out reasons, then set interim_reasons_mask to the value of onlySomeReasons in the IDP CRL extension.
    • (3) If the IDP CRL extension is not present or leaves out onlySomeReasons, but the DP includes reasons, then set interim_reasons_mask to the value of the DP reasons.
    • (4) If the IDP CRL extension is not present or leaves out onlySomeReasons, AND the DP leaves out reasons, then set interim_reasons_mask to the special value all-reasons. ๐Ÿฆ‹
  • (e) Check that interim_reasons_mask includes one or more reasons that are NOT already in the reasons_mask. ๐Ÿ’…
  • (f) Obtain and validate the certification path for the complete CRL's issuer. The trust anchor for this path MUST be the same trust anchor used to validate the target certificate. If a key usage extension is present in the CRL issuer's certificate, check that the cRLSign bit is set. ๐Ÿ”
  • (g) Validate the signature on the complete CRL using the public key validated in step (f). ๐Ÿ”ฅ
  • (h) If use-deltas is set, validate the signature on the delta CRL using the public key validated in step (f). ๐ŸŒธ
  • (i) If use-deltas is set, search the delta CRL for the cert. If an entry matches the cert issuer and serial number as described in Section 5.3.3, set the cert_status variable to the indicated reason, like this: ๐Ÿ”
    • (1) If the reason code CRL entry extension is present, set cert_status to the value of the reason code CRL entry extension.
    • (2) If the reason code CRL entry extension is not present, set cert_status to the value unspecified. ๐Ÿ“
  • (j) If cert_status is UNREVOKED, search the complete CRL for the cert. If an entry matches the cert issuer and serial number as described in Section 5.3.3, set the cert_status variable to the indicated reason as described in step (i). โœจ
  • (k) If cert_status is removeFromCRL, set cert_status to UNREVOKED. ๐Ÿงš
  • (l) Set the reasons_mask state variable to the union of its previous value and the value of the interim_reasons_mask state variable. ๐Ÿ’–

If reasons_mask is all-reasons OR cert_status is not UNREVOKED, then the revocation status has been determined, so return cert_status. ๐Ÿ‘‘

If the revocation status still hasn't been determined, repeat the whole process above with any available CRLs that aren't specified in a distribution point but were issued by the cert issuer. For these CRLs, assume a DP with both the reasons and the cRLIssuer fields left out, and a distribution point name of the cert issuer. In other words, the sequence of names in fullName is generated from the cert issuer field AND the issuerAltName extension. After processing these CRLs, if the revocation status STILL hasn't been determined, then return the cert_status UNDETERMINED. ๐Ÿ™ˆ

bestie, UNDETERMINED means we couldn't figure it out, so don't just assume the cert is good! ๐Ÿšจ

7. Processing Rules for Internationalized Names ๐ŸŒ

Internationalized names can show up in tons of certificate and CRL fields and extensions, like distinguished names, internationalized domain names, email addresses, and Internationalized Resource Identifiers (IRIs). Storing, comparing, and presenting these names needs special care ๐Ÿซถ. Some characters can be encoded in more than one way, and the same name can be written in multiple encodings (e.g., ASCII or UTF8). This section sets the conformance requirements for storing or comparing each of these name forms. Informative guidance on presentation is given for some of them. ๐ŸŽ€

7.1. Internationalized Names in Distinguished Names ๐Ÿฆ‹

Internationalized names in distinguished names are covered in Sections 4.1.2.4, Issuer Name, and 4.1.2.6, Subject Name. Standard naming attributes, like common name, use the DirectoryString type, which supports internationalized names through a bunch of language encodings ๐ŸŒˆ. Conforming implementations MUST support UTF8String and PrintableString. RFC 3280 only required binary comparison of attribute values encoded in UTF8String, but this spec asks for a more thorough approach to comparison, so it's giving upgrade ๐Ÿ’…. Implementations may run into certificates and CRLs with names encoded in TeletexString, BMPString, or UniversalString, but support for these is OPTIONAL. ๐Ÿ“

Conforming implementations MUST use the LDAP StringPrep profile (including insignificant space handling), as specified in [RFC4518], as the basis for comparing distinguished name attributes encoded in either PrintableString or UTF8String. Conforming implementations MUST support name comparisons using caseIgnoreMatch. Support for attribute types that use other equality matching rules is optional. โœจ

Before comparing names using the caseIgnoreMatch matching rule, conforming implementations MUST perform the six-step string preparation algorithm described in [RFC4518] for each attribute of type DirectoryString, with these clarifications: ๐Ÿงฎ

  • In step 2, Map, the mapping shall include case folding as specified in Appendix B.2 of [RFC3454].
  • In step 6, Insignificant Character Removal, perform white space compression as specified in Section 2.6.1, Insignificant Space Handling, of [RFC4518].

When performing the string preparation algorithm, attributes MUST be treated as stored values. ๐Ÿ”

Comparisons of domainComponent attributes MUST be performed as specified in Section 7.3. ๐ŸŒธ

Two naming attributes match if the attribute types are the same AND the values of the attributes are an exact match after processing with the string preparation algorithm. Two relative distinguished names RDN1 and RDN2 match if they have the same number of naming attributes AND, for each naming attribute in RDN1, there's a matching naming attribute in RDN2. Two distinguished names DN1 and DN2 match if they have the same number of RDNs, each RDN in DN1 has a matching RDN in DN2, AND the matching RDNs appear in the same order in both DNs. ๐Ÿ” A distinguished name DN1 is within the subtree defined by the distinguished name DN2 if DN1 contains at least as many RDNs as DN2, AND DN1 and DN2 are a match when trailing RDNs in DN1 are ignored. ๐Ÿ‘‘

7.2. Internationalized Domain Names in GeneralName

okay so IDNs (internationalized domain names ๐ŸŒ) are allowed to show up in certificates and CRLs ๐Ÿ’– in the subjectAltName and issuerAltName extensions, the name constraints extension, the authority information access extension, the subject information access extension, the CRL distribution points extension, and the issuing distribution point extension โœจ. All of these use the GeneralName type, and one of its choices is the dNSName field, which is defined as type IA5String.

bestie, IA5String is only ASCII ๐Ÿ™ˆ so IDNs need a little glow-up first. To make them fit, conforming implementations MUST convert internationalized domain names to the ASCII Compatible Encoding (ACE) format from Section 4 of RFC 3490 before storing them in the dNSName field ๐ŸŽ€. The conversion MUST follow Section 4 of RFC 3490, with these clarifications:

  • in step 1, the domain name SHALL be considered a "stored string". That is, the AllowUnassigned flag SHALL NOT be set;
  • in step 3, set the flag called "UseSTD3ASCIIRules";
  • in step 4, process each label with the "ToASCII" operation; and
  • in step 5, change all label separators to U+002E (full stop).

now for comparing ๐Ÿ‘€ when you check DNS names for equality, conforming implementations MUST perform a case-insensitive exact match on the entire DNS name. when evaluating name constraints, conforming implementations MUST perform a case-insensitive exact match on a label-by-label basis. As noted in Section 4.2.1.10, any DNS name that may be constructed by adding labels to the left-hand side of the domain name given as the constraint is considered to fall within the indicated subtree ๐ŸŒธ

for display, implementations should convert IDNs to Unicode before showing them ๐Ÿ’… specifically, conforming implementations should perform the conversion operation from Section 4 of RFC 3490, with these clarifications:

  • in step 1, the domain name SHALL be considered a "stored string". That is, the AllowUnassigned flag SHALL NOT be set;
  • in step 3, set the flag called "UseSTD3ASCIIRules";
  • in step 4, process each label with the "ToUnicode" operation; and
  • skip step 5.
Note: Implementations MUST allow for increased space requirements for IDNs. An IDN ACE label will begin with the four additional characters xn-- and may require as many as five ASCII characters to specify a single international character. it's giving space-hungry ๐Ÿ™ˆ๐Ÿ’€

7.3. Internationalized Domain Names in Distinguished Names

okay so domain names can also be written as distinguished names using domain components ๐Ÿงš in the subject field, the issuer field, the subjectAltName extension, or the issuerAltName extension. just like the dNSName in GeneralName, the value of this attribute is defined as an IA5String ๐ŸŽ€ each domainComponent attribute represents a single label.

to represent a label from an IDN in the distinguished name, the implementation MUST perform the "ToASCII" label conversion from Section 4.1 of RFC 3490 ๐ŸŒˆ the label SHALL be considered a "stored string". That is, the AllowUnassigned flag SHALL NOT be set.

conforming implementations shall perform a case-insensitive exact match when comparing domainComponent attributes in distinguished names, as described in Section 7.2 ๐Ÿซถ

implementations should convert ACE labels to Unicode before display โœจ specifically, conforming implementations should perform the "ToUnicode" conversion operation, as described in Section 7.2, on each ACE label before displaying the name ๐Ÿ’–


7.4. Internationalized Resource Identifiers

okay this one is giving main character energy ๐Ÿ‘‘ IRIs (Internationalized Resource Identifiers) are the internationalized sibling of the Uniform Resource Identifier (URI) ๐Ÿฆ‹ IRIs are sequences of characters from Unicode, while URIs are sequences of characters from the ASCII character set. [RFC3987] defines a mapping from IRIs to URIs. IRIs don't get encoded directly into any certificate fields or extensions, but their mapped URIs may be included in certificates and CRLs ๐ŸŒธ

URIs may show up in the subjectAltName and issuerAltName extensions, the name constraints extension, the authority information access extension, the subject information access extension, the issuing distribution point extension, and the CRL distribution points extension ๐Ÿ“ each of these uses the GeneralName type, and URIs are encoded in the uniformResourceIdentifier field in GeneralName, which is defined as type IA5String.

to fit IRIs into the current structure, conforming implementations MUST map IRIs to URIs as specified in Section 3.1 of [RFC3987], with these clarifications:

  • in step 1, generate a UCS character sequence from the original IRI format normalizing according to the NFC as specified in Variant b (normalization according to NFC);
  • perform step 2 using the output from step 1.

Implementations MUST NOT convert the ireg-name component before performing step 2 ๐Ÿ™ˆ

before URIs get compared, conforming implementations MUST perform a combination of the syntax-based and scheme-based normalization techniques described in [RFC3987] ๐Ÿ”ฅ specifically, conforming implementations MUST prepare URIs for comparison as follows:

  • Step 1: Where IRIs allow the usage of IDNs, those names MUST be converted to ASCII Compatible Encoding as specified in Section 7.2 above.
  • Step 2: The scheme and host are normalized to lowercase, as described in Section 5.3.2.1 of [RFC3987].
  • Step 3: Perform percent-encoding normalization, as specified in Section 5.3.2.3 of [RFC3987].
  • Step 4: Perform path segment normalization, as specified in Section 5.3.2.4 of [RFC3987].
  • Step 5: If recognized, the implementation MUST perform scheme-based normalization as specified in Section 5.3.3 of [RFC3987].

Conforming implementations MUST recognize and perform scheme-based normalization for the following schemes: ldap, http, https, and ftp ๐Ÿงš if the scheme is not recognized, step 5 is omitted.

when comparing URIs for equivalence, conforming implementations shall perform a case-sensitive exact match ๐Ÿ’œ

implementations should convert URIs to Unicode before display ๐ŸŽ€ specifically, conforming implementations should perform the conversion operation specified in Section 3.2 of [RFC3987] โœจ


7.5. Internationalized Electronic Mail Addresses

okay email addresses ๐Ÿ“ง can show up in certificates and CRLs in the subjectAltName and issuerAltName extensions, the name constraints extension, the authority information access extension, the subject information access extension, the issuing distribution point extension, or the CRL distribution points extension ๐ŸŒˆ each of these uses the GeneralName construct, and GeneralName includes the rfc822Name choice, which is defined as type IA5String. to fit email addresses with internationalized domain names into the current structure, conforming implementations MUST convert the addresses into an ASCII representation ๐Ÿซถ

where the host-part (the Domain of the Mailbox) contains an internationalized name, the domain name MUST be converted from an IDN to the ASCII Compatible Encoding (ACE) format as specified in Section 7.2 ๐Ÿ’…

two email addresses are considered to match if:

  1. the local-part of each name is an exact match, AND
  2. the host-part of each name matches using a case-insensitive ASCII comparison.

implementations should convert the host-part of internationalized email addresses specified in these extensions to Unicode before display ๐Ÿ’– specifically, conforming implementations should perform the conversion of the host-part of the Mailbox as described in Section 7.2 ๐Ÿฆ‹


8. Security Considerations ๐Ÿšจ

okay this section is serious bestie, so grab your snacks and listen up ๐Ÿ“ the majority of this specification is about the format and content of certificates and CRLs. Since certificates and CRLs are digitally signed, no additional integrity service is necessary. Neither certificates nor CRLs need to be kept secret, and unrestricted and anonymous access to certificates and CRLs has no security implications ๐ŸŒธ

however, security factors outside the scope of this specification will affect the assurance provided to certificate users ๐Ÿ‘€ this section highlights critical issues that implementers, administrators, and users need to think about ๐Ÿ’œ

the procedures CAs and RAs use to validate the binding of the subject's identity to their public key hugely affect how much assurance should be placed in the certificate ๐Ÿ”ฅ relying parties might wish to review the CA's certification practice statement. this is especially important when issuing certificates to other CAs ๐Ÿงš

the use of a single key pair for both signature and other purposes is strongly discouraged ๐Ÿ™…โ€โ™€๏ธ using separate key pairs for signature and key management gives users several benefits ๐ŸŽ€ the ramifications of losing or disclosing a signature key are different from losing or disclosing a key management key, and separate key pairs let you respond in a balanced and flexible way โœจ similarly, different validity periods or key lengths for each key pair may be appropriate in some application environments. Unfortunately, some legacy applications (e.g., Secure Sockets Layer (SSL)) use a single key pair for signature and key management ๐Ÿ’€

the protection of private keys is a critical security factor ๐Ÿ” on a small scale, if users don't protect their private keys, an attacker can pretend to be them or decrypt their personal information ๐Ÿ˜ญ on a larger scale, compromise of a CA's private signing key may have a catastrophic effect ๐Ÿšจ if an attacker gets the private key without anyone noticing, the attacker may issue bogus certificates and CRLs. Existence of bogus certificates and CRLs will undermine confidence in the system ๐Ÿ’” if such a compromise is detected, all certificates issued to the compromised CA MUST be revoked, which prevents services between its users and users of other CAs. Rebuilding after such a compromise will be problematic, so CAs are advised to combine strong technical measures (e.g., tamper-resistant cryptographic modules) with appropriate management procedures (e.g., separation of duties) to avoid such an incident ๐Ÿ›ก๏ธ

Loss of a CA's private signing key may also be problematic. The CA would not be able to produce CRLs or perform normal key rollover. CAs SHOULD maintain secure backup for signing keys. The security of the key backup procedures is a critical factor in avoiding key compromise. bestie, back up those keys like your life depends on it ๐Ÿซถ๐Ÿ’œ

The availability and freshness of revocation info is literally what decides how much you can trust a cert ๐Ÿฅบ Certs expire on their own, but stuff can happen during their lifetime that breaks the link between the subject and the public key ๐Ÿ’” If revocation info is late or missing, the assurance drops fast ๐Ÿ˜ญ Relying parties might not even be able to process every critical extension that can show up in a CRL. CAs SHOULD take extra care when they only put revocation info in CRLs with critical extensions, esp if this profile doesn't require support for those extensions ๐Ÿซถ For example, say you use delta CRLs and full CRLs, and the deltas come out more often than the fulls. Then relying parties that can't handle the critical delta CRL extensions won't be able to get the newest revocation info ๐Ÿ’€ But if a full CRL goes out every time a delta CRL does, then timely revocation info is available to everyone ๐Ÿ™Œ Similarly, implementations of the path validation mechanism in Section 6 that skip revocation checking give you less assurance than the ones that do support it โœจ

Path validation depends on knowing for sure the public keys (and other info) of one or more trusted CAs ๐Ÿ”‘ Deciding to trust a CA is a huge deal bc it basically decides how much trust any cert gets ๐Ÿ‘‘ Getting trusted CA public keys (usually as a "self-signed" certificate) in an authenticated way is a security critical out-of-band process, and it's beyond the scope of this spec ๐Ÿซฃ

In addition, when a key compromise or CA failure happens for a trusted CA, the user will need to change the info given to the path validation routine ๐Ÿ˜ฌ Too many trusted CAs makes that info a nightmare to maintain ๐Ÿฅด But trusting only one CA could lock users into a closed community ๐Ÿ”’

The quality of implementations that process certs also affects the assurance ๐Ÿ’… Path validation in Section 6 relies on the integrity of the trusted CA info, especially the integrity of the public keys tied to those trusted CAs ๐Ÿ›ก๏ธ If an attacker swaps in public keys they hold the private key for, they can trick the user into accepting fake certs ๐Ÿ‘€

The binding between a key and cert subject can't be stronger than the crypto module implementation and the algorithms used to generate the signature ๐Ÿ’ช Short key lengths or weak hash algorithms limit how useful a cert is ๐Ÿ“‰ CAs are encouraged to keep up with advances in cryptology so they can use strong crypto techniques ๐Ÿ“š In addition, CAs SHOULD decline to issue certificates to CAs or end entities that generate weak signatures ๐Ÿ™…โ€โ™€๏ธ

Inconsistent application of name comparison rules can lead to accepting invalid X.509 cert paths or rejecting valid ones ๐Ÿคฏ The X.500 series defines rules for comparing distinguished names that require comparing strings without regard to case, character set, multi-character white space substring, or leading and trailing white space ๐Ÿง This spec relaxes those requirements, requiring support for binary comparison at a minimum ๐Ÿ’…

CAs MUST encode the distinguished name in the subject field of a CA certificate identically to the distinguished name in the issuer field in certificates issued by that CA ๐Ÿšจ If CAs use different encodings, implementations might fail to recognize name chains for paths that include this certificate. As a consequence, valid paths could be rejected ๐Ÿ˜ฉ

In addition, name constraints for distinguished names MUST be stated identically to the encoding used in the subject field or subjectAltName extension ๐Ÿ“ If not, name constraints stated as excludedSubtrees won't match and invalid paths will be accepted, and name constraints expressed as permittedSubtrees won't match and valid paths will be rejected ๐Ÿ™ƒ To avoid accepting invalid paths, CAs SHOULD state name constraints for distinguished names as permittedSubtrees wherever possible ๐ŸŒธ

In general, using the nameConstraints extension to constrain one name form (e.g., DNS names) offers no protection against use of other name forms (e.g., electronic mail addresses) ๐Ÿ™…โ€โ™€๏ธ

X.509 mandates that names be unambiguous, but there's a risk that two unrelated authorities will issue certificates and/or CRLs under the same issuer name ๐Ÿ‘ฏ As a means of reducing problems and security issues related to issuer name collisions, CA and CRL issuer names SHOULD be formed in a way that reduces the likelihood of name collisions ๐Ÿงฉ Implementers should take into account the possible existence of multiple unrelated CAs and CRL issuers with the same name ๐Ÿง  At a minimum, implementations validating CRLs MUST ensure that the certification path of a certificate and the CRL issuer certification path used to validate the certificate terminate at the same trust anchor ๐ŸŽฏ

While the local-part of an electronic mail address is case sensitive [RFC2821], emailAddress attribute values are not case sensitive [RFC2985] ๐Ÿ“ง As a result, two different email addresses might be treated as the same address when the matching rule for the emailAddress attribute is used, if the email server exploits the case sensitivity of mailbox local-parts ๐Ÿ˜ฌ Implementers should not include an email address in the emailAddress attribute if the email server that hosts the email address treats the local-part of email addresses as case sensitive ๐Ÿ™…โ€โ™€๏ธ

Implementers should be aware of risks involved if the CRL distribution points or authority information access extensions of corrupted certificates or CRLs contain links to malicious code ๐Ÿฆ  Implementers should always take the steps of validating the retrieved data to ensure that the data is properly formed ๐Ÿ”

When certificates include a cRLDistributionPoints extension with an https URI or similar scheme, circular dependencies can be introduced ๐Ÿ”„ The relying party is forced to perform an additional path validation in order to obtain the CRL required to complete the initial path validation! ๐Ÿคฏ Circular conditions can also be created with an https URI (or similar scheme) in the authorityInfoAccess or subjectInfoAccess extensions. At worst, this situation can create unresolvable dependencies ๐Ÿ’€

CAs SHOULD NOT include URIs that specify https, ldaps, or similar schemes in extensions. CAs that include an https URI in one of these extensions MUST ensure that the server's certificate can be validated without using the information that is pointed to by the URI. Relying parties that choose to validate the server's certificate when obtaining information pointed to by an https URI in the cRLDistributionPoints, authorityInfoAccess, or subjectInfoAccess extensions MUST be prepared for the possibility that this will result in unbounded recursion ๐ŸŒ€

Self-issued certificates give CAs one automated mechanism to indicate changes in the CA's operations ๐Ÿฆ‹ In particular, self-issued certificates may be used to implement a graceful change-over from one non-compromised CA key pair to the next. Detailed procedures for "CA key update" are specified in [RFC4210], where the CA protects its new public key using its previous private key and vice versa, using two self-issued certificates. Conforming client implementations will process the self-issued certificate and determine whether certificates issued under the new key may be trusted โœ… Self-issued certificates MAY be used to support other changes in CA operations, such as additions to the CA's policy set, using similar procedures ๐ŸŒˆ

Some legacy implementations support names encoded in the ISO 8859-1 character set (Latin1String) [ISO8859] but tag them as TeletexString ๐Ÿฅด TeletexString encodes a larger character set than ISO 8859-1, but it encodes some characters differently. The name comparison rules specified in Section 7.1 assume that TeletexStrings are encoded as described in the ASN.1 standard. When comparing names encoded using the Latin1String character set, false positives and negatives are possible ๐Ÿ™ƒ

When strings are mapped from internal representations to visual representations, sometimes two different strings will have the same or similar visual representations ๐Ÿ‘€ This can happen for many different reasons, including use of similar glyphs and use of composed characters (such as e + ' equaling U+00E9, the Korean composed characters, and vowels above consonant clusters in certain languages). As a result, people doing visual comparisons between two different names may think they are the same when in fact they are not. Also, people may mistake one string for another ๐Ÿ˜ต Issuers of certificates and relying parties both need to be aware of this situation ๐Ÿซถ


9. IANA Considerations โœจ

Extensions in certificates and CRLs are identified using object identifiers. The objects are defined in an arc delegated by IANA to the PKIX Working Group. No further action by IANA is necessary for this document or any anticipated updates ๐ŸŽ€

10. Acknowledgments ๐Ÿ’œ

Warwick Ford participated with the authors in some of the design team meetings that directed development of this document. The design team's efforts were guided by contributions from Matt Crawford, Tom Gindin, Steve Hanna, Stephen Henson, Paul Hoffman, Takashi Ito, Denis Pinkas, and Wen-Cheng Wang ๐Ÿซถ

11. References ๐Ÿ“š

11.1. Normative References ๐Ÿ“šโœจ

  • [RFC791] Postel, J., "Internet Protocol", STD 5, RFC 791, September 1981.
  • [RFC1034] Mockapetris, P., "Domain Names - Concepts and Facilities", STD 13, RFC 1034, November 1987.
  • [RFC1123] Braden, R., Ed., "Requirements for Internet Hosts -- Application and Support", STD 3, RFC 1123, October 1989.
  • [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
  • [RFC2460] Deering, S. and R. Hinden, "Internet Protocol, Version 6 (IPv6) Specification", RFC 2460, December 1998.
  • [RFC2585] Housley, R. and P. Hoffman, "Internet X.509 Public Key Infrastructure: Operational Protocols: FTP and HTTP", RFC 2585, May 1999.
  • [RFC2616] Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, "Hypertext Transfer Protocol -- HTTP/1.1", RFC 2616, June 1999.
  • [RFC2797] Myers, M., Liu, X., Schaad, J., and J. Weinstein, "Certificate Management Messages over CMS", RFC 2797, April 2000.
  • [RFC2821] Klensin, J., Ed., "Simple Mail Transfer Protocol", RFC 2821, April 2001.
  • [RFC3454] Hoffman, P. and M. Blanchet, "Preparation of Internationalized Strings ("stringprep")", RFC 3454, December 2002.
  • [RFC3490] Faltstrom, P., Hoffman, P., and A. Costello, "Internationalizing Domain Names in Applications (IDNA)", RFC 3490, March 2003.
  • [RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO 10646", STD 63, RFC 3629, November 2003.
  • [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986, January 2005.
  • [RFC3987] Duerst, M. and M. Suignard, "Internationalized Resource Identifiers (IRIs)", RFC 3987, January 2005.
  • [RFC4516] Smith, M., Ed., and T. Howes, "Lightweight Directory Access Protocol (LDAP): Uniform Resource Locator", RFC 4516, June 2006.
  • [RFC4518] Zeilenga, K., "Lightweight Directory Access Protocol (LDAP): Internationalized String Preparation", RFC 4518, June 2006.
  • [RFC4523] Zeilenga, K., "Lightweight Directory Access Protocol (LDAP) Schema Definitions for X.509 Certificates", RFC 4523, June 2006.
  • [RFC4632] Fuller, V. and T. Li, "Classless Inter-domain Routing (CIDR): The Internet Address Assignment and Aggregation Plan", BCP 122, RFC 4632, August 2006.
  • [X.680] ITU-T Recommendation X.680 (2002) | ISO/IEC 8824-1:2002, Information technology - Abstract Syntax Notation One (ASN.1): Specification of basic notation.
  • [X.690] ITU-T Recommendation X.690 (2002) | ISO/IEC 8825-1:2002, Information technology - ASN.1 encoding rules: Specification of Basic Encoding Rules (BER), Canonical Encoding Rules (CER) and Distinguished Encoding Rules (DER).

11.2. Informative References ๐Ÿฆ‹

  • [ISO8859] ISO/IEC 8859-1:1998. Information technology -- 8-bit single-byte coded graphic character sets -- Part 1: Latin alphabet No. 1.
  • [ISO10646] ISO/IEC 10646:2003. Information technology -- Universal Multiple-Octet Coded Character Set (UCS).
  • [NFC] Davis, M. and M. Duerst, "Unicode Standard Annex #15: Unicode Normalization Forms", October 2006, <http://www.unicode.org/reports/tr15/>.
  • [RFC1422] Kent, S., "Privacy Enhancement for Internet Electronic Mail: Part II: Certificate-Based Key Management", RFC 1422, February 1993.
  • [RFC2277] Alvestrand, H., "IETF Policy on Character Sets and Languages", BCP 18, RFC 2277, January 1998.
  • [RFC2459] Housley, R., Ford, W., Polk, W., and D. Solo, "Internet X.509 Public Key Infrastructure Certificate and CRL Profile", RFC 2459, January 1999.
  • [RFC2560] Myers, M., Ankney, R., Malpani, A., Galperin, S., and C. Adams, "X.509 Internet Public Key Infrastructure Online Certificate Status Protocol - OCSP", RFC 2560, June 1999.
  • [RFC2985] Nystrom, M. and B. Kaliski, "PKCS #9: Selected Object Classes and Attribute Types Version 2.0", RFC 2985, November 2000.
  • [RFC3161] Adams, C., Cain, P., Pinkas, D., and R. Zuccherato, "Internet X.509 Public Key Infrastructure Time-Stamp Protocol (TSP)", RFC 3161, August 2001.
  • [RFC3279] Bassham, L., Polk, W., and R. Housley, "Algorithms and Identifiers for the Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile", RFC 3279, April 2002.
  • [RFC3280] Housley, R., Polk, W., Ford, W., and D. Solo, "Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile", RFC 3280, April 2002.
  • [RFC4055] Schaad, J., Kaliski, B., and R. Housley, "Additional Algorithms and Identifiers for RSA Cryptography for use in the Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile", RFC 4055, June 2005.
  • [RFC4120] Neuman, C., Yu, T., Hartman, S., and K. Raeburn, "The Kerberos Network Authentication Service (V5)", RFC 4120, July 2005.
  • [RFC4210] Adams, C., Farrell, S., Kause, T., and T. Mononen, "Internet X.509 Public Key Infrastructure Certificate Management Protocol (CMP)", RFC 4210, September 2005.
  • [RFC4325] Santesson, S. and R. Housley, "Internet X.509 Public Key Infrastructure Authority Information Access Certificate Revocation List (CRL) Extension", RFC 4325, December 2005.
  • [RFC4491] Leontiev, S., Ed., and D. Shefanovski, Ed., "Using the GOST R 34.10-94, GOST R 34.10-2001, and GOST R 34.11-94 Algorithms with the Internet X.509 Public Key Infrastructure Certificate and CRL Profile", RFC 4491, May 2006.
  • [RFC4510] Zeilenga, K., Ed., "Lightweight Directory Access Protocol (LDAP): Technical Specification Road Map", RFC 4510, June 2006.
  • [RFC4512] Zeilenga, K., Ed., "Lightweight Directory Access Protocol (LDAP): Directory Information Models", RFC 4512, June 2006.
  • [RFC4514] Zeilenga, K., Ed., "Lightweight Directory Access Protocol (LDAP): String Representation of Distinguished Names", RFC 4514, June 2006.
  • [RFC4519] Sciberras, A., Ed., "Lightweight Directory Access Protocol (LDAP): Schema for User Applications", RFC 4519, June 2006.
  • [RFC4630] Housley, R. and S. Santesson, "Update to DirectoryString Processing in the Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile", RFC 4630, August 2006.
  • [X.500] ITU-T Recommendation X.500 (2005) | ISO/IEC 9594-1:2005, Information technology - Open Systems Interconnection - The Directory: Overview of concepts, models and services.
  • [X.501] ITU-T Recommendation X.501 (2005) | ISO/IEC 9594-2:2005, Information technology - Open Systems Interconnection - The Directory: Models.
  • [X.509] ITU-T Recommendation X.509 (2005) | ISO/IEC 9594-8:2005, Information technology - Open Systems Interconnection - The Directory: Public-key and attribute certificate frameworks.
  • [X.520] ITU-T Recommendation X.520 (2005) | ISO/IEC 9594-6:2005, Information technology - Open Systems Interconnection - The Directory: Selected attribute types.
  • [X.660] ITU-T Recommendation X.660 (2004) | ISO/IEC 9834-1:2005, Information technology - Open Systems Interconnection - Procedures for the operation of OSI Registration Authorities: General procedures, and top arcs of the ASN.1 Object Identifier tree.
  • [X.683] ITU-T Recommendation X.683 (2002) | ISO/IEC 8824-4:2002, Information technology - Abstract Syntax Notation One (ASN.1): Parameterization of ASN.1 specifications.
  • [X9.55] ANSI X9.55-1997, Public Key Cryptography for the Financial Services Industry: Extensions to Public Key Certificates and Certificate Revocation Lists, January 1997.

Appendix A. Pseudo-ASN.1 Structures and OIDs ๐Ÿงฉ

Okay so this appendix is where the data objects that conforming PKI components use get described, written in an "ASN.1-like" syntax ๐Ÿค“. It's kind of a mashup of the 1988 and 1993 ASN.1 syntaxes, and the 1988 one gets three extra UNIVERSAL types added on top: UniversalString, BMPString, and UTF8String ๐Ÿ’….

Here's the catch, bestie ๐Ÿ™ˆ. ASN.1 doesn't let you put type statements in the module, and the 1993 standard doesn't let you use the new UNIVERSAL types in a 1988-syntax module. So this module doesn't fully conform to either version. Iconic chaos, but it's intentional ๐Ÿ’€.

If you ever need it in plain 1988 ASN.1, you can convert it by swapping the UNIVERSAL type definitions for the 1988 catch-all "ANY" โœจ.

A.1. Explicitly Tagged Module, 1988 Syntax ๐ŸŽ€

PKIX1Explicit88 { iso(1) identified-organization(3) dod(6) internet(1)
  security(5) mechanisms(5) pkix(7) id-mod(0) id-pkix1-explicit(18) }

DEFINITIONS EXPLICIT TAGS ::=

BEGIN

-- EXPORTS ALL --

-- IMPORTS NONE --

-- UNIVERSAL Types defined in 1993 and 1998 ASN.1
-- and required by this specification

UniversalString ::= [UNIVERSAL 28] IMPLICIT OCTET STRING
        -- UniversalString is defined in ASN.1:1993

BMPString ::= [UNIVERSAL 30] IMPLICIT OCTET STRING
      -- BMPString is the subtype of UniversalString and models
      -- the Basic Multilingual Plane of ISO/IEC 10646

UTF8String ::= [UNIVERSAL 12] IMPLICIT OCTET STRING
      -- The content of this type conforms to RFC 3629.

-- PKIX specific OIDs

id-pkix  OBJECT IDENTIFIER  ::=
         { iso(1) identified-organization(3) dod(6) internet(1)
                    security(5) mechanisms(5) pkix(7) }

-- PKIX arcs

id-pe OBJECT IDENTIFIER ::= { id-pkix 1 }
        -- arc for private certificate extensions
id-qt OBJECT IDENTIFIER ::= { id-pkix 2 }
        -- arc for policy qualifier types
id-kp OBJECT IDENTIFIER ::= { id-pkix 3 }
        -- arc for extended key purpose OIDS
id-ad OBJECT IDENTIFIER ::= { id-pkix 48 }
        -- arc for access descriptors

-- policyQualifierIds for Internet policy qualifiers

id-qt-cps      OBJECT IDENTIFIER ::=  { id-qt 1 }
      -- OID for CPS qualifier
id-qt-unotice  OBJECT IDENTIFIER ::=  { id-qt 2 }
      -- OID for user notice qualifier

-- access descriptor definitions

id-ad-ocsp         OBJECT IDENTIFIER ::= { id-ad 1 }
id-ad-caIssuers    OBJECT IDENTIFIER ::= { id-ad 2 }
id-ad-timeStamping OBJECT IDENTIFIER ::= { id-ad 3 }
id-ad-caRepository OBJECT IDENTIFIER ::= { id-ad 5 }

-- attribute data types

Attribute               ::= SEQUENCE {
      type             AttributeType,
      values    SET OF AttributeValue }
            -- at least one value is required

AttributeType           ::= OBJECT IDENTIFIER

AttributeValue          ::= ANY -- DEFINED BY AttributeType

AttributeTypeAndValue   ::= SEQUENCE {
        type    AttributeType,
        value   AttributeValue }

okay bestie, this part is all about the naming attributes ๐ŸŽ€ the little labels that tell you what each bit of a name is โœจ

-- suggested naming attributes: Definition of the following
--   information object set may be augmented to meet local
--   requirements.  Note that deleting members of the set may
--   prevent interoperability with conforming implementations.
-- presented in pairs: the AttributeType followed by the
--   type definition for the corresponding AttributeValue
-- Arc for standard naming attributes

id-at OBJECT IDENTIFIER ::= { joint-iso-ccitt(2) ds(5) 4 }

-- Naming attributes of type X520name

id-at-name                AttributeType ::= { id-at 41 }
id-at-surname             AttributeType ::= { id-at  4 }
id-at-givenName           AttributeType ::= { id-at 42 }
id-at-initials            AttributeType ::= { id-at 43 }
id-at-generationQualifier AttributeType ::= { id-at 44 }

-- Naming attributes of type X520Name:
--   X520name ::= DirectoryString (SIZE (1..ub-name))
--
-- Expanded to avoid parameterized type:
X520name ::= CHOICE {
      teletexString     TeletexString   (SIZE (1..ub-name)),
      printableString   PrintableString (SIZE (1..ub-name)),
      universalString   UniversalString (SIZE (1..ub-name)),
      utf8String        UTF8String      (SIZE (1..ub-name)),
      bmpString         BMPString       (SIZE (1..ub-name)) }

ngl the X520name thing is giving "same energy, different outfit" ๐Ÿ’… it's the same five string flavours, just wearing a different length limit ๐ŸŒธ

-- Naming attributes of type X520CommonName

id-at-commonName        AttributeType ::= { id-at 3 }

-- Naming attributes of type X520CommonName:
--   X520CommonName ::= DirectoryName (SIZE (1..ub-common-name))
--
-- Expanded to avoid parameterized type:
X520CommonName ::= CHOICE {
      teletexString     TeletexString   (SIZE (1..ub-common-name)),
      printableString   PrintableString (SIZE (1..ub-common-name)),
      universalString   UniversalString (SIZE (1..ub-common-name)),
      utf8String        UTF8String      (SIZE (1..ub-common-name)),
      bmpString         BMPString       (SIZE (1..ub-common-name)) }

-- Naming attributes of type X520LocalityName

id-at-localityName      AttributeType ::= { id-at 7 }

-- Naming attributes of type X520LocalityName:
--   X520LocalityName ::= DirectoryName (SIZE (1..ub-locality-name))
--
-- Expanded to avoid parameterized type:
X520LocalityName ::= CHOICE {
      teletexString     TeletexString   (SIZE (1..ub-locality-name)),
      printableString   PrintableString (SIZE (1..ub-locality-name)),
      universalString   UniversalString (SIZE (1..ub-locality-name)),
      utf8String        UTF8String      (SIZE (1..ub-locality-name)),
      bmpString         BMPString       (SIZE (1..ub-locality-name)) }

-- Naming attributes of type X520StateOrProvinceName

id-at-stateOrProvinceName AttributeType ::= { id-at 8 }

-- Naming attributes of type X520StateOrProvinceName:
--   X520StateOrProvinceName ::= DirectoryName (SIZE (1..ub-state-name))
--
-- Expanded to avoid parameterized type:
X520StateOrProvinceName ::= CHOICE {
      teletexString     TeletexString   (SIZE (1..ub-state-name)),
      printableString   PrintableString (SIZE (1..ub-state-name)),
      universalString   UniversalString (SIZE (1..ub-state-name)),
      utf8String        UTF8String      (SIZE (1..ub-state-name)),
      bmpString         BMPString       (SIZE (1..ub-state-name)) }

-- Naming attributes of type X520OrganizationName

id-at-organizationName  AttributeType ::= { id-at 10 }

-- Naming attributes of type X520OrganizationName:
--   X520OrganizationName ::=
--          DirectoryName (SIZE (1..ub-organization-name))
--
-- Expanded to avoid parameterized type:
X520OrganizationName ::= CHOICE {
      teletexString     TeletexString
                          (SIZE (1..ub-organization-name)),
      printableString   PrintableString
                          (SIZE (1..ub-organization-name)),
      universalString   UniversalString
                          (SIZE (1..ub-organization-name)),
      utf8String        UTF8String
                          (SIZE (1..ub-organization-name)),
      bmpString         BMPString
                          (SIZE (1..ub-organization-name))  }

-- Naming attributes of type X520OrganizationalUnitName

id-at-organizationalUnitName AttributeType ::= { id-at 11 }

-- Naming attributes of type X520OrganizationalUnitName:
--   X520OrganizationalUnitName ::=
--          DirectoryName (SIZE (1..ub-organizational-unit-name))
--
-- Expanded to avoid parameterized type:
X520OrganizationalUnitName ::= CHOICE {
      teletexString     TeletexString
                          (SIZE (1..ub-organizational-unit-name)),
      printableString   PrintableString
                          (SIZE (1..ub-organizational-unit-name)),
      universalString   UniversalString
                          (SIZE (1..ub-organizational-unit-name)),
      utf8String        UTF8String
                          (SIZE (1..ub-organizational-unit-name)),
      bmpString         BMPString
                          (SIZE (1..ub-organizational-unit-name)) }

-- Naming attributes of type X520Title

id-at-title             AttributeType ::= { id-at 12 }

-- Naming attributes of type X520Title:
--   X520Title ::= DirectoryName (SIZE (1..ub-title))
--
-- Expanded to avoid parameterized type:
X520Title ::= CHOICE {
      teletexString     TeletexString   (SIZE (1..ub-title)),
      printableString   PrintableString (SIZE (1..ub-title)),
      universalString   UniversalString (SIZE (1..ub-title)),
      utf8String        UTF8String      (SIZE (1..ub-title)),
      bmpString         BMPString       (SIZE (1..ub-title)) }

-- Naming attributes of type X520dnQualifier

id-at-dnQualifier       AttributeType ::= { id-at 46 }

X520dnQualifier ::=     PrintableString

-- Naming attributes of type X520countryName (digraph from IS 3166)

id-at-countryName       AttributeType ::= { id-at 6 }

X520countryName ::=     PrintableString (SIZE (2))

-- Naming attributes of type X520SerialNumber

id-at-serialNumber      AttributeType ::= { id-at 5 }

X520SerialNumber ::=    PrintableString (SIZE (1..ub-serial-number))

-- Naming attributes of type X520Pseudonym

id-at-pseudonym         AttributeType ::= { id-at 65 }

-- Naming attributes of type X520Pseudonym:
--   X520Pseudonym ::= DirectoryName (SIZE (1..ub-pseudonym))
--
-- Expanded to avoid parameterized type:
X520Pseudonym ::= CHOICE {
   teletexString     TeletexString   (SIZE (1..ub-pseudonym)),
   printableString   PrintableString (SIZE (1..ub-pseudonym)),
   universalString   UniversalString (SIZE (1..ub-pseudonym)),
   utf8String        UTF8String      (SIZE (1..ub-pseudonym)),
   bmpString         BMPString       (SIZE (1..ub-pseudonym)) }

-- Naming attributes of type DomainComponent (from RFC 4519)

id-domainComponent   AttributeType ::= { 0 9 2342 19200300 100 1 25 }

DomainComponent ::=  IA5String

-- Legacy attributes

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

id-emailAddress      AttributeType ::= { pkcs-9 1 }

EmailAddress ::=     IA5String (SIZE (1..ub-emailaddress-length))

-- naming data types --

Name ::= CHOICE { -- only one possibility for now --
      rdnSequence  RDNSequence }

RDNSequence ::= SEQUENCE OF RelativeDistinguishedName

DistinguishedName ::=   RDNSequence

RelativeDistinguishedName ::= SET SIZE (1..MAX) OF AttributeTypeAndValue

-- Directory string type --

DirectoryString ::= CHOICE {
      teletexString       TeletexString   (SIZE (1..MAX)),
      printableString     PrintableString (SIZE (1..MAX)),
      universalString     UniversalString (SIZE (1..MAX)),
      utf8String          UTF8String      (SIZE (1..MAX)),
      bmpString           BMPString       (SIZE (1..MAX)) }

-- certificate and CRL specific structures begin here

Certificate  ::=  SEQUENCE  {
     tbsCertificate       TBSCertificate,
     signatureAlgorithm   AlgorithmIdentifier,
     signature            BIT STRING  }

TBSCertificate  ::=  SEQUENCE  {
     version         [0]  Version DEFAULT v1,
     serialNumber         CertificateSerialNumber,
     signature            AlgorithmIdentifier,
     issuer               Name,
     validity             Validity,
     subject              Name,
     subjectPublicKeyInfo SubjectPublicKeyInfo,
     issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
                          -- If present, version MUST be v2 or v3
     subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
                          -- If present, version MUST be v2 or v3
     extensions      [3]  Extensions OPTIONAL
                          -- If present, version MUST be v3 --  }

Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }

CertificateSerialNumber  ::=  INTEGER

Validity ::= SEQUENCE {
     notBefore      Time,
     notAfter       Time  }

Time ::= CHOICE {
     utcTime        UTCTime,
     generalTime    GeneralizedTime }

UniqueIdentifier  ::=  BIT STRING

SubjectPublicKeyInfo  ::=  SEQUENCE  {
     algorithm            AlgorithmIdentifier,
     subjectPublicKey     BIT STRING  }

Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension

Extension  ::=  SEQUENCE  {
     extnID      OBJECT IDENTIFIER,
     critical    BOOLEAN DEFAULT FALSE,
     extnValue   OCTET STRING
                 -- contains the DER encoding of an ASN.1 value
                 -- corresponding to the extension type identified
                 -- by extnID
     }

-- CRL structures

CertificateList  ::=  SEQUENCE  {
     tbsCertList          TBSCertList,
     signatureAlgorithm   AlgorithmIdentifier,
     signature            BIT STRING  }

TBSCertList  ::=  SEQUENCE  {
     version                 Version OPTIONAL,
                                   -- if present, MUST be v2
     signature               AlgorithmIdentifier,
     issuer                  Name,
     thisUpdate              Time,
     nextUpdate              Time OPTIONAL,
     revokedCertificates     SEQUENCE OF SEQUENCE  {
          userCertificate         CertificateSerialNumber,
          revocationDate          Time,
          crlEntryExtensions      Extensions OPTIONAL
                                   -- if present, version MUST be v2
                               }  OPTIONAL,
     crlExtensions           [0] Extensions OPTIONAL }
                                   -- if present, version MUST be v2

-- Version, Time, CertificateSerialNumber, and Extensions were
-- defined earlier for use in the certificate structure

AlgorithmIdentifier  ::=  SEQUENCE  {
     algorithm               OBJECT IDENTIFIER,
     parameters              ANY DEFINED BY algorithm OPTIONAL  }
                                -- contains a value of the type
                                -- registered for use with the
                                -- algorithm object identifier value

-- X.400 address syntax starts here

ORAddress ::= SEQUENCE {
   built-in-standard-attributes BuiltInStandardAttributes,
   built-in-domain-defined-attributes
                   BuiltInDomainDefinedAttributes OPTIONAL,
   -- see also teletex-domain-defined-attributes
   extension-attributes ExtensionAttributes OPTIONAL }

-- Built-in Standard Attributes

BuiltInStandardAttributes ::= SEQUENCE {
   country-name                  CountryName OPTIONAL,
   administration-domain-name    AdministrationDomainName OPTIONAL,
   network-address           [0] IMPLICIT NetworkAddress OPTIONAL,
     -- see also extended-network-address
   terminal-identifier       [1] IMPLICIT TerminalIdentifier OPTIONAL,
   private-domain-name       [2] PrivateDomainName OPTIONAL,
   organization-name         [3] IMPLICIT OrganizationName OPTIONAL,
     -- see also teletex-organization-name
   numeric-user-identifier   [4] IMPLICIT NumericUserIdentifier
                                 OPTIONAL,
   personal-name             [5] IMPLICIT PersonalName OPTIONAL,
     -- see also teletex-personal-name
   organizational-unit-names [6] IMPLICIT OrganizationalUnitNames
                                 OPTIONAL }
     -- see also teletex-organizational-unit-names
CountryName ::= [APPLICATION 1] CHOICE {
   x121-dcc-code         NumericString
                           (SIZE (ub-country-name-numeric-length)),
   iso-3166-alpha2-code  PrintableString
                           (SIZE (ub-country-name-alpha-length)) }

AdministrationDomainName ::= [APPLICATION 2] CHOICE {
   numeric   NumericString   (SIZE (0..ub-domain-name-length)),
   printable PrintableString (SIZE (0..ub-domain-name-length)) }

NetworkAddress ::= X121Address  -- see also extended-network-address

X121Address ::= NumericString (SIZE (1..ub-x121-address-length))

TerminalIdentifier ::= PrintableString (SIZE (1..ub-terminal-id-length))

PrivateDomainName ::= CHOICE {
   numeric   NumericString   (SIZE (1..ub-domain-name-length)),
   printable PrintableString (SIZE (1..ub-domain-name-length)) }

OrganizationName ::= PrintableString
                            (SIZE (1..ub-organization-name-length))
  -- see also teletex-organization-name

NumericUserIdentifier ::= NumericString
                            (SIZE (1..ub-numeric-user-id-length))

PersonalName ::= SET {
   surname     [0] IMPLICIT PrintableString
                    (SIZE (1..ub-surname-length)),
   given-name  [1] IMPLICIT PrintableString
                    (SIZE (1..ub-given-name-length)) OPTIONAL,
   initials    [2] IMPLICIT PrintableString
                    (SIZE (1..ub-initials-length)) OPTIONAL,
   generation-qualifier [3] IMPLICIT PrintableString
                    (SIZE (1..ub-generation-qualifier-length))
                    OPTIONAL }
  -- see also teletex-personal-name

OrganizationalUnitNames ::= SEQUENCE SIZE (1..ub-organizational-units)
                             OF OrganizationalUnitName
  -- see also teletex-organizational-unit-names

OrganizationalUnitName ::= PrintableString (SIZE
                    (1..ub-organizational-unit-name-length))

-- Built-in Domain-defined Attributes

BuiltInDomainDefinedAttributes ::= SEQUENCE SIZE
                    (1..ub-domain-defined-attributes) OF
                    BuiltInDomainDefinedAttribute

BuiltInDomainDefinedAttribute ::= SEQUENCE {
   type PrintableString (SIZE
                   (1..ub-domain-defined-attribute-type-length)),
   value PrintableString (SIZE
                   (1..ub-domain-defined-attribute-value-length)) }

-- Extension Attributes

ExtensionAttributes ::= SET SIZE (1..ub-extension-attributes) OF
               ExtensionAttribute

ExtensionAttribute ::=  SEQUENCE {
   extension-attribute-type [0] IMPLICIT INTEGER
                   (0..ub-extension-attributes),
   extension-attribute-value [1]
                   ANY DEFINED BY extension-attribute-type }

-- Extension types and attribute values

common-name INTEGER ::= 1

CommonName ::= PrintableString (SIZE (1..ub-common-name-length))
teletex-common-name INTEGER ::= 2

TeletexCommonName ::= TeletexString (SIZE (1..ub-common-name-length))

teletex-organization-name INTEGER ::= 3

TeletexOrganizationName ::=
                TeletexString (SIZE (1..ub-organization-name-length))

teletex-personal-name INTEGER ::= 4

TeletexPersonalName ::= SET {
   surname     [0] IMPLICIT TeletexString
                    (SIZE (1..ub-surname-length)),
   given-name  [1] IMPLICIT TeletexString
                    (SIZE (1..ub-given-name-length)) OPTIONAL,
   initials    [2] IMPLICIT TeletexString
                    (SIZE (1..ub-initials-length)) OPTIONAL,
   generation-qualifier [3] IMPLICIT TeletexString
                    (SIZE (1..ub-generation-qualifier-length))
                    OPTIONAL }

teletex-organizational-unit-names INTEGER ::= 5

TeletexOrganizationalUnitNames ::= SEQUENCE SIZE
      (1..ub-organizational-units) OF TeletexOrganizationalUnitName

TeletexOrganizationalUnitName ::= TeletexString
                  (SIZE (1..ub-organizational-unit-name-length))

pds-name INTEGER ::= 7

PDSName ::= PrintableString (SIZE (1..ub-pds-name-length))

physical-delivery-country-name INTEGER ::= 8

PhysicalDeliveryCountryName ::= CHOICE {
   x121-dcc-code NumericString (SIZE (ub-country-name-numeric-length)),
   iso-3166-alpha2-code PrintableString
                               (SIZE (ub-country-name-alpha-length)) }

postal-code INTEGER ::= 9

PostalCode ::= CHOICE {
   numeric-code   NumericString (SIZE (1..ub-postal-code-length)),
   printable-code PrintableString (SIZE (1..ub-postal-code-length)) }

physical-delivery-office-name INTEGER ::= 10
PhysicalDeliveryOfficeName ::= PDSParameter

physical-delivery-office-number INTEGER ::= 11

PhysicalDeliveryOfficeNumber ::= PDSParameter

extension-OR-address-components INTEGER ::= 12

ExtensionORAddressComponents ::= PDSParameter

physical-delivery-personal-name INTEGER ::= 13

PhysicalDeliveryPersonalName ::= PDSParameter

physical-delivery-organization-name INTEGER ::= 14

PhysicalDeliveryOrganizationName ::= PDSParameter

extension-physical-delivery-address-components INTEGER ::= 15

ExtensionPhysicalDeliveryAddressComponents ::= PDSParameter

unformatted-postal-address INTEGER ::= 16

UnformattedPostalAddress ::= SET {
   printable-address SEQUENCE SIZE (1..ub-pds-physical-address-lines)
        OF PrintableString (SIZE (1..ub-pds-parameter-length)) OPTIONAL,
   teletex-string TeletexString
        (SIZE (1..ub-unformatted-address-length)) OPTIONAL }

street-address INTEGER ::= 17

StreetAddress ::= PDSParameter

post-office-box-address INTEGER ::= 18

PostOfficeBoxAddress ::= PDSParameter

poste-restante-address INTEGER ::= 19

PosteRestanteAddress ::= PDSParameter

unique-postal-name INTEGER ::= 20

UniquePostalName ::= PDSParameter

local-postal-attributes INTEGER ::= 21
LocalPostalAttributes ::= PDSParameter

PDSParameter ::= SET {
   printable-string PrintableString
                (SIZE(1..ub-pds-parameter-length)) OPTIONAL,
   teletex-string TeletexString
                (SIZE(1..ub-pds-parameter-length)) OPTIONAL }

extended-network-address INTEGER ::= 22

ExtendedNetworkAddress ::= CHOICE {
   e163-4-address SEQUENCE {
      number      [0] IMPLICIT NumericString
                       (SIZE (1..ub-e163-4-number-length)),
      sub-address [1] IMPLICIT NumericString
                       (SIZE (1..ub-e163-4-sub-address-length))
                       OPTIONAL },
   psap-address   [0] IMPLICIT PresentationAddress }

PresentationAddress ::= SEQUENCE {
    pSelector     [0] EXPLICIT OCTET STRING OPTIONAL,
    sSelector     [1] EXPLICIT OCTET STRING OPTIONAL,
    tSelector     [2] EXPLICIT OCTET STRING OPTIONAL,
    nAddresses    [3] EXPLICIT SET SIZE (1..MAX) OF OCTET STRING }

terminal-type  INTEGER ::= 23

TerminalType ::= INTEGER {
   telex        (3),
   teletex      (4),
   g3-facsimile (5),
   g4-facsimile (6),
   ia5-terminal (7),
   videotex     (8) } (0..ub-integer-options)

-- Extension Domain-defined Attributes

teletex-domain-defined-attributes INTEGER ::= 6

TeletexDomainDefinedAttributes ::= SEQUENCE SIZE
   (1..ub-domain-defined-attributes) OF TeletexDomainDefinedAttribute

TeletexDomainDefinedAttribute ::= SEQUENCE {
        type TeletexString
               (SIZE (1..ub-domain-defined-attribute-type-length)),
        value TeletexString
               (SIZE (1..ub-domain-defined-attribute-value-length)) }

--  specifications of Upper Bounds MUST be regarded as mandatory
--  from Annex B of ITU-T X.411 Reference Definition of MTS Parameter
--  Upper Bounds

-- Upper Bounds
ub-name INTEGER ::= 32768
ub-common-name INTEGER ::= 64
ub-locality-name INTEGER ::= 128
ub-state-name INTEGER ::= 128
ub-organization-name INTEGER ::= 64
ub-organizational-unit-name INTEGER ::= 64
ub-title INTEGER ::= 64
ub-serial-number INTEGER ::= 64
ub-match INTEGER ::= 128
ub-emailaddress-length INTEGER ::= 255
ub-common-name-length INTEGER ::= 64
ub-country-name-alpha-length INTEGER ::= 2
ub-country-name-numeric-length INTEGER ::= 3
ub-domain-defined-attributes INTEGER ::= 4
ub-domain-defined-attribute-type-length INTEGER ::= 8
ub-domain-defined-attribute-value-length INTEGER ::= 128
ub-domain-name-length INTEGER ::= 16
ub-extension-attributes INTEGER ::= 256
ub-e163-4-number-length INTEGER ::= 15
ub-e163-4-sub-address-length INTEGER ::= 40
ub-generation-qualifier-length INTEGER ::= 3
ub-given-name-length INTEGER ::= 16
ub-initials-length INTEGER ::= 5
ub-integer-options INTEGER ::= 256
ub-numeric-user-id-length INTEGER ::= 32
ub-organization-name-length INTEGER ::= 64
ub-organizational-unit-name-length INTEGER ::= 32
ub-organizational-units INTEGER ::= 4
ub-pds-name-length INTEGER ::= 16
ub-pds-parameter-length INTEGER ::= 30
ub-pds-physical-address-lines INTEGER ::= 6
ub-postal-code-length INTEGER ::= 16
ub-pseudonym INTEGER ::= 128
ub-surname-length INTEGER ::= 40
ub-terminal-id-length INTEGER ::= 24
ub-unformatted-address-length INTEGER ::= 180
ub-x121-address-length INTEGER ::= 16

-- Note - upper bounds on string types, such as TeletexString, are
-- measured in characters.  Excepting PrintableString or IA5String, a
-- significantly greater number of octets will be required to hold
-- such a value.  As a minimum, 16 octets, or twice the specified
-- upper bound, whichever is the larger, should be allowed for
-- TeletexString.  For UTF8String or UniversalString at least four
-- times the upper bound should be allowed.

END

okay the vibe shifts here, we're officially in the implicit tags era ๐Ÿงšโœจ

A.2. Implicitly Tagged Module, 1988 Syntax ๐ŸŽ€

PKIX1Implicit88 { iso(1) identified-organization(3) dod(6) internet(1)
  security(5) mechanisms(5) pkix(7) id-mod(0) id-pkix1-implicit(19) }

DEFINITIONS IMPLICIT TAGS ::=

BEGIN

-- EXPORTS ALL --

IMPORTS
      id-pe, id-kp, id-qt-unotice, id-qt-cps,
      -- delete following line if "new" types are supported --
      BMPString, UTF8String,  -- end "new" types --
      ORAddress, Name, RelativeDistinguishedName,
      CertificateSerialNumber, Attribute, DirectoryString
      FROM PKIX1Explicit88 { iso(1) identified-organization(3)
            dod(6) internet(1) security(5) mechanisms(5) pkix(7)
            id-mod(0) id-pkix1-explicit(18) };

-- ISO arc for standard certificate and CRL extensions

id-ce OBJECT IDENTIFIER  ::=  {joint-iso-ccitt(2) ds(5) 29}

-- authority key identifier OID and syntax

id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::=  { id-ce 35 }

AuthorityKeyIdentifier ::= SEQUENCE {
    keyIdentifier             [0] KeyIdentifier            OPTIONAL,
    authorityCertIssuer       [1] GeneralNames             OPTIONAL,
    authorityCertSerialNumber [2] CertificateSerialNumber  OPTIONAL }
    -- authorityCertIssuer and authorityCertSerialNumber MUST both
    -- be present or both be absent

KeyIdentifier ::= OCTET STRING
-- subject key identifier OID and syntax

id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::=  { id-ce 14 }

SubjectKeyIdentifier ::= KeyIdentifier

-- key usage extension OID and syntax

id-ce-keyUsage OBJECT IDENTIFIER ::=  { id-ce 15 }

KeyUsage ::= BIT STRING {
     digitalSignature        (0),
     nonRepudiation          (1),  -- recent editions of X.509 have
                                -- renamed this bit to contentCommitment
     keyEncipherment         (2),
     dataEncipherment        (3),
     keyAgreement            (4),
     keyCertSign             (5),
     cRLSign                 (6),
     encipherOnly            (7),
     decipherOnly            (8) }

-- private key usage period extension OID and syntax

id-ce-privateKeyUsagePeriod OBJECT IDENTIFIER ::=  { id-ce 16 }

PrivateKeyUsagePeriod ::= SEQUENCE {
     notBefore       [0]     GeneralizedTime OPTIONAL,
     notAfter        [1]     GeneralizedTime OPTIONAL }
     -- either notBefore or notAfter MUST be present

-- certificate policies extension OID and syntax

id-ce-certificatePolicies OBJECT IDENTIFIER ::=  { id-ce 32 }

anyPolicy OBJECT IDENTIFIER ::= { id-ce-certificatePolicies 0 }

CertificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation

PolicyInformation ::= SEQUENCE {
     policyIdentifier   CertPolicyId,
     policyQualifiers   SEQUENCE SIZE (1..MAX) OF
             PolicyQualifierInfo OPTIONAL }

CertPolicyId ::= OBJECT IDENTIFIER

okay so we're still deep in the ASN.1 module, bestie ๐Ÿ’… policy qualifiers are the extra little sticky notes that ride along with a policy ๐ŸŽ€ each one is a pair: an ID, then whatever the qualifier is, and the ID decides what that payload looks like ๐Ÿงš

PolicyQualifierInfo ::= SEQUENCE {
     policyQualifierId  PolicyQualifierId,
     qualifier          ANY DEFINED BY policyQualifierId }

-- Implementations that recognize additional policy qualifiers MUST
-- augment the following definition for PolicyQualifierId

PolicyQualifierId ::= OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice )

-- CPS pointer qualifier

CPSuri ::= IA5String

-- user notice qualifier

UserNotice ::= SEQUENCE {
     noticeRef        NoticeReference OPTIONAL,
     explicitText     DisplayText OPTIONAL }

NoticeReference ::= SEQUENCE {
     organization     DisplayText,
     noticeNumbers    SEQUENCE OF INTEGER }

DisplayText ::= CHOICE {
     ia5String        IA5String      (SIZE (1..200)),
     visibleString    VisibleString  (SIZE (1..200)),
     bmpString        BMPString      (SIZE (1..200)),
     utf8String       UTF8String     (SIZE (1..200)) }

ngl the DisplayText part is so cute, it's a CHOICE of four string types, each capped at 200 ๐ŸŒธ pick your fave and go ๐Ÿ’–


okay now the policy mapping extension, which gets its own OID and shape ๐Ÿฆ‹

-- policy mapping extension OID and syntax

id-ce-policyMappings OBJECT IDENTIFIER ::=  { id-ce 33 }

PolicyMappings ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE {
     issuerDomainPolicy      CertPolicyId,
     subjectDomainPolicy     CertPolicyId }

-- subject alternative name extension OID and syntax

id-ce-subjectAltName OBJECT IDENTIFIER ::=  { id-ce 17 }

SubjectAltName ::= GeneralNames

GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
GeneralName ::= CHOICE {
     otherName                 [0]  AnotherName,
     rfc822Name                [1]  IA5String,
     dNSName                   [2]  IA5String,
     x400Address               [3]  ORAddress,
     directoryName             [4]  Name,
     ediPartyName              [5]  EDIPartyName,
     uniformResourceIdentifier [6]  IA5String,
     iPAddress                 [7]  OCTET STRING,
     registeredID              [8]  OBJECT IDENTIFIER }

-- AnotherName replaces OTHER-NAME ::= TYPE-IDENTIFIER, as
-- TYPE-IDENTIFIER is not supported in the '88 ASN.1 syntax

AnotherName ::= SEQUENCE {
     type-id    OBJECT IDENTIFIER,
     value      [0] EXPLICIT ANY DEFINED BY type-id }

EDIPartyName ::= SEQUENCE {
     nameAssigner              [0]  DirectoryString OPTIONAL,
     partyName                 [1]  DirectoryString }

-- issuer alternative name extension OID and syntax

id-ce-issuerAltName OBJECT IDENTIFIER ::=  { id-ce 18 }

IssuerAltName ::= GeneralNames

id-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::=  { id-ce 9 }

SubjectDirectoryAttributes ::= SEQUENCE SIZE (1..MAX) OF Attribute

-- basic constraints extension OID and syntax

id-ce-basicConstraints OBJECT IDENTIFIER ::=  { id-ce 19 }

BasicConstraints ::= SEQUENCE {
     cA                      BOOLEAN DEFAULT FALSE,
     pathLenConstraint       INTEGER (0..MAX) OPTIONAL }

-- name constraints extension OID and syntax

id-ce-nameConstraints OBJECT IDENTIFIER ::=  { id-ce 30 }

NameConstraints ::= SEQUENCE {
     permittedSubtrees       [0]     GeneralSubtrees OPTIONAL,
     excludedSubtrees        [1]     GeneralSubtrees OPTIONAL }

GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree

GeneralSubtree ::= SEQUENCE {
     base                    GeneralName,
     minimum         [0]     BaseDistance DEFAULT 0,
     maximum         [1]     BaseDistance OPTIONAL }

BaseDistance ::= INTEGER (0..MAX)

-- policy constraints extension OID and syntax

id-ce-policyConstraints OBJECT IDENTIFIER ::=  { id-ce 36 }

PolicyConstraints ::= SEQUENCE {
     requireExplicitPolicy   [0]     SkipCerts OPTIONAL,
     inhibitPolicyMapping    [1]     SkipCerts OPTIONAL }

SkipCerts ::= INTEGER (0..MAX)

-- CRL distribution points extension OID and syntax

id-ce-cRLDistributionPoints     OBJECT IDENTIFIER  ::=  {id-ce 31}

CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint

DistributionPoint ::= SEQUENCE {
     distributionPoint       [0]     DistributionPointName OPTIONAL,
     reasons                 [1]     ReasonFlags OPTIONAL,
     cRLIssuer               [2]     GeneralNames OPTIONAL }

DistributionPointName ::= CHOICE {
     fullName                [0]     GeneralNames,
     nameRelativeToCRLIssuer [1]     RelativeDistinguishedName }

ReasonFlags ::= BIT STRING {
     unused                  (0),
     keyCompromise           (1),
     cACompromise            (2),
     affiliationChanged      (3),
     superseded              (4),
     cessationOfOperation    (5),
     certificateHold         (6),
     privilegeWithdrawn      (7),
     aACompromise            (8) }

-- extended key usage extension OID and syntax

id-ce-extKeyUsage OBJECT IDENTIFIER ::= {id-ce 37}

ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId

KeyPurposeId ::= OBJECT IDENTIFIER

-- permit unspecified key uses

anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 }

-- extended key purpose OIDs

id-kp-serverAuth             OBJECT IDENTIFIER ::= { id-kp 1 }
id-kp-clientAuth             OBJECT IDENTIFIER ::= { id-kp 2 }
id-kp-codeSigning            OBJECT IDENTIFIER ::= { id-kp 3 }
id-kp-emailProtection        OBJECT IDENTIFIER ::= { id-kp 4 }
id-kp-timeStamping           OBJECT IDENTIFIER ::= { id-kp 8 }
id-kp-OCSPSigning            OBJECT IDENTIFIER ::= { id-kp 9 }

-- inhibit any policy OID and syntax

id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::=  { id-ce 54 }

InhibitAnyPolicy ::= SkipCerts

-- freshest (delta)CRL extension OID and syntax

id-ce-freshestCRL OBJECT IDENTIFIER ::=  { id-ce 46 }

FreshestCRL ::= CRLDistributionPoints
-- authority info access

id-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pe 1 }

AuthorityInfoAccessSyntax  ::=
        SEQUENCE SIZE (1..MAX) OF AccessDescription

AccessDescription  ::=  SEQUENCE {
        accessMethod          OBJECT IDENTIFIER,
        accessLocation        GeneralName  }

-- subject info access

id-pe-subjectInfoAccess OBJECT IDENTIFIER ::= { id-pe 11 }

SubjectInfoAccessSyntax  ::=
        SEQUENCE SIZE (1..MAX) OF AccessDescription

-- CRL number extension OID and syntax

id-ce-cRLNumber OBJECT IDENTIFIER ::= { id-ce 20 }

CRLNumber ::= INTEGER (0..MAX)

-- issuing distribution point extension OID and syntax

id-ce-issuingDistributionPoint OBJECT IDENTIFIER ::= { id-ce 28 }

IssuingDistributionPoint ::= SEQUENCE {
     distributionPoint          [0] DistributionPointName OPTIONAL,
     onlyContainsUserCerts      [1] BOOLEAN DEFAULT FALSE,
     onlyContainsCACerts        [2] BOOLEAN DEFAULT FALSE,
     onlySomeReasons            [3] ReasonFlags OPTIONAL,
     indirectCRL                [4] BOOLEAN DEFAULT FALSE,
     onlyContainsAttributeCerts [5] BOOLEAN DEFAULT FALSE }
     -- at most one of onlyContainsUserCerts, onlyContainsCACerts,
     -- and onlyContainsAttributeCerts may be set to TRUE.

id-ce-deltaCRLIndicator OBJECT IDENTIFIER ::= { id-ce 27 }

BaseCRLNumber ::= CRLNumber
-- reason code extension OID and syntax

id-ce-cRLReasons OBJECT IDENTIFIER ::= { id-ce 21 }

CRLReason ::= ENUMERATED {
     unspecified             (0),
     keyCompromise           (1),
     cACompromise            (2),
     affiliationChanged      (3),
     superseded              (4),
     cessationOfOperation    (5),
     certificateHold         (6),
     removeFromCRL           (8),
     privilegeWithdrawn      (9),
     aACompromise           (10) }

-- certificate issuer CRL entry extension OID and syntax

id-ce-certificateIssuer OBJECT IDENTIFIER ::= { id-ce 29 }

CertificateIssuer ::= GeneralNames

-- hold instruction extension OID and syntax

id-ce-holdInstructionCode OBJECT IDENTIFIER ::= { id-ce 23 }

HoldInstructionCode ::= OBJECT IDENTIFIER

-- ANSI x9 arc holdinstruction arc

holdInstruction OBJECT IDENTIFIER ::=
          {joint-iso-itu-t(2) member-body(2) us(840) x9cm(10040) 2}

-- ANSI X9 holdinstructions

id-holdinstruction-none OBJECT IDENTIFIER  ::=
                                      {holdInstruction 1} -- deprecated

id-holdinstruction-callissuer OBJECT IDENTIFIER ::= {holdInstruction 2}

id-holdinstruction-reject OBJECT IDENTIFIER ::= {holdInstruction 3}
-- invalidity date CRL entry extension OID and syntax

id-ce-invalidityDate OBJECT IDENTIFIER ::= { id-ce 24 }

InvalidityDate ::=  GeneralizedTime

END

Appendix B. ASN.1 Notes โœจ

okay bestie, the ASN.1 notes are where the real drama is ๐Ÿ’… first up, CAs MUST force the serialNumber to be a non-negative integer. That means the sign bit in the DER encoding of the INTEGER value MUST be zero ๐Ÿ” If it isn't, you can fix it by adding a leading (leftmost) 00'H octet, and that clears up a potential ambiguity when you map a string of octets to an integer value ๐Ÿงฉ

As noted in Section 4.1.2.2, serial numbers can be expected to contain long integers ๐Ÿ“œ so certificate users MUST be able to handle serialNumber values up to 20 octets in length. Conforming CAs MUST NOT use serialNumber values longer than 20 octets ๐Ÿ™…

As noted in Section 5.2.3, CRL numbers can be expected to be long too ๐Ÿ”ข so CRL validators MUST be able to handle cRLNumber values up to 20 octets in length. Conforming CRL issuers MUST NOT use cRLNumber values longer than 20 octets ๐Ÿ™…

The construct SEQUENCE SIZE (1..MAX) OF shows up in a bunch of ASN.1 constructs ๐ŸŒˆ a valid ASN.1 sequence can have zero or more entries, but the SIZE (1..MAX) construct makes it have at least one entry. MAX just means the upper bound is unspecified, and implementations are free to pick an upper bound that suits their environment ๐Ÿงš

The character string type PrintableString is pretty basic ๐Ÿ“ it supports the lowercase letters a through z, uppercase letters A through Z, the digits 0 through 9, and eleven special characters: ' = ( ) + , - . / : ? and space.

Implementers should note that the at sign (@) and underscore (_) characters are NOT supported by PrintableString, and these characters show up a LOT in internet addresses ๐Ÿ™ˆ Such addresses MUST be encoded using an ASN.1 type that supports them. They're usually encoded as IA5String in either the emailAddress attribute within a distinguished name or the rfc822Name field of GeneralName. Conforming implementations MUST NOT encode strings that include either the at sign or underscore character as PrintableString ๐Ÿšซ

The character string type TeletexString is a superset of PrintableString ๐Ÿ’œ It supports a fairly standard, ASCII-like Latin character set: Latin characters with non-spacing accents and Japanese characters ๐ŸŽ€

Named bit lists are BIT STRINGs where the values have been given names โœจ This specification uses named bit lists for the key usage, CRL distribution points, and freshest CRL certificate extensions, plus the freshest CRL and issuing distribution point CRL extensions. When DER encoding a named bit list, trailing zeros MUST be omitted. In other words, the encoded value ends with the last named bit that is set to one ๐Ÿฆ‹

The character string type UniversalString supports any of the characters allowed by [ISO10646]. ISO 10646 is the Universal multiple-octet coded Character Set (UCS) ๐ŸŒ

The character string type UTF8String came in with the 1997 version of ASN.1, and it was added to the list of choices for DirectoryString in the 2001 version of [X.520] ๐Ÿซถ It's a universal type and has been assigned tag number 12. Its content was defined by RFC 2044 and updated in RFC 2279, which was updated in [RFC3629] ๐ŸŒธ

In anticipation of these changes, and in conformance with IETF Best Practices codified in [RFC2277], IETF Policy on Character Sets and Languages, this document includes UTF8String as a choice in DirectoryString and in the userNotice certificate policy qualifier ๐Ÿ’–

For many of the attribute types defined in [X.520], the AttributeValue uses the DirectoryString type ๐Ÿ’… Of the attributes specified in Appendix A, the name, surname, givenName, initials, generationQualifier, commonName, localityName, stateOrProvinceName, organizationName, organizationalUnitName, title, and pseudonym attributes all use the DirectoryString type. X.520 uses a parameterized type definition [X.683] of DirectoryString to specify the syntax for each of these attributes, and the parameter is used to indicate the maximum string length allowed for the attribute ๐Ÿ“

Here's the tea: in Appendix A, to avoid parameterized type definitions, the DirectoryString type is written in its expanded form for each of these attribute types ๐Ÿต So the ASN.1 in Appendix A describes the syntax as a CHOICE of TeletexString, PrintableString, UniversalString, UTF8String, and BMPString, with the appropriate string length constraints applied to each type in the CHOICE, rather than using the ASN.1 type DirectoryString itself ๐Ÿง

Implementers should note that the DER encoding of the SET OF values requires ordering of the encodings of the values. This issue comes up especially with distinguished names ๐Ÿ—‚๏ธ

Implementers should note that the DER encoding of SET or SEQUENCE components whose value is the DEFAULT omits the component from the encoded certificate or CRL ๐Ÿ™ˆ For example, a BasicConstraints extension whose cA value is FALSE would leave the cA boolean out of the encoded certificate ๐Ÿ‘€

Object Identifiers (OIDs) are used all over this specification to identify certificate policies, public key and signature algorithms, certificate extensions, and so on ๐Ÿ”‘ There is no maximum size for OIDs. This specification mandates support for OIDs that have arc element values less than 2^28. That means they MUST be between 0 and 268,435,455, inclusive, which lets each arc element fit in a single 32-bit word ๐Ÿ’œ Implementations MUST also support OIDs where the length of the dotted decimal (see Section 1.4 of [RFC4512]) string representation can be up to 100 bytes (inclusive). Implementations MUST be able to handle OIDs with up to 20 elements (inclusive) ๐Ÿง  CAs SHOULD NOT issue certificates that contain OIDs that exceed these requirements. Likewise, CRL issuers SHOULD NOT issue CRLs that contain OIDs that exceed these requirements โš ๏ธ

The content-specific rules for encoding GeneralName field values in the nameConstraints extension are DIFFERENT from the rules in other extensions ๐Ÿ˜ญ In all other certificate, CRL, and CRL entry extensions specified in this document, the encoding rules conform to the rules for the underlying type. For example, values in the uniformResourceIdentifier field must contain a valid URI as specified in [RFC3986]. The content-specific rules for encoding values in the nameConstraints extension are specified in Section 4.2.1.10, and these rules may not conform to the rules for the underlying type. For example, when the uniformResourceIdentifier field appears in a nameConstraints extension, it must hold a DNS name (e.g., "host.example.com" or ".example.com") rather than a URI.

Implementors are warned that the X.500 standards community has developed a series of extensibility rules ๐Ÿšจ These rules determine when an ASN.1 definition can be changed without assigning a new Object Identifier (OID). For example, at least two extension definitions included in [RFC2459], the predecessor to this profile document, have different ASN.1 definitions in this specification, but the same OID is used. If unknown elements appear within an extension, and the extension is not marked as critical, those unknown elements ought to be ignored, as follows:

  • (a) ignore all unknown bit name assignments within a bit string;
  • (b) ignore all unknown named numbers in an ENUMERATED type or INTEGER type that is being used in the enumerated style, provided the number occurs as an optional element of a SET or SEQUENCE; and
  • (c) ignore all unknown elements in SETs, at the end of SEQUENCEs, or in CHOICEs where the CHOICE is itself an optional element of a SET or SEQUENCE.

If an extension containing unexpected values is marked as critical, the implementation MUST reject the certificate or CRL containing the unrecognized extension ๐Ÿ›‘


Appendix C. Examples ๐ŸŽฌ

This appendix contains four examples: three certificates and a CRL ๐ŸŽ€ The first two certificates and the CRL make up a minimal certification path โœจ

Appendix C.1 contains an annotated hex dump of a "self-signed" certificate issued by a CA whose distinguished name is cn=Example CA,dc=example,dc=com. The certificate contains an RSA public key, and it's signed by the corresponding RSA private key ๐Ÿ”

Appendix C.2 contains an annotated hex dump of an end entity certificate. The end entity certificate contains an RSA public key, and it's signed by the private key that corresponds to the "self-signed" certificate in Appendix C.1 ๐Ÿซถ

Appendix C.3 contains an annotated hex dump of an end entity certificate that contains a DSA public key with parameters, and it's signed with DSA and SHA-1. This certificate is NOT part of the minimal certification path ๐Ÿ™…

Appendix C.4 contains an annotated hex dump of a CRL ๐Ÿ“œ The CRL is issued by the CA whose distinguished name is cn=Example CA,dc=example,dc=com, and the list of revoked certificates includes the end entity certificate presented in Appendix C.2 ๐Ÿ’€

The certificates were processed using Peter Gutmann's dumpasn1 utility to generate the output ๐Ÿงš The source for the dumpasn1 utility is available at <http://www.cs.auckland.ac.nz/~pgut001/dumpasn1.c>. The binaries for the certificates and CRLs are available at http://csrc.nist.gov/groups/ST/crypto_apps_infra/documents/pkixtools ๐ŸŒธ

In places in this appendix where a distinguished name is specified using a string representation, the strings are formatted using the rules specified in [RFC4514] ๐Ÿ’œ

C.1. RSA Self-Signed Certificate ๐ŸŽ€

Okay bestie, this one is a real-deal annotated hex dump of a 578 byte version 3 certificate ๐Ÿ’– Here's what it's giving:

  • (a) the serial number is 17;
  • (b) the certificate is signed with RSA and the SHA-1 hash algorithm;
  • (c) the issuer's distinguished name is cn=Example CA,dc=example,dc=com;
  • (d) the subject's distinguished name is cn=Example CA,dc=example,dc=com;
  • (e) the certificate was issued on April 30, 2004 and expired on April 30, 2005;
  • (f) the certificate contains a 1024-bit RSA public key;
  • (g) the certificate contains a subject key identifier extension generated using method (1) of Section 4.2.1.2; and
  • (h) the certificate is a CA certificate (as indicated through the basic constraints extension).
   0  574: SEQUENCE {
   4  423:   SEQUENCE {
   8    3:     [0] {
  10    1:       INTEGER 2
         :       }
  13    1:     INTEGER 17
  16   13:     SEQUENCE {
  18    9:       OBJECT IDENTIFIER
         :         sha1withRSAEncryption (1 2 840 113549 1 1 5)
  29    0:       NULL
         :       }
  31   67:     SEQUENCE {
  33   19:       SET {
  35   17:         SEQUENCE {
  37   10:           OBJECT IDENTIFIER
         :             domainComponent (0 9 2342 19200300 100 1 25)
  49    3:           IA5String 'com'
         :           }
         :         }
  54   23:       SET {
  56   21:         SEQUENCE {
  58   10:           OBJECT IDENTIFIER
         :             domainComponent (0 9 2342 19200300 100 1 25)
  70    7:           IA5String 'example'
         :           }
         :         }
  79   19:       SET {
  81   17:         SEQUENCE {
  83    3:           OBJECT IDENTIFIER commonName (2 5 4 3)
  88   10:           PrintableString 'Example CA'
         :           }
         :         }
         :       }
 100   30:     SEQUENCE {
 102   13:       UTCTime 30/04/2004 14:25:34 GMT
 117   13:       UTCTime 30/04/2005 14:25:34 GMT
         :       }
 132   67:     SEQUENCE {
 134   19:       SET {
 136   17:         SEQUENCE {
 138   10:           OBJECT IDENTIFIER
         :             domainComponent (0 9 2342 19200300 100 1 25)
 150    3:           IA5String 'com'
         :           }
         :         }
 155   23:       SET {
 157   21:         SEQUENCE {
 159   10:           OBJECT IDENTIFIER
         :             domainComponent (0 9 2342 19200300 100 1 25)
 171    7:           IA5String 'example'
         :           }
         :         }
 180   19:       SET {
 182   17:         SEQUENCE {
 184    3:           OBJECT IDENTIFIER commonName (2 5 4 3)
 189   10:           PrintableString 'Example CA'
         :           }
         :         }
         :       }
 201  159:     SEQUENCE {
 204   13:       SEQUENCE {
 206    9:         OBJECT IDENTIFIER
         :           rsaEncryption (1 2 840 113549 1 1 1)
 217    0:         NULL
         :         }
 219  141:       BIT STRING, encapsulates {
 223  137:         SEQUENCE {
 226  129:           INTEGER
         :             00 C2 D7 97 6D 28 70 AA 5B CF 23 2E 80 70 39 EE
         :             DB 6F D5 2D D5 6A 4F 7A 34 2D F9 22 72 47 70 1D
         :             EF 80 E9 CA 30 8C 00 C4 9A 6E 5B 45 B4 6E A5 E6
         :             6C 94 0D FA 91 E9 40 FC 25 9D C7 B7 68 19 56 8F
         :             11 70 6A D7 F1 C9 11 4F 3A 7E 3F 99 8D 6E 76 A5
         :             74 5F 5E A4 55 53 E5 C7 68 36 53 C7 1D 3B 12 A6
         :             85 FE BD 6E A1 CA DF 35 50 AC 08 D7 B9 B4 7E 5C
         :             FE E2 A3 2C D1 23 84 AA 98 C0 9B 66 18 9A 68 47
         :             E9
 358    3:           INTEGER 65537
         :           }
         :         }
         :       }
 363   66:     [3] {
 365   64:       SEQUENCE {
 367   29:         SEQUENCE {
 369    3:           OBJECT IDENTIFIER subjectKeyIdentifier (2 5 29 14)
 374   22:           OCTET STRING, encapsulates {
 376   20:             OCTET STRING
         :               08 68 AF 85 33 C8 39 4A 7A F8 82 93 8E 70 6A 4A
         :               20 84 2C 32
         :             }
         :           }
 398   14:         SEQUENCE {
 400    3:           OBJECT IDENTIFIER keyUsage (2 5 29 15)
 405    1:           BOOLEAN TRUE
 408    4:           OCTET STRING, encapsulates {
 410    2:             BIT STRING 1 unused bits
         :               '0000011'B
         :             }
         :           }
 414   15:         SEQUENCE {
 416    3:           OBJECT IDENTIFIER basicConstraints (2 5 29 19)
 421    1:           BOOLEAN TRUE
 424    5:           OCTET STRING, encapsulates {
 426    3:             SEQUENCE {
 428    1:               BOOLEAN TRUE
         :               }
         :             }
         :           }
         :         }
         :       }
         :     }
 431   13:   SEQUENCE {
 433    9:     OBJECT IDENTIFIER
         :         sha1withRSAEncryption (1 2 840 113549 1 1 5)
 444    0:     NULL
         :     }
 446  129:   BIT STRING
         :     6C F8 02 74 A6 61 E2 64 04 A6 54 0C 6C 72 13 AD
         :     3C 47 FB F6 65 13 A9 85 90 33 EA 76 A3 26 D9 FC
         :     D1 0E 15 5F 28 B7 EF 93 BF 3C F3 E2 3E 7C B9 52
         :     FC 16 6E 29 AA E1 F4 7A 6F D5 7F EF B3 95 CA F3
         :     66 88 83 4E A1 35 45 84 CB BC 9B B8 C8 AD C5 5E
         :     46 D9 0B 0E 8D 80 E1 33 2B DC BE 2B 92 7E 4A 43
         :     A9 6A EF 8A 63 61 B3 6E 47 38 BE E8 0D A3 67 5D
         :     F3 FA 91 81 3C 92 BB C5 5F 25 25 EB 7C E7 D8 A1
         :   }

C.2. End Entity Certificate Using RSA ๐Ÿ’…

Next up, an annotated hex dump of a 629-byte version 3 certificate, and this one is the end entity cert ๐Ÿฆ‹ Here's the lowdown:

  • (a) the serial number is 18;
  • (b) the certificate is signed with RSA and the SHA-1 hash algorithm;
  • (c) the issuer's distinguished name is cn=Example CA,dc=example,dc=com;
  • (d) the subject's distinguished name is cn=End Entity,dc=example,dc=com;
  • (e) the certificate was valid from September 15, 2004 through March 15, 2005;
  • (f) the certificate contains a 1024-bit RSA public key;
  • (g) the certificate is an end entity certificate, as the basic constraints extension is not present;
  • (h) the certificate contains an authority key identifier extension matching the subject key identifier of the certificate in appendix C.1; and
  • (i) the certificate includes one alternative name -- an electronic mail address (rfc822Name) of "end.entity@example.com".
   0  625: SEQUENCE {
   4  474:   SEQUENCE {
   8    3:     [0] {
  10    1:       INTEGER 2
         :       }
  13    1:     INTEGER 18
  16   13:     SEQUENCE {
  18    9:       OBJECT IDENTIFIER
         :         sha1withRSAEncryption (1 2 840 113549 1 1 5)
  29    0:       NULL
         :       }
  31   67:     SEQUENCE {
  33   19:       SET {
  35   17:         SEQUENCE {
  37   10:           OBJECT IDENTIFIER
         :             domainComponent (0 9 2342 19200300 100 1 25)
  49    3:           IA5String 'com'
         :           }
         :         }
  54   23:       SET {
  56   21:         SEQUENCE {
  58   10:           OBJECT IDENTIFIER
         :             domainComponent (0 9 2342 19200300 100 1 25)
  70    7:           IA5String 'example'
         :           }
         :         }
  79   19:       SET {
  81   17:         SEQUENCE {
  83    3:           OBJECT IDENTIFIER commonName (2 5 4 3)
  88   10:           PrintableString 'Example CA'
         :           }
         :         }
         :       }
 100   30:     SEQUENCE {
 102   13:       UTCTime 15/09/2004 11:48:21 GMT
 117   13:       UTCTime 15/03/2005 11:48:21 GMT
         :       }
 132   67:     SEQUENCE {
 134   19:       SET {
 136   17:         SEQUENCE {
 138   10:           OBJECT IDENTIFIER
         :             domainComponent (0 9 2342 19200300 100 1 25)
 150    3:           IA5String 'com'
         :           }
         :         }
 155   23:       SET {
 157   21:         SEQUENCE {
 159   10:           OBJECT IDENTIFIER
         :             domainComponent (0 9 2342 19200300 100 1 25)
 171    7:           IA5String 'example'
         :           }
         :         }
 180   19:       SET {
 182   17:         SEQUENCE {
 184    3:           OBJECT IDENTIFIER commonName (2 5 4 3)
 189   10:           PrintableString 'End Entity'
         :           }
         :         }
         :       }
 201  159:     SEQUENCE {
 204   13:       SEQUENCE {
 206    9:         OBJECT IDENTIFIER
         :           rsaEncryption (1 2 840 113549 1 1 1)
 217    0:         NULL
         :         }
 219  141:       BIT STRING, encapsulates {
 223  137:         SEQUENCE {
 226  129:           INTEGER

         :             00 E1 6A E4 03 30 97 02 3C F4 10 F3 B5 1E 4D 7F
         :             14 7B F6 F5 D0 78 E9 A4 8A F0 A3 75 EC ED B6 56
         :             96 7F 88 99 85 9A F2 3E 68 77 87 EB 9E D1 9F C0
         :             B4 17 DC AB 89 23 A4 1D 7E 16 23 4C 4F A8 4D F5
         :             31 B8 7C AA E3 1A 49 09 F4 4B 26 DB 27 67 30 82
         :             12 01 4A E9 1A B6 C1 0C 53 8B 6C FC 2F 7A 43 EC
         :             33 36 7E 32 B2 7B D5 AA CF 01 14 C6 12 EC 13 F2
         :             2D 14 7A 8B 21 58 14 13 4C 46 A3 9A F2 16 95 FF
         :             23
 358    3:           INTEGER 65537
         :           }
         :         }
         :       }
 363  117:     [3] {
 365  115:       SEQUENCE {
 367   33:         SEQUENCE {
 369    3:           OBJECT IDENTIFIER subjectAltName (2 5 29 17)
 374   26:           OCTET STRING, encapsulates {
 376   24:             SEQUENCE {
 378   22:               [1] 'end.entity@example.com'
         :               }
         :             }
         :           }
 402   29:         SEQUENCE {
 404    3:           OBJECT IDENTIFIER subjectKeyIdentifier (2 5 29 14)
 409   22:           OCTET STRING, encapsulates {
 411   20:             OCTET STRING
         :               17 7B 92 30 FF 44 D6 66 E1 90 10 22 6C 16 4F C0
         :               8E 41 DD 6D
         :             }
         :           }
 433   31:         SEQUENCE {
 435    3:           OBJECT IDENTIFIER
         :             authorityKeyIdentifier (2 5 29 35)
 440   24:           OCTET STRING, encapsulates {
 442   22:             SEQUENCE {
 444   20:               [0]
         :                 08 68 AF 85 33 C8 39 4A 7A F8 82 93 8E 70 6A
         :                 4A 20 84 2C 32
         :               }
         :             }
         :           }
 466   14:         SEQUENCE {
 468    3:           OBJECT IDENTIFIER keyUsage (2 5 29 15)
 473    1:           BOOLEAN TRUE
 476    4:           OCTET STRING, encapsulates {
 478    2:             BIT STRING 6 unused bits
         :               '11'B
         :             }
         :           }
         :         }
         :       }
         :     }
 482   13:   SEQUENCE {
 484    9:     OBJECT IDENTIFIER
         :         sha1withRSAEncryption (1 2 840 113549 1 1 5)
 495    0:     NULL
         :     }
 497  129:   BIT STRING
         :     00 20 28 34 5B 68 32 01 BB 0A 36 0E AD 71 C5 95
         :     1A E1 04 CF AE AD C7 62 14 A4 1B 36 31 C0 E2 0C
         :     3D D9 1E C0 00 DC 10 A0 BA 85 6F 41 CB 62 7A B7
         :     4C 63 81 26 5E D2 80 45 5E 33 E7 70 45 3B 39 3B
         :     26 4A 9C 3B F2 26 36 69 08 79 BB FB 96 43 77 4B
         :     61 8B A1 AB 91 64 E0 F3 37 61 3C 1A A3 A4 C9 8A
         :     B2 BF 73 D4 4D E4 58 E4 62 EA BC 20 74 92 86 0E
         :     CE 84 60 76 E9 73 BB C7 85 D3 91 45 EA 62 5D CD
         :   }

C.3. End Entity Certificate Using DSA ๐Ÿฆ‹

okay bestie, this appendix is an annotated hex dump of a 914-byte version 3 certificate, and it's giving full detective energy ๐Ÿ”โœจ here's what's inside:

  • (a) the serial number is 256;
  • (b) the certificate is signed with DSA and the SHA-1 hash algorithm;
  • (c) the issuer's distinguished name is cn=Example DSA CA,dc=example,dc=com;
  • (d) the subject's distinguished name is cn=DSA End Entity,dc=example,dc=com;
  • (e) the certificate was issued on May 2, 2004 and expired on May 2, 2005;
  • (f) the certificate contains a 1024-bit DSA public key with parameters;
  • (g) the certificate is an end entity certificate (not a CA certificate);
  • (h) the certificate includes a subject alternative name of "http://www.example.com/users/DSAendentity.html" and an issuer alternative name of "http://www.example.com" -- both are URLs;
  • (i) the certificate includes an authority key identifier extension and a certificate policies extension specifying the policy OID 2.16.840.1.101.3.2.1.48.9; and
  • (j) the certificate includes a critical key usage extension specifying that the public key is intended for verification of digital signatures.

Here's the full dump, so you can see every byte doing its little job ๐Ÿ’…๐ŸŽ€

   0  910: SEQUENCE {
   4  846:   SEQUENCE {
   8    3:     [0] {
  10    1:       INTEGER 2
         :       }
  13    2:     INTEGER 256
  17    9:     SEQUENCE {
  19    7:       OBJECT IDENTIFIER dsaWithSha1 (1 2 840 10040 4 3)
         :       }
  28   71:     SEQUENCE {
  30   19:       SET {
  32   17:         SEQUENCE {
  34   10:           OBJECT IDENTIFIER
         :             domainComponent (0 9 2342 19200300 100 1 25)
  46    3:           IA5String 'com'
         :           }
         :         }
  51   23:       SET {
  53   21:         SEQUENCE {
  55   10:           OBJECT IDENTIFIER
         :             domainComponent (0 9 2342 19200300 100 1 25)
  67    7:           IA5String 'example'
         :           }
         :         }
  76   23:       SET {
  78   21:         SEQUENCE {
  80    3:           OBJECT IDENTIFIER commonName (2 5 4 3)
  85   14:           PrintableString 'Example DSA CA'
         :           }
         :         }
         :       }
 101   30:     SEQUENCE {
 103   13:       UTCTime 02/05/2004 16:47:38 GMT
 118   13:       UTCTime 02/05/2005 16:47:38 GMT
         :       }
 133   71:     SEQUENCE {
 135   19:       SET {
 137   17:         SEQUENCE {
 139   10:           OBJECT IDENTIFIER
         :             domainComponent (0 9 2342 19200300 100 1 25)

 151    3:           IA5String 'com'
         :           }
         :         }
 156   23:       SET {
 158   21:         SEQUENCE {
 160   10:           OBJECT IDENTIFIER
         :             domainComponent (0 9 2342 19200300 100 1 25)
 172    7:           IA5String 'example'
         :           }
         :         }
 181   23:       SET {
 183   21:         SEQUENCE {
 185    3:           OBJECT IDENTIFIER commonName (2 5 4 3)
 190   14:           PrintableString 'DSA End Entity'
         :           }
         :         }
         :       }
 206  439:     SEQUENCE {
 210  300:       SEQUENCE {
 214    7:         OBJECT IDENTIFIER dsa (1 2 840 10040 4 1)
 223  287:         SEQUENCE {
 227  129:           INTEGER
         :             00 B6 8B 0F 94 2B 9A CE A5 25 C6 F2 ED FC FB 95
         :             32 AC 01 12 33 B9 E0 1C AD 90 9B BC 48 54 9E F3
         :             94 77 3C 2C 71 35 55 E6 FE 4F 22 CB D5 D8 3E 89
         :             93 33 4D FC BD 4F 41 64 3E A2 98 70 EC 31 B4 50
         :             DE EB F1 98 28 0A C9 3E 44 B3 FD 22 97 96 83 D0
         :             18 A3 E3 BD 35 5B FF EE A3 21 72 6A 7B 96 DA B9
         :             3F 1E 5A 90 AF 24 D6 20 F0 0D 21 A7 D4 02 B9 1A
         :             FC AC 21 FB 9E 94 9E 4B 42 45 9E 6A B2 48 63 FE
         :             43
 359   21:           INTEGER
         :             00 B2 0D B0 B1 01 DF 0C 66 24 FC 13 92 BA 55 F7
         :             7D 57 74 81 E5
 382  129:           INTEGER
         :             00 9A BF 46 B1 F5 3F 44 3D C9 A5 65 FB 91 C0 8E
         :             47 F1 0A C3 01 47 C2 44 42 36 A9 92 81 DE 57 C5
         :             E0 68 86 58 00 7B 1F F9 9B 77 A1 C5 10 A5 80 91
         :             78 51 51 3C F6 FC FC CC 46 C6 81 78 92 84 3D F4
         :             93 3D 0C 38 7E 1A 5B 99 4E AB 14 64 F6 0C 21 22
         :             4E 28 08 9C 92 B9 66 9F 40 E8 95 F6 D5 31 2A EF
         :             39 A2 62 C7 B2 6D 9E 58 C4 3A A8 11 81 84 6D AF
         :             F8 B4 19 B4 C2 11 AE D0 22 3B AA 20 7F EE 1E 57
         :             18
         :           }
         :         }
 514  132:       BIT STRING, encapsulates {
 518  128:         INTEGER

         :           30 B6 75 F7 7C 20 31 AE 38 BB 7E 0D 2B AB A0 9C
         :           4B DF 20 D5 24 13 3C CD 98 E5 5F 6C B7 C1 BA 4A
         :           BA A9 95 80 53 F0 0D 72 DC 33 37 F4 01 0B F5 04
         :           1F 9D 2E 1F 62 D8 84 3A 9B 25 09 5A 2D C8 46 8E
         :           2B D4 F5 0D 3B C7 2D C6 6C B9 98 C1 25 3A 44 4E
         :           8E CA 95 61 35 7C CE 15 31 5C 23 13 1E A2 05 D1
         :           7A 24 1C CB D3 72 09 90 FF 9B 9D 28 C0 A1 0A EC
         :           46 9F 0D B8 D0 DC D0 18 A6 2B 5E F9 8F B5 95 BE
         :         }
         :       }
 649  202:     [3] {
 652  199:       SEQUENCE {
 655   57:         SEQUENCE {
 657    3:           OBJECT IDENTIFIER subjectAltName (2 5 29 17)
 662   50:           OCTET STRING, encapsulates {
 664   48:             SEQUENCE {
 666   46:               [6]
         :                 'http://www.example.com/users/DSAendentity.'
         :                 'html'
         :               }
         :             }
         :           }
 714   33:         SEQUENCE {
 716    3:           OBJECT IDENTIFIER issuerAltName (2 5 29 18)
 721   26:           OCTET STRING, encapsulates {
 723   24:             SEQUENCE {
 725   22:               [6] 'http://www.example.com'
         :               }
         :             }
         :           }
 749   29:         SEQUENCE {
 751    3:           OBJECT IDENTIFIER subjectKeyIdentifier (2 5 29 14)
 756   22:           OCTET STRING, encapsulates {
 758   20:             OCTET STRING
         :               DD 25 66 96 43 AB 78 11 43 44 FE 95 16 F9 D9 B6
         :               B7 02 66 8D
         :             }
         :           }
 780   31:         SEQUENCE {
 782    3:           OBJECT IDENTIFIER
         :             authorityKeyIdentifier (2 5 29 35)
 787   24:           OCTET STRING, encapsulates {
 789   22:             SEQUENCE {
 791   20:               [0]
         :                 86 CA A5 22 81 62 EF AD 0A 89 BC AD 72 41 2C
         :                 29 49 F4 86 56
         :               }
         :             }
         :           }
 813   23:         SEQUENCE {
 815    3:           OBJECT IDENTIFIER certificatePolicies (2 5 29 32)
 820   16:           OCTET STRING, encapsulates {
 822   14:             SEQUENCE {
 824   12:               SEQUENCE {
 826   10:                 OBJECT IDENTIFIER '2 16 840 1 101 3 2 1 48 9'
         :                 }
         :               }
         :             }
         :           }
 838   14:         SEQUENCE {
 840    3:           OBJECT IDENTIFIER keyUsage (2 5 29 15)
 845    1:           BOOLEAN TRUE
 848    4:           OCTET STRING, encapsulates {
 850    2:             BIT STRING 7 unused bits
         :               '1'B (bit 0)
         :             }
         :           }
         :         }
         :       }
         :     }
 854    9:   SEQUENCE {
 856    7:     OBJECT IDENTIFIER dsaWithSha1 (1 2 840 10040 4 3)
         :     }
 865   47:   BIT STRING, encapsulates {
 868   44:     SEQUENCE {
 870   20:       INTEGER
         :         65 57 07 34 DD DC CA CC 5E F4 02 F4 56 42 2C 5E
         :         E1 B3 3B 80
 892   20:       INTEGER
         :         60 F4 31 17 CA F4 CF FF EE F4 08 A7 D9 B2 61 BE
         :         B1 C3 DA BF
         :       }
         :     }
         :   }

C.4. Certificate Revocation List ๐ŸŒธ

this one is an annotated hex dump of a version 2 CRL, and it's got two extensions, cRLNumber and authorityKeyIdentifier ๐Ÿงš the CRL was issued by cn=Example CA,dc=example,dc=com on February 5, 2005, and the next scheduled issuance was February 6, 2005. it includes one revoked certificate: serial number 18, which was revoked on November 19, 2004 due to keyCompromise ๐Ÿ’€ the CRL itself is number 12, and it was signed with RSA and SHA-1 ๐Ÿ”ฅ

   0  352: SEQUENCE {
   4  202:   SEQUENCE {
   7    1:     INTEGER 1
  10   13:     SEQUENCE {
  12    9:       OBJECT IDENTIFIER
         :         sha1withRSAEncryption (1 2 840 113549 1 1 5)
  23    0:       NULL
         :       }
  25   67:     SEQUENCE {
  27   19:       SET {
  29   17:         SEQUENCE {
  31   10:           OBJECT IDENTIFIER
         :             domainComponent (0 9 2342 19200300 100 1 25)
  43    3:           IA5String 'com'
         :           }
         :         }
  48   23:       SET {
  50   21:         SEQUENCE {
  52   10:           OBJECT IDENTIFIER
         :             domainComponent (0 9 2342 19200300 100 1 25)
  64    7:           IA5String 'example'
         :           }
         :         }
  73   19:       SET {
  75   17:         SEQUENCE {
  77    3:           OBJECT IDENTIFIER commonName (2 5 4 3)
  82   10:           PrintableString 'Example CA'
         :           }
         :         }
         :       }
  94   13:     UTCTime 05/02/2005 12:00:00 GMT
 109   13:     UTCTime 06/02/2005 12:00:00 GMT
 124   34:     SEQUENCE {
 126   32:       SEQUENCE {
 128    1:         INTEGER 18
 131   13:         UTCTime 19/11/2004 15:57:03 GMT
 146   12:         SEQUENCE {
 148   10:           SEQUENCE {
 150    3:             OBJECT IDENTIFIER cRLReason (2 5 29 21)
 155    3:             OCTET STRING, encapsulates {
 157    1:               ENUMERATED 1
         :               }
         :             }
         :           }
         :         }
         :       }
 160   47:     [0] {
 162   45:       SEQUENCE {
 164   31:         SEQUENCE {
 166    3:           OBJECT IDENTIFIER
         :             authorityKeyIdentifier (2 5 29 35)
 171   24:           OCTET STRING, encapsulates {
 173   22:             SEQUENCE {
 175   20:               [0]
         :                 08 68 AF 85 33 C8 39 4A 7A F8 82 93 8E 70 6A
         :                 4A 20 84 2C 32
         :               }
         :             }
         :           }
 197   10:         SEQUENCE {
 199    3:           OBJECT IDENTIFIER cRLNumber (2 5 29 20)
 204    3:           OCTET STRING, encapsulates {
 206    1:             INTEGER 12
         :             }
         :           }
         :         }
         :       }
         :     }
 209   13:   SEQUENCE {
 211    9:     OBJECT IDENTIFIER
         :         sha1withRSAEncryption (1 2 840 113549 1 1 5)
 222    0:     NULL
         :     }
 224  129:   BIT STRING
         :     22 DC 18 7D F7 08 CE CC 75 D0 D0 6A 9B AD 10 F4
         :     76 23 B4 81 6E B5 6D BE 0E FB 15 14 6C C8 17 6D
         :     1F EE 90 17 A2 6F 60 E4 BD AA 8C 55 DE 8E 84 6F
         :     92 F8 9F 10 12 27 AF 4A D4 2F 85 E2 36 44 7D AA
         :     A3 4C 25 38 15 FF 00 FD 3E 7E EE 3D 26 12 EB D8
         :     E7 2B 62 E2 2B C3 46 80 EF 78 82 D1 15 C6 D0 9C
         :     72 6A CB CE 7A ED 67 99 8B 6E 70 81 7D 43 42 74
         :     C1 A6 AF C1 55 17 A2 33 4C D6 06 98 2B A4 FC 2E
         :   }

Authors' Addresses ๐Ÿ’–

okay bestie, these are the six people who wrote this ๐Ÿซถ the names and addresses are below exactly as they appear in the original:

David Cooper
National Institute of Standards and Technology
100 Bureau Drive, Mail Stop 8930
Gaithersburg, MD 20899-8930
USA
EMail: david.cooper@nist.gov

Stefan Santesson
Microsoft
One Microsoft Way
Redmond, WA 98052
USA
EMail: stefans@microsoft.com

Stephen Farrell
Distributed Systems Group
Computer Science Department
Trinity College Dublin
Ireland
EMail: stephen.farrell@cs.tcd.ie

Sharon Boeyen
Entrust
1000 Innovation Drive
Ottawa, Ontario
Canada K2K 3E7
EMail: sharon.boeyen@entrust.com

Russell Housley
Vigil Security, LLC
918 Spring Knoll Drive
Herndon, VA 20170
USA
EMail: housley@vigilsec.com

Tim Polk
National Institute of Standards and Technology
100 Bureau Drive, Mail Stop 8930
Gaithersburg, MD 20899-8930
USA
EMail: wpolk@nist.gov

the copyright is held by the IETF Trust, and the year is Copyright (C) The IETF Trust (2008) ๐Ÿ’…

this document is covered by the rights, licenses and restrictions in BCP 78. outside of what BCP 78 says, the authors keep all of their rights โœจ

the document and everything in it is handed over "AS IS" ๐Ÿซ  the contributor, the organization they represent or are sponsored by (if there is one), the Internet Society, the IETF Trust and the Internet Engineering Task Force all turn down every warranty, whether it's stated or implied. that includes no promise that using the information here won't infringe anyone's rights, and no implied warranty of merchantability or fitness for a particular purpose. it's a bit of a plot twist, but it's the legal fine print ๐Ÿ’€

Intellectual Property ๐Ÿฆ‹

the IETF doesn't take a side on whether any intellectual property or other rights someone might claim over this technology are valid or how far they reach ๐Ÿง it also doesn't say it has searched for any of those rights. if you want the details on how rights work for RFC documents, check out BCP 78 and BCP 79 ๐Ÿ“š

people can look at IPR disclosures that were sent to the IETF Secretariat, and at any promises of licenses. they can also see what happens when someone tries to get a general license or permission to use proprietary rights for this spec. all of that lives in the IETF online IPR repository at http://www.ietf.org/ipr ๐ŸŒธ

the IETF also wants to hear from anyone who knows about copyrights, patents, patent applications or other proprietary rights that might cover tech needed to implement this standard. just send that info to ietf-ipr@ietf.org ๐Ÿซถ

๐Ÿ“ฆ where this page comes from