RFC 4210

Internet X.509 Public Key Infrastructure Certificate Management Protocol (CMP)

๐Ÿ“… published September 2005, from ietf

RFC 4210: Internet X.509 Public Key Infrastructure Certificate Management Protocol (CMP) ๐ŸŽ€

okay bestie, this is RFC 4210 ๐Ÿฆ‹ It's a Standards Track doc from the Network Working Group, published in September 2005. The authors are C. Adams (University of Ottawa), S. Farrell (Trinity College Dublin), T. Kause (SSH), and T. Mononen (SafeNet) ๐Ÿซถ It obsoletes RFC 2510, so that one is officially retired and this is the new main character ๐Ÿ‘‘

Status of This Memo โœจ

so this is an Internet standards track protocol for the whole Internet community ๐ŸŒธ It's literally asking for discussion and suggestions for improvements ๐Ÿ’ฌ If you want the current standardization state and status, check the current edition of "Internet Official Protocol Standards" (STD 1) ๐Ÿ’œ And distribution of this memo is unlimited, so share away ๐Ÿงš

Copyright (C) The Internet Society (2005). Legal stuff isn't my fave, but a clean notice is still iconic ๐Ÿ’…

Abstract ๐Ÿ“

the vibe here: this doc describes the Internet X.509 Public Key Infrastructure (PKI) Certificate Management Protocol (CMP) ๐Ÿ”ฅ It defines protocol messages for creating and managing X.509v3 certificates ๐Ÿฆ‹ CMP gives PKI components on-line interactions, including an exchange between a Certification Authority (CA) and a client system โœจ ngl that's giving main character energy ๐Ÿ’–

Table of Contents ๐Ÿ“‹

   1. Introduction ....................................................5
   2. Requirements ....................................................5
   3. PKI Management Overview .........................................5
      3.1. PKI Management Model .......................................6
           3.1.1. Definitions of PKI Entities .........................6
                  3.1.1.1. Subjects and End Entities ..................6
                  3.1.1.2. Certification Authority ....................7
                  3.1.1.3. Registration Authority .....................7
           3.1.2. PKI Management Requirements .........................8
           3.1.3. PKI Management Operations ..........................10
   4. Assumptions and Restrictions ...................................14
      4.1. End Entity Initialization .................................14
      4.2. Initial Registration/Certification ........................14
           4.2.1. Criteria Used ......................................15
                  4.2.1.1. Initiation of Registration/Certification ..15
                  4.2.1.2. End Entity Message Origin Authentication ..15
                  4.2.1.3. Location of Key Generation ................15
                  4.2.1.4. Confirmation of Successful Certification ..16
           4.2.2. Mandatory Schemes ..................................16
                  4.2.2.1. Centralized Scheme ........................16
                  4.2.2.2. Basic Authenticated Scheme ................17
      4.3. Proof-of-Possession (POP) of Private Key ..................17
           4.3.1. Signature Keys .....................................18
           4.3.2. Encryption Keys ....................................18
           4.3.3. Key Agreement Keys .................................19
      4.4. Root CA Key Update ........................................19
           4.4.1. CA Operator Actions ................................20
           4.4.2. Verifying Certificates .............................21
                  4.4.2.1. Verification in Cases 1, 4, 5, and 8 ......22
                  4.4.2.2. Verification in Case 2 ....................22
                  4.4.2.3. Verification in Case 3 ....................23
                  4.4.2.4. Failure of Verification in Case 6 .........23
                  4.4.2.5. Failure of Verification in Case 7 .........23
           4.4.3. Revocation - Change of CA Key ......................23
   5. Data Structures ................................................24
      5.1. Overall PKI Message .......................................24
           5.1.1. PKI Message Header .................................24
                  5.1.1.1. ImplicitConfirm ...........................27
                  5.1.1.2. ConfirmWaitTime ...........................27
           5.1.2. PKI Message Body ...................................27
           5.1.3. PKI Message Protection .............................28
                  5.1.3.1. Shared Secret Information .................29
                  5.1.3.2. DH Key Pairs ..............................30
                  5.1.3.3. Signature .................................30
                  5.1.3.4. Multiple Protection .......................30
      5.2. Common Data Structures ....................................31
           5.2.1. Requested Certificate Contents .....................31
           5.2.2. Encrypted Values ...................................31
           5.2.3. Status codes and Failure Information for
                  PKI Messages .......................................32
           5.2.4. Certificate Identification .........................33
           5.2.5. Out-of-band root CA Public Key .....................33
           5.2.6. Archive Options ....................................34
           5.2.7. Publication Information ............................34
           5.2.8. Proof-of-Possession Structures .....................34
                  5.2.8.1. Inclusion of the Private Key ..............35
                  5.2.8.2. Indirect Method ...........................35
                  5.2.8.3. Challenge-Response Protocol ...............35
                  5.2.8.4. Summary of PoP Options ....................37

      5.3. Operation-Specific Data Structures ........................38
           5.3.1. Initialization Request .............................38
           5.3.2. Initialization Response ............................39
           5.3.3. Certification Request ..............................39
           5.3.4. Certification Response .............................39
           5.3.5. Key Update Request Content .........................40
           5.3.6. Key Update Response Content ........................41
           5.3.7. Key Recovery Request Content .......................41
           5.3.8. Key Recovery Response Content ......................41
           5.3.9. Revocation Request Content .........................41
           5.3.10. Revocation Response Content .......................42
           5.3.11. Cross Certification Request Content ...............42
           5.3.12. Cross Certification Response Content ..............42
           5.3.13. CA Key Update Announcement Content ................42
           5.3.14. Certificate Announcement ..........................43
           5.3.15. Revocation Announcement ...........................43
           5.3.16. CRL Announcement ..................................43
           5.3.17. PKI Confirmation Content ..........................43
           5.3.18. Certificate Confirmation Content ..................44
           5.3.19. PKI General Message Content .......................44
                  5.3.19.1. CA Protocol Encryption Certificate .......44
                  5.3.19.2. Signing Key Pair Types ...................45
                  5.3.19.3. Encryption/Key Agreement Key Pair Types ..45
                  5.3.19.4. Preferred Symmetric Algorithm ............45
                  5.3.19.5. Updated CA Key Pair ......................45
                  5.3.19.6. CRL ......................................46
                  5.3.19.7. Unsupported Object Identifiers ...........46
                  5.3.19.8. Key Pair Parameters ......................46
                  5.3.19.9. Revocation Passphrase ....................46
                  5.3.19.10. ImplicitConfirm .........................46
                  5.3.19.11. ConfirmWaitTime .........................47
                  5.3.19.12. Original PKIMessage .....................47
                  5.3.19.13. Supported Language Tags .................47
           5.3.20. PKI General Response Content ......................47
           5.3.21. Error Message Content .............................47
           5.3.22. Polling Request and Response ......................48
   6. Mandatory PKI Management Functions .............................51
      6.1. Root CA Initialization ....................................51
      6.2. Root CA Key Update ........................................51
      6.3. Subordinate CA Initialization .............................51
      6.4. CRL production ............................................52
      6.5. PKI Information Request ...................................52
      6.6. Cross Certification .......................................52
           6.6.1. One-Way Request-Response Scheme: ...................52
      6.7. End Entity Initialization .................................54
           6.7.1. Acquisition of PKI Information .....................54
           6.7.2. Out-of-Band Verification of Root-CA Key ............55
      6.8. Certificate Request .......................................55
      6.9. Key Update ................................................55
   7. Version Negotiation ............................................56
      7.1. Supporting RFC 2510 Implementations .......................56
           7.1.1. Clients Talking to RFC 2510 Servers ................56
           7.1.2. Servers Receiving Version cmp1999 PKIMessages ......57
   8. Security Considerations ........................................57
      8.1. Proof-Of-Possession with a Decryption Key .................57
      8.2. Proof-Of-Possession by Exposing the Private Key ...........57
      8.3. Attack Against Diffie-Hellman Key Exchange ................57
   9. IANA Considerations ............................................58
   Normative References ..............................................58
   Informative References ............................................59
   A. Reasons for the Presence of RAs ................................61
   B. The Use of Revocation Passphrase ...............................61
   C. Request Message Behavioral Clarifications ......................63
   D. PKI Management Message Profiles (REQUIRED) .....................65
      D.1. General Rules for Interpretation of These Profiles ........65
      D.2. Algorithm Use Profile .....................................66
      D.3. Proof-of-Possession Profile ...............................68
      D.4. Initial Registration/Certification (Basic
           Authenticated Scheme) .....................................68
      D.5. Certificate Request .......................................74
      D.6. Key Update Request ........................................75
   E. PKI Management Message Profiles (OPTIONAL) .....................75
      E.1. General Rules for Interpretation of These Profiles ........76
      E.2. Algorithm Use Profile .....................................76
      E.3. Self-Signed Certificates ..................................76
      E.4. Root CA Key Update ........................................77
      E.5. PKI Information Request/Response ..........................77
      E.6. Cross Certification Request/Response (1-way) ..............79
      E.7. In-Band Initialization Using External Identity
           Certificate  ..............................................82
   F. Compilable ASN.1 Definitions ...................................83
   G. Acknowledgements ...............................................93

1. Introduction โœจ

Okay so this doc is all about the Internet X.509 Public Key Infrastructure (PKI) Certificate Management Protocol (CMP) ๐ŸŽ€. It defines protocol messages for creating and managing certificates. When it says "certificate," it means an X.509v3 Certificate as defined in [X509] ๐Ÿ’–.

This spec obsoletes RFC 2510 ๐Ÿซถ, and here's the tea on what changed:

  • The PKI management message profile section got split into two appendices: the required profile and the optional profile. Some stuff that used to be mandatory got moved into the optional one ๐Ÿฆ‹
  • The message confirmation mechanism changed substantially ๐Ÿ”ฅ
  • A new polling mechanism shows up, and the old polling method at the CMP transport level is now deprecated ๐Ÿ’€
  • CMP transport issues now live in their own doc, [CMPtrans], so the Transports section got removed ๐Ÿงš
  • A new implicit confirmation method cuts down on how many protocol messages get swapped in a transaction โœจ
  • There are some less prominent protocol enhancements, plus better explanatory text on several issues ๐ŸŒธ

2. Requirements ๐ŸŽ€

Okay, the key words are the ones that set the rules, so here's how they're defined ๐Ÿ’…. The key words "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document (in uppercase, as shown) are to be interpreted as described in [RFC2119] ๐Ÿซถ.

3. PKI Management Overview ๐Ÿ’…

The PKI must be structured to match the kinds of people who have to run it ๐Ÿง . Giving admins unbounded choices doesn't just make the software more complicated, it also raises the odds that one subtle mistake by an admin or software developer turns into a much broader compromise ๐Ÿ’€. On the flip side, making admins wrestle with clunky mechanisms means they'll just... not use the PKI ๐Ÿ™ˆ.

Management protocols are REQUIRED to support on-line interactions between Public Key Infrastructure (PKI) components ๐Ÿ’œ. For example, a management protocol might run between a Certification Authority (CA) and a client system that has a key pair associated with it, or between two CAs that issue cross-certificates for each other ๐Ÿฆ‹.

3.1. PKI Management Model ๐Ÿฆ‹

Before we get into specific message formats and procedures, we first define the entities involved in PKI management and how they interact (in terms of the PKI management functions required) โœจ. Then we group those functions so they fit the different identifiable types of end entities ๐Ÿงš.

3.1.1. Definitions of PKI Entities ๐ŸŒˆ

The entities involved in PKI management include the end entity (aka the entity the certificate is issued to) and the certification authority (aka the entity that issues the certificate) ๐Ÿ’–. A registration authority MAY also be involved in PKI management ๐ŸŽ€.

3.1.1.1. Subjects and End Entities ๐Ÿซถ

The word "subject" here refers to the entity the certificate is issued to, which is usually named in the subject or subjectAltName field of a certificate ๐Ÿ’…. When we want to separate out the tools or software the subject uses (like a local certificate management module), we call that "subject equipment" ๐Ÿง . Generally we prefer "end entity" (EE) over "subject" so nobody mixes it up with the field name ๐Ÿ™ˆ.

Quick heads up, end entities aren't just humans clicking around in apps. They also include the apps themselves (for example, for IP security) ๐Ÿ”ฅ. This matters because application software is way more likely to know exactly which certificate extensions it needs than a human user is ๐Ÿค“. PKI management entities are end entities too, since they can be named in the subject or subjectAltName field of a certificate or cross-certificate ๐Ÿ’œ. When we need to talk about end entities that aren't PKI management entities, we use the term "end-entity" ๐Ÿฆ‹.

All end entities need secure local access to some information. At a minimum, that's their own name and private key, the name of a CA that is directly trusted by this entity, and that CA's public key (or a fingerprint of the public key where a self-certified version is available elsewhere) ๐Ÿ”. Implementations MAY use secure local storage for more than this minimum, like the end entity's own certificate or app-specific information โœจ. The form of that storage varies a lot, from plain files all the way to tamper-resistant cryptographic tokens ๐ŸŒธ. The info kept in this local, trusted storage is what we call the end entity's Personal Security Environment (PSE) ๐Ÿ‘‘.

PSE formats are out of scope here, since they're super dependent on the equipment, et cetera ๐Ÿ™„. But this doc does define a generic interchange format for PSEs: a certification response message MAY be used ๐ŸŽ€.

3.1.1.2. Certification Authority ๐ŸŒˆ

The certification authority (CA) may or may not be a real "third party" from the end entity's point of view ๐Ÿ‘€. Honestly, the CA is often part of the same organization as the end entities it supports ๐Ÿข.

Again, we use "CA" to mean the entity named in the issuer field of a certificate ๐Ÿ’…. When we need to separate out the software or hardware tools the CA uses, we call that "CA equipment" ๐Ÿง . The CA equipment often includes both an "off-line" component and an "on-line" component, with the CA private key only available to the "off-line" component ๐Ÿ”’. This is a matter for implementers, though it's also relevant as a policy issue ๐Ÿ’–.

We use "root CA" for a CA that an end entity directly trusts. That means getting the root CA's public key securely takes some out-of-band step(s) ๐Ÿซถ. This term doesn't mean a root CA is necessarily at the top of some hierarchy, just that it's trusted directly ๐ŸŒธ.

A "subordinate CA" is one that isn't a root CA for the end entity in question ๐Ÿฆ‹. Often a subordinate CA won't be a root CA for anybody, but this is not mandatory ๐ŸŒˆ.

3.1.1.3. Registration Authority ๐ŸŽ€

Plenty of environments also have a Registration Authority (RA) that's separate from the Certification Authority ๐Ÿ’œ. What an RA does varies from case to case, but it MAY include personal authentication, token distribution, revocation reporting, name assignment, key generation, archival of key pairs, et cetera โœจ.

This document treats the RA as an OPTIONAL component ๐Ÿงš. When there isn't one, the CA is assumed to be able to do the RA's functions, so the PKI management protocols look the same from the end entity's point of view ๐Ÿ‘‘. We still tell apart the RA and its tools (the "RA equipment") whenever it matters ๐Ÿ”ง.

An RA is itself an end entity ๐Ÿ’…. We assume all RAs are actually certified end entities, and that RAs have private keys they can use for signing ๐Ÿ”‘. How a particular CA equipment figures out which end entities are RAs is an implementation issue, since this document doesn't specify any special RA certification operation ๐Ÿ™ˆ. We don't mandate that the RA is certified by the CA it's currently working with, so one RA may work with more than one CA while only being certified once ๐ŸŒธ.

Last but not least, end entities sometimes talk directly to a CA even when an RA is around ๐Ÿ’–. For example, the subject might use its RA for initial registration and/or certification, but then talk straight to the CA to refresh its certificate ๐Ÿซถ.

3.1.2. PKI Management Requirements โœจ

okay so bestie, this is the checklist ๐Ÿ’… the protocols in here have to hit. PKI management must meet all of these, no skipping ๐Ÿซถ

  1. PKI management must conform to the ISO/IEC 9594-8/ITU-T X.509 standards ๐Ÿ“œ
  2. It must be possible to regularly update any key pair without affecting any other key pair ๐Ÿ”‘โœจ
  3. The use of confidentiality in PKI management protocols must be kept to a minimum, so it's easier to get accepted in environments where strong confidentiality might cause regulatory problems ๐Ÿ™ˆ
  4. PKI management protocols must allow the use of different industry-standard cryptographic algorithms, specifically including RSA, DSA, MD5, and SHA-1. This means any given CA, RA, or end entity may, in principle, use whichever algorithms suit it for its own key pair(s) ๐ŸŒˆ
  5. PKI management protocols must not preclude the generation of key pairs by the end-entity concerned, by an RA, or by a CA. Key generation may also happen elsewhere, but for PKI management purposes, we can treat key generation as happening wherever the key first shows up at an end entity, RA, or CA ๐Ÿงš
  6. PKI management protocols must support the publication of certificates by the end-entity concerned, by an RA, or by a CA. Different implementations and environments may pick any of the above approaches ๐ŸŽ€
  7. PKI management protocols must support the production of Certificate Revocation Lists (CRLs) by letting certified end entities request the revocation of certificates. This must be done in a way that does not make the denial-of-service attacks, which are possible, any easier ๐Ÿ›ก๏ธ
  8. PKI management protocols must be usable over a variety of "transport" mechanisms, specifically including mail, http, TCP/IP, and ftp ๐Ÿฆ‹
  9. Final authority for certificate creation rests with the CA ๐Ÿ‘‘ No RA or end-entity equipment can assume that a certificate issued by a CA will contain what was requested. A CA may alter certificate field values or may add, delete, or alter extensions according to its operating policy. So all PKI entities (end entities, RAs, and CAs) must be able to handle responses to certificate requests where the certificate actually issued is different from the one requested. For example, a CA may shorten the requested validity period ๐ŸŒธ Also, policy may say the CA must not publish or otherwise distribute the certificate until the requesting entity has reviewed and accepted the newly created certificate, typically through use of the certConf message ๐Ÿ’–
  10. A graceful, scheduled change-over from one non-compromised CA key pair to the next (CA key update) must be supported ๐Ÿ”„ If the CA key is compromised, though, re-initialization must be performed for all entities in that CA's domain ๐Ÿšจ An end entity whose PSE contains the new CA public key (following a CA key update) must also be able to verify certificates that can be verified using the old public key. End entities that directly trust the old CA key pair must also be able to verify certificates signed using the new CA private key. This is required for situations where the old CA public key is "hardwired" into the end entity's cryptographic equipment ๐Ÿ”ฅ
  11. The functions of an RA may, in some implementations or environments, be carried out by the CA itself. The protocols must be designed so that end entities use the same protocol regardless of whether they're talking to an RA or a CA. Naturally, the end entity must use the correct RA of CA public key to protect the communication ๐Ÿซถ
  12. Where an end entity requests a certificate containing a given public key value, the end entity must be ready to demonstrate possession of the corresponding private key value ๐Ÿ” This can be accomplished in various ways, depending on the type of certification request. See Section 4.3 for details of the in-band methods defined for the PKIX-CMP (i.e., Certificate Management Protocol) messages โœจ

3.1.3. PKI Management Operations โœจ

okay so here's the big picture ๐Ÿ–ผ๏ธ. The letters in the diagram are the "protocols" bit, meaning a defined set of PKI management messages can ride along each lettered line ๐Ÿฆ‹

     +---+     cert. publish        +------------+      j
     |   |  <---------------------  | End Entity | <-------
     | C |             g            +------------+      "out-of-band"
     | e |                            | ^                loading
     | r |                            | |      initial
     | t |                          a | | b     registration/
     |   |                            | |       certification
     | / |                            | |      key pair recovery
     |   |                            | |      key pair update
     | C |                            | |      certificate update
     | R |  PKI "USERS"               V |      revocation request
     | L | -------------------+-+-----+-+------+-+-------------------
     |   |  PKI MANAGEMENT    | ^              | ^
     |   |    ENTITIES      a | | b          a | | b
     | R |                    V |              | |
     | e |             g   +------+    d       | |
     | p |   <------------ | RA   | <-----+    | |
     | o |      cert.      |      | ----+ |    | |
     | s |       publish   +------+   c | |    | |
     | i |                              | |    | |
     | t |                              V |    V |
     | o |          g                 +------------+   i
     | r |   <------------------------|     CA     |------->
     | y |          h                 +------------+  "out-of-band"
     |   |      cert. publish              | ^         publication
     |   |      CRL publish                | |
     +---+                                 | |    cross-certification
                                         e | | f  cross-certificate
                                           | |       update
                                           | |
                                           V |
                                         +------+
                                         | CA-2 |
                                         +------+

Figure 1 - PKI Entities

Okay, so at a high level, the operations that have management messages defined for them can be sorted into these groups ๐Ÿ—‚๏ธ๐Ÿ’…

  1. CA establishment: when you're standing up a brand new CA, certain steps are required (e.g., producing initial CRLs, exporting the CA public key) ๐Ÿ—๏ธ
  2. End entity initialization: this covers importing a root CA public key and asking a PKI management entity what options it supports ๐Ÿ”‘
  3. Certification: a bunch of different operations end up creating new certificates ๐Ÿ“œ
    1. initial registration/certification: this is the process where an end entity first introduces itself to a CA or RA, before the CA issues any certificate or certificates for it ๐Ÿ™‹ If it works out, the CA issues a certificate for the end entity's public key and hands it back to the end entity and/or posts it in a public repository. This process may, and typically will, involve multiple "steps", possibly including initializing the end entity's equipment ๐Ÿงฐ For example, the end entity's equipment has to be securely initialized with a CA's public key so it can be used for validating certificate paths. And an end entity typically needs to be initialized with its own key pair(s) too ๐Ÿ—๏ธ
    2. key pair update: every key pair needs regular updating (so it gets replaced with a new key pair), and a new certificate needs to be issued ๐Ÿ”„
    3. certificate update: as certificates expire, they may be "refreshed" if nothing relevant in the environment has changed โ™ป๏ธ
    4. CA key pair update: CA key pairs need regular updating too, just like end entities ๐Ÿ”, but different mechanisms are required ๐Ÿ› ๏ธ
    5. cross-certification request: one CA asks another CA to issue it a cross-certificate ๐Ÿค For this standard, a few terms are defined. A "cross-certificate" is a certificate where the subject CA and the issuer CA are distinct and SubjectPublicKeyInfo contains a verification key (i.e., the certificate has been issued for the subject CA's signing key pair) ๐Ÿ’ซ If you need to be more specific, you may use these terms: a cross-certificate is called an "inter-domain cross-certificate" if the subject and issuer CAs belong to different administrative domains, and it's called an "intra-domain cross-certificate" otherwise ๐Ÿฐ
      1. Note 1. The above definition of "cross-certificate" lines up with the defined term "CA-certificate" in X.509. Just don't mix it up with the X.500 "cACertificate" attribute type, because that one is totally unrelated ๐Ÿ™…
      2. Note 2. In a lot of environments, "cross-certificate", unless it's further qualified, is going to be understood as meaning the same thing as "inter-domain cross-certificate" as defined above ๐ŸŒ
      3. Note 3. Issuing cross-certificates may be, but isn't necessarily, mutual. So two CAs can issue cross-certificates for each other ๐Ÿ‘ฏ
    6. cross-certificate update: basically a normal certificate update, but for a cross-certificate ๐Ÿชž
  4. Certificate/CRL discovery operations: some PKI management operations end up publishing certificates or CRLs ๐Ÿ“ข
    1. certificate publication: once you've gone to the trouble of making a certificate, you need some way to publish it ๐Ÿ“ฃ The "means" defined in PKIX MAY involve the messages specified in Sections 5.3.13 to 5.3.16, or MAY involve other methods (LDAP, for example) as described in [RFC2559], [RFC2585] (the "Operational Protocols" documents of the PKIX series of specifications) ๐Ÿ“š
    2. CRL publication: same deal as certificate publication ๐Ÿ”
  5. Recovery operations: some PKI management operations come into play when an end entity has "lost" its PSE ๐Ÿ†˜
    1. key pair recovery: as an option, user client key materials (e.g., a user's private key used for decryption purposes) MAY be backed up by a CA, an RA, or a key backup system associated with a CA or RA ๐Ÿ” If an entity needs to recover these backed up key materials (e.g., because of a forgotten password or a lost key chain file), a protocol exchange may be needed to support that recovery ๐Ÿ™
  6. Revocation operations: some PKI operations result in new CRL entries and/or new CRLs being created ๐Ÿšซ
    1. revocation request: an authorized person tells a CA about an abnormal situation that calls for certificate revocation ๐Ÿšจ
  7. PSE operations: whilst the definition of PSE operations (e.g., moving a PSE, changing a PIN, etc.) is beyond the scope of this specification, we do define a PKIMessage (CertRepMessage) that can form the basis of such operations ๐Ÿงฉ

Note that online protocols aren't the only way to do any of this ๐Ÿ’ป For all operations 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 the operations MAY be achieved as part of the physical token delivery ๐Ÿ“ฆ

Later sections define a set of standard messages that support the operations above. Transport protocols for carrying these exchanges in different environments (file-based, online, E-mail, and WWW) are beyond the scope of this document and are specified separately ๐Ÿšš๐ŸŽ€


4. Assumptions and Restrictions ๐ŸŽ€

4.1. End Entity Initialization

The first step for an end entity dealing with PKI management entities is to request information about the PKI functions supported and to securely acquire a copy of the relevant root CA public key(s) ๐Ÿ”‘โœจ

4.2. Initial Registration/Certification

There are loads of schemes you can use for initial registration and certification of end entities ๐ŸŒˆ No single method works for every situation, because CAs can implement all sorts of policies and end entities come in lots of different types ๐Ÿซ 

Here's the tea ๐Ÿต The word "initial", above, is crucial. We're dealing with the situation where the end entity has had no previous contact with the PKI. If the end entity already has certified keys, some simplifications and alternatives are possible ๐Ÿฆ‹

Once we've sorted the schemes this specification supports, we can make some of them mandatory and leave the others optional. The goal is that the mandatory schemes cover enough of the cases that come up in real use, while the optional schemes are there for the special cases that show up less often. That way we get a balance between flexibility and ease of implementation ๐Ÿ’–

Let's go through the classification of initial registration/certification schemes ๐Ÿ“‹

4.2.1. Criteria Used

4.2.1.1. Initiation of Registration/Certification

In terms of the PKI messages that get produced, we can say the initial registration/certification exchanges start wherever the first PKI message about the end entity is produced ๐Ÿš€ The real-world start of the registration/certification procedure may happen somewhere else, though (e.g., a personnel department may phone an RA operator) ๐Ÿ“ž

The possible locations are the end entity, an RA, or a CA ๐Ÿข

4.2.1.2. End Entity Message Origin Authentication

The online messages the end entity produces that need a certificate may or may not be authenticated. The requirement here is to authenticate the origin of any messages going from the end entity to the PKI (CA/RA) ๐Ÿ•ต๏ธโ€โ™€๏ธ

In this specification, that authentication works like this: the PKI (CA/RA) gives the end entity a secret value (initial authentication key) and a reference value (used to identify that secret value) through some out-of-band means ๐Ÿคซ The initial authentication key can then be used to protect the relevant PKI messages ๐Ÿ”

So we can classify the initial registration/certification scheme based on whether the online end entity -> PKI messages are authenticated or not ๐Ÿง

Note 1: We aren't going to discuss authentication of the PKI -> end entity messages here, because that is always REQUIRED. Honestly, it's easy to handle: once the root-CA public key has been installed on the end entity's equipment, it can be done, or it can be based on the initial authentication key ๐Ÿ™Œ

Note 2: An initial registration/certification procedure can be secure where the messages from the end entity are authenticated via some out-of-band means (e.g., a subsequent visit) ๐Ÿซถ

4.2.1.3. Location of Key Generation ๐Ÿ”‘

okay so in this spec, "key generation" counts as happening wherever the public or private half of a key pair first shows up in a PKIMessage ๐Ÿ’– that does NOT mean you can't have a centralized key generation service, bestie! the actual key pair MAY have been generated somewhere else and then delivered to the end entity, RA, or CA through a key generation request/response protocol (proprietary or standardized, but that's outside this spec) ๐ŸŽ€

so there are three possible locations for "key generation": the end entity, an RA, or a CA ๐Ÿงš

4.2.1.4. Confirmation of Successful Certification โœ…

once an initial certificate exists for an end entity, you can get extra assurance by having the end entity explicitly confirm it received the message that contains the certificate (or says it was created) ๐Ÿซถ and ngl this confirmation message must be protected (based on the initial authentication key or other means) ๐Ÿ”

that gives two more possibilities: confirmed or not ๐Ÿ’…

4.2.2. Mandatory Schemes ๐ŸŒˆ

the criteria above allow a huge number of initial registration/certification schemes ๐Ÿคฏ but this spec says conforming CA equipment, RA equipment, and EE equipment MUST support the second scheme listed below (Section 4.2.2.2). any entity MAY also support other schemes if it wants ๐Ÿ’œ

4.2.2.1. Centralized Scheme ๐Ÿฐ

in terms of the classification above, this one is kinda the simplest possible, where:

  • initiation occurs at the certifying CA;
  • no on-line message authentication is required;
  • "key generation" occurs at the certifying CA (see Section 4.2.1.3);
  • no confirmation message is required.

in terms of message flow, this scheme means the only message required is sent from the CA to the end entity ๐Ÿ“ฉ the message must contain the entire PSE for the end entity. some out-of-band means must be provided so the end entity can authenticate the message it received and decrypt any encrypted values ๐Ÿ”“

4.2.2.2. Basic Authenticated Scheme ๐Ÿ”

in terms of the classification above, this scheme is where:

  • initiation occurs at the end entity;
  • message authentication is REQUIRED;
  • "key generation" occurs at the end entity (see Section 4.2.1.3);
  • a confirmation message is REQUIRED.

in terms of message flow, the basic authenticated scheme goes like this ๐Ÿ‘€

  End entity                                          RA/CA
  ==========                                      =============
       out-of-band distribution of Initial Authentication
       Key (IAK) and reference value (RA/CA -> EE)
  Key generation
  Creation of certification request
  Protect request with IAK
                -->>-- certification request -->>--
                                                 verify request
                                                 process request
                                                 create response
                -<<-- certification response --<<--
  handle response
  create confirmation
                -->>-- cert conf message      -->>--
                                                 verify confirmation
                                                 create response
                -<<-- conf ack (optional)    --<<--
  handle response
(Where verification of the cert confirmation message fails, the RA/CA MUST revoke the newly issued certificate if it has been published or otherwise made available.) ๐Ÿšจ

Wait, the diagram above has a minor change in arrow glyphs. I need to show the diagram verbatim, so here is the corrected version:

  End entity                                          RA/CA
  ==========                                      =============
       out-of-band distribution of Initial Authentication
       Key (IAK) and reference value (RA/CA -> EE)
  Key generation
  Creation of certification request
  Protect request with IAK
                -->>-- certification request -->>--
                                                 verify request
                                                 process request
                                                 create response
                --<<-- certification response --<<--
  handle response
  create confirmation
                -->>-- cert conf message      -->>--
                                                 verify confirmation
                                                 create response
                --<<-- conf ack (optional)    --<<--
  handle response

4.3. Proof-of-Possession (POP) of Private Key ๐Ÿ”‘

so the whole point here is to stop certain attacks and let a CA/RA properly check that the end entity really belongs with the key pair. the PKI management operations here make it possible for an end entity to prove it has possession of (i.e., is able to use) the private key that matches the public key it wants certified ๐Ÿ’… a CA/RA is free to pick how it enforces POP (e.g., out-of-band procedural means versus PKIX-CMP in-band messages) in its certification exchanges, so that can be a policy thing. BUT it is REQUIRED that CAs/RAs MUST enforce POP by some means, because lots of non-PKIX operational protocols are already out there (various electronic mail protocols are one example) that don't explicitly check the binding between the end entity and the private key ๐Ÿ˜ฌ until operational protocols that DO verify the binding (for signature, encryption, and key agreement key pairs) exist and are everywhere, this binding can only be assumed to have been verified by the CA/RA. so if the CA/RA doesn't verify it, certificates in the Internet Public-Key Infrastructure end up being kinda less meaningful ๐Ÿ“‰

POP works differently depending on the type of key a certificate is requested for. if a key can be used for multiple purposes (e.g., an RSA key), then any appropriate method MAY be used (e.g., a key that may be used for signing, as well as other purposes, SHOULD NOT be sent to the CA/RA in order to prove possession) ๐ŸŒธ

this spec explicitly allows for cases where an end entity gives the proof to an RA, and the RA then attests to the CA that the required proof was received (and validated!) โœจ for example, an end entity that wants a signing key certified could send the signature to the RA, which just tells the relevant CA that the end entity supplied the required proof. of course, some policies might disallow this (e.g., CAs may be the only entities permitted to verify POP during certification) ๐Ÿ™…โ€โ™€๏ธ

4.3.1. Signature Keys โœ๏ธ

for signature keys, the end entity can sign a value to prove it has the private key ๐Ÿ’–

4.3.2. Encryption Keys ๐Ÿ”

for encryption keys, the end entity can hand the private key to the CA/RA, or it can be required to decrypt a value to prove possession of the private key (see Section 5.2.8). decrypting can be done either directly or indirectly ๐Ÿ™Œ

the direct method is for the RA/CA to issue a random challenge that the EE has to answer immediately ๐Ÿƒโ€โ™€๏ธ

the indirect method is to issue a certificate that's encrypted for the end entity, and then have the end entity show it can decrypt that certificate in the confirmation message ๐ŸŽ this lets a CA issue a certificate in a form that only the intended end entity can use.

this spec encourages the indirect method because it needs no extra messages (the proof can be shown using the {request, response, confirmation} triple of messages) ๐Ÿง โœจ

4.3.3. Key Agreement Keys ๐Ÿค

for key agreement keys, the end entity and the PKI management entity (i.e., CA or RA) must establish a shared secret key to prove that the end entity has possession of the private key ๐Ÿ—๏ธ

this doesn't put any restrictions on the keys a given CA can certify, though ๐Ÿ™†โ€โ™€๏ธ especially for Diffie-Hellman keys, the end entity can freely choose its algorithm parameters, as long as the CA can generate a short-term (or one-time) key pair with the appropriate parameters when it's needed โญ

4.4. Root CA Key Update ๐Ÿ‘‘

this discussion only applies to CAs that some end entities trust directly. Self-signed CAs SHALL be considered as directly trusted CAs ๐Ÿ’… whether a non-self-signed CA is supposed to be directly trusted for some end entities is a CA policy matter, so it's beyond the scope of this document ๐Ÿ™ˆ

the whole idea is that the CA protects its new public key using its previous private key, and vice versa ๐Ÿ”„ so when a CA updates its key pair, it must generate two extra cACertificate attribute values if certificates are made available using an X.500 directory (four total: OldWithOld, OldWithNew, NewWithOld, and NewWithNew) ๐Ÿ“š

when a CA changes its key pair, the entities most affected are the ones who got the old CA public key through "out-of-band" means. they're the ones who'll need the new CA public key protected with the old CA private key ๐Ÿซ  but they only need it for a limited time (until they've acquired the new CA public key through the "out-of-band" mechanism). this will usually be easy once their certificates expire โณ

the data structure used to protect the new and old CA public keys is a standard certificate (which can also contain extensions). no new data structures are needed ๐Ÿ™Œ

Note 1. This scheme doesn't use any of the X.509 v3 extensions, because it has to work even for version 1 certificates. the KeyIdentifier extension would make things more efficient ๐ŸŽ๏ธ

Note 2. The scheme could be generalized to cover cases where the CA updates its key pair more than once during the validity period of one of its end entities' certificates, but this generalization seems of dubious value ๐Ÿคจ without that generalization, the validity periods of certificates issued with the old CA key pair can't go past the end of the OldWithNew validity period.

Note 3. This scheme makes sure end entities will acquire the new CA public key at the latest by the expiry of the last certificate they owned that was signed with the old CA private key (via the "out-of-band" means). certificate and/or key update operations at other times don't necessarily need this (depending on the end entity's equipment) ๐ŸŽฏ

4.4.1. CA Operator Actions ๐Ÿง‘โ€๐Ÿ’ป

to change the key of the CA, the CA operator does the following:

  1. Generate a new key pair;
  2. Create a certificate containing the old CA public key signed with the new private key (the "old with new" certificate);
  3. Create a certificate containing the new CA public key signed with the old private key (the "new with old" certificate);
  4. Create a certificate containing the new CA public key signed with the new private key (the "new with new" certificate);
  5. Publish these new certificates via the repository and/or other means (perhaps using a CAKeyUpdAnn message);
  6. Export the new CA public key so that end entities may acquire it using the "out-of-band" mechanism (if required).

the old CA private key isn't needed anymore ๐Ÿ”’ but the old CA public key will stick around for a while ๐Ÿ•ฐ๏ธ the old CA public key is no longer required (other than for non-repudiation) once all end entities of this CA have securely acquired the new CA public key ๐Ÿ’œ

the "old with new" certificate must have a validity period that starts at the generation time of the old key pair and ends at the expiry date of the old public key ๐Ÿ“…

the "new with old" certificate must have a validity period that starts at the generation time of the new key pair and ends at the time by which all end entities of this CA will securely possess the new CA public key (at the latest, the expiry date of the old public key) ๐Ÿ—“๏ธ

the "new with new" certificate must have a validity period that starts at the generation time of the new key pair and ends at or before the time by which the CA will next update its key pair ๐Ÿซถ

4.4.2. Verifying Certificates โœจ

okay so normally when you verify a signature, you check (among other things) the certificate holding the signer's public key ๐Ÿ” but once a CA is allowed to update its key, things get way more interesting ๐Ÿฆ‹ there's a whole range of new possibilities, and the table below lays them all out ๐Ÿ’…

            Repository contains NEW     Repository contains only OLD
              and OLD public keys        public key (due to, e.g.,
                                          delay in publication)

               PSE      PSE Contains  PSE Contains    PSE Contains
            Contains     OLD public    NEW public      OLD public
           NEW public       key            key            key
               key

Signer's   Case 1:      Case 3:       Case 5:        Case 7:
certifi-   This is      In this case  Although the   In this case
cate is    the          the verifier  CA operator    the CA
protected  standard     must access   has not        operator  has
using NEW  case where   the           updated the    not updated
public     the          repository in repository the the repository
key        verifier     order to get  verifier can   and so the
           can          the value of  verify the     verification
           directly     the NEW       certificate    will FAIL
           verify the   public key    directly -
           certificate                this is thus
           without                    the same as
           using the                  case 1.
           repository

Signer's   Case 2:      Case 4:       Case 6:        Case 8:
certifi-   In this      In this case  The verifier   Although the
cate is    case the     the verifier  thinks this    CA operator
protected  verifier     can directly  is the         has not
using OLD  must         verify the    situation of   updated the
public     access the   certificate   case 2 and     repository the
key        repository   without       will access    verifier can
           in order     using the     the            verify the
           to get the   repository    repository;    certificate
           value of                   however, the   directly -
           the OLD                    verification   this is thus
           public key                 will FAIL      the same as
                                                     case 4.

4.4.2.1. Verification in Cases 1, 4, 5, and 8 ๐ŸŒธ

in these cases the verifier has a local copy of the CA public key, so it can verify the certificate directly ๐Ÿ™Œ honestly this is the same vibe as when no key change has happened at all, so no drama here ๐Ÿ’–

note that case 8 can show up between the moment the CA operator generates the new key pair and the moment they actually store the updated attributes in the repository โณ and case 5 can only happen if the CA operator issued both the signer's and the verifier's certificates during that "gap" (the CA operator SHOULD avoid this, because it leads to the failure cases described below) ๐Ÿ™ˆ

4.4.2.2. Verification in Case 2 ๐ŸŽ€

in case 2, the verifier has to get its hands on the OLD public key of the CA ๐Ÿ”‘ here's what it does:

  1. Look up the caCertificate attribute in the repository and pick the OldWithNew certificate (determined based on validity periods; note that the subject and issuer fields must match);
  2. Verify that this is correct using the new CA key (which the verifier has locally);
  3. If correct, check the signer's certificate using the old CA key.

case 2 pops up when the CA operator issues the signer's certificate, then changes the key, then issues the verifier's certificate ๐Ÿงš so yeah, it's quite a typical case โœจ

4.4.2.3. Verification in Case 3 ๐Ÿ’œ

in case 3, the verifier has to get its hands on the NEW public key of the CA ๐Ÿ—๏ธ here's the move:

  1. Look up the CACertificate attribute in the repository and pick the NewWithOld certificate (determined based on validity periods; note that the subject and issuer fields must match);
  2. Verify that this is correct using the old CA key (which the verifier has stored locally);
  3. If correct, check the signer's certificate using the new CA key.

case 3 happens when the CA operator issues the verifier's certificate, then changes the key, then issues the signer's certificate ๐ŸŒˆ also quite a typical case, bestie ๐Ÿ’…

4.4.2.4. Failure of Verification in Case 6 ๐Ÿ’€

in this case the CA has issued the verifier's PSE, which contains the new key, but it never updated the repository attributes ๐Ÿ˜ญ so the verifier has zero way to get a trustworthy version of the CA's old key, and verification fails ๐Ÿ™ƒ

note that the failure is the CA operator's fault ๐Ÿซถ

4.4.2.5. Failure of Verification in Case 7 ๐Ÿฅ€

in this case the CA has issued the signer's certificate protected with the new key, but it didn't update the repository attributes ๐Ÿ˜ฉ so the verifier can't get a trustworthy version of the CA's new key, and verification fails ๐Ÿ’”

note that the failure is, again, the CA operator's fault ๐Ÿ˜ค

4.4.3. Revocation - Change of CA Key ๐Ÿฆ‹

as we saw above, verifying a certificate gets way more complex once the CA is allowed to change its key ๐ŸŒ€ and it's just as messy for revocation checks, because the CA may have signed the CRL using a newer private key than the one inside the user's PSE ๐Ÿ‘€

the analysis of the alternatives is the same as for certificate verification, so no need to reinvent the wheel ๐Ÿ™Œ

5. Data Structures ๐Ÿ“

this section has the descriptions of the data structures that PKI management messages need ๐Ÿ“ฆ Section 6 covers the constraints on their values and the sequence of events for each of the various PKI management operations ๐Ÿ—บ๏ธ

5.1. Overall PKI Message ๐Ÿ’Œ

every message used in this specification for PKI management uses the following structure ๐Ÿ’–

   PKIMessage ::= SEQUENCE {
      header           PKIHeader,
      body             PKIBody,
      protection   [0] PKIProtection OPTIONAL,
      extraCerts   [1] SEQUENCE SIZE (1..MAX) OF CMPCertificate
                       OPTIONAL
  }
  PKIMessages ::= SEQUENCE SIZE (1..MAX) OF PKIMessage

the PKIHeader holds info that's common to lots of PKI messages ๐Ÿ“

the PKIBody holds the message-specific stuff ๐ŸŽ

the PKIProtection, when it's used, has the bits that protect the PKI message ๐Ÿ”

the extraCerts field can hold certificates that might be useful to the recipient ๐Ÿงƒ for example, a CA or RA can use it to give an end entity the certificates it needs to verify its own new certificate (say, if the CA that issued the end entity's certificate isn't a root CA for that end entity) ๐ŸŒธ but heads up: this field doesn't necessarily contain a certification path ๐Ÿ™ˆ the recipient might have to sort, select from, or otherwise process the extra certificates before it can actually use them โœจ

5.1.1. PKI Message Header โœจ

okay so every PKI message needs some header info for addressing and keeping track of the transaction ๐Ÿ’Œ some of it also shows up in the transport envelope, but if the message is protected, the header gets protected too. no assumptions about secure transport here, bestie ๐Ÿ”

PKIHeader ::= SEQUENCE {
    pvno                INTEGER     { cmp1999(1), cmp2000(2) },
    sender              GeneralName,
    recipient           GeneralName,
    messageTime     [0] GeneralizedTime         OPTIONAL,
    protectionAlg   [1] AlgorithmIdentifier     OPTIONAL,
    senderKID       [2] KeyIdentifier           OPTIONAL,
    recipKID        [3] KeyIdentifier           OPTIONAL,
    transactionID   [4] OCTET STRING            OPTIONAL,
    senderNonce     [5] OCTET STRING            OPTIONAL,
    recipNonce      [6] OCTET STRING            OPTIONAL,
    freeText        [7] PKIFreeText             OPTIONAL,
    generalInfo     [8] SEQUENCE SIZE (1..MAX) OF
                        InfoTypeAndValue     OPTIONAL
}
PKIFreeText ::= SEQUENCE SIZE (1..MAX) OF UTF8String

the pvno field is locked at 2 for this version of the spec ๐Ÿ”’

the sender field holds the name of whoever sent the PKIMessage ๐Ÿ“ฎ this name, together with senderKID if it's supplied, should be enough to figure out which key to use to verify the protection. now, if the sender doesn't know anything about itself (like in the init. req. message, where the end entity might not even know its own Distinguished Name (DN), email name, IP address, etc.), then the "sender" field MUST contain a "NULL" value. that means the SEQUENCE OF relative distinguished names is zero length ๐Ÿซ  in that case, the senderKID field MUST hold an identifier (a reference number) that tells the receiver which shared secret information to use to verify the message ๐Ÿ—๏ธ

the recipient field holds the name of the person getting the PKIMessage ๐Ÿ’Œ together with recipKID, if supplied, it should be usable to verify the protection on the message.

the protectionAlg field says which algorithm protected the message ๐Ÿ›ก๏ธ if there are no protection bits (remember, PKIProtection is OPTIONAL), then this field MUST be omitted. if protection bits ARE supplied, then this field MUST be supplied. no in-between, periodt ๐Ÿ’…

senderKID and recipKID are there to show which keys were used to protect the message ๐Ÿ”‘ (recipKID will normally only be required when the protection uses Diffie-Hellman (DH) keys).

these fields MUST be used if they're required to uniquely identify a key (for example, if more than one key is tied to a given sender name), and SHOULD be left out otherwise. no extra clutter, bestie โœจ

the transactionID field is how the recipient links a message to an ongoing transaction ๐Ÿงต this is needed for every transaction that's more than a single request/response pair. for the single request/response ones, here's the tea:

  • a client MAY fill in the transactionID of the request.
  • if a server gets a request with transactionID set, it MUST set the transactionID of the response to that same value.
  • if a server gets a request with a missing transactionID, it MAY set one in the response.

for transactions with more than one request/response pair, things get a bit more structured ๐Ÿ“š

  • clients SHOULD generate a transactionID for the first request.
  • if a server gets such a request with transactionID set, it MUST set the transactionID of the response to the same value.
  • if a server gets such a request with a missing transactionID, it MUST fill the response's transactionID with a server-generated ID.
  • every later request and response MUST set transactionID to that established value.

and in every case where a transactionID is used, a given client MUST NOT have more than one transaction with the same transactionID in progress at any time (to a given server). servers get to decide whether they need transactionIDs to be unique, as long as they can still match messages to the right transaction ๐Ÿงฉ usually that means a server will require the {client, transactionID} pair to be unique, or even the transactionID alone to be unique, if it can't tell clients apart using transport-level info.

if a server gets the first message of a multi-pair transaction with a transactionID that breaks those rules (usually because it's already being used), it MUST send back an ErrorMsgContent with a PKIFailureInfo of transactionIdInUse ๐Ÿšซ yikes, not a vibe.

it is RECOMMENDED that clients fill the transactionID with 128 bits of (pseudo-) random data when a transaction starts, which makes it way less likely the ID is already in use at the server ๐ŸŽฒ literally iconic behavior.

the senderNonce and recipNonce fields protect the PKIMessage against replay attacks ๐Ÿ›‘ the senderNonce is typically 128 bits of (pseudo-) random data made by the sender, while the recipNonce is copied from the senderNonce of the previous message in the transaction. it's giving checks and balances ๐Ÿค

the messageTime field has the time the sender made the message โฐ this can help end entities check or correct their local time against a central system's time.

the freeText field can carry a human-readable message to the recipient (in any number of languages) ๐ŸŒ the first language in the sequence is the one replies should use. main character language choice ๐Ÿ‘‘

the generalInfo field can carry machine-processable extra data for the recipient ๐Ÿค– these generalInfo extensions are defined and MAY be supported. ๐ŸŽ€

5.1.1.1. ImplicitConfirm ๐Ÿ™ˆ

this is how the EE tells the CA that it does NOT want to send a certificate confirmation for issued certificates ๐Ÿ™…โ€โ™€๏ธ

implicitConfirm OBJECT IDENTIFIER ::= {id-it 13}
ImplicitConfirmValue ::= NULL

if the CA says yes to the request, it MUST put the same extension in the PKIHeader of the response. and if the EE doesn't find the extension in the response, it MUST send the certificate confirmation. no skipping this step, bestie ๐Ÿ’€

5.1.1.2. ConfirmWaitTime โณ

the CA uses this to tell the EE how long it plans to wait for the certificate confirmation before it revokes the certificate and deletes the transaction ๐Ÿ˜ฌ time's ticking, babe.

confirmWaitTime OBJECT IDENTIFIER ::= {id-it 14}
ConfirmWaitTimeValue ::= GeneralizedTime

5.1.2. PKI Message Body ๐ŸŽ

PKIBody ::= CHOICE {
  ir       [0]  CertReqMessages,       --Initialization Req
  ip       [1]  CertRepMessage,        --Initialization Resp
  cr       [2]  CertReqMessages,       --Certification Req
  cp       [3]  CertRepMessage,        --Certification Resp
  p10cr    [4]  CertificationRequest,  --PKCS #10 Cert.  Req.
  popdecc  [5]  POPODecKeyChallContent --pop Challenge
  popdecr  [6]  POPODecKeyRespContent, --pop Response
  kur      [7]  CertReqMessages,       --Key Update Request
  kup      [8]  CertRepMessage,        --Key Update Response
  krr      [9]  CertReqMessages,       --Key Recovery Req
  krp      [10] KeyRecRepContent,      --Key Recovery Resp
  rr       [11] RevReqContent,         --Revocation Request
  rp       [12] RevRepContent,         --Revocation Response
  ccr      [13] CertReqMessages,       --Cross-Cert.  Request
  ccp      [14] CertRepMessage,        --Cross-Cert.  Resp
  ckuann   [15] CAKeyUpdAnnContent,    --CA Key Update Ann.
  cann     [16] CertAnnContent,        --Certificate Ann.
  rann     [17] RevAnnContent,         --Revocation Ann.
  crlann   [18] CRLAnnContent,         --CRL Announcement
  pkiconf  [19] PKIConfirmContent,     --Confirmation
  nested   [20] NestedMessageContent,  --Nested Message
  genm     [21] GenMsgContent,         --General Message
  genp     [22] GenRepContent,         --General Response
  error    [23] ErrorMsgContent,       --Error Message
  certConf [24] CertConfirmContent,    --Certificate confirm
  pollReq  [25] PollReqContent,        --Polling request
  pollRep  [26] PollRepContent         --Polling response
  }

the specific types get their own rundown in Section 5.3 below ๐Ÿง

5.1.3. PKI Message Protection ๐Ÿ”

some PKI messages get protected for integrity ๐Ÿ›ก๏ธ (quick note: if an asymmetric algorithm protects a message and the matching public component is already certified, then the origin of the message can be authenticated too ๐Ÿซถ but if the public component is uncertified, the message origin can't be authenticated automatically. it might still be authenticated through out-of-band means.)

when protection is applied, this structure is used:

PKIProtection ::= BIT STRING

the input to the calculation of PKIProtection is the DER encoding of this data structure:

ProtectedPart ::= SEQUENCE {
    header    PKIHeader,
    body      PKIBody
}

there MAY be cases where the PKIProtection BIT STRING is deliberately NOT used to protect a message (aka this OPTIONAL field gets left out) because other protection, external to PKIX, is applied instead. this choice is explicitly allowed in this spec ๐Ÿ™Œ examples of external protection include PKCS #7 [PKCS7] and Security Multiparts [RFC1847] encapsulation of the PKIMessage (or just the PKIBody, leaving out the CHOICE tag, if the relevant PKIHeader info is securely carried by the external mechanism).

that said, lots of these external mechanisms need the end entity to already have a public-key certificate, and/or a unique Distinguished Name, and/or other infrastructure-related info ๐Ÿฅบ so they might not fit initial registration, key-recovery, or any other process with "boot-strapping" characteristics. for those cases, it may be necessary to use the PKIProtection parameter. if external mechanisms ever get updated to handle boot-strapping scenarios, PKIProtection may become rare or non-existent. future glow-up era ๐ŸŒˆ

depending on the circumstances, the PKIProtection bits may hold a Message Authentication Code (MAC) or a signature ๐Ÿ” only the following cases can occur:

5.1.3.1. Shared Secret Information โœจ

okay so this case is giving old-school friends-with-a-secret-handshake energy ๐Ÿซถ The sender and recipient already share secret info, either set up out-of-band or from an earlier PKI management operation. PKIProtection holds a MAC value, and the protectionAlg is this (see also Appendix D.2) ๐Ÿ”

  id-PasswordBasedMac OBJECT IDENTIFIER ::= {1 2 840 113533 7 66 13}
  PBMParameter ::= SEQUENCE {
    salt                OCTET STRING,
    owf                 AlgorithmIdentifier,
    iterationCount      INTEGER,
    mac                 AlgorithmIdentifier
  }

So in that protectionAlg, the salt gets tacked onto the end of the shared secret input ๐Ÿง‚ Then the OWF gets applied iterationCount times. The salted secret goes in for the first round, and every round after that eats the output of the round before it ๐Ÿ” The result of the last round is called "BASEKEY" (it's H bits long) and it's what forms the symmetric key ๐Ÿ”‘ If the MAC algorithm wants a K-bit key and K <= H, you take the most significant K bits of BASEKEY. If K > H, then all of BASEKEY covers the most significant H bits, OWF("1" || BASEKEY) covers the next H bits, OWF("2" || BASEKEY) covers the next H bits after that, and you keep going until all K bits are derived ๐Ÿ’… Here "N" is the ASCII byte that encodes the number N, and "||" just means concatenation ๐ŸŽ€

Note: it is RECOMMENDED that the fields of PBMParameter remain constant throughout the messages of a single transaction (e.g., ir/ip/certConf/pkiConf) in order to reduce the overhead associated with PasswordBasedMac computation). ๐Ÿง โœจ Honestly this is such a smart move because it keeps the computation from getting extra heavy ๐Ÿ’–

5.1.3.2. DH Key Pairs

Okay this one is so pretty ๐Ÿฆ‹ When the sender and receiver both have Diffie-Hellman certificates with compatible DH parameters, the end entity has to generate a symmetric key using its private DH key value and the DH public key of the PKI message's recipient ๐ŸŒธ PKIProtection holds a MAC value keyed with that derived symmetric key, and the protectionAlg is this:

     id-DHBasedMac OBJECT IDENTIFIER ::= {1 2 840 113533 7 66 30}

     DHBMParameter ::= SEQUENCE {
         owf                 AlgorithmIdentifier,
         -- AlgId for a One-Way Function (SHA-1 recommended)
         mac                 AlgorithmIdentifier
         -- the MAC AlgId (e.g., DES-MAC, Triple-DES-MAC [PKCS11],
     }   -- or HMAC [RFC2104, RFC2202])

In that protectionAlg, the OWF gets applied to the result of the Diffie-Hellman computation ๐Ÿง The OWF output is called "BASEKEY" (size H) and it's what forms the symmetric key ๐Ÿ—๏ธ If the MAC algorithm needs a K-bit key and K <= H, you grab the most significant K bits of BASEKEY. If K > H, all of BASEKEY covers the most significant H bits, OWF("1" || BASEKEY) covers the next H bits, OWF("2" || BASEKEY) covers the next H bits after that, and so on until all K bits are derived ๐ŸŒˆ Here "N" is the ASCII byte encoding the number N, and "||" means concatenation ๐Ÿ’œ

5.1.3.3. Signature

Simple and iconic ๐Ÿ‘‘ In this case the sender has a signature key pair and just signs the PKI message โœ๏ธ PKIProtection holds the signature value, and the protectionAlg is an AlgorithmIdentifier for a digital signature (e.g., md5WithRSAEncryption or dsaWithSha-1). No notes, no drama, just vibes ๐Ÿ’…

5.1.3.4. Multiple Protection

Okay this is the group-project-with-a-manager situation ๐Ÿ“ When an end entity sends a protected PKI message to an RA, the RA MAY forward that message to a CA and attach its own protection. That protection MAY be a MAC or a signature, depending on the information and certificates the RA and CA share ๐Ÿซง To do this, the entire message from the end entity gets nested inside a new PKI message. The structure looks like this:

        NestedMessageContent ::= PKIMessages

(The use of PKIMessages, a SEQUENCE OF PKIMessage, lets the RA batch the requests of several EEs in a single new message. For simplicity, all messages in the batch MUST be of the same type (e.g., ir).) ๐Ÿ“ฆโœจ If the RA wants to change the message(s) somehow (for example, adding particular field values or new extensions), then it MAY create its own desired PKIBody ๐ŸŽ€ The original PKIMessage from the EE MAY be included in the generalInfo field of PKIHeader. This helps in cases where the CA wants to check POP or other info from the original EE message ๐Ÿ” The infoType for this situation is {id-it 15} (see Section 5.3.19 for the value of id-it), and the infoValue is PKIMessages. The contents MUST be in the same order as the requests in PKIBody ๐Ÿซถ


5.2. Common Data Structures ๐Ÿงš

Before we get into the specific types that can go in a PKIBody, we're defining some data structures that show up in more than one case ๐Ÿ’–

5.2.1. Requested Certificate Contents

Lowkey so many PKI management messages need the originator to say which fields should be in a certificate ๐Ÿ“œ The CertTemplate structure lets an end entity or RA request as much as it wants about the certificate it needs. CertTemplate is basically a Certificate, except every field is optional ๐ŸŒธ

Here's the tea: even if the originator fully specifies the contents of the certificate it needs, a CA is free to change fields in the certificate it actually issues ๐Ÿ™ˆ If the modified certificate is unacceptable to the requester, the requester MUST send back a certConf message. That message either does not include this certificate (via a CertHash), or it does include this certificate (via a CertHash) along with a status of "rejected" โŒ See Section 5.3.18 for the definition and use of CertHash and the certConf message ๐Ÿ’œ

See Appendix C and [CRMF] for CertTemplate syntax. โœจ

5.2.2. Encrypted Values

When encrypted values get sent in PKI messages (in this specification, they're restricted to either private keys or certificates), the EncryptedValue data structure is used ๐Ÿ”

See [CRMF] for EncryptedValue syntax. ๐ŸŽ€

Using this data structure means the creator and intended recipient need to be able to encrypt and decrypt, respectively. Typically that means the sender and recipient have a shared secret key, or can generate one ๐Ÿ—๏ธ

If the recipient of the PKIMessage already has a private key that can decrypt, then the encSymmKey field MAY contain a session key encrypted using the recipient's public key ๐Ÿฆ‹

5.2.3. Status codes and Failure Information for PKI Messages

All response messages include some status info ๐Ÿ“ฌ These values are defined:

     PKIStatus ::= INTEGER {
         accepted               (0),
         grantedWithMods        (1),
         rejection              (2),
         waiting                (3),
         revocationWarning      (4),
         revocationNotification (5),
         keyUpdateWarning       (6)
     }

Responders may use the following syntax to give more info about failure cases ๐Ÿ™ˆ

     PKIFailureInfo ::= BIT STRING {
         badAlg              (0),
         badMessageCheck     (1),
         badRequest          (2),
         badTime             (3),
         badCertId           (4),
         badDataFormat       (5),
         wrongAuthority      (6),
         incorrectData       (7),
         missingTimeStamp    (8),
         badPOP              (9),
         certRevoked         (10),
         certConfirmed       (11),
         wrongIntegrity      (12),
         badRecipientNonce   (13),
         timeNotAvailable    (14),
         unacceptedPolicy    (15),
         unacceptedExtension (16),
         addInfoNotAvailable (17),
         badSenderNonce      (18),
         badCertTemplate     (19),
         signerNotTrusted    (20),
         transactionIdInUse  (21),
         unsupportedVersion  (22),
         notAuthorized       (23),
         systemUnavail       (24),
         systemFailure       (25),
         duplicateCertReq    (26)
     }

     PKIStatusInfo ::= SEQUENCE {
         status        PKIStatus,
         statusString  PKIFreeText     OPTIONAL,
         failInfo      PKIFailureInfo  OPTIONAL
     }

5.2.4. Certificate Identification

To identify particular certificates, we use the CertId data structure ๐Ÿชช

See [CRMF] for CertId syntax. ๐Ÿ’…

5.2.5. Out-of-band root CA Public Key

Each root CA has to be able to publish its current public key through some "out-of-band" means ๐Ÿ“ฃ Those mechanisms are beyond the scope of this document, but we define data structures that can support them ๐Ÿงš

There are generally two methods available. Either the CA directly publishes its self-signed certificate, or the info is available via the Directory (or equivalent) and the CA publishes a hash of this value so you can verify its integrity before using it ๐Ÿ”

     OOBCert ::= Certificate

The fields in this certificate are restricted as follows:

  • The certificate MUST be self-signed (i.e., the signature must be verifiable using the SubjectPublicKeyInfo field);
  • The subject and issuer fields MUST be identical;
  • If the subject field is NULL, then both subjectAltNames and issuerAltNames extensions MUST be present and have exactly the same value;
  • The values of all other extensions must be suitable for a self-signed certificate (e.g., key identifiers for subject and issuer must be the same).
     OOBCertHash ::= SEQUENCE {
         hashAlg     [0] AlgorithmIdentifier     OPTIONAL,
         certId      [1] CertId                  OPTIONAL,
         hashVal         BIT STRING
     }

The whole point of the hash value is that anyone who has securely received it (via the out-of-band means) can verify a self-signed certificate for that CA ๐Ÿซถโœจ

5.2.6. Archive Options

Requesters may indicate that they want the PKI to archive a private key value using the PKIArchiveOptions structure ๐Ÿ—„๏ธ

See [CRMF] for PKIArchiveOptions syntax. ๐ŸŽ€

5.2.7. Publication Information

Requesters may indicate that they want the PKI to publish a certificate using the PKIPublicationInfo structure ๐Ÿ“ข

See [CRMF] for PKIPublicationInfo syntax. ๐Ÿ’–

5.2.8. Proof-of-Possession Structures

If the certification request is for a signing key pair (i.e., a request for a verification certificate), then proof-of-possession of the private signing key is shown through the POPOSigningKey structure โœ๏ธ

See Appendix C and [CRMF] for POPOSigningKey syntax, but note that POPOSigningKeyInput has the following semantic stipulations in this specification ๐Ÿง

     POPOSigningKeyInput ::= SEQUENCE {
         authInfo            CHOICE {
             sender              [0] GeneralName,
             publicKeyMAC            PKMACValue
         },
         publicKey           SubjectPublicKeyInfo
     }

On the other hand, if the certification request is for an encryption key pair (i.e., a request for an encryption certificate), then proof-of-possession of the private decryption key may be demonstrated in one of three ways ๐Ÿ”๐ŸŒธ

5.2.8.1. Inclusion of the Private Key

This first way is giving "here, take my whole secret" ๐Ÿ™ˆ It's done by including the private key (encrypted) in the CertRequest. That happens either in the thisMessage field of POPOPrivKey (see Appendix C) or in the PKIArchiveOptions control structure, depending on whether archival of the private key is also wanted ๐Ÿ—๏ธ๐Ÿ’œ

5.2.8.2. Indirect Method ๐ŸŽ€

Okay so, the indirect method is giving "send them a locked box, then hand over the key later" ๐Ÿ“ฆ๐Ÿ”‘. The CA doesn't return the certificate itself. It returns an encrypted certificate: the certificate is encrypted under a randomly-generated symmetric key, and that symmetric key is encrypted under the public key the certification request is for. This is the "indirect" method I mentioned back in Section 4.3.2 ๐Ÿงš

Here's how the EE proves it has the private decryption key: it sends the correct CertHash for this certificate in the certConf message. Why does that work? The EE can only compute the right CertHash if it can recover the certificate, and it can only recover the certificate if it can decrypt the symmetric key with the required private key. So the proof is basically baked into the math ๐Ÿ’…

Real talk though, this only works if the CA holds off on publishing. The CA MUST NOT publish the certificate until the certConf message arrives, because certHash is what demonstrates POP. For more details, see Section 5.3.18 ๐Ÿซถ

5.2.8.3. Challenge-Response Protocol ๐Ÿ’œ

This is the "direct" method I mentioned in Section 4.3.2. The EE does a challenge-response with the CA between CertReqMessages and CertRepMessage, using the messages POPODecKeyChall and POPODecKeyResp (more on those below) โœจ This one typically shows up when an RA verifies POP and then makes the certification request to the CA on the EE's behalf. In that setup, the CA trusts the RA to have done POP correctly before the RA asks for a certificate for the end entity ๐ŸŒธ

Here's the full flow. Quick note: req' doesn't have to wrap req as a nested message.

                EE            RA            CA
                 ---- req ---->
                 <--- chall ---
                 ---- resp --->
                               ---- req' --->
                               <--- rep -----
                               ---- conf --->
                               <--- ack -----
                 <--- rep -----
                 ---- conf --->
                 <--- ack -----

Honestly, this is way longer than the 3-way exchange in choice (2) above ๐Ÿ˜ญ But it lets a local Registration Authority get involved, and it has the iconic property that the certificate itself isn't actually created until the proof-of-possession is complete ๐Ÿ‘‘ Some environments need a different order, which might be decided by policy:

                EE            RA            CA
                 ---- req ---->
                 <--- chall ---
                 ---- resp --->
                               ---- req' --->
                               <--- rep -----
                 <--- rep -----
                 ---- conf --->
                               ---- conf --->
                               <--- ack -----
                 <--- ack -----

Now for key agreement key (KAK) pairs. The POP can use any of the 3 ways from above for encryption key pairs, with two tweaks ๐Ÿฆ‹ First, the parenthetical in bullet 2) gets swapped out for "(i.e., the certificate encrypted under the symmetric key derived from the CA's private KAK and the public key for which the certification request is being made)". Second, the first parenthetical in the challenge field of "Challenge" below gets swapped for "(using PreferredSymmAlg (see Section 5.3.19.4 and Appendix E.5) and a symmetric key derived from the CA's private KAK and the public key for which the certification request is being made)". There's also a fourth option: the POP can use the POPOSigningKey structure from [CRMF], where the alg field is DHBasedMAC and the signature field is the MAC. This works if the CA already has a D-H certificate that the EE knows about ๐Ÿงš

The challenge-response messages for proving possession of a private decryption key are below. See [MvOV97], p.404 for details ๐Ÿ“ This challenge-response exchange is tied to the earlier cert. request message (and the later cert. response and confirmation messages) by the transactionID in the PKIHeader, plus the protection (MACing or signing) applied to the PKIMessage ๐Ÿ”ฅ

     POPODecKeyChallContent ::= SEQUENCE OF Challenge
     Challenge ::= SEQUENCE {
         owf                 AlgorithmIdentifier  OPTIONAL,
         witness             OCTET STRING,
         challenge           OCTET STRING
     }

Note that the size of Rand needs to fit encryption under the requester's public key. Since "int" typically won't be longer than 64 bits, that leaves well over 100 bytes of room for the "sender" field when the modulus is 1024 bits ๐ŸŒˆ If names in some environment are so long they can't fit (for example, very long DNs), then whatever portion will fit should be used, as long as it includes at least the common name and as long as the receiver can deal meaningfully with the abbreviation ๐Ÿ™ˆ

     POPODecKeyRespContent ::= SEQUENCE OF INTEGER

5.2.8.4. Summary of PoP Options ๐ŸŒธ

This section gives several POP technique options. Using "SK" for "signing key", "EK" for "encryption key", and "KAK" for "key agreement key", the techniques boil down to this list โœจ

     RAVerified;
     SKPOP;
     EKPOPThisMessage;
     KAKPOPThisMessage;
     KAKPOPThisMessageDHMAC;
     EKPOPEncryptedCert;
     KAKPOPEncryptedCert;
     EKPOPChallengeResp; and
     KAKPOPChallengeResp.

So naturally, an end entity wants to know what the CA/RA actually supports (meaning which options it can use when requesting certificates) ๐Ÿค” These guidelines should make that clear for EE implementers ๐Ÿ’…

RAVerified. This isn't an EE decision. The RA uses this if and only if it has verified POP before forwarding the request to the CA, so the EE can't pick this technique ๐Ÿ™…โ€โ™€๏ธ

SKPOP. If the EE has a signing key pair, this is the only POP method specified for the request for the matching certificate ๐Ÿ–‹๏ธ

EKPOPThisMessage and KAKPOPThisMessage. Whether to hand its private key over to the CA/RA is an EE decision ๐Ÿ”‘ If the EE decides to reveal its key, these are the only POP methods in this specification that do it, and the key pair type decides which of the two to use ๐Ÿฆ‹

KAKPOPThisMessageDHMAC. The EE can only use this method if (1) the CA has a DH certificate available for this purpose, and (2) the EE already has a copy of that certificate. If both conditions hold, this technique is clearly supported and the EE may use it if it wants ๐Ÿ’–

EKPOPEncryptedCert, KAKPOPEncryptedCert, EKPOPChallengeResp, KAKPOPChallengeResp. The EE picks one of these (in the subsequentMessage field) in the request message, depending on preference and key pair type. The EE isn't doing POP at this point. It's just saying which method it wants to use ๐ŸŽ€ So if the CA/RA replies with a "badPOP" error, the EE can re-request using the other POP method chosen in subsequentMessage. Also, note that this specification encourages the use of the EncryptedCert choice, and says the challenge-response would typically be used when an RA is involved and doing POP verification. So the EE should be able to make an intelligent decision about which of these POP methods to pick in the request message ๐Ÿง โœจ


5.3. Operation-Specific Data Structures ๐Ÿงš

5.3.1. Initialization Request ๐ŸŒท

An Initialization request message has a CertReqMessages data structure as its PKIBody, which specifies the requested certificate(s). Typically, SubjectPublicKeyInfo, KeyId, and Validity are the template fields that can be supplied for each requested certificate (see Appendix D profiles for further information). This message is meant for entities when they first initialize into the PKI ๐ŸŒฑ

See Appendix C and [CRMF] for CertReqMessages syntax ๐Ÿ“š

5.3.2. Initialization Response ๐Ÿ’–

An Initialization response message has a CertRepMessage data structure as its PKIBody. That structure has a PKIStatusInfo field for each requested certificate, a subject certificate, and possibly a private key (normally encrypted with a session key, which is itself encrypted with the protocolEncrKey) ๐Ÿ”

See Section 5.3.4 for CertRepMessage syntax. Note that if the PKI Message Protection is "shared secret information" (see Section 5.1.3), then any certificate carried in the caPubs field may be directly trusted as a root CA certificate by the initiator ๐Ÿ‘‘

5.3.3. Certification Request ๐Ÿฆ‹

A Certification request message has a CertReqMessages data structure as its PKIBody, which specifies the requested certificates. This message is meant for existing PKI entities who want additional certificates ๐Ÿ’…

See Appendix C and [CRMF] for CertReqMessages syntax ๐Ÿ“š

Alternatively, the PKIBody MAY be a CertificationRequest (this structure is fully specified by the ASN.1 structure CertificationRequest given in [PKCS10]). This structure may be required for certificate requests for signing key pairs when interoperation with legacy systems is desired, but its use is strongly discouraged whenever it isn't absolutely necessary ๐Ÿ™ˆ

5.3.4. Certification Response ๐Ÿ“

A Certification response message has a CertRepMessage data structure as its PKIBody. It holds a status value for each requested certificate, and optionally a CA public key, failure information, a subject certificate, and an encrypted private key ๐ŸŒธ

  CertRepMessage ::= SEQUENCE {
      caPubs          [1] SEQUENCE SIZE (1..MAX) OF Certificate
                          OPTIONAL,
      response            SEQUENCE OF CertResponse
  }

  CertResponse ::= SEQUENCE {
      certReqId           INTEGER,
      status              PKIStatusInfo,
      certifiedKeyPair    CertifiedKeyPair    OPTIONAL,
      rspInfo             OCTET STRING        OPTIONAL
      -- analogous to the id-regInfo-utf8Pairs string defined
      -- for regInfo in CertReqMsg [CRMF]
  }

  CertifiedKeyPair ::= SEQUENCE {
      certOrEncCert       CertOrEncCert,
      privateKey      [0] EncryptedValue      OPTIONAL,
      -- see [CRMF] for comment on encoding
      publicationInfo [1] PKIPublicationInfo  OPTIONAL
  }

  CertOrEncCert ::= CHOICE {
      certificate     [0] Certificate,
      encryptedCert   [1] EncryptedValue
  }

Only one of the failInfo (in PKIStatusInfo) and certificate (in CertifiedKeyPair) fields can be present in each CertResponse, depending on the status. For some status values (e.g., waiting), neither of the optional fields will be present โญ

An EncryptedCert plus the relevant decryption key gets you the certificate. The point here is to let a CA return a certificate's value, with the rule that only the intended recipient can get the actual certificate ๐Ÿ”’ The benefit is that a CA can reply with a certificate even without proof that the requester is the end entity that can use the relevant private key (the proof isn't obtained until the certConf message arrives at the CA). So the CA won't have to revoke that certificate if something goes wrong with the proof-of-possession, although it MAY do so anyway, depending on policy ๐Ÿซถ

5.3.5. Key Update Request Content โœจ

okay so for key update requests we reuse the CertReqMessages syntax ๐ŸŽ€ Usually SubjectPublicKeyInfo, KeyId, and Validity are the template fields you can fill in for each key being updated. This message is for requesting updates to existing certificates that are (non-revoked and non-expired), which is why people sometimes call it a "Certificate Update" operation ๐Ÿ”„ An update is a replacement certificate that either has a new subject public key or keeps the current one (though keeping the current one may not be appropriate in some environments, so be careful, bestie ๐Ÿซถ).

See Appendix C and [CRMF] for CertReqMessages syntax.

5.3.6. Key Update Response Content ๐Ÿ’Œ

for key update responses we use the CertRepMessage syntax ๐Ÿ’… The response is identical to the initialization response, so no new surprises here.

See Section 5.3.4 for CertRepMessage syntax.

5.3.7. Key Recovery Request Content ๐Ÿ”‘

for key recovery requests the syntax is identical to the initialization request CertReqMessages ๐Ÿ’– Typically SubjectPublicKeyInfo and KeyId are the template fields that may be used to supply a signature public key you need a certificate for (check Appendix D profiles for more info ๐Ÿงš).

See Appendix C and [CRMF] for CertReqMessages syntax. Note that if a key history is required, the requester must supply a Protocol Encryption Key control in the request message. this part is SO important, don't skip it ๐ŸŒˆ

5.3.8. Key Recovery Response Content ๐Ÿ“

for key recovery responses, this is the syntax ๐Ÿ‘‘ For some status values (like waiting), none of the optional fields will show up at all.

KeyRecRepContent ::= SEQUENCE {
    status          PKIStatusInfo,
    newSigCert  [0] Certificate                   OPTIONAL,
    caCerts     [1] SEQUENCE SIZE (1..MAX) OF
                                 Certificate      OPTIONAL,
    keyPairHist [2] SEQUENCE SIZE (1..MAX) OF
                                 CertifiedKeyPair OPTIONAL
}

5.3.9. Revocation Request Content ๐Ÿ™ˆ

when you request revocation of a certificate (or several), this data structure is the one to use ๐Ÿซฃ The name of the requester lives in the PKIHeader structure, so you don't need to repeat it here.

RevReqContent ::= SEQUENCE OF RevDetails

RevDetails ::= SEQUENCE {
    certDetails         CertTemplate,
    crlEntryDetails     Extensions       OPTIONAL
}

5.3.10. Revocation Response Content ๐Ÿ’œ

the revocation response answers the request above ๐Ÿ’… If it gets produced, it goes back to whoever asked for the revocation. (A separate revocation announcement message MAY be sent to the subject of the certificate for which revocation was requested. โœจ)

RevRepContent ::= SEQUENCE {
    status        SEQUENCE SIZE (1..MAX) OF PKIStatusInfo,
    revCerts  [0] SEQUENCE SIZE (1..MAX) OF CertId OPTIONAL,
    crls      [1] SEQUENCE SIZE (1..MAX) OF CertificateList
                  OPTIONAL
}

5.3.11. Cross Certification Request Content ๐Ÿฆ‹

cross certification requests use the same syntax (CertReqMessages) as normal certification requests, but with a big restriction ๐Ÿšจ The key pair MUST have been generated by the requesting CA, and the private key MUST NOT be sent to the responding CA. This request MAY also be used by subordinate CAs to get their certificates signed by the parent CA ๐ŸŒธ

See Appendix C and [CRMF] for CertReqMessages syntax.

5.3.12. Cross Certification Response Content ๐ŸŽ€

cross certification responses use the same syntax (CertRepMessage) as normal certification responses, with one restriction: no encrypted private key can be sent ๐Ÿ”’

See Section 5.3.4 for CertRepMessage syntax.

5.3.13. CA Key Update Announcement Content ๐Ÿ“ฃ

when a CA updates its own key pair, this data structure MAY be used to announce the event ๐ŸŽ‰

CAKeyUpdAnnContent ::= SEQUENCE {
   oldWithNew         Certificate,
   newWithOld         Certificate,
   newWithNew         Certificate
}

5.3.14. Certificate Announcement ๐Ÿงš

this structure MAY be used to announce the existence of certificates โœจ

Note that this message is meant for the cases (if any) where there is no pre-existing way to publish certificates. It is not meant for situations where, for example, X.500 is the publication method ๐Ÿ“š

CertAnnContent ::= Certificate

5.3.15. Revocation Announcement โš ๏ธ

when a CA has revoked, or is about to revoke, a particular certificate, it MAY issue an announcement about that (possibly upcoming) event ๐Ÿ“ข

RevAnnContent ::= SEQUENCE {
    status              PKIStatus,
    certId              CertId,
    willBeRevokedAt     GeneralizedTime,
    badSinceDate        GeneralizedTime,
    crlDetails          Extensions  OPTIONAL
}

A CA MAY use such an announcement to warn (or notify) a subject that its certificate is about to be (or has been) revoked ๐Ÿ’€ This would typically happen when the revocation request didn't come from the subject concerned.

The willBeRevokedAt field contains the time at which a new entry will be added to the relevant CRLs โฐ

5.3.16. CRL Announcement ๐Ÿ“œ

when a CA issues a new CRL (or a set of CRLs), this data structure MAY be used to announce it ๐Ÿ’ซ

CRLAnnContent ::= SEQUENCE OF CertificateList

5.3.17. PKI Confirmation Content ๐Ÿซถ

this data structure is used in the protocol exchange as the final PKIMessage ๐Ÿ Its content is the same in all cases. Honestly there is no content, since the PKIHeader carries all the required information ๐Ÿ™ƒ

PKIConfirmContent ::= NULL

Use of this message for certificate confirmation is NOT RECOMMENDED; certConf SHOULD be used instead ๐Ÿ™…โ€โ™€๏ธ Upon receiving a PKIConfirm for a certificate response, the recipient MAY treat it as a certConf with all certificates being accepted ๐Ÿ’–

5.3.18. Certificate Confirmation Content ๐Ÿ’…

this data structure is how the client sends a confirmation to the CA/RA to accept or reject certificates ๐ŸŽ€

CertConfirmContent ::= SEQUENCE OF CertStatus

CertStatus ::= SEQUENCE {
   certHash    OCTET STRING,
   certReqId   INTEGER,
   statusInfo  PKIStatusInfo OPTIONAL
}

For any particular CertStatus, leaving out the statusInfo field means ACCEPTANCE of the specified certificate โœ… Alternatively, explicit status details (about acceptance or rejection) MAY be provided in the statusInfo field, perhaps for auditing purposes at the CA/RA ๐Ÿ—‚๏ธ

Within CertConfirmContent, leaving out a CertStatus structure for a certificate from the previous response message means REJECTION of that certificate โŒ So an empty CertConfirmContent (a zero-length SEQUENCE) MAY be used to indicate rejection of all supplied certificates ๐Ÿฅ€ See Section 5.2.8, item (2), for a discussion of the certHash field with respect to proof-of-possession ๐Ÿ”

5.3.19. PKI General Message Content ๐ŸŒˆ

InfoTypeAndValue ::= SEQUENCE {
    infoType               OBJECT IDENTIFIER,
    infoValue              ANY DEFINED BY infoType  OPTIONAL
}
-- where {id-it} = {id-pkix 4} = {1 3 6 1 5 5 7 4}
GenMsgContent ::= SEQUENCE OF InfoTypeAndValue

5.3.19.1. CA Protocol Encryption Certificate ๐Ÿ”

this MAY be used by the EE to get a certificate from the CA, which it can use to protect sensitive information during the protocol ๐Ÿ›ก๏ธ

GenMsg:    {id-it 1}, < absent >
GenRep:    {id-it 1}, Certificate | < absent >

EEs MUST ensure that the correct certificate is used for this purpose ๐ŸŽฏ

5.3.19.2. Signing Key Pair Types โœ๏ธ

this MAY be used by the EE to get the list of signature algorithms (like RSA or DSA) whose subject public key values the CA is willing to certify ๐Ÿ“‹ Quick note: for the purposes of this exchange, rsaEncryption and rsaWithSHA1, for example, count as equivalent. The question being asked is basically, "Is the CA willing to certify an RSA public key?" ๐Ÿค”

GenMsg:    {id-it 2}, < absent >
GenRep:    {id-it 2}, SEQUENCE SIZE (1..MAX) OF
                      AlgorithmIdentifier

5.3.19.3. Encryption/Key Agreement Key Pair Types ๐Ÿ—๏ธ

this MAY be used by the client to get the list of encryption/key agreement algorithms whose subject public key values the CA is willing to certify ๐Ÿ’ซ

GenMsg:    {id-it 3}, < absent >
GenRep:    {id-it 3}, SEQUENCE SIZE (1..MAX) OF
                      AlgorithmIdentifier

5.3.19.4. Preferred Symmetric Algorithm ๐ŸŽ€

this MAY be used by the client to get the CA-preferred symmetric encryption algorithm for any confidential information that needs to go between the EE and the CA (for example, if the EE wants to send its private decryption key to the CA for archival purposes) ๐Ÿ—„๏ธ

GenMsg:    {id-it 4}, < absent >
GenRep:    {id-it 4}, AlgorithmIdentifier

5.3.19.5. Updated CA Key Pair ๐Ÿ†•

this MAY be used by the CA to announce a CA key update event ๐Ÿ“ฃ

GenMsg:    {id-it 5}, CAKeyUpdAnnContent

5.3.19.6. CRL ๐Ÿ“ƒ

this MAY be used by the client to get a copy of the latest CRL ๐Ÿฆ‹

GenMsg:    {id-it 6}, < absent >
GenRep:    {id-it 6}, CertificateList

5.3.19.7. Unsupported Object Identifiers ๐Ÿ™…

this is used by the server to send back a list of object identifiers it doesn't recognize or support from the list the client submitted ๐Ÿซค

GenRep:    {id-it 7}, SEQUENCE SIZE (1..MAX) OF OBJECT IDENTIFIER

5.3.19.8. Key Pair Parameters โš™๏ธ

this MAY be used by the EE to request the domain parameters to use when generating the key pair for certain public-key algorithms ๐Ÿงฎ It can be used, for example, to request the appropriate P, Q, and G to generate the DH/DSA key, or to request a set of well-known elliptic curves โœจ

GenMsg:    {id-it 10}, OBJECT IDENTIFIER -- (Algorithm object-id)
GenRep:    {id-it 11}, AlgorithmIdentifier | < absent >

An absent infoValue in the GenRep means the algorithm specified in GenMsg is not supported ๐Ÿšซ

EEs MUST ensure that the parameters are acceptable to it and that the GenRep message is authenticated (to avoid substitution attacks) ๐Ÿ›ก๏ธ no skipping this one, it's giving security ๐Ÿ’€

5.3.19.9. Revocation Passphrase ๐Ÿ”‘

this MAY be used by the EE to send a passphrase to a CA/RA for authenticating a later revocation request (in case the appropriate signing private key isn't available anymore to authenticate the request) ๐Ÿฅน See Appendix B for further details on how this mechanism works ๐Ÿ“–

GenMsg:    {id-it 12}, EncryptedValue
GenRep:    {id-it 12}, < absent >

5.3.19.10. ImplicitConfirm ๐Ÿซง

See Section 5.1.1.1 for the definition and use of {id-it 13}.

5.3.19.11. ConfirmWaitTime โณ

See Section 5.1.1.2 for the definition and use of {id-it 14}.

5.3.19.12 Original PKIMessage ๐ŸŒท

See Section 5.1.3 for the definition and use of {id-it 15}.

5.3.19.13. Supported Language Tags ๐ŸŒ

this MAY be used to figure out the right language tag for later messages ๐Ÿ’ฌ The sender sends its list of supported languages (in order, most preferred to least), and the receiver sends back the one it wants to use. (Note: each UTF8String MUST include a language tag. ๐Ÿท๏ธ) If none of the offered tags are supported, an error MUST be returned ๐Ÿšจ

GenMsg:    {id-it 16}, SEQUENCE SIZE (1..MAX) OF UTF8String
GenRep:    {id-it 16}, SEQUENCE SIZE (1) OF UTF8String

5.3.20. PKI General Response Content ๐ŸŽ

GenRepContent ::= SEQUENCE OF InfoTypeAndValue

Examples of GenReps that MAY be supported include those listed in the subsections of Section 5.3.19 ๐Ÿงšโ€โ™€๏ธ

5.3.21. Error Message Content ๐Ÿšจ

okay so this is the data structure that EE, CA, or RA can use to spill the tea on what went wrong ๐Ÿ’… It MAY be used to carry error info, and here's how it's shaped:

ErrorMsgContent ::= SEQUENCE {
    pKIStatusInfo          PKIStatusInfo,
    errorCode              INTEGER           OPTIONAL,
    errorDetails           PKIFreeText       OPTIONAL
}

This message MAY be generated at any time during a PKI transaction ๐ŸŒธ If the client sends this request, the server MUST respond with a PKIConfirm response, or with another ErrorMsg if any part of the header isn't valid ๐Ÿ™ˆ Both sides MUST treat this message as the end of the transaction (if a transaction is actually in progress), so it's basically the period at the end of the sentence ๐Ÿ’œ

If you want protection on the message, the client MUST protect it with the same technique (signature or MAC) that the starting message of the transaction used, so the vibes match ๐Ÿซถ The CA MUST always sign it with a signature key, no exceptions ๐Ÿ”ฅ


5.3.22. Polling Request and Response ๐Ÿฆ‹

this pair of messages is for when the client needs to keep checking on the server to find out how an outstanding ir, cr, or kur transaction is doing ๐Ÿ˜ญ Basically, this is the "are we there yet?" moment, and it happens when the "waiting" PKIStatus has been received โณ

PollReqContent ::= SEQUENCE OF SEQUENCE {
    certReqId    INTEGER }

PollRepContent ::= SEQUENCE OF SEQUENCE {
    certReqId    INTEGER,
    checkAfter   INTEGER,  -- time in seconds
    reason       PKIFreeText OPTIONAL }

Here's the lowdown on when polling shows up and how it goes down. It's assumed that multiple certConf messages can be sent during transactions, and there will be one sent in response to each ip, cp, or kup that contains a CertStatus for an issued certificate ๐ŸŽ€

  1. In response to an ip, cp, or kup message, an EE will send a certConf for all issued certificates and, following the ack, a pollReq for all pending certificates โœจ
  2. In response to a pollReq, a CA/RA will return an ip, cp, or kup if one or more of the pending certificates is ready; otherwise, it will return a pollRep ๐ŸŒˆ
  3. If the EE receives a pollRep, it will wait for at least as long as the checkAfter value before sending another pollReq โญ
  4. If an ip, cp, or kup is received in response to a pollReq, then it will be treated in the same way as the initial response ๐Ÿ’–
                               START
                                 |
                                 v
                              Send ir
                                 | ip
                                 v
                            Check status
                            of returned <------------------------+
                               certs                             |
                                 |                               |
       +------------------------>|<------------------+           |
       |                         |                   |           |
       |        (issued)         v       (waiting)   |           |
     Add to <----------- Check CertResponse ------> Add to       |
    conf list           for each certificate      pending list   |
                                 /                               |
                                /                                |
                   (conf list) /     (empty conf list)           |
                              /                     ip           |
                             /                 +----------------+
      (empty pending list)  /                  |    pRep
        END <---- Send certConf         Send pReq------------>Wait
                         |                 ^   ^               |
                         |                 |   |               |
                         +-----------------+   +---------------+
                            (pending list)

In the next exchange, the end entity is enrolling for two certificates in one request, so let's watch the whole choreography play out ๐Ÿ‘€

Step  End Entity                       PKI
--------------------------------------------------------------------
1   Format ir
2                    -> ir      ->
3                                    Handle ir
4                                    Manual intervention is
                                     required for both certs.
5                    <- ip      <-
6   Process ip
7   Format pReq
8                    -> pReq     ->
9                                    Check status of cert requests
10                                   Certificates not ready
11                                   Format pRep
12                   <- pRep     <-
13  Wait
14  Format pReq
15                   -> pReq     ->
16                                   Check status of cert requests
17                                   One certificate is ready
18                                   Format ip
19                   <- ip       <-
20  Handle ip
21  Format certConf
22                   -> certConf ->
23                                   Handle certConf
24                                   Format ack
25                   <- pkiConf   <-
26  Format pReq
27                   -> pReq     ->
28                                   Check status of certificate
29                                   Certificate is ready
30                                   Format ip
31                   <- ip       <-
31  Handle ip
32  Format certConf
33                   -> certConf ->
34                                   Handle certConf
35                                   Format ack
36                   <- pkiConf  <-

6. Mandatory PKI Management Functions ๐Ÿ‘‘

some of the PKI management functions from Section 3.1 above get their own spotlight in this section โœจ

this section is about functions that are "mandatory", meaning every end entity and CA/RA implementation MUST be able to provide the functionality described here ๐Ÿซถ Think of this part as the profile of PKI management functionality that MUST be supported ๐Ÿ’… Heads up though: the functions in this section don't have to go through the PKI messages from Section 5 if alternate means work for your environment (see Appendix D for profiles of the PKIMessages that MUST be supported) ๐Ÿฆ‹

6.1. Root CA Initialization ๐ŸŒฑ

[See Section 3.1.1.2 for this document's definition of "root CA".]

a newly created root CA must produce a "self-certificate", which is a Certificate structure with the profile defined for the "newWithNew" certificate issued following a root CA key update ๐Ÿ“

so the CA's self certificate is actually useful to end entities that don't get it through "out-of-band" means, the CA must also produce a fingerprint for its certificate ๐Ÿ” End entities that grab this fingerprint securely via some "out-of-band" means can then verify the CA's self-certificate and, hence, the other attributes contained therein ๐Ÿ”

the data structure used to carry the fingerprint is the OOBCertHash ๐Ÿงš

6.2. Root CA Key Update ๐Ÿ”„

CA keys (as all other keys) have a finite lifetime, so they'll need updating on a periodic basis โฐ The certificates NewWithNew, NewWithOld, and OldWithNew (see Section 4.4.1) MAY be issued by the CA to help existing end entities who hold the current self-signed CA certificate (OldWithOld) transition securely to the new self-signed CA certificate (NewWithNew) ๐ŸŽ€ They can also help new end entities who will hold NewWithNew acquire OldWithOld securely for verification of existing data ๐Ÿ’œ

6.3. Subordinate CA Initialization ๐ŸŒฟ

[See Section 3.1.1.2 for this document's definition of "subordinate CA".]

from the perspective of PKI management protocols, initializing a subordinate CA is the same as initializing an end entity ๐Ÿ™Œ The only difference is that the subordinate CA must also produce an initial revocation list ๐Ÿ“œ

6.4. CRL production ๐Ÿ“‹

before issuing any certificates, a newly established CA (which issues CRLs) must produce "empty" versions of each CRL that will be periodically produced ๐Ÿซง

6.5. PKI Information Request ๐Ÿ’ฌ

when a PKI entity (CA, RA, or EE) wants to find out the current status of a CA, it MAY send that CA a request for such information ๐Ÿ”Ž

The CA MUST respond to the request by providing (at least) all of the information the requester asked for ๐Ÿฅฐ If some of the information can't be provided, then an error must be conveyed to the requester ๐Ÿ˜ฌ

If PKIMessages are used to request and supply this PKI information, then the request MUST be the GenMsg message, the response MUST be the GenRep message, and the error MUST be the Error message ๐Ÿ“จ These messages are protected using a MAC based on shared secret information (i.e., PasswordBasedMAC) or using any other authenticated means (if the end entity has an existing certificate) ๐Ÿ”’

6.6. Cross Certification ๐Ÿค

The requester CA is the CA that will become the subject of the cross-certificate; the responder CA will become the issuer of the cross-certificate ๐Ÿง 

the requester CA must be "up and running" before initiating the cross-certification operation ๐Ÿš€

6.6.1. One-Way Request-Response Scheme โœจ

okay so cross-certification is lowkey a one way thing ๐Ÿฆ‹. When it works, you end up with exactly one brand-new cross-certificate. If you want certs going both directions, then each CA has to take its turn and kick off its own cross-certification operation (or use some other scheme) ๐Ÿ’….

This scheme is giving perfect for when the two CAs can already verify each other's signatures (they've got some common points of trust), or when there's an out-of-band check on where the certification request actually came from ๐Ÿซถ.

Detailed Description:

Cross certification gets started at one CA, the one called the responder ๐Ÿ‘‘. The responder's CA administrator picks the CA they want to cross certify, and the responder CA equipment generates an authorization code. The responder CA administrator passes that code along by out-of-band means to the requester CA administrator. Then the requester CA administrator types the authorization code into the requester CA to kick off the on-line exchange ๐ŸŽ€.

The authorization code handles authentication and integrity. It gets used to make a symmetric key, and that symmetric key is what generates Message Authentication Codes (MACs) on every message exchanged ๐Ÿ”. (Authentication can alternatively be done with signatures instead of MACs, if the CAs can retrieve and validate the required public keys by some means, such as an out-of-band hash comparison ๐ŸŒธ.)

The requester CA starts the exchange by generating a cross-certification request (ccr) with a fresh random number (requester random number) ๐ŸŒˆ. Then it sends the ccr message over to the responder CA. The fields in this message are protected from modification with a MAC based on the authorization code ๐Ÿ›ก๏ธ.

When the responder CA gets the ccr message, it validates the message and the MAC, saves the requester random number, and generates its own random number (responder random number) โœจ. Then it generates (and archives, if it wants to) a new requester certificate. That cert contains the requester CA public key and is signed with the responder CA signature private key ๐Ÿ’œ. The responder CA sends back the cross certification response (ccp) message. The fields in this message are protected from modification with a MAC based on the authorization code ๐Ÿ“.

When the requester CA gets the ccp message, it validates the message (including the random numbers it received) and the MAC. Then it responds with the certConf message. The fields in this message are protected from modification with a MAC based on the authorization code ๐Ÿงš. The requester CA MAY write the requester certificate to the Repository as an aid to later certificate path construction ๐ŸŽ€.

When the responder CA gets the certConf message, it validates the message and the MAC, then sends back an acknowledgement using the PKIConfirm message ๐Ÿซถ. It MAY also publish the requester certificate as an aid to later path construction ๐Ÿ’–.

Notes:

  1. The ccr message must contain a "complete" certification request. Translation: all fields except the serial number (including, e.g., a BasicConstraints extension) must be specified by the requester CA ๐Ÿ“.
  2. The ccp message SHOULD contain the verification certificate of the responder CA. If it's there, the requester CA must then verify this certificate (for example, via the "out-of-band" mechanism) ๐Ÿ”.

(A simpler, non-interactive model of cross-certification may also be envisioned, in which the issuing CA acquires the subject CA's public key from some repository, verifies it via some out-of-band mechanism, and creates and publishes the cross-certificate without the subject CA's explicit involvement. This model may be perfectly legitimate for many environments, but since it does not require any protocol message exchanges, its detailed description is outside the scope of this specification. ๐ŸŒ™)


6.7. End Entity Initialization ๐ŸŒธ

As with CAs, end entities need to get initialized too ๐Ÿ™ˆ. Initialization of end entities takes at least two steps:

  • acquisition of PKI information
  • out-of-band verification of one root-CA public key

(other possible steps include the retrieval of trust condition information and/or out-of-band verification of other CA public keys ๐Ÿ”Ž).

6.7.1. Acquisition of PKI Information ๐Ÿ“ฅ

The information REQUIRED is:

  • the current root-CA public key
  • (if the certifying CA is not a root-CA) the certification path from the root CA to the certifying CA together with appropriate revocation lists
  • the algorithms and algorithm parameters that the certifying CA supports for each relevant usage

Additional information could be needed (e.g., supported extensions or CA policy information) to produce a certification request that will succeed. But honestly, for simplicity, we don't mandate that the end entity gets this information via the PKI messages ๐Ÿคทโ€โ™€๏ธ. The end result is just that some certification requests may fail (e.g., if the end entity wants to generate its own encryption key, but the CA doesn't allow that) ๐Ÿ’€.

The required information MAY be acquired as described in Section 6.5 ๐Ÿงš.

6.7.2. Out-of-Band Verification of Root-CA Key ๐Ÿ”

An end entity must securely possess the public key of its root CA. One way to do that is to give the end entity the CA's self-certificate fingerprint via some secure "out-of-band" means. Then the end entity can securely use the CA's self-certificate ๐Ÿ’œ.

See Section 6.1 for further details ๐ŸŽ€.


6.8. Certificate Request ๐Ÿ“œ

An initialized end entity MAY request an additional certificate at any time (for any purpose) โœจ. This request gets made using the certification request (cr) message. If the end entity already has a signing key pair (with a corresponding verification certificate), then this cr message will typically be protected by the entity's digital signature ๐Ÿ–‹๏ธ. The CA returns the new certificate (if the request works out) in a CertRepMessage ๐Ÿ“.


6.9. Key Update ๐Ÿ”‘

When a key pair is about to expire, the relevant end entity MAY request a key update. That means it MAY request that the CA issue a new certificate for a new key pair (or, in certain circumstances, a new certificate for the same key pair) ๐Ÿ”„. The request is made using a key update request (kur) message (called a "Certificate Update" operation in some environments ๐ŸŒˆ). If the end entity already has a signing key pair (with a corresponding verification certificate), then this message will typically be protected by the entity's digital signature ๐Ÿ›ก๏ธ. The CA returns the new certificate (if the request works) in a key update response (kup) message, which is syntactically identical to a CertRepMessage ๐Ÿ‘‘.


7. Version Negotiation ๐Ÿฆ‹

This section defines the version negotiation used to support older protocols between client and servers ๐Ÿง .

If a client knows the protocol version(s) the server supports (e.g., from a previous PKIMessage exchange or via some out-of-band means), then it MUST send a PKIMessage with the highest version supported by both it and the server ๐Ÿค. If a client doesn't know what version(s) the server supports, then it MUST send a PKIMessage using the highest version it supports ๐ŸŽฏ.

If a server receives a message with a version it supports, then the version of the response message MUST be the same as the received version โœ…. If a server receives a message with a version higher or lower than it supports, then it MUST send back an ErrorMsg with the unsupportedVersion bit set (in the failureInfo field of the pKIStatusInfo) ๐Ÿšจ. If the received version is higher than the highest supported version, then the version in the error message MUST be the highest version the server supports. If the received version is lower than the lowest supported version, then the version in the error message MUST be the lowest version the server supports ๐Ÿ“.

If a client gets back an ErrorMsgContent with the unsupportedVersion bit set and a version it supports, then it MAY retry the request with that version ๐Ÿ”.

7.1. Supporting RFC 2510 Implementations ๐Ÿ•ฐ๏ธ

RFC 2510 didn't specify how implementations should behave when they receive versions they don't understand, since there was only one version in existence back then ๐Ÿ™ƒ. With the introduction of this present revision of the specification, the following versioning behaviour is recommended ๐ŸŒŸ.

7.1.1. Clients Talking to RFC 2510 Servers ๐Ÿค™

If, after sending a cmp2000 message, a client receives an ErrorMsgContent with a version of cmp1999, then it MUST abort the current transaction. It MAY subsequently retry the transaction using cmp1999 messages ๐Ÿ”„.

If a client receives a non-error PKIMessage with a version of cmp1999, then it MAY decide to continue the transaction (if the transaction hasn't finished) using RFC 2510 semantics ๐Ÿงฉ. If it doesn't choose to do that and the transaction isn't finished, then it MUST abort the transaction and send an ErrorMsgContent with a version of cmp1999 ๐Ÿ›‘.

7.1.2. Servers Receiving Version cmp1999 PKIMessages ๐Ÿ–ฅ๏ธ

If a server receives a version cmp1999 message, it MAY revert to RFC 2510 behaviour and respond with version cmp1999 messages ๐Ÿ•น๏ธ. If it doesn't choose to do that, then it MUST send back an ErrorMsgContent as described above in Section 7 ๐Ÿ“จ.


8. Security Considerations ๐Ÿ”ฅ

โš ๏ธ Heads up, bestie: this part is seriously important. Please read it carefully before you ship anything ๐Ÿ˜ญ.

8.1. Proof-Of-Possession with a Decryption Key ๐Ÿ”“

Some cryptographic considerations are worth spelling out explicitly ๐Ÿง. In the protocols specified above, when an end entity is required to prove possession of a decryption key, it is effectively challenged to decrypt something (its own certificate). This scheme (and many others!) could be vulnerable to an attack if the possessor of the decryption key in question could be fooled into decrypting an arbitrary challenge and returning the cleartext to an attacker ๐Ÿ˜ฑ. Although in this specification a number of other failures in security are required in order for this attack to succeed, it's conceivable that some future services (e.g., notary, trusted time) could potentially be vulnerable to such attacks ๐Ÿ•ต๏ธโ€โ™€๏ธ. For this reason, we re-iterate the general rule that implementations should be very careful about decrypting arbitrary "ciphertext" and revealing recovered "plaintext," since that practice can lead to serious security vulnerabilities ๐Ÿšซ.

8.2. Proof-Of-Possession by Exposing the Private Key ๐Ÿ—๏ธ

Note also that exposing a private key to the CA/RA as a proof-of-possession technique can carry some security risks (depending on whether or not the CA/RA can be trusted to handle that material appropriately) ๐Ÿฅบ. Implementers are advised to:

  • Exercise caution in selecting and using this particular POP mechanism
  • When appropriate, have the user of the application explicitly state that they are willing to trust the CA/RA to have a copy of their private key before proceeding to reveal the private key ๐Ÿ™

8.3. Attack Against Diffie-Hellman Key Exchange ๐Ÿ’…

okay bestie, this one is a whole plot twist ๐Ÿ˜ญ a small subgroup attack during a Diffie-Hellman key exchange can go like this. a sneaky end entity deliberately picks D-H parameters so they can work out (a significant number of bits of) the D-H private key of the CA during a key archival or key recovery operation. ๐Ÿ•ต๏ธโ€โ™€๏ธ once they have that, the EE can retrieve the decryption private key of another unsuspecting end entity, EE2, during EE2's totally legit key archival or key recovery operation with that CA. not okay!! ๐Ÿ’€

so how do we avoid this? there are two courses of action. (1) the CA may generate a fresh D-H key pair to be used as a protocol encryption key pair for each EE it interacts with. ๐Ÿฆ‹ (2) the CA may enter into a key validation protocol (not specified in this document) with each requesting end entity, to make sure that the EE's protocol encryption key pair won't make this attack possible. ๐Ÿ”

option (1) is clearly the simpler one, since it needs no extra protocol exchanges from either party, so it is RECOMMENDED ๐ŸŽ€โœจ


9. IANA Considerations ๐ŸŒธ

so the PKI General Message types are identified by object identifiers (OIDs) ๐Ÿ”ข and the OIDs for the PKI General Message types defined in this document were assigned from an arc that IANA delegated to the PKIX Working Group. ๐Ÿ“

the cryptographic algorithms mentioned in this document are identified by OIDs too, and those OIDs came from several arcs owned by different orgs, including RSA Security, Entrust Technologies, IANA and IETF. it's giving teamwork ๐Ÿซถ

if new encryption algorithms show up later, the advocates for those algorithms are expected to assign the necessary OIDs from their own arcs. ๐Ÿงš

and no further action by IANA is necessary for this document or any anticipated updates. โœ… slay, IANA gets a break ๐Ÿ’–


Normative References ๐Ÿ“š

  • [X509] International Organization for Standardization and International Telecommunications Union, "Information technology - Open Systems Interconnection - The Directory: Public-key and attribute certificate frameworks", ISO Standard 9594-8:2001, ITU-T Recommendation X.509, March 2000. ๐Ÿ’œ
  • [MvOV97] Menezes, A., van Oorschot, P. and S. Vanstone, "Handbook of Applied Cryptography", CRC Press ISBN 0-8493-8523-7, 1996. ๐Ÿ“–
  • [RFC2104] Krawczyk, H., Bellare, M., and R. Canetti, "HMAC: Keyed-Hashing for Message Authentication", RFC 2104, February 1997. ๐Ÿ”
  • [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997. ๐Ÿ‘‘
  • [RFC2202] Cheng, P. and R. Glenn, "Test Cases for HMAC-MD5 and HMAC-SHA-1", RFC 2202, September 1997. ๐Ÿงช
  • [RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO 10646", STD 63, RFC 3629, November 2003. ๐ŸŒˆ
  • [RFC2482] Whistler, K. and G. Adams, "Language Tagging in Unicode Plain Text", RFC 2482, January 1999. ๐Ÿท๏ธ
  • [CRMF] Schaad, J., "Internet X.509 Public Key Infrastructure Certificate Request Message Format (CRMF)", RFC 4211, September 2005. ๐Ÿ“จ
  • [RFC3066] Alvestrand, H., "Tags for the Identification of Languages", BCP 47, RFC 3066, January 2001. ๐ŸŒ

Informative References ๐Ÿฆ‹

  • [CMPtrans] Kapoor, A., Tschalar, R. and T. Kause, "Internet X.509 Public Key Infrastructure -- Transport Protocols for CMP", Work in Progress. 2004. ๐Ÿšง
  • [PKCS7] RSA Laboratories, "The Public-Key Cryptography Standards - Cryptographic Message Syntax Standard. Version 1.5", PKCS 7, November 1993. ๐Ÿ’Œ
  • [PKCS10] Nystrom, M., and B. Kaliski, "The Public-Key Cryptography Standards - Certification Request Syntax Standard, Version 1.7", RFC 2986, May 2000. ๐Ÿ“
  • [PKCS11] RSA Laboratories, "The Public-Key Cryptography Standards - Cryptographic Token Interface Standard. Version 2.10", PKCS 11, December 1999. ๐Ÿ”‘
  • [RFC1847] Galvin, J., Murphy, S., Crocker, S., and N. Freed, "Security Multiparts for MIME: Multipart/Signed and Multipart/Encrypted", RFC 1847, October 1995. ๐Ÿ“Ž
  • [RFC2559] Boeyen, S., Howes, T. and P. Richard, "Internet X.509 Public Key Infrastructure Operational Protocols - LDAPv2", RFC 2559, April 1999. ๐Ÿ—‚๏ธ
  • [RFC2585] Housley, R. and P. Hoffman, "Internet X.509 Public Key Infrastructure Operational Protocols: FTP and HTTP", RFC 2585, May 1999. ๐ŸŒ
  • [FIPS-180] National Institute of Standards and Technology, "Secure Hash Standard", FIPS PUB 180-1, May 1994. ๐Ÿงฎ
  • [FIPS-186] National Institute of Standards and Technology, "Digital Signature Standard", FIPS PUB 186, May 1994. โœ๏ธ
  • [ANSI-X9.42] American National Standards Institute, "Public Key Cryptography for The Financial Services Industry: Agreement of Symmetric Keys Using Discrete Logarithm Cryptography", ANSI X9.42, February 2000. ๐Ÿฆ

Appendix A. Reasons for the Presence of RAs ๐ŸŽ€

okay so the reasons that justify having an RA can be split into technical factors and organizational ones. ๐Ÿง 

technical reasons include the following:

  • if hardware tokens are in use, not all end entities will have the equipment needed to initialize them. the RA equipment can include the necessary functionality (this may also be a matter of policy). ๐Ÿ”ง
  • some end entities may not be able to publish certificates. again, the RA may be suitably placed for this. ๐Ÿ“ค
  • the RA will be able to issue signed revocation requests on behalf of the end entities associated with it, whereas the end entity may not be able to do this (if the key pair is completely lost). ๐Ÿ˜ฑ

some of the organizational reasons that argue for an RA are these:

  • it may be more cost effective to concentrate functionality in the RA equipment than to supply functionality to all end entities (especially if special token initialization equipment is to be used). ๐Ÿ’ธ
  • establishing RAs within an organization can reduce the number of CAs required, which is sometimes desirable. โœจ
  • RAs may be better placed to identify people with their "electronic" names, especially if the CA is physically remote from the end entity. ๐Ÿ›ฐ๏ธ
  • for many applications, there will already be some administrative structure in place, so candidates for the role of RA are easy to find (which may not be true of the CA). ๐Ÿ™Œ

Appendix B. The Use of Revocation Passphrase ๐Ÿ”โœจ

okay bestie, revoking a cert is a whole serious moment, so the request needs real security or literally anyone could try to take your cert down ๐Ÿ’€. A digital signature on the request is MANDATORY to support in this spec if revocation requests are supported at all ๐Ÿ–Š๏ธ. It can handle the authentication, BUT sometimes another method is lowkey better, like when your private key is gone and you still need to revoke before you re-certify with a new key pair ๐Ÿ˜ญ. So a PasswordBasedMAC on the request is also MANDATORY to support in this spec (subject to local security policy for a given environment) if revocation requests are supported AND shared secret info can be set up between the requester and the responder before anyone needs to revoke ๐Ÿ”‘.

Some environments have been using something called a "revocation passphrase" ๐ŸŽ€. It's a value with lots of entropy (so a long passphrase, not a short password) that gets shared between (only) the entity and the CA/RA at some point before revocation. Later, that value is used to authenticate the revocation request โœจ.

In this spec, the technique for setting up shared secret info (aka a revocation passphrase) is OPTIONAL to support ๐ŸŒธ. Here's exactly how it works in CMP messages:

  • โœจ The OID and value from Section 5.3.19.9 MAY be sent in a GenMsg message at any time, or MAY be sent in the generalInfo field of the PKIHeader of any PKIMessage at any time. (Like, the EncryptedValue can ride along in the header of the certConf message that confirms acceptance of certs requested in an initialization request or certificate request message.) This sends a revocation passphrase the entity picked (aka the decrypted bytes of the encValue field) over to the relevant CA/RA, and the transfer has proper confidentiality because the passphrase is encrypted under the CA/RA's protocolEncryptionKey ๐Ÿ”’.
  • ๐Ÿ’… If a CA/RA receives the revocation passphrase (OID and value specified in Section 5.3.19.9) in a GenMsg, it MUST construct and send a GenRep message that includes the OID (with absent value) specified in Section 5.3.19.9. If the CA/RA receives the revocation passphrase in the generalInfo field of a PKIHeader of any PKIMessage, it MUST include the OID (with absent value) in the generalInfo field of the PKIHeader of the corresponding response PKIMessage. If the CA/RA can't return the appropriate response message for any reason, it MUST send an error message with a status of "rejection" and, optionally, a failInfo reason set.
  • ๐Ÿงš The valueHint field of EncryptedValue MAY contain a key identifier (chosen by the entity, along with the passphrase itself) to help with later retrieval of the correct passphrase (e.g., when the revocation request is constructed by the entity and received by the CA/RA).
  • ๐Ÿฆ‹ The revocation request message is protected by a PasswordBasedMAC, with the revocation passphrase as the key. If appropriate, the senderKID field in the PKIHeader MAY contain the value previously transmitted in valueHint.

Using this technique, the revocation passphrase can be initially established and updated at any time without requiring extra messages or out-of-band exchanges ๐Ÿ™Œ. For example, the revocation request message itself (protected and authenticated through a MAC that uses the revocation passphrase as a key) may contain, in the PKIHeader, a new revocation passphrase to be used for authenticating future revocation requests for any of the entity's other certificates. In some environments this may be preferable to mechanisms that reveal the passphrase in the revocation request message, because revealing it can allow a denial-of-service attack where an unauthorized third party uses the revealed passphrase to authenticate revocation requests on the entity's other certificates ๐Ÿ˜ฑ. However, since the passphrase is not revealed in the request message, there is no requirement that the passphrase must always be updated when a revocation request is made (that is, the same passphrase MAY be used by an entity to authenticate revocation requests for different certificates at different times).

Also, this technique can give strong cryptographic protection over the entire revocation request message even when a digital signature is not used ๐Ÿ›ก๏ธ. Techniques that authenticate the revocation request by simply revealing the revocation passphrase typically don't protect the fields of the request message cryptographically. That means a request to revoke one certificate could be changed by an unauthorized third party into a request to revoke another certificate for that entity ๐Ÿ™ˆ.

Appendix C. Request Message Behavioral Clarifications ๐Ÿ“๐Ÿ’–

In the case of updates to [CRMF] that cause interpretation or interoperability issues, [CRMF] SHALL be the normative document ๐Ÿซถ.

The following definitions are from [CRMF]. They're included here to codify behavioral clarifications to that request message. Otherwise, all syntax and semantics are identical to [CRMF] ๐Ÿ’œ.

CertRequest ::= SEQUENCE {
    certReqId     INTEGER,
    certTemplate  CertTemplate,
    controls      Controls OPTIONAL }

-- If certTemplate is an empty SEQUENCE (i.e., all fields
-- omitted), then controls MAY contain the
-- id-regCtrl-altCertTemplate control, specifying a template
-- for a certificate other than an X.509v3 public-key
-- certificate.  Conversely, if certTemplate is not empty
-- (i.e., at least one field is present), then controls MUST
-- NOT contain id-regCtrl- altCertTemplate.  The new control is
-- defined as follows:

id-regCtrl-altCertTemplate OBJECT IDENTIFIER ::= {id-regCtrl 7}
AltCertTemplate ::= AttributeTypeAndValue

POPOSigningKey ::= SEQUENCE {
    poposkInput           [0] POPOSigningKeyInput OPTIONAL,
    algorithmIdentifier   AlgorithmIdentifier,
    signature             BIT STRING }

-- **********
-- * For the purposes of this specification, the ASN.1 comment
-- * given in [CRMF] pertains not only to certTemplate, but
-- * also to the altCertTemplate control.  That is,
-- **********
-- * The signature (using "algorithmIdentifier") is on the
-- * DER-encoded value of poposkInput (i.e., the "value" OCTETs
-- * of the POPOSigningKeyInput DER).  NOTE: If CertReqMsg
-- * certReq certTemplate (or the altCertTemplate control)
-- * contains the subject and publicKey values, then poposkInput
-- * MUST be omitted and the signature MUST be computed on the
-- * DER-encoded value of CertReqMsg certReq (or the DER-
-- * encoded value of AltCertTemplate).  If
-- * certTemplate/altCertTemplate does not contain both the
-- * subject and public key values (i.e., if it contains only
-- * one of these, or neither), then poposkInput MUST be present
-- * and MUST be signed.
-- **********

POPOPrivKey ::= CHOICE {
    thisMessage       [0] BIT STRING,

-- **********
-- * the type of "thisMessage" is given as BIT STRING in
-- * [CRMF]; it should be "EncryptedValue" (in accordance
-- * with Section 5.2.2, "Encrypted Values", of this specification).
-- * Therefore, this document makes the behavioral clarification
-- * of specifying that the contents of "thisMessage" MUST be encoded
-- * as an EncryptedValue and then wrapped in a BIT STRING.  This
-- * allows the necessary conveyance and protection of the
-- * private key while maintaining bits-on-the-wire compatibility
-- * with [CRMF].
-- **********

    subsequentMessage [1] SubsequentMessage,
    dhMAC             [2] BIT STRING }

Appendix D. PKI Management Message Profiles (REQUIRED). ๐ŸŽ€โœจ

This appendix has the detailed profiles for the PKIMessages that MUST be supported by conforming implementations (see Section 6) ๐Ÿ’….

Profiles for the PKIMessages used in these PKI management operations are provided:

  • initial registration/certification ๐ŸŒˆ
  • basic authenticated scheme ๐Ÿ”
  • certificate request ๐Ÿ“œ
  • key update ๐Ÿ”„

D.1. General Rules for Interpretation of These Profiles. ๐Ÿ“–

  1. Where OPTIONAL or DEFAULT fields aren't mentioned in individual profiles, they SHOULD be absent from the relevant message (i.e., a receiver can validly reject a message containing such fields as being syntactically incorrect). Mandatory fields aren't mentioned if they have an obvious value (e.g., in this version of the specification, pvno is always 2) ๐Ÿ‘‘.
  2. Where structures occur in more than one message, they are separately profiled as appropriate ๐Ÿงฉ.
  3. The algorithmIdentifiers from PKIMessage structures are profiled separately ๐Ÿ”.
  4. A "special" X.500 DN is called the "NULL-DN". This means a DN containing a zero-length SEQUENCE OF RelativeDistinguishedNames (its DER encoding is then '3000'H) ๐Ÿซง.
  5. Where a GeneralName is required for a field, but no suitable value is available (e.g., an end entity produces a request before knowing its name), then the GeneralName is to be an X.500 NULL-DN (i.e., the Name field of the CHOICE is to contain a NULL-DN). This special value can be called a "NULL-GeneralName" ๐Ÿ™ˆ.
  6. Where a profile omits to specify the value for a GeneralName, then the NULL-GeneralName value is to be present in the relevant PKIMessage field. This happens with the sender field of the PKIHeader for some messages ๐Ÿ“.
  7. Where any ambiguity comes up due to naming of fields, the profile names these using a "dot" notation (e.g., "certTemplate.subject" means the subject field within a field called certTemplate) ๐Ÿฆ‹.
  8. Where a "SEQUENCE OF types" is part of a message, a zero-based array notation is used to describe fields within the SEQUENCE OF (e.g., crm[0].certReq.certTemplate.subject refers to a subfield of the first CertReqMsg contained in a request message) ๐ŸŒธ.
  9. All PKI message exchanges in Appendix D.4 to D.6 require a certConf message to be sent by the initiating entity and a PKIConfirm to be sent by the responding entity. The PKIConfirm isn't included in some of the profiles given, since its body is NULL and its header contents are clear from the context. Any authenticated means can be used for the protectionAlg (e.g., password-based MAC, if shared secret information is known, or signature) ๐Ÿซถ.

D.2. Algorithm Use Profile ๐Ÿ’…

okay bestie, this is the algorithm cheat sheet ๐Ÿงš The table shows where each algorithm gets used inside PKI management protocols. The columns are:

  • Name: an identifier used for message profiles โœจ
  • Use: where and for what the algorithm gets used ๐ŸŒธ
  • Mandatory: an AlgorithmIdentifier which MUST be supported by conforming implementations ๐Ÿซถ (that MUST is the big one, everyone has to have it, no exceptions)
  • Others: alternatives to the mandatory AlgorithmIdentifier ๐Ÿฆ‹
Name         Use                      Mandatory        Others

MSG_SIG_ALG  Protection of PKI        DSA/SHA-1        RSA/MD5,
             messages using signature                  ECDSA, ...
MSG_MAC_ALG  protection of PKI        PasswordBasedMac HMAC,
             messages using MACing                     X9.9...
SYM_PENC_ALG symmetric encryption of  3-DES (3-key-    AES,RC5,
             an end entity's private  EDE, CBC mode)   CAST-128...
             key where symmetric
             key is distributed
             out-of-band
PROT_ENC_ALG asymmetric algorithm     D-H              RSA,
             used for encryption of                    ECDH, ...
             (symmetric keys for
             encryption of) private
             keys transported in
             PKIMessages
PROT_SYM_ALG symmetric encryption     3-DES (3-key-    AES,RC5,
             algorithm used for       EDE, CBC mode)   CAST-128...
             encryption of private
             key bits (a key of this
             type is encrypted using
             PROT_ENC_ALG)

Mandatory AlgorithmIdentifiers and Specifications: here's the full lineup ๐Ÿ‘‘

DSA/SHA-1: ๐Ÿ”ฅ

  • AlgId: {1 2 840 10040 4 3};
  • Digital Signature Standard [FIPS-186]
  • Public Modulus size: 1024 bits.

PasswordBasedMac: ๐Ÿ’œ

  • AlgId: {1 2 840 113533 7 66 13}, with SHA-1 {1 3 14 3 2 26} as the owf parameter and HMAC-SHA1 {1 3 6 1 5 5 8 1 2} as the mac parameter;
  • (this specification), along with
  • Secure Hash Standard [FIPS-180] and [RFC2104]
  • HMAC key size: 160 bits (i.e., "K" = "H" in Section 5.1.3.1, "Shared secret information")

3-DES: ๐ŸŽ€

  • AlgId: {1 2 840 113549 3 7};
  • (used in RSA's BSAFE and in S/MIME).

D-H: ๐ŸŒˆ

  • AlgId: {1 2 840 10046 2 1};

[ANSI-X9.42] ๐Ÿ“

  • Public Modulus Size: 1024 bits.
DomainParameters ::= SEQUENCE {
   p       INTEGER, -- odd prime, p=jq +1
   g       INTEGER, -- generator, g^q = 1 mod p
   q       INTEGER, -- prime factor of p-1
   j       INTEGER OPTIONAL, -- cofactor, j>=2
   validationParms  ValidationParms OPTIONAL

}
ValidationParms ::= SEQUENCE {
   seed          BIT STRING, -- seed for prime generation
   pGenCounter   INTEGER     -- parameter verification
}

D.3. Proof-of-Possession Profile ๐Ÿฆ‹

okay so this bit is about proof-of-possession, which is basically showing you actually own the key you're asking a certificate for ๐Ÿ”‘ The POP fields go in the signature field of the pop field of the ProofOfPossession structure, and this is for when you're proving you hold a private signing key that matches a public verification key you've requested a certificate for โœจ

Field               Value         Comment

algorithmIdentifier MSG_SIG_ALG   only signature protection is
                                  allowed for this proof

signature           present       bits calculated using MSG_SIG_ALG
Heads up: proof-of-possession for a private decryption key (the one matching a public encryption key you requested a cert for) does NOT use this profile. Instead, the CertHash field of the certConf message gets used ๐Ÿ™ˆ

Not every CA/RA is going to do Proof-of-Possession (of a signing key, a decryption key, or a key agreement key) in the PKIX-CMP in-band certification request protocol ๐Ÿ’… How POP gets done MAY ultimately be a policy issue, and that should be made explicit for each CA in its publicized Policy OID and Certification Practice Statement. ๐Ÿ’–

Here's the main point though: this specification MANDATES that CA/RA entities MUST do POP (by some means) as part of the certification process ๐Ÿ˜ญ And every end entity MUST be prepared to provide POP, which means these components of the PKIX-CMP protocol MUST be supported. No skipping this one, periodt ๐Ÿ‘‘

D.4. Initial Registration/Certification (Basic Authenticated Scheme) โœจ

okay so this one is the "brand new end entity asking for its very first certificate" flow ๐Ÿผ๐Ÿ’– an (uninitialized) end entity asks a CA for a first certificate. The CA replies with a message holding the certificate, the end entity sends back a certificate confirmation, and then the CA sends a PKIConfirm to close the transaction ๐Ÿ”’ and yes, every message is authenticated, no cap ๐Ÿซถ

this scheme lets the end entity ask for a certificate on a key it generated locally, which is usually a signature key ๐Ÿ–Š๏ธ the end entity MAY also choose to ask for the CA to centrally generate and certify another key pair, which is usually an encryption key pair ๐ŸŽ€

certification can only be requested for one locally generated public key at a time. if you want more, send separate PKIMessages ๐Ÿ“ฆ

the end entity MUST support proof-of-possession of the private key that goes with the locally generated public key ๐Ÿ”‘ this part is non-negotiable bestie ๐Ÿ˜ค

Preconditions:

  1. The end entity can authenticate the CA's signature based on out-of-band means ๐Ÿ•ต๏ธโ€โ™€๏ธ
  2. The end entity and the CA share a symmetric MACing key ๐Ÿค

Message flow:

 Step# End entity                           PKI
   1   format ir
   2                      ->   ir      ->
   3                                        handle ir
   4                                        format ip
   5                      <-   ip      <-
   6   handle ip
   7   format certConf
   8                      ->   certConf ->
   9                                        handle certConf
  10                                        format PKIConf
  11                      <-   PKIConf  <-
  12   handle PKIConf

for this profile we're setting some strict rules, because we're being so organised about it ๐Ÿ“‹ the end entity MUST include all of its CertReqMsg (that's one or two) in a single PKIMessage. the PKI (CA) MUST send back a single response PKIMessage containing the complete response, including the OPTIONAL second key pair if it was asked for and centralized key generation is supported. for simplicity, this message MUST be the final one, so no "waiting" status value allowed ๐Ÿ™…โ€โ™€๏ธ

the end entity has an out-of-band interaction with the CA/RA ๐Ÿคณ that transaction sets up the shared secret, the referenceNumber, and optionally the distinguished name used for both the sender and the subject name in the certificate template ๐ŸŒธ it is RECOMMENDED that the shared secret be at least 12 characters long ๐Ÿ’ช

Initialization Request -- ir

Field                Value

recipient            CA name

  -- the name of the CA who is being asked to produce a certificate
protectionAlg        MSG_MAC_ALG
  -- only MAC protection is allowed for this request, based
  -- on initial authentication key
senderKID            referenceNum
  -- the reference number which the CA has previously issued
  -- to the end entity (together with the MACing key)
transactionID        present
  -- implementation-specific value, meaningful to end
  -- entity.
  -- [If already in use at the CA, then a rejection message MUST
  -- be produced by the CA]

senderNonce          present
  -- 128 (pseudo-)random bits
freeText             any valid value
body                 ir (CertReqMessages)
                     only one or two CertReqMsg
                     are allowed
  -- if more certificates are required, requests MUST be
  -- packaged in separate PKIMessages

CertReqMsg           one or two present
  -- see below for details, note: crm[0] means the first
  -- (which MUST be present), crm[1] means the second (which
  -- is OPTIONAL, and used to ask for a centrally-generated key)

crm[0].certReq.      fixed value of zero
   certReqId
  -- this is the index of the template within the message
crm[0].certReq       present
   certTemplate
  -- MUST include subject public key value, otherwise unconstrained
crm[0].pop...        optionally present if public key
   POPOSigningKey    from crm[0].certReq.certTemplate is
                     a signing key
  -- proof-of-possession MAY be required in this exchange
  -- (see Appendix D.3 for details)
crm[0].certReq.      optionally present
   controls.archiveOptions
  -- the end entity MAY request that the locally-generated
  -- private key be archived

crm[0].certReq.      optionally present
   controls.publicationInfo
  -- the end entity MAY ask for publication of resulting cert.

crm[1].certReq       fixed value of one

   certReqId
  -- the index of the template within the message
crm[1].certReq       present
   certTemplate
   -- MUST NOT include actual public key bits, otherwise
   -- unconstrained (e.g., the names need not be the same as in
   -- crm[0]).  Note that subjectPublicKeyInfo MAY be present
   -- and contain an AlgorithmIdentifier followed by a
   -- zero-length BIT STRING for the subjectPublicKey if it is
   -- desired to inform the CA/RA of algorithm and parameter
   -- preferences regarding the to-be-generated key pair.

crm[1].certReq.      present [object identifier MUST be PROT_ENC_ALG]

   controls.protocolEncrKey
  -- if centralized key generation is supported by this CA,
  -- this short-term asymmetric encryption key (generated by
  -- the end entity) will be used by the CA to encrypt (a
  -- symmetric key used to encrypt) a private key generated by
  -- the CA on behalf of the end entity

crm[1].certReq.      optionally present
   controls.archiveOptions
crm[1].certReq.      optionally present
   controls.publicationInfo
protection           present
  -- bits calculated using MSG_MAC_ALG

Initialization Response -- ip

Field                Value

sender               CA name
  -- the name of the CA who produced the message
messageTime          present
  -- time at which CA produced message
protectionAlg        MS_MAC_ALG
  -- only MAC protection is allowed for this response
senderKID            referenceNum
  -- the reference number that the CA has previously issued to the
  -- end entity (together with the MACing key)
transactionID        present
  -- value from corresponding ir message
senderNonce          present
  -- 128 (pseudo-)random bits
recipNonce           present
  -- value from senderNonce in corresponding ir message
freeText             any valid value
body                 ip (CertRepMessage)
                     contains exactly one response
                     for each request

  -- The PKI (CA) responds to either one or two requests as
  -- appropriate.  crc[0] denotes the first (always present);
  -- crc[1] denotes the second (only present if the ir message
  -- contained two requests and if the CA supports centralized
  -- key generation).
crc[0].              fixed value of zero
   certReqId
  -- MUST contain the response to the first request in the
  -- corresponding ir message

crc[0].status.       present, positive values allowed:
   status               "accepted", "grantedWithMods"
                     negative values allowed:
                        "rejection"
crc[0].status.       present if and only if
   failInfo          crc[0].status.status is "rejection"
crc[0].              present if and only if
   certifiedKeyPair  crc[0].status.status is
                        "accepted" or "grantedWithMods"
certificate          present unless end entity's public
                     key is an encryption key and POP
                     is done in this in-band exchange
encryptedCert        present if and only if end entity's
                     public key is an encryption key and
                     POP done in this in-band exchange
publicationInfo      optionally present

  -- indicates where certificate has been published (present
  -- at discretion of CA)

crc[1].              fixed value of one
   certReqId
  -- MUST contain the response to the second request in the
  -- corresponding ir message
crc[1].status.       present, positive values allowed:
   status               "accepted", "grantedWithMods"
                     negative values allowed:
                        "rejection"
crc[1].status.       present if and only if
   failInfo          crc[0].status.status is "rejection"
crc[1].              present if and only if
   certifiedKeyPair  crc[0].status.status is "accepted"
                     or "grantedWithMods"
certificate          present
privateKey           present
  -- see Appendix C, Request Message Behavioral Clarifications
publicationInfo      optionally present
  -- indicates where certificate has been published (present
  -- at discretion of CA)

protection           present
  -- bits calculated using MSG_MAC_ALG
extraCerts           optionally present
  -- the CA MAY provide additional certificates to the end
  -- entity

Certificate confirm; certConf

Field                Value

sender               present
  -- same as in ir
recipient            CA name
  -- the name of the CA who was asked to produce a certificate
transactionID        present
  -- value from corresponding ir and ip messages
senderNonce          present
  -- 128 (pseudo-) random bits
recipNonce           present
  -- value from senderNonce in corresponding ip message
protectionAlg        MSG_MAC_ALG
  -- only MAC protection is allowed for this message.  The
  -- MAC is based on the initial authentication key shared
  -- between the EE and the CA.

senderKID            referenceNum
  -- the reference number which the CA has previously issued
  -- to the end entity (together with the MACing key)

body                 certConf
  -- see Section 5.3.18, "PKI Confirmation Content", for the
  -- contents of the certConf fields.
  -- Note: two CertStatus structures are required if both an
  -- encryption and a signing certificate were sent.

protection           present
  -- bits calculated using MSG_MAC_ALG

Confirmation; PKIConf

Field                Value
sender               present
  -- same as in ip
recipient            present
  -- sender name from certConf
transactionID        present
  -- value from certConf message
senderNonce          present
  -- 128 (pseudo-) random bits
recipNonce           present
  -- value from senderNonce from certConf message
protectionAlg        MSG_MAC_ALG
  -- only MAC protection is allowed for this message.
senderKID            referenceNum
body                 PKIConf
protection           present
  -- bits calculated using MSG_MAC_ALG

D.5. Certificate Request ๐Ÿงพ

okay this one is for the end entity that's already initialized ๐Ÿฅฐ it asks a CA for a certificate for any reason at all. when the CA replies with a message holding the certificate, the end entity sends back a certificate confirmation, and the CA replies with a PKIConfirm to close the transaction. all messages are authenticated, obviously ๐Ÿ”

the profile here is basically identical to the one in Appendix D.4, with these changes:

  • sender name SHOULD be present โœจ
  • MSG_SIG_ALG MUST be supported (MSG_MAC_ALG MAY also be supported) in request, response, certConfirm, and PKIConfirm messages ๐Ÿ–Š๏ธ
  • senderKID and recipKID are only present if they're required for message verification ๐Ÿ™ƒ
  • body is cr or cp ๐Ÿ“ฌ
  • body may contain one or two CertReqMsg structures, and either CertReqMsg may be used to request certification of a locally-generated public key or a centrally-generated public key. in other words, the position-dependence requirement of Appendix D.4 is removed ๐Ÿฆ‹
  • protection bits are calculated according to the protectionAlg field ๐Ÿ”ฅ

D.6. Key Update Request โœจ

okay so this one is for an end entity that's already initialized and wants a fresh certificate from a CA ๐Ÿ”‘ It's updating the key pair and/or the certificate it already has. When the CA sends back a message with a certificate, the end entity replies with a certificate confirmation, and then the CA sends a PKIConfirm to close the transaction. bestie, every message here is authenticated ๐Ÿซถ

The profile is basically the same as Appendix D.4, with a few upgrades:

  1. sender name SHOULD be present ๐Ÿ’–
  2. protectionAlg of MSG_SIG_ALG MUST be supported (MSG_MAC_ALG MAY also be supported) in request, response, certConfirm, and PKIConfirm messages; ๐Ÿ”
  3. senderKID and recipKID are only present if required for message verification; ๐Ÿงš
  4. body is kur or kup; ๐ŸŽ€
  5. body may contain one or two CertReqMsg structures, but either CertReqMsg may be used to request certification of a locally-generated public key or a centrally-generated public key (i.e., the position-dependence requirement of Appendix D.4 is removed); the chaos is actually elegant โœจ
  6. protection bits are calculated according to the protectionAlg field; ๐Ÿฆ‹
  7. regCtrl OldCertId SHOULD be used (unless it is clear to both sender and receiver -- by means not specified in this document -- that it is not needed). ๐ŸŒธ

Appendix E. PKI Management Message Profiles (OPTIONAL) ๐Ÿ‘‘

this appendix is the bonus round ๐ŸŽ€ It has detailed profiles for the PKIMessages that MAY be supported by implementations, on top of the ones that MUST be supported (see Section 6 and Appendix D). so the required stuff is the baseline, and this is the extra credit ๐Ÿ’…

Profiles are provided for the PKIMessages used in these PKI management operations:

  • root CA key update
  • information request/response
  • cross-certification request/response (1-way)
  • in-band initialization using external identity certificate

later versions of this document may extend the list below (along with other operations, if desired) ๐ŸŒˆ

  • revocation request
  • certificate publication
  • CRL publication

E.1. General Rules for Interpretation of These Profiles. ๐Ÿ’œ

Identical to Appendix D.1. no new rules, we're good ๐Ÿ™Œ

E.2. Algorithm Use Profile ๐Ÿง 

Identical to Appendix D.2. same vibes, same algorithms, we move ๐Ÿซถ

E.3. Self-Signed Certificates ๐Ÿชž

okay this is the profile for how a Certificate structure can be "self-signed" ๐Ÿ“ These structures are used to distribute CA public keys. It can happen in one of three ways (see Section 4.4 above for a description of the use of these structures):

Type          Function
-----------------------------------------------------------------
newWithNew a true "self-signed" certificate; the contained
           public key MUST be usable to verify the signature
           (though this provides only integrity and no
           authentication whatsoever)
oldWithNew previous root CA public key signed with new private key
newWithOld new root CA public key signed with previous private key

Such certificates (including relevant extensions) must contain "sensible" values for all fields. For example, when present, subjectAltName MUST be identical to issuerAltName, and, when present, keyIdentifiers must contain appropriate values, et cetera. โœจ "sensible" is doing a LOT of work in that sentence, bestie ๐Ÿ˜ญ

E.4. Root CA Key Update ๐Ÿ”ฅ

a root CA updates its key pair, then makes a CA key update announcement message that can be shared (via some transport mechanism) with the relevant end entities. A confirmation message is NOT REQUIRED from the end entities ๐Ÿ’…

ckuann message:

 Field        Value                        Comment
--------------------------------------------------------------
 sender       CA name CA name
 body         ckuann(CAKeyUpdAnnContent)
 oldWithNew   present                  see Appendix E.3 above
 newWithOld   present                  see Appendix E.3 above
 newWithNew   present                  see Appendix E.3 above
 extraCerts   optionally present       can be used to "publish"
                                       certificates (e.g.,
                                       certificates signed using
                                       the new private key)

E.5. PKI Information Request/Response ๐Ÿฆ‹

the end entity sends a general message to the PKI asking for details it'll need for later PKI management operations ๐Ÿงš RA/CA replies with a general response. If an RA makes the response, it just forwards the equivalent message it got from the CA, maybe with extra certificates added to the extraCerts fields of the PKIMessage. A confirmation message is NOT REQUIRED from the end entity ๐Ÿซถ

Message Flows:

Step# End entity                        PKI

   1  format genm
   2                ->   genm   ->
   3                                    handle genm
   4                                    produce genp
   5                <-   genp   <-
   6  handle genp

genM:

Field               Value

recipient           CA name
  -- the name of the CA as contained in issuerAltName
  -- extensions or issuer fields within certificates
protectionAlg       MSG_MAC_ALG or MSG_SIG_ALG
  -- any authenticated protection alg.
SenderKID           present if required
  -- must be present if required for verification of message
  -- protection
freeText            any valid value
body                genr (GenReqContent)
GenMsgContent       empty SEQUENCE
  -- all relevant information requested
protection          present
  -- bits calculated using MSG_MAC_ALG or MSG_SIG_ALG

genP:

Field                Value

sender               CA name
  -- name of the CA which produced the message
protectionAlg        MSG_MAC_ALG or MSG_SIG_ALG
  -- any authenticated protection alg.
senderKID            present if required
  -- must be present if required for verification of message
  -- protection
body                 genp (GenRepContent)
CAProtEncCert        present (object identifier one
                     of PROT_ENC_ALG), with relevant
                     value
  -- to be used if end entity needs to encrypt information for
  -- the CA (e.g., private key for recovery purposes)

SignKeyPairTypes     present, with relevant value
  -- the set of signature algorithm identifiers that this CA will
  -- certify for subject public keys
EncKeyPairTypes      present, with relevant value
  -- the set of encryption/key agreement algorithm identifiers that
  -- this CA will certify for subject public keys
PreferredSymmAlg     present (object identifier one
                     of PROT_SYM_ALG) , with relevant
                     value
  -- the symmetric algorithm that this CA expects to be used
  -- in later PKI messages (for encryption)
CAKeyUpdateInfo      optionally present, with
                     relevant value
  -- the CA MAY provide information about a relevant root CA
  -- key pair using this field (note that this does not imply
  -- that the responding CA is the root CA in question)
CurrentCRL           optionally present, with relevant value

  -- the CA MAY provide a copy of a complete CRL (i.e.,
  -- fullest possible one)
protection           present
  -- bits calculated using MSG_MAC_ALG or MSG_SIG_ALG
extraCerts           optionally present
  -- can be used to send some certificates to the end
  -- entity. An RA MAY add its certificate here.

E.6. Cross Certification Request/Response (1-way) ๐Ÿฆ‹

okay so this one is about making one cross-certificate at a time (not two at once, bestie ๐Ÿ™…โ€โ™€๏ธ). The requesting CA MAY pick who handles publishing the cross-certificate the responding CA makes, using the PKIPublicationInfo control. ๐ŸŽ€

Before anyone starts, two things have to be true:

  1. The responding CA can check where the request came from (which might need out-of-band checks) before it touches the request. ๐Ÿ”
  2. The requesting CA can check that the response really came from who it says it did (which might also need out-of-band checks) before it processes the response. ๐Ÿซถ

Whether certificate confirmation (and the matching server confirmation) happens is decided by the generalInfo field in the PKIHeader (see Section 5.1.1). This profile does not require support for either one, so it's kinda up to you ๐Ÿ’…

Message Flows:

Step# Requesting CA                       Responding CA
  1   format ccr
  2                   ->    ccr    ->
  3                                       handle ccr
  4                                       produce ccp
  5                   <-    ccp    <-
  6   handle ccp

ccr:

Field                 Value

sender                Requesting CA name
  -- the name of the CA who produced the message
recipient             Responding CA name
  -- the name of the CA who is being asked to produce a certificate
messageTime           time of production of message

  -- current time at requesting CA
protectionAlg         MSG_SIG_ALG
  -- only signature protection is allowed for this request
senderKID             present if required
  -- must be present if required for verification of message
  -- protection
recipKID             present if required
  -- must be present if required for verification of message
  -- protection
transactionID         present
  -- implementation-specific value, meaningful to requesting CA.
  -- [If already in use at responding CA then a rejection message
  -- MUST be produced by responding CA]
senderNonce           present
  -- 128 (pseudo-)random bits
freeText              any valid value
body                  ccr (CertReqMessages)
                      only one CertReqMsg
                      allowed
  -- if multiple cross certificates are required, they MUST be
  -- packaged in separate PKIMessages
certTemplate          present
  -- details follow
version               v1 or v3
  -- v3 STRONGLY RECOMMENDED
signingAlg            present
  -- the requesting CA must know in advance with which algorithm it
  -- wishes the certificate to be signed

subject               present
  -- may be NULL-DN only if subjectAltNames extension value proposed
validity              present
  -- MUST be completely specified (i.e., both fields present)
issuer                present
  -- may be NULL-DN only if issuerAltNames extension value proposed
publicKey             present
  -- the key to be certified (which must be for a signing algorithm)
extensions            optionally present
  -- a requesting CA must propose values for all extensions
  -- that it requires to be in the cross-certificate
POPOSigningKey        present
  -- see Section D3: Proof-of-possession profile
protection            present
  -- bits calculated using MSG_SIG_ALG
extraCerts            optionally present
  -- MAY contain any additional certificates that requester wishes
  -- to include

ccp:

Field                 Value

sender                Responding CA name
  -- the name of the CA who produced the message
recipient             Requesting CA name
  -- the name of the CA who asked for production of a certificate
messageTime           time of production of message
  -- current time at responding CA
protectionAlg         MSG_SIG_ALG
  -- only signature protection is allowed for this message
senderKID             present if required
  -- must be present if required for verification of message
  -- protection
recipKID              present if required
transactionID         present
  -- value from corresponding ccr message
senderNonce           present
  -- 128 (pseudo-)random bits
recipNonce            present
-- senderNonce from corresponding ccr message
freeText              any valid value
body                  ccp (CertRepMessage)
                      only one CertResponse allowed
  -- if multiple cross certificates are required they MUST be
  -- packaged in separate PKIMessages
response              present
status                present

PKIStatusInfo.status  present
  -- if PKIStatusInfo.status is one of:
  --   accepted, or
  --   grantedWithMods,
  -- then certifiedKeyPair MUST be present and failInfo MUST
  -- be absent

failInfo              present depending on
                      PKIStatusInfo.status
  -- if PKIStatusInfo.status is:
  --   rejection
  -- then certifiedKeyPair MUST be absent and failInfo MUST be
  -- present and contain appropriate bit settings

certifiedKeyPair      present depending on
                      PKIStatusInfo.status
certificate           present depending on
                      certifiedKeyPair

  -- content of actual certificate must be examined by requesting CA
  -- before publication
protection            present
  -- bits calculated using MSG_SIG_ALG
extraCerts            optionally present
  -- MAY contain any additional certificates that responder wishes
  -- to include

E.7. In-Band Initialization Using External Identity Certificate ๐Ÿงš

so picture this: an end entity (EE) that isn't in the PKI yet wants to get initialized with a CA called CA-1. โœจ For authentication it uses an identity certificate that already exists, issued by a different (external) CA called CA-X. First, CA-1 and CA-X have to already trust each other, so CA-1 can validate the EE's identity certificate that CA-X signed. ๐Ÿ” Also, the EE's Personal Security Environment (PSE) has to already be set up so it can authenticate and verify PKIMessages signed by CA-1. For example, the PSE might hold a certificate for CA-1's public key, signed by some other CA the EE trusts through out-of-band authentication. ๐Ÿ’œ

Here's the flow. The EE sends an initialization request to start the transaction. When CA-1 replies with a message containing the new certificate, the end entity sends back a certificate confirmation. Then CA-1 sends a PKIConfirm to close things out. ๐ŸŽ€ Every message is signed. The EE signs with the private key that matches the public key in its external identity certificate. CA-1 signs with the private key that matches the public key in a certificate that chains to a trust anchor in the EE's PSE. ๐Ÿซถ

This exchange follows the profile in Appendix D.4, with these exceptions:

  • the EE and CA-1 do not share a symmetric MACing key (so there's no out-of-band shared secret between them) ๐Ÿ™…โ€โ™€๏ธ;
  • sender name in ir MUST be present (and identical to the subject name present in the external identity certificate);
  • protectionAlg of MSG_SIG_ALG MUST be used in all messages;
  • external identity cert. MUST be carried in ir extraCerts field;
  • senderKID and recipKID are not used;
  • body is ir or ip;
  • protection bits are calculated according to the protectionAlg field.

Appendix F. Compilable ASN.1 Definitions ๐Ÿ“œ๐ŸŒธ

okay this is the compilable ASN.1 module, and it's giving tidy and organised ๐Ÿ’…

PKIXCMP {iso(1) identified-organization(3)
      dod(6) internet(1) security(5) mechanisms(5) pkix(7)
      id-mod(0) id-mod-cmp2000(16)}

DEFINITIONS EXPLICIT TAGS ::=

BEGIN

-- EXPORTS ALL --

IMPORTS

    Certificate, CertificateList, Extensions, AlgorithmIdentifier,
    UTF8String -- if required; otherwise, comment out
           FROM PKIX1Explicit88 {iso(1) identified-organization(3)
           dod(6) internet(1) security(5) mechanisms(5) pkix(7)
           id-mod(0) id-pkix1-explicit-88(1)}

    GeneralName, KeyIdentifier
           FROM PKIX1Implicit88 {iso(1) identified-organization(3)
           dod(6) internet(1) security(5) mechanisms(5) pkix(7)
           id-mod(0) id-pkix1-implicit-88(2)}

    CertTemplate, PKIPublicationInfo, EncryptedValue, CertId,
    CertReqMessages
           FROM PKIXCRMF-2005 {iso(1) identified-organization(3)
           dod(6) internet(1) security(5) mechanisms(5) pkix(7)
           id-mod(0) id-mod-crmf2005(36)}

    -- see also the behavioral clarifications to CRMF codified in
    -- Appendix C of this specification

    CertificationRequest
           FROM PKCS-10 {iso(1) member-body(2)
                         us(840) rsadsi(113549)
                         pkcs(1) pkcs-10(10) modules(1) pkcs-10(1)}

    -- (specified in RFC 2986 with 1993 ASN.1 syntax and IMPLICIT
    -- tags).  Alternatively, implementers may directly include
    -- the [PKCS10] syntax in this module
    ;

-- the rest of the module contains locally-defined OIDs and
-- constructs

   CMPCertificate ::= CHOICE {
      x509v3PKCert        Certificate
   }
-- This syntax, while bits-on-the-wire compatible with the
-- standard X.509 definition of "Certificate", allows the
-- possibility of future certificate types (such as X.509
-- attribute certificates, WAP WTLS certificates, or other kinds
-- of certificates) within this certificate management protocol,
-- should a need ever arise to support such generality.  Those
-- implementations that do not foresee a need to ever support
-- other certificate types MAY, if they wish, comment out the
-- above structure and "un-comment" the following one prior to
-- compiling this ASN.1 module.  (Note that interoperability
-- with implementations that don't do this will be unaffected by
-- this change.)

-- CMPCertificate ::= Certificate

   PKIMessage ::= SEQUENCE {
      header           PKIHeader,
      body             PKIBody,
      protection   [0] PKIProtection OPTIONAL,
      extraCerts   [1] SEQUENCE SIZE (1..MAX) OF CMPCertificate
                       OPTIONAL
  }

  PKIMessages ::= SEQUENCE SIZE (1..MAX) OF PKIMessage

okay bestie, we're still deep in the ASN.1 zone ๐Ÿ’… this chunk is the whole message-header and body menu, the status and failure codes, the proof-of-possession challenge stuff, and the certificate response wrapper. it's giving structure ๐ŸŽ€


     PKIHeader ::= SEQUENCE {
         pvno                INTEGER     { cmp1999(1), cmp2000(2) },
         sender              GeneralName,
         -- identifies the sender
         recipient           GeneralName,
         -- identifies the intended recipient
         messageTime     [0] GeneralizedTime         OPTIONAL,
         -- time of production of this message (used when sender
         -- believes that the transport will be "suitable"; i.e.,
         -- that the time will still be meaningful upon receipt)
         protectionAlg   [1] AlgorithmIdentifier     OPTIONAL,
         -- algorithm used for calculation of protection bits
         senderKID       [2] KeyIdentifier           OPTIONAL,
         recipKID        [3] KeyIdentifier           OPTIONAL,
         -- to identify specific keys used for protection
         transactionID   [4] OCTET STRING            OPTIONAL,
         -- identifies the transaction; i.e., this will be the same in
         -- corresponding request, response, certConf, and PKIConf
         -- messages
         senderNonce     [5] OCTET STRING            OPTIONAL,
         recipNonce      [6] OCTET STRING            OPTIONAL,
         -- nonces used to provide replay protection, senderNonce
         -- is inserted by the creator of this message; recipNonce
         -- is a nonce previously inserted in a related message by
         -- the intended recipient of this message
         freeText        [7] PKIFreeText             OPTIONAL,
         -- this may be used to indicate context-specific instructions
         -- (this field is intended for human consumption)
         generalInfo     [8] SEQUENCE SIZE (1..MAX) OF
                                InfoTypeAndValue     OPTIONAL
         -- this may be used to convey context-specific information
         -- (this field not primarily intended for human consumption)
     }

     PKIFreeText ::= SEQUENCE SIZE (1..MAX) OF UTF8String
         -- text encoded as UTF-8 String [RFC3629] (note: each
         -- UTF8String MAY include an [RFC3066] language tag
         -- to indicate the language of the contained text
         -- see [RFC2482] for details)

     PKIBody ::= CHOICE {       -- message-specific body elements
         ir       [0]  CertReqMessages,        --Initialization Request
         ip       [1]  CertRepMessage,         --Initialization Response
         cr       [2]  CertReqMessages,        --Certification Request
         cp       [3]  CertRepMessage,         --Certification Response
         p10cr    [4]  CertificationRequest,   --imported from [PKCS10]
         popdecc  [5]  POPODecKeyChallContent, --pop Challenge
         popdecr  [6]  POPODecKeyRespContent,  --pop Response
         kur      [7]  CertReqMessages,        --Key Update Request
         kup      [8]  CertRepMessage,         --Key Update Response
         krr      [9]  CertReqMessages,        --Key Recovery Request
         krp      [10] KeyRecRepContent,       --Key Recovery Response
         rr       [11] RevReqContent,          --Revocation Request
         rp       [12] RevRepContent,          --Revocation Response
         ccr      [13] CertReqMessages,        --Cross-Cert. Request
         ccp      [14] CertRepMessage,         --Cross-Cert. Response
         ckuann   [15] CAKeyUpdAnnContent,     --CA Key Update Ann.
         cann     [16] CertAnnContent,         --Certificate Ann.
         rann     [17] RevAnnContent,          --Revocation Ann.
         crlann   [18] CRLAnnContent,          --CRL Announcement
         pkiconf  [19] PKIConfirmContent,      --Confirmation
         nested   [20] NestedMessageContent,   --Nested Message
         genm     [21] GenMsgContent,          --General Message
         genp     [22] GenRepContent,          --General Response
         error    [23] ErrorMsgContent,        --Error Message
         certConf [24] CertConfirmContent,     --Certificate confirm
         pollReq  [25] PollReqContent,         --Polling request
         pollRep  [26] PollRepContent          --Polling response
     }

     PKIProtection ::= BIT STRING

     ProtectedPart ::= SEQUENCE {
         header    PKIHeader,
         body      PKIBody
     }

     id-PasswordBasedMac OBJECT IDENTIFIER ::= {1 2 840 113533 7 66 13}
     PBMParameter ::= SEQUENCE {
         salt                OCTET STRING,
         -- note:  implementations MAY wish to limit acceptable sizes
         -- of this string to values appropriate for their environment
         -- in order to reduce the risk of denial-of-service attacks
         owf                 AlgorithmIdentifier,
         -- AlgId for a One-Way Function (SHA-1 recommended)
         iterationCount      INTEGER,
         -- number of times the OWF is applied
         -- note:  implementations MAY wish to limit acceptable sizes
         -- of this integer to values appropriate for their environment
         -- in order to reduce the risk of denial-of-service attacks
         mac                 AlgorithmIdentifier
         -- the MAC AlgId (e.g., DES-MAC, Triple-DES-MAC [PKCS11],
     }   -- or HMAC [RFC2104, RFC2202])

     id-DHBasedMac OBJECT IDENTIFIER ::= {1 2 840 113533 7 66 30}
     DHBMParameter ::= SEQUENCE {
         owf                 AlgorithmIdentifier,
         -- AlgId for a One-Way Function (SHA-1 recommended)
         mac                 AlgorithmIdentifier
         -- the MAC AlgId (e.g., DES-MAC, Triple-DES-MAC [PKCS11],
     }   -- or HMAC [RFC2104, RFC2202])


     NestedMessageContent ::= PKIMessages

     PKIStatus ::= INTEGER {
         accepted                (0),
         -- you got exactly what you asked for
         grantedWithMods        (1),
         -- you got something like what you asked for; the
         -- requester is responsible for ascertaining the differences
         rejection              (2),
         -- you don't get it, more information elsewhere in the message
         waiting                (3),
         -- the request body part has not yet been processed; expect to
         -- hear more later (note: proper handling of this status
         -- response MAY use the polling req/rep PKIMessages specified
         -- in Section 5.3.22; alternatively, polling in the underlying
         -- transport layer MAY have some utility in this regard)
         revocationWarning      (4),
         -- this message contains a warning that a revocation is
         -- imminent
         revocationNotification (5),
         -- notification that a revocation has occurred
         keyUpdateWarning       (6)
         -- update already done for the oldCertId specified in
         -- CertReqMsg
     }

     PKIFailureInfo ::= BIT STRING {
     -- since we can fail in more than one way!
     -- More codes may be added in the future if/when required.
         badAlg              (0),
         -- unrecognized or unsupported Algorithm Identifier
         badMessageCheck     (1),
         -- integrity check failed (e.g., signature did not verify)
         badRequest          (2),
         -- transaction not permitted or supported
         badTime             (3),
         -- messageTime was not sufficiently close to the system time,
         -- as defined by local policy
         badCertId           (4),
         -- no certificate could be found matching the provided criteria
         badDataFormat       (5),
         -- the data submitted has the wrong format
         wrongAuthority      (6),
         -- the authority indicated in the request is different from the
         -- one creating the response token
         incorrectData       (7),
         -- the requester's data is incorrect (for notary services)
         missingTimeStamp    (8),
         -- when the timestamp is missing but should be there
         -- (by policy)
         badPOP              (9),
         -- the proof-of-possession failed
         certRevoked         (10),
            -- the certificate has already been revoked
         certConfirmed       (11),
            -- the certificate has already been confirmed

         wrongIntegrity      (12),
            -- invalid integrity, password based instead of signature or
            -- vice versa
         badRecipientNonce   (13),
            -- invalid recipient nonce, either missing or wrong value
         timeNotAvailable    (14),
            -- the TSA's time source is not available
         unacceptedPolicy    (15),
            -- the requested TSA policy is not supported by the TSA.
         unacceptedExtension (16),
            -- the requested extension is not supported by the TSA.
         addInfoNotAvailable (17),
            -- the additional information requested could not be
            -- understood or is not available
         badSenderNonce      (18),
            -- invalid sender nonce, either missing or wrong size
         badCertTemplate     (19),
            -- invalid cert. template or missing mandatory information
         signerNotTrusted    (20),
            -- signer of the message unknown or not trusted
         transactionIdInUse  (21),
            -- the transaction identifier is already in use
         unsupportedVersion  (22),
            -- the version of the message is not supported
         notAuthorized       (23),
            -- the sender was not authorized to make the preceding
            -- request or perform the preceding action
         systemUnavail       (24),
         -- the request cannot be handled due to system unavailability
         systemFailure       (25),
         -- the request cannot be handled due to system failure
         duplicateCertReq    (26)
         -- certificate cannot be issued because a duplicate
         -- certificate already exists
     }

     PKIStatusInfo ::= SEQUENCE {
         status        PKIStatus,
         statusString  PKIFreeText     OPTIONAL,
         failInfo      PKIFailureInfo  OPTIONAL
     }

     OOBCert ::= CMPCertificate

     OOBCertHash ::= SEQUENCE {
         hashAlg     [0] AlgorithmIdentifier     OPTIONAL,
         certId      [1] CertId                  OPTIONAL,
         hashVal         BIT STRING
         -- hashVal is calculated over the DER encoding of the
         -- self-signed certificate with the identifier certID.
     }

     POPODecKeyChallContent ::= SEQUENCE OF Challenge
     -- One Challenge per encryption key certification request (in the
     -- same order as these requests appear in CertReqMessages).

     Challenge ::= SEQUENCE {
         owf                 AlgorithmIdentifier  OPTIONAL,

         -- MUST be present in the first Challenge; MAY be omitted in
         -- any subsequent Challenge in POPODecKeyChallContent (if
         -- omitted, then the owf used in the immediately preceding
         -- Challenge is to be used).

         witness             OCTET STRING,
         -- the result of applying the one-way function (owf) to a
         -- randomly-generated INTEGER, A.  [Note that a different
         -- INTEGER MUST be used for each Challenge.]
         challenge           OCTET STRING
         -- the encryption (under the public key for which the cert.
         -- request is being made) of Rand, where Rand is specified as
         --   Rand ::= SEQUENCE {
         --      int      INTEGER,
         --       - the randomly-generated INTEGER A (above)
         --      sender   GeneralName
         --       - the sender's name (as included in PKIHeader)
         --   }
     }

     POPODecKeyRespContent ::= SEQUENCE OF INTEGER
     -- One INTEGER per encryption key certification request (in the
     -- same order as these requests appear in CertReqMessages).  The
     -- retrieved INTEGER A (above) is returned to the sender of the
     -- corresponding Challenge.

     CertRepMessage ::= SEQUENCE {
         caPubs       [1] SEQUENCE SIZE (1..MAX) OF CMPCertificate
                          OPTIONAL,
         response         SEQUENCE OF CertResponse
     }

okay so the ASN.1 module keeps going, and it's giving "every field has a job" energy ๐Ÿ’… Here's the rest of it, copied exactly so the bits are still in order ๐ŸŽ€

     CertResponse ::= SEQUENCE {
         certReqId           INTEGER,
         -- to match this response with corresponding request (a value
         -- of -1 is to be used if certReqId is not specified in the
         -- corresponding request)
         status              PKIStatusInfo,
         certifiedKeyPair    CertifiedKeyPair    OPTIONAL,
         rspInfo             OCTET STRING        OPTIONAL
         -- analogous to the id-regInfo-utf8Pairs string defined
         -- for regInfo in CertReqMsg [CRMF]
     }

     CertifiedKeyPair ::= SEQUENCE {
         certOrEncCert       CertOrEncCert,
         privateKey      [0] EncryptedValue      OPTIONAL,
         -- see [CRMF] for comment on encoding
         publicationInfo [1] PKIPublicationInfo  OPTIONAL
     }

     CertOrEncCert ::= CHOICE {
         certificate     [0] CMPCertificate,
         encryptedCert   [1] EncryptedValue
     }

     KeyRecRepContent ::= SEQUENCE {
         status                  PKIStatusInfo,
         newSigCert          [0] CMPCertificate OPTIONAL,
         caCerts             [1] SEQUENCE SIZE (1..MAX) OF
                                             CMPCertificate OPTIONAL,
         keyPairHist         [2] SEQUENCE SIZE (1..MAX) OF
                                             CertifiedKeyPair OPTIONAL
     }

     RevReqContent ::= SEQUENCE OF RevDetails

     RevDetails ::= SEQUENCE {
         certDetails         CertTemplate,
         -- allows requester to specify as much as they can about
         -- the cert. for which revocation is requested
         -- (e.g., for cases in which serialNumber is not available)
         crlEntryDetails     Extensions       OPTIONAL
         -- requested crlEntryExtensions
     }

     RevRepContent ::= SEQUENCE {
         status       SEQUENCE SIZE (1..MAX) OF PKIStatusInfo,
         -- in same order as was sent in RevReqContent
         revCerts [0] SEQUENCE SIZE (1..MAX) OF CertId
                                             OPTIONAL,
         -- IDs for which revocation was requested
         -- (same order as status)
         crls     [1] SEQUENCE SIZE (1..MAX) OF CertificateList
                                             OPTIONAL

         -- the resulting CRLs (there may be more than one)
     }

     CAKeyUpdAnnContent ::= SEQUENCE {
         oldWithNew   CMPCertificate, -- old pub signed with new priv
         newWithOld   CMPCertificate, -- new pub signed with old priv
         newWithNew   CMPCertificate  -- new pub signed with new priv
     }

     CertAnnContent ::= CMPCertificate

     RevAnnContent ::= SEQUENCE {
         status              PKIStatus,
         certId              CertId,
         willBeRevokedAt     GeneralizedTime,
         badSinceDate        GeneralizedTime,
         crlDetails          Extensions  OPTIONAL
         -- extra CRL details (e.g., crl number, reason, location, etc.)
     }

     CRLAnnContent ::= SEQUENCE OF CertificateList

     CertConfirmContent ::= SEQUENCE OF CertStatus

     CertStatus ::= SEQUENCE {
        certHash    OCTET STRING,
        -- the hash of the certificate, using the same hash algorithm
        -- as is used to create and verify the certificate signature
        certReqId   INTEGER,
        -- to match this confirmation with the corresponding req/rep
        statusInfo  PKIStatusInfo OPTIONAL
     }

     PKIConfirmContent ::= NULL

     InfoTypeAndValue ::= SEQUENCE {
         infoType               OBJECT IDENTIFIER,
         infoValue              ANY DEFINED BY infoType  OPTIONAL
     }
     -- Example InfoTypeAndValue contents include, but are not limited
     -- to, the following (un-comment in this ASN.1 module and use as
     -- appropriate for a given environment):
     --
     --   id-it-caProtEncCert    OBJECT IDENTIFIER ::= {id-it 1}
     --      CAProtEncCertValue      ::= CMPCertificate
     --   id-it-signKeyPairTypes OBJECT IDENTIFIER ::= {id-it 2}
     --      SignKeyPairTypesValue   ::= SEQUENCE OF AlgorithmIdentifier
     --   id-it-encKeyPairTypes  OBJECT IDENTIFIER ::= {id-it 3}
     --      EncKeyPairTypesValue    ::= SEQUENCE OF AlgorithmIdentifier
     --   id-it-preferredSymmAlg OBJECT IDENTIFIER ::= {id-it 4}
     --      PreferredSymmAlgValue   ::= AlgorithmIdentifier
     --   id-it-caKeyUpdateInfo  OBJECT IDENTIFIER ::= {id-it 5}
     --      CAKeyUpdateInfoValue    ::= CAKeyUpdAnnContent
     --   id-it-currentCRL       OBJECT IDENTIFIER ::= {id-it 6}
     --      CurrentCRLValue         ::= CertificateList
     --   id-it-unsupportedOIDs  OBJECT IDENTIFIER ::= {id-it 7}
     --      UnsupportedOIDsValue    ::= SEQUENCE OF OBJECT IDENTIFIER
     --   id-it-keyPairParamReq  OBJECT IDENTIFIER ::= {id-it 10}
     --      KeyPairParamReqValue    ::= OBJECT IDENTIFIER
     --   id-it-keyPairParamRep  OBJECT IDENTIFIER ::= {id-it 11}
     --      KeyPairParamRepValue    ::= AlgorithmIdentifer
     --   id-it-revPassphrase    OBJECT IDENTIFIER ::= {id-it 12}
     --      RevPassphraseValue      ::= EncryptedValue
     --   id-it-implicitConfirm  OBJECT IDENTIFIER ::= {id-it 13}
     --      ImplicitConfirmValue    ::= NULL
     --   id-it-confirmWaitTime  OBJECT IDENTIFIER ::= {id-it 14}
     --      ConfirmWaitTimeValue    ::= GeneralizedTime
     --   id-it-origPKIMessage   OBJECT IDENTIFIER ::= {id-it 15}
     --      OrigPKIMessageValue     ::= PKIMessages
     --   id-it-suppLangTags     OBJECT IDENTIFIER ::= {id-it 16}
     --      SuppLangTagsValue       ::= SEQUENCE OF UTF8String
     --
     -- where
     --
     --   id-pkix OBJECT IDENTIFIER ::= {
     --      iso(1) identified-organization(3)
     --      dod(6) internet(1) security(5) mechanisms(5) pkix(7)}
     -- and
     --   id-it   OBJECT IDENTIFIER ::= {id-pkix 4}
     --
     --
     -- This construct MAY also be used to define new PKIX Certificate
     -- Management Protocol request and response messages, or general-
     -- purpose (e.g., announcement) messages for future needs or for
     -- specific environments.

     GenMsgContent ::= SEQUENCE OF InfoTypeAndValue

     -- May be sent by EE, RA, or CA (depending on message content).
     -- The OPTIONAL infoValue parameter of InfoTypeAndValue will
     -- typically be omitted for some of the examples given above.
     -- The receiver is free to ignore any contained OBJ. IDs that it
     -- does not recognize. If sent from EE to CA, the empty set
     -- indicates that the CA may send
     -- any/all information that it wishes.

     GenRepContent ::= SEQUENCE OF InfoTypeAndValue
     -- Receiver MAY ignore any contained OIDs that it does not
     -- recognize.

     ErrorMsgContent ::= SEQUENCE {
         pKIStatusInfo          PKIStatusInfo,
         errorCode              INTEGER           OPTIONAL,
         -- implementation-specific error codes
         errorDetails           PKIFreeText       OPTIONAL
         -- implementation-specific error details
     }

     PollReqContent ::= SEQUENCE OF SEQUENCE {
         certReqId              INTEGER
     }

     PollRepContent ::= SEQUENCE OF SEQUENCE {
         certReqId              INTEGER,
         checkAfter             INTEGER,  -- time in seconds
         reason                 PKIFreeText OPTIONAL
     }

     END -- of CMP module

Appendix G. Acknowledgements โœจ

The authors say a big thank you to the IETF PKIX Working Group folks and to the ICSA CA-talk mailing list ๐Ÿซถ (that list was all about CMP interoperability, so it was super on-topic). Lots of those contributions made the spec way clearer and more useful. Tomi Kause also thanks Vesa Suontama and Toni Tammisalo for reviewing and commenting ๐Ÿ’œ

Authors' Addresses ๐Ÿฆ‹

Here's where you can find the authors, bestie ๐Ÿ“ฎ

   Carlisle Adams
   University of Ottawa
   800 King Edward Avenue
   P.O.Box 450, Station A
   Ottawa, Ontario  K1N 6N5
   CA

   Phone: (613) 562-5800 ext. 2345
   Fax:   (613) 562-5664
   EMail: cadams@site.uottawa.ca


   Stephen Farrell
   Trinity College Dublin
   Distributed Systems Group
   Computer Science Department
   Dublin
   IE

   Phone: +353-1-608-2945
   EMail: stephen.farrell@cs.tcd.ie


   Tomi Kause
   SSH Communications Security Corp
   Valimotie 17
   Helsinki  00380
   FI

   Phone: +358 20 500 7415
   EMail: toka@ssh.com


   Tero Mononen
   SafeNet, Inc.
   Fredrikinkatu 47
   Helsinki  00100
   FI

   Phone: +358 20 500 7814
   EMail: tmononen@safenet-inc.com

The Internet Society owns the copyright here, and it's dated 2005 ๐ŸŒธ This document is subject to the rights, licenses and restrictions in BCP 78. Except for what BCP 78 says, the authors keep all their rights ๐Ÿ”’

The document and its info come "AS IS", and the contributor, the organization they represent or sponsor (if any), the Internet Society, and the Internet Engineering Task Force all disclaim every warranty, express or implied. That includes, but isn't limited to, a warranty that using the info won't infringe anyone's rights, and any implied warranties of merchantability or fitness for a particular purpose. Here's the legal text exactly as written:

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

Intellectual Property ๐ŸŒˆ

The IETF doesn't take a position on whether any Intellectual Property Rights (or other rights someone might claim) are valid or how far they reach. That covers implementing or using the tech in this document, and whether any license for those rights is available. It also doesn't say it has looked into finding those rights itself ๐Ÿง For the rules on rights in RFC documents, check out BCP 78 and BCP 79.

Copies of IPR disclosures sent to the IETF Secretariat, any promised licenses, and the results of any attempt to get a general license or permission for implementers or users are all available from the IETF's online IPR repository at http://www.ietf.org/ipr ๐Ÿ“š

The IETF also invites anyone to flag any copyrights, patents, patent applications, or other proprietary rights that might cover tech needed to implement this standard. Send that info to the IETF at ietf-ipr@ietf.org ๐Ÿ“ฌ

Acknowledgement ๐Ÿซถ

Funding for the RFC Editor function is currently provided by the Internet Society. Thank you, Internet Society ๐Ÿ’•๐ŸŽ€

๐Ÿ“ฆ where this page comes from