RFC 9810

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

๐Ÿ“… published July 2025, from ietf

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

Okay bestie, here's the tea on this one. This is RFC 9810, a Standards Track doc from the IETF, dated July 2025 (ISSN 2070-1721). It's the official spec for CMP, the protocol that handles X.509v3 certificate creation and management. The authors are H. Brockhaus, D. von Oheimb (Siemens), M. Ounsworth, and J. Gray (Entrust). It obsoletes RFC 4210 and RFC 9480 (so those are retired now ๐Ÿ˜ญ) and updates RFC 5912. The squad is serving full main character energy ๐Ÿ’…โœจ

Table of Contents (verbatim)

1.  Introduction
  1.1.  Changes Made by RFC 4210
  1.2.  Updates Made by RFC 9480
  1.3.  Changes Made by This Document
2.  Terminology and Abbreviations
3.  PKI Management Overview
  3.1.  PKI Management Model
    3.1.1.  Definitions of PKI Entities
      3.1.1.1.  Subjects and End Entities
      3.1.1.2.  Certification Authority
      3.1.1.3.  Registration Authority
      3.1.1.4.  Key Generation Authority
    3.1.2.  PKI Management Requirements
    3.1.3.  PKI Management Operations
4.  Assumptions and Restrictions
  4.1.  End Entity Initialization
  4.2.  Initial Registration/Certification
    4.2.1.  Criteria Used
      4.2.1.1.  Initiation of Registration/Certification
      4.2.1.2.  End Entity Message Origin Authentication
      4.2.1.3.  Location of Key Generation
      4.2.1.4.  Confirmation of Successful Certification
    4.2.2.  Initial Registration/Certification Schemes
      4.2.2.1.  Centralized Scheme
      4.2.2.2.  Basic Authenticated Scheme
  4.3.  POP of Private Key
    4.3.1.  Signature Keys
    4.3.2.  Encryption Keys
    4.3.3.  Key Agreement Keys
    4.3.4.  KEM Keys
  4.4.  Root CA Key Update
    4.4.1.  CA Operator Actions
    4.4.2.  Verifying Certificates
      4.4.2.1.  Verification in Cases 1 and 4
      4.4.2.2.  Verification in Case 2
      4.4.2.3.  Verification in Case 3
    4.4.3.  Revocation - Change of the CA Key
  4.5.  EKU for PKI Entities
5.  Data Structures
  5.1.  Overall PKI Message
    5.1.1.  PKI Message Header
      5.1.1.1.  ImplicitConfirm
      5.1.1.2.  ConfirmWaitTime
      5.1.1.3.  OrigPKIMessage
      5.1.1.4.  CertProfile
      5.1.1.5.  KemCiphertextInfo
    5.1.2.  PKI Message Body
    5.1.3.  PKI Message Protection
      5.1.3.1.  Shared Secret Information
      5.1.3.2.  DH Key Pairs
      5.1.3.3.  Signature
      5.1.3.4.  Key Encapsulation
      5.1.3.5.  Multiple Protection
  5.2.  Common Data Structures
    5.2.1.  Requested Certificate Contents
    5.2.2.  Encrypted Values
    5.2.3.  Status Codes and Failure Information for PKI Messages
    5.2.4.  Certificate Identification
    5.2.5.  Out-of-Band Root CA Public Key
    5.2.6.  Archive Options
    5.2.7.  Publication Information
    5.2.8.  POP Structures
      5.2.8.1.  raVerified
      5.2.8.2.  POPOSigningKey Structure
      5.2.8.3.  POPOPrivKey Structure
      5.2.8.4.  Summary of POP Options
    5.2.9.  GeneralizedTime
  5.3.  Operation-Specific Data Structures
    5.3.1.  Initialization Request
    5.3.2.  Initialization Response
    5.3.3.  Certification Request
    5.3.4.  Certification Response
    5.3.5.  Key Update Request Content
    5.3.6.  Key Update Response Content
    5.3.7.  Key Recovery Request Content
    5.3.8.  Key Recovery Response Content
    5.3.9.  Revocation Request Content
    5.3.10. Revocation Response Content
    5.3.11. Cross-Certification Request Content
    5.3.12. Cross-Certification Response Content
    5.3.13. CA Key Update Announcement Content
    5.3.14. Certificate Announcement
    5.3.15. Revocation Announcement
    5.3.16. CRL Announcement
    5.3.17. PKI Confirmation Content
    5.3.18. Certificate Confirmation Content
    5.3.19. PKI General Message Content
      5.3.19.1.  CA Protocol Encryption Certificate
      5.3.19.2.  Signing Key Pair Types
      5.3.19.3.  Encryption / Key Agreement Key Pair Types
      5.3.19.4.  Preferred Symmetric Algorithm
      5.3.19.5.  Updated CA Key Pair
      5.3.19.6.  CRL
      5.3.19.7.  Unsupported Object Identifiers
      5.3.19.8.  Key Pair Parameters
      5.3.19.9.  Revocation Passphrase
      5.3.19.10. ImplicitConfirm
      5.3.19.11. ConfirmWaitTime
      5.3.19.12. Original PKIMessage
      5.3.19.13. Supported Language Tags
      5.3.19.14. CA Certificates
      5.3.19.15. Root CA Update
      5.3.19.16. Certificate Request Template
      5.3.19.17. CRL Update Retrieval
      5.3.19.18. KEM Ciphertext
    5.3.20. PKI General Response Content
    5.3.21. Error Message Content
    5.3.22. Polling Request and Response
6.  Mandatory PKI Management Functions
  6.1.  Root CA Initialization
  6.2.  Root CA Key Update
  6.3.  Subordinate CA Initialization
  6.4.  CRL Production
  6.5.  PKI Information Request
  6.6.  Cross-Certification
    6.6.1.  One-Way Request-Response Scheme
  6.7.  End Entity Initialization
    6.7.1.  Acquisition of PKI Information
    6.7.2.  Out-of-Band Verification of the Root CA Key
  6.8.  Certificate Request
  6.9.  Key Update
7.  Version Negotiation
  7.1.  Supporting RFC 2510 Implementations
    7.1.1.  Clients Talking to RFC 2510 Servers
    7.1.2.  Servers Receiving Version cmp1999 PKIMessages
8.  Security Considerations
  8.1.  On the Necessity of POP
  8.2.  POP with a Decryption Key
  8.3.  POP by Exposing the Private Key
  8.4.  Attack Against DH Key Exchange
  8.5.  Perfect Forward Secrecy
  8.6.  Private Keys for Certificate Signing and CMP Message
         Protection
  8.7.  Entropy of Random Numbers, Key Pairs, and Shared Secret
         Information
  8.8.  Recurring Usage of KEM Keys for Message Protection
  8.9.  Trust Anchor Provisioning Using CMP Messages
  8.10. Authorizing Requests for Certificates with Specific EKUs
  8.11. Usage of CT Logs
9.  IANA Considerations
10. References
  10.1.  Normative References
  10.2.  Informative References
Appendix A.  Reasons for the Presence of RAs
Appendix B.  The Use of Revocation Passphrase
Appendix C.  PKI Management Message Profiles (REQUIRED)
  C.1.  General Rules for Interpretation of These Profiles
  C.2.  Algorithm Use Profile
  C.3.  POP Profile
  C.4.  Initial Registration/Certification (Basic Authenticated
        Scheme)
  C.5.  Certificate Request
  C.6.  Key Update Request
Appendix D.  PKI Management Message Profiles (OPTIONAL)
  D.1.  General Rules for Interpretation of These Profiles
  D.2.  Algorithm Use Profile
  D.3.  Self-Signed Certificates
  D.4.  Root CA Key Update
  D.5.  PKI Information Request/Response
  D.6.  Cross-Certification Request/Response (1-way)
  D.7.  In-Band Initialization Using External Identity Certificate
Appendix E.  Variants of Using KEM Keys for PKI Message Protection
Appendix F.  Compilable ASN.1 Definitions
Acknowledgements
Authors' Addresses

Abstract โœจ

This doc describes the Internet X.509 Public Key Infrastructure (PKI) Certificate Management Protocol (CMP). It defines protocol messages for X.509v3 certificate creation and management, and CMP lets client systems talk to PKI components like a Registration Authority (RA) and a Certification Authority (CA).

This doc adds support for managing certificates that contain a Key Encapsulation Mechanism (KEM) public key, and it switches from EncryptedValue to EnvelopedData ๐Ÿ”ฅ It also pulls in the updates from Section 2 and Appendix A.2 of RFC 9480.

RFC 4210 is obsoleted by this doc, and together with RFC 9811 it also obsoletes RFC 9480 (teamwork makes the dream work ๐Ÿซถ). Appendix F of this doc updates Section 9 of RFC 5912.

Status of This Memo ๐Ÿ“œ

This is an Internet Standards Track document.

This doc is a product of the Internet Engineering Task Force (IETF). It represents the consensus of the IETF community, got public review, and was approved for publication by the Internet Engineering Steering Group (IESG). For more on Internet Standards, check Section 2 of RFC 7841.

For the current status, any errata, and how to send feedback, go to https://www.rfc-editor.org/info/rfc9810.

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

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.

1. Introduction ๐Ÿฆ‹

This doc describes the Internet X.509 PKI CMP. Protocol messages are defined for certificate creation and management. When this doc says "certificate," it means an X.509v3 certificate as defined in [RFC5280].

1.1. Changes Made by RFC 4210 ๐ŸŒธ

Okay so RFC 4210 is the glow-up of [RFC2510]. Here's what changed:

  • The PKI management message profile section got split into two appendices: a required profile and an optional profile. Some of the stuff that used to be mandatory got moved into the optional one ๐Ÿ™ˆ
  • The message confirmation mechanism got a major makeover.
  • A new polling mechanism showed up, and it deprecates the old polling method at the CMP transport level.
  • The CMP transport protocol issues are now handled in a separate document, [RFC6712], so the "Transports" section is gone ๐Ÿ‘‹
  • A new implicit confirmation method was added to cut down on the number of protocol messages exchanged in a transaction. Less chatter, more slay ๐Ÿ’–
  • The new spec has some less flashy protocol enhancements and clearer explanations of several issues.
To be continued! Part 2 is up next, starting with Section 1.2 (Updates Made by RFC 9480) ๐Ÿ’…๐ŸŽ€

1.2. Updates Made by RFC 9480 ๐Ÿ’–

Okay bestie, so [RFC9480] (CMP Updates) and [RFC9481] (CMP Algorithms) updated [RFC4210] ๐ŸŽ€ Their whole job was supporting the PKI management operations in the Lightweight CMP Profile [RFC9483], and they changed these areas:

  • Added new extended key usages (EKUs) for various CMP server types, e.g., RA and CA, to express the authorization of the certificate holder that acts as the indicated type of PKI management entity. ๐Ÿ‘‘
  • Extended the description of multiple protection to cover additional use cases, e.g., batch processing of messages. ๐Ÿ”ฅ
  • Used the Cryptographic Message Syntax (CMS) [RFC5652] type EnvelopedData as the preferred choice instead of EncryptedValue to better support crypto agility in CMP. ๐Ÿฆ‹

For reasons of completeness and consistency, the type EncryptedValue has been exchanged in all occurrences. This includes the protection of centrally generated private keys, encryption of certificates, Proof-of-Possession (POP) methods, and protection of revocation passphrases. To properly differentiate the support of EnvelopedData instead of EncryptedValue, CMP version 3 is introduced in case a transaction is supposed to use EnvelopedData. โœจ

Note: According to point 9 in Section 2.1 of [RFC4211], the use of the EncryptedValue structure has been deprecated in favor of the EnvelopedData structure. [RFC4211] offers the EncryptedKey structure a choice of EncryptedValue and EnvelopedData for migration to EnvelopedData. ๐Ÿ™ˆ

  • Offered an optional hashAlg field in CertStatus supporting cases when a certificate needs to be confirmed, but the certificate was signed using a signature algorithm that does not indicate a specific hash algorithm to use for computing the certHash. This is also in preparation for upcoming post-quantum algorithms. ๐ŸŒˆ
  • Added new general message types to request CA certificates, a root CA update, a certificate request template, or Certificate Revocation List (CRL) updates. ๐Ÿงš
  • Extended the use of polling to p10cr, certConf, rr, genm, and error messages. ๐ŸŒธ
  • Deleted the mandatory algorithm profile in Appendix C.2 and instead referred to Section 7 of [RFC9481]. ๐Ÿ’…
  • Added Sections 8.6, 8.7, 8.9, and 8.10 to the security considerations. ๐Ÿ’œ

1.3. Changes Made by This Document โœจ

This document obsoletes [RFC4210] and [RFC9480]. ๐Ÿ’€

Backward compatibility with CMP version 2 is maintained wherever possible. Updates to CMP version 2 improve crypto agility, extend the polling mechanism, add new general message types, and add EKUs to identify special CMP server authorizations. CMP version 3 is introduced for changes to the ASN.1 syntax, which support EnvelopedData, certConf with hashAlg, POPOPrivKey with agreeMAC, and RootCaKeyUpdateContent in ckuann messages. ๐ŸŽ€

The updates made in this document include the changes specified by Section 2 and Appendix A.2 of [RFC9480] as described in Section 1.2. Additionally, this document updates the content of [RFC4210] in the following areas:

  • Added Section 3.1.1.4 introducing the Key Generation Authority (KGA). ๐Ÿ”‘
  • Extended Section 3.1.2 regarding use of Certificate Transparency (CT) logs. ๐Ÿฆ‹
  • Updated Section 4.4 introducing RootCaKeyUpdateContent as an alternative to using a repository to acquire new root CA certificates. ๐Ÿ“
  • Added Section 5.1.1.3 containing a description of origPKIMessage content, moved here from Section 5.1.3.4. ๐Ÿซถ
  • Added support for KEM keys for POP to Sections 4.3 and 5.2.8, for message protection to Sections 5.1.1 and 5.1.3.4 and Appendix E, and for usage with CMS EnvelopedData to Section 5.2.2. ๐ŸŒˆ
  • Deprecated CAKeyUpdAnnContent in favor of RootCaKeyUpdateContent. ๐Ÿ˜ญ
  • Incorporated the request message behavioral clarifications from Appendix C of [RFC4210] to Section 5. The definition of altCertTemplate was incorporated into Section 5.2.1, and the clarification on POPOSigningKey and on POPOPrivKey was incorporated into Section 5.2.8. ๐Ÿ“
  • Added support for CMS EnvelopedData to different POP methods for transferring encrypted private keys, certificates, and challenges to Section 5.2.8. ๐Ÿ”ฅ
  • Added Sections 8.1, 8.5, 8.8, and 8.11 to the security considerations. ๐Ÿ›ก๏ธ

2. Terminology and Abbreviations ๐Ÿ’…

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here. ๐Ÿง 

This document relies on the terminology defined in [RFC5280]. The most important abbreviations are listed below: ๐Ÿ“š

CA:  Certification Authority

CMP:  Certificate Management Protocol

CMS:  Cryptographic Message Syntax

CRL:  Certificate Revocation List

CRMF:  Certificate Request Message Format

KEM:  Key Encapsulation Mechanism

KGA:  Key Generation Authority

LRA:  Local Registration Authority

MAC:  Message Authentication Code

PKI:  Public Key Infrastructure

POP:  Proof-of-Possession

RA:  Registration Authority

TEE:  Trusted Execution Environment

3. PKI Management Overview โœจ

The PKI must be structured to be consistent with the types of individuals who must administer it. Providing such administrators with unbounded choices not only complicates the software required but also increases the chances that a subtle mistake by an administrator or software developer will result in broader compromise. Similarly, restricting administrators with cumbersome mechanisms will cause them not to use the PKI. ๐Ÿ™ˆ

Management protocols are REQUIRED to support online interactions between PKI components. For example, a management protocol might be used between a CA and a client system with which a key pair is associated or between two CAs that issue cross-certificates for each other. ๐Ÿค

3.1. PKI Management Model ๐Ÿฆ‹

Before specifying particular message formats and procedures, we first define the entities involved in PKI management and their interactions (in terms of the PKI management functions required). We then group these functions in order to accommodate different identifiable types of end entities. ๐Ÿงฉ

3.1.1. Definitions of PKI Entities ๐ŸŽ€

The entities involved in PKI management include the end entity (i.e., the entity to whom the certificate is issued) and the CA (i.e., the entity that issues the certificate). An RA might also be involved in PKI management.

3.1.1.1. Subjects and End Entities ๐ŸŒธ

The term "subject" is used here to refer to the entity to whom the certificate is issued, typically named in the subject or subjectAltName field of a certificate. When we wish to distinguish the tools and/or software used by the subject (e.g., a local certificate management module), we will use the term "subject equipment". In general, the term "end entity", rather than "subject", is preferred in order to avoid confusion with the field name. It is important to note that the end entities here will include not only human users of applications but also applications themselves (e.g., for Internet Key Exchange Protocol (IKE) / IPsec) or devices (e.g., routers or industrial control systems). This factor influences the protocols that the PKI management operations use; for example, application software is far more likely to know exactly which certificate extensions are required than are human users. PKI management entities are also end entities in the sense that they are sometimes named in the subject or subjectAltName field of a certificate or cross-certificate. Where appropriate, the term "end entity" will be used to refer to end entities who are not PKI management entities. ๐Ÿง 

All end entities require secure local access to some information -- at a minimum, 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 (e.g., the end entity's own certificates or application-specific information). The form of storage will also vary -- from files to tamper-resistant cryptographic tokens. The information stored in such local, trusted storage is referred to here as the end entity's TEE, also known as Personal Security Environment (PSE). ๐Ÿ”

Though TEE formats are beyond the scope of this document (they are very dependent on equipment, et cetera), a generic interchange format for TEEs is defined here: a certification response message (see Section 5.3.4) MAY be used. ๐Ÿ“

3.1.1.2. Certification Authority ๐Ÿ‘‘

The CA may or may not actually be a real "third party" from the end entity's point of view. Quite often, the CA will actually belong to the same organization as the end entities it supports. ๐Ÿข

Again, we use the term "CA" to refer to the entity named in the issuer field of a certificate. When it is necessary to distinguish the software or hardware tools used by the CA, we use the term "CA equipment". ๐Ÿ› ๏ธ

The CA equipment will often include both an "offline" component and an "online" component, with the CA private key only available to the "offline" component. This is, however, a matter for implementers (though it is also relevant as a policy issue). ๐Ÿ”’

We use the term "root CA" to indicate a CA that is directly trusted by an end entity; that is, securely acquiring the value of a root CA public key requires some out-of-band step(s). This term is not meant to imply that a root CA is necessarily at the top of any hierarchy, simply that the CA in question is trusted directly. The "root CA" may provide its trust anchor information with or without using a certificate. In some circumstances, such a certificate may be self-signed, but in other circumstances, it may be cross-signed, signed by a peer, signed by a superior CA, or unsigned. ๐ŸŒˆ

Note that other documents like [X509.2019] and [RFC5280] use the term "trusted CA" or "trust anchor" instead of "root CA". This document continues using "root CA" based on the above definition because it is also present in the ASN.1 syntax that cannot be changed easily. ๐Ÿงš

A "subordinate CA" is one that is not a root CA for the end entity in question. Often, a subordinate CA will not be a root CA for any entity, but this is not mandatory. ๐Ÿ’–

3.1.1.3. Registration Authority ๐ŸŽ€

okay so, lots of environments want an RA sitting separate from the CA ๐Ÿ’… The jobs an RA can do change from case to case, but it MAY handle identity checking, token distribution, checking certificate requests and authentication of their origin, revocation reporting, name assignment, archival of key pairs, et cetera โœจ

This document treats the RA as an OPTIONAL component ๐Ÿฆ‹ If there's no RA, the CA is assumed to be able to do the RA's jobs, so the PKI management protocols look exactly the same from the end entity's point of view. Iconic โœจ

Again, when it matters, we split the RA from the tools it uses (the "RA equipment") ๐Ÿงš

Note that an RA is itself an end entity ๐Ÿ’– We also assume that every RA is actually a certified end entity and that RAs have private keys that are usable for signing. How a particular CA equipment identifies some end entities as RAs is an implementation issue (so this document specifies no special RA certification operation, bestie ๐Ÿ™ˆ). We do not mandate that the RA is certified by the CA it's currently interacting with, so one RA may work with more than one CA whilst only being certified once ๐ŸŒˆ

In some circumstances, end entities will talk directly to a CA even when an RA is present. For example, for initial registration and/or certification, the end entity may use its RA but communicate directly with the CA to refresh its certificate. Main character energy ๐Ÿ‘‘

3.1.1.4. Key Generation Authority ๐Ÿ“

A KGA is a PKI management entity generating key pairs on behalf of an end entity. Since the KGA generates the key pair, it knows both the public and the private part. Lowkey a lot of trust, ngl ๐Ÿ˜ญ

This document treats the KGA as an OPTIONAL component. When it's not present and central key generation is needed, the CA is assumed to be able to do the KGA's functions, so the PKI management protocol messages look the same from the end entity's point of view. If certain tasks of a CA are delegated to other components, that delegation needs authorization, which can be indicated by EKUs (see Section 4.5) ๐Ÿ”

Note: When doing central generation of key pairs, implementers should consider the implications of server-side retention on the overall security of the system. In some cases retention is good, for example for escrow reasons, but in other cases the server should clear its copy after delivery to the end entity. Choose wisely, besties ๐Ÿซถ

Note: If the CA delegates key generation to a KGA, the KGA can be collocated with the RA. โœจ

3.1.2. PKI Management Requirements ๐Ÿ’œ

The protocols given here meet the following requirements on PKI management. Here's the checklist, no cap ๐Ÿ’…

  1. PKI management must conform to the ISO/IEC 9594-8/ITU-T X.509 standards, in particular [X509.2019]. ๐Ÿ“œ
  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 in order to ease acceptance in environments where strong confidentiality might cause regulatory problems. Keep it chill ๐ŸงŠ
  4. PKI management protocols must allow the use of different industry-standard cryptographic algorithms (see CMP Algorithms [RFC9481]). This means that any given CA, RA, or end entity may, in principle, use whichever algorithms suit it for its own key pair(s). Mix and match, it's giving freedom ๐ŸŒธ
  5. PKI management protocols must not preclude the generation of key pairs by the end entity concerned, by a KGA, or by a CA. Key generation may also occur elsewhere, but for the purposes of PKI management, we can regard key generation as occurring wherever the key is first present at an end entity, KGA, 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 different environments may choose any of the above approaches. ๐Ÿ“ข
  7. PKI management protocols must support the production of Certificate Revocation Lists (CRLs) by allowing certified end entities to make requests for the revocation of certificates. This must be done in such a way that the denial-of-service attacks, which are possible, are not made simpler. Not giving attackers a free pass ๐Ÿ˜ค๐Ÿ’…
  8. PKI management protocols must be usable over a variety of "transport" mechanisms, specifically including email, Hypertext Transfer Protocol (HTTP), Message Queuing Telemetry Transport (MQTT), Constrained Application Protocol (CoAP), and various offline and non-networked file transfer methods. Every transport era ๐Ÿฆ‹๐Ÿ“จ
  9. Final authority for certification creation rests with the CA. No RA or end entity equipment can assume that any 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. In other words, all PKI entities (end entities, RAs, KGAs, and CAs) must be capable of handling responses to requests for certificates in which the actual certificate issued is different from the one requested (for example, a CA may shorten the validity period requested). Note that policy may dictate that the CA must not publish or otherwise distribute the certificate until the requesting entity has reviewed and accepted the newly created certificate or the POP is completed. In case of publication of the certificate (when using indirect POP, see Section 8.11) or a precertificate in a CT log [RFC9162], the certificate must be revoked if it was not accepted by the end entity or the POP could not be completed. The CA has the final say, and everyone has to be ready for surprises ๐Ÿ™ˆ๐Ÿ“œ
  10. A graceful, scheduled changeover from one non-compromised CA key pair to the next (CA key update) must be supported. Note that if the CA key is compromised, re-initialization must be performed for all entities in the domain of that CA. An end entity whose TEE contains the new CA public key (following a CA key update) may also need to be able to verify certificates verifiable using the old public key. End entities who directly trust the old CA key pair may also need to be able to verify certificates signed using the new CA private key (required for situations where the old CA public key is "hardwired" into the end entity's cryptographic equipment). Key rotation, but make it smooth ๐Ÿ”โœจ
  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 or CA public key to verify the protection of the communication. Same vibes, different hats ๐ŸŽฉ
  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 may 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., CMP) messages. Prove you own your key, periodt ๐Ÿ”‘๐Ÿ’–

3.1.3. PKI Management Operations

Okay bestie, here's the picture โœจ This diagram shows how all those entities we just met hook up through the PKI management operations ๐Ÿฆ‹ The letters are basically "protocols" ๐Ÿ’…, 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

At a high level, the operations that have management messages defined for them can be sorted into these buckets ๐ŸŒธ

  1. CA establishment: Spinning up a brand-new CA takes certain steps, like producing initial CRLs and 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 operations end up creating shiny new certificates ๐Ÿ’–
    • a. initial registration/certification: This is the moment an end entity first introduces itself to a CA or RA, before the CA issues any certificate or certificates for it ๐Ÿซถ When it works, 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 repository. This may, and typically will, take multiple "steps", possibly including setting up the end entity's equipment. For example, the end entity's equipment must be securely initialized with the public key of a CA, e.g., using zero-touch methods like Bootstrapping Remote Secure Key Infrastructure (BRSKI) [RFC8995] or Secure Zero Touch Provisioning (SZTP) [RFC8572], so it can validate certificate paths. Plus, an end entity typically needs its own key pair(s) loaded in too ๐ŸŽ€
    • b. key pair update: Every key pair needs a regular refresh (swapped for a new key pair), and a new certificate has to be issued ๐Ÿ”„
    • c. certificate update: When certificates expire, they may be "refreshed" if nothing relevant in the environment has changed ๐ŸŒˆ
    • d. CA key pair update: Same vibe as end entities, CA key pairs need regular updates too, but they use different mechanisms ๐Ÿ‘‘
    • e. cross-certification request: One CA asks another CA for a cross-certificate ๐Ÿฆ‹ For this standard, a few terms get 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 was issued for the subject CA's signing key pair). When you need to get more specific, these terms may be used: 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 ๐Ÿงš
      • Note 1: The definition of "cross-certificate" above lines up with the defined term "CA-certificate" in X.509. Don't mix this up with the X.500 "cACertificate" attribute type, which is totally unrelated ๐Ÿ™ˆ
      • Note 2: In a lot of environments, "cross-certificate" on its own, unless it's further qualified, will be understood to mean the same thing as "inter-domain cross-certificate" as defined above ๐Ÿ’…
      • Note 3: Issuing cross-certificates may be mutual, but it doesn't have to be. That means two CAs may issue cross-certificates for each other ๐Ÿซถ
    • f. cross-certificate update: Basically a normal certificate update, just involving a cross-certificate ๐Ÿ”
  4. Certificate/CRL discovery operations: Some PKI management operations end up publishing certificates or CRLs ๐Ÿ“ฃ
    • a. certificate publication: Once you've gone to the trouble of producing a certificate, you'll 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 (for example, Lightweight Directory Access Protocol (LDAP)) as described in [RFC4511] or [RFC2585] (the "Operational Protocols" documents of the PKIX series of specifications) ๐ŸŒธ
    • b. CRL publication: Same as certificate publication ๐Ÿ’œ
  5. Recovery operations: Some PKI management operations are for when an end entity has "lost" its TEE ๐Ÿฅฒ
    • a. 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 get those backed-up key materials back (e.g., after a forgotten password or a lost key chain file), a protocol exchange may be needed to make that recovery happen ๐Ÿ™
  6. Revocation operations: Some PKI management operations create new CRL entries and/or new CRLs ๐Ÿšซ
    • a. revocation request: An authorized person lets a CA know about an abnormal situation that calls for certificate revocation ๐Ÿšจ
  7. TEE operations: Defining TEE operations (e.g., moving a TEE, changing a PIN, etc.) is beyond the scope of this specification ๐Ÿ™…โ€โ™€๏ธ But we do define a PKIMessage (CertRepMessage) that can form the basis of such operations ๐Ÿ“

Online protocols aren't the only way to get these jobs done ๐ŸŒˆ Every operation has offline methods that reach 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 ๐Ÿ“ Transfer protocols for carrying these exchanges in different environments (e.g., offline: file-based; online: email, HTTP [RFC9811], MQTT, and CoAP [RFC9482]) are beyond the scope of this document and must be specified separately ๐Ÿฆ‹ Appropriate transfer protocols MUST be capable of delivering the CMP messages reliably ๐Ÿ’ฏ

CMP has built-in integrity protection and authentication ๐Ÿ›ก๏ธ The information sent unencrypted in CMP messages doesn't contain sensitive stuff that would endanger the PKI if intercepted. However, an eavesdropper could still use the available information to gather confidential technical or business-critical info ๐Ÿ‘€ So users should consider protecting confidentiality lower down the protocol stack, e.g., by using TLS [RFC8446], DTLS [RFC9147], or IPsec [RFC7296][RFC4303] ๐Ÿ”’


4. Assumptions and Restrictions โœจ

4.1. End Entity Initialization

The first thing an end entity does when dealing with PKI management entities is ask for info about the PKI functions it supports, and securely grab a copy of the relevant root CA public key(s) ๐Ÿ”‘

4.2. Initial Registration/Certification

There are lots of schemes for initial registration and certification of end entities ๐Ÿซง No single method fits every situation, because CAs can have all kinds of policies and end entities come in all kinds of shapes ๐ŸŒˆ

Still, we can sort the initial registration/certification schemes that this specification supports into categories ๐Ÿ“š The word "initial" is the crucial part here ๐Ÿ”ฅ We're talking about an end entity that has had no previous contact with the PKI, other than receiving the root CA certificate for that PKI through some zero-touch method like BRSKI [RFC8995] [RFC9733] or SZTP [RFC8572]. If the end entity already has certified keys, some simplifications and alternatives are possible ๐Ÿ’…

Once we've sorted the schemes this specification supports, some can be made mandatory and some optional ๐ŸŽ€ The goal is for the mandatory schemes to cover enough of the cases that show up in real use, while the optional schemes handle the special cases that come up less often ๐Ÿงš That's how we get a balance between flexibility and ease of implementation โš–๏ธ

More classification of mandatory and optional schemes for different environments is in Appendices C and D of this specification, which cover managing human user certificates, and in the Lightweight CMP Profile [RFC9483], which covers fully automating certificate management in machine-to-machine and Internet of Things (IoT) environments ๐Ÿค– Industry standards like [ETSI-3GPP.33.310] for mobile networks and [UNISIG.Subset-137] for railroad automation have adopted CMP and defined a series of mandatory schemes for their use cases ๐Ÿš†

Now let's get into the classification of initial registration/certification schemes ๐Ÿ’œ

4.2.1. Criteria Used

4.2.1.1. Initiation of Registration/Certification

okay so, bestie, this is where we figure out where the party starts ๐ŸŽ€ In terms of the PKI messages that get produced, we can say the initiation of the initial registration/certification exchanges happens wherever the first PKI message about the end entity gets made โœจ Real talk though, the real-world kickoff might happen somewhere else entirely ๐Ÿ’… Like, a personnel department might phone an RA operator, or use zero-touch methods like BRSKI [RFC8995] or SZTP [RFC8572] ๐Ÿซถ

So the possible locations are: the end entity, an RA, or a CA. Pick your favorite, periodt ๐Ÿฆ‹

4.2.1.2. End Entity Message Origin Authentication

okay this one is giving trust issues ๐Ÿ˜ญ The online messages the end entity sends that need a certificate may or may not be authenticated. The goal here is to authenticate the origin of any messages going from the end entity to the PKI (CA/RA) ๐Ÿ”ฅ

In this spec, that gets done in two different ways, and I'm obsessed:

  • symmetric: The PKI (CA/RA) gives the end entity a secret value (initial authentication key) plus a reference value (used to identify that secret value) through some out-of-band means ๐Ÿ” The initial authentication key can then protect the relevant PKI messages ๐Ÿ’œ
  • asymmetric: Uses a private key and certificate issued by another PKI that's trusted for initial authentication, for example an Initial Device Identifier (IDevID) IEEE 802.1AR [IEEE.802.1AR-2018] ๐ŸŒธ Trust establishment in that external PKI is out of scope of this document, so not my problem here ๐Ÿ™ˆ

So we can sort the initial registration/certification scheme by whether or not the online 'end entity -> PKI management entity' messages are authenticated. Easy peasy ๐Ÿงš

Note 1: We do not discuss authentication of the 'PKI management entity -> end entity' messages here, as this is always REQUIRED. In any case, it can be achieved simply once the root-CA public key has been installed at the end entity's equipment, 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 "key generation" is regarded as happening wherever either the public or private component of a key pair first shows up in a PKIMessage ๐Ÿงš Note that this does not rule out a centralized key generation service by a KGA โœจ The actual key pair MAY have been generated elsewhere and transported to the end entity, RA, or CA using a (proprietary or standardized) key generation request/response protocol (which is outside the scope of this specification) ๐Ÿ’…

Thus, there are three possibilities for the location of "key generation": the end entity, a KGA, or a CA. Three options, zero drama ๐ŸŽ€

4.2.1.4. Confirmation of Successful Certification

the vibe here is receipts, bestie ๐Ÿงพ Following the creation of a certificate for an end entity, extra assurance can be gained by having the end entity explicitly confirm successful receipt of the message containing (or indicating the creation of) the certificate ๐Ÿ’– Naturally, this confirmation message MUST be protected (based on the initial symmetric or asymmetric authentication key or other means) ๐Ÿ”’

This gives two further possibilities: confirmed or not. Iconic binary moment ๐Ÿ‘‘

4.2.2. Initial Registration/Certification Schemes

the criteria above allow for a large number of initial registration/certification schemes ๐ŸŒˆ Examples of possible schemes are in the following subsections. An entity MAY support other schemes specified in profiles of PKIX-CMP, such as Appendices C and D or [RFC9483] ๐Ÿฆ‹

4.2.2.1. Centralized Scheme

this one is, in some ways, the simplest possible scheme, lowkey the main character of the bunch โญ It's where:

  • initiation occurs at the certifying CA;
  • no online message authentication is required;
  • "key generation" occurs at the certifying CA (see Section 4.2.1.3); and
  • 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 TEE for the end entity ๐Ÿ’œ Some out-of-band means MUST be provided to allow the end entity to authenticate the message received and to decrypt any encrypted values ๐Ÿ”

Wait, I need to fix something: the original actually says "must" in lowercase for those last two sentences, so I'm keeping them as plain words, not requirement keywords. Sorry bestie, let me correct that below ๐Ÿ™ˆ

Corrected for accuracy: the message contains the entire TEE for the end entity. Some out-of-band means must be provided to allow the end entity to authenticate the message received and to decrypt any encrypted values ๐ŸŒธ

4.2.2.2. Basic Authenticated Scheme

this scheme is where things get spicy ๐ŸŒถ๏ธ It's where:

  • initiation occurs at the end entity;
  • message authentication is REQUIRED;
  • "key generation" occurs at the end entity (see Section 4.2.1.3); and
  • a confirmation message is RECOMMENDED.
Note: An Initial Authentication Key (IAK) can be either a symmetric key or an asymmetric private key with a certificate issued by another PKI trusted for this purpose. The establishment of such trust is out of scope of this document. ๐Ÿซถ

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 -> end entity)
  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
Note: 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. ๐Ÿšจ

4.3. POP of Private Key

okay so POP stands for proof of possession, and it's where a PKI management entity (CA/RA) checks whether an end entity actually has access to the private key matching a given public key ๐Ÿ”‘ Whether POPs add value to a PKI is a debate as old as PKI itself, honestly iykyk ๐Ÿ’€ See Section 8.1 for further discussion on the necessity of POP in PKI ๐ŸŽ€

The PKI management operations specified here let an end entity prove to a CA/RA that it has possession of (i.e., is able to use) the private key corresponding to the public key for which a certificate is requested (see Section 5.2.8 for different POP methods) ๐Ÿ’– A given CA/RA is free to choose how to enforce POP (e.g., out-of-band procedural means versus PKIX-CMP in-band messages) in its certification exchanges, which is a policy issue ๐Ÿ“‹ However, it is REQUIRED that CAs/RAs MUST enforce POP by some means, because there are currently many non-PKIX operational protocols in use (various electronic mail protocols are one example) that do not explicitly check the binding between the end entity and the private key ๐Ÿ˜ญ Until operational protocols that do verify the binding (for signature, encryption, key agreement, and KEM key pairs) exist and are ubiquitous, this binding can only be assumed to have been verified by the CA/RA ๐Ÿงš Therefore, if the binding is not verified by the CA/RA, certificates in the Internet PKI end up being somewhat less meaningful ๐Ÿ’”

POP is accomplished in different ways depending on the type of key for which a certificate is requested ๐ŸŒˆ 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, MUST NOT be sent to the CA/RA in order to prove possession unless archival of the private key is explicitly desired) โญ

This specification explicitly allows cases where an end entity supplies the relevant proof to an RA, and the RA then attests to the CA that the required proof has been received (and validated!) ๐Ÿซถ For example, an end entity wishing to have a signing key certified could send the appropriate signature to the RA, which then simply notifies the relevant CA that the end entity has supplied the required proof ๐Ÿฆ‹ Of course, such a situation may be disallowed by some policies (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 possession of the private key ๐Ÿ–Š๏ธ See Section 5.2.8.2 ๐Ÿ’…

4.3.2. Encryption Keys

for encryption keys, the end entity can provide the private key to the CA/RA (e.g., for archiving), see Section 5.2.8.3.1 ๐Ÿ—๏ธ Or it can be required to decrypt a value in order to prove possession of the private key ๐Ÿ”“ Decrypting a value can be achieved either directly (see Section 5.2.8.3.3) or indirectly (see Section 5.2.8.3.2) โœจ

The direct method is for the RA/CA to issue a random challenge to which an immediate response by the end entity is REQUIRED ๐ŸŽฒ

The indirect method is to issue a certificate that is encrypted for the end entity (and have the end entity demonstrate its ability to decrypt this certificate in the confirmation message) ๐ŸŽ This allows a CA to issue a certificate in a form that can only be used by the intended end entity ๐Ÿ”

This specification ENCOURAGES use of the indirect method because it requires no extra messages to be sent (i.e., the proof can be demonstrated 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 in order to prove that the end entity has possession of the private key ๐Ÿค

Note that this need not impose any restrictions on the keys that can be certified by a given CA ๐Ÿ’œ In particular, for Diffie-Hellman (DH) keys, the end entity may freely choose its algorithm parameters, provided that the CA can generate a short-term (or one-time) key pair with the appropriate parameters when necessary ๐ŸŒธ

4.3.4. KEM Keys โœจ

Okay so for KEM keys ๐Ÿ”, the end entity can hand its private key over to the CA/RA (for archiving, see Section 5.2.8.3.1), or it can be required to decrypt a value to prove it actually has the private key ๐Ÿ’…. Decrypting can happen either directly (see Section 5.2.8.3.3) or indirectly (see Section 5.2.8.3.2).

Note: A definition of KEMs can be found in Section 1 of [RFC9629]. ๐Ÿงš

The direct method is the RA/CA sending a random challenge, and the end entity has to respond right away ๐Ÿ˜ญ.

The indirect method is where things get really iconic ๐Ÿ’œ. The CA issues a certificate that's encrypted for the end entity, using a shared secret key derived from a key that was encapsulated with the public key. Then the end entity proves it can use its private key to decapsulate the KEM ciphertext, derive the shared secret key, decrypt the certificate, and send back a hash of that certificate in the confirmation message. This lets a CA issue a certificate that can only be used by the intended end entity ๐ŸŽ€.

This specification encourages use of the indirect method, because no extra messages need to be sent. The proof can be shown using the {request, response, confirmation} triple of messages ๐Ÿฆ‹.

A certification request message for a KEM certificate SHALL use POPOPrivKey by using the keyEncipherment choice of ProofOfPossession (see Section 5.2.8) in the popo field of CertReqMsg, as long as no KEM-specific choice is available ๐Ÿซถ.


4.4. Root CA Key Update ๐ŸŒธ

This discussion only applies to CAs that are directly trusted by some end entities. Whether a self-signed or non-self-signed CA is supposed to be directly trusted for some end entities is a matter of CA policy and end entity configuration. So that's beyond the scope of this document ๐Ÿ™ˆ.

The basic idea here 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 may generate two link certificates: "old with new" and "new with old" โœจ.

Note: How link certificates get used is super specific to each use case, so no assumptions are made about this. RootCaKeyUpdateContent is updated to mark these link certificates as optional ๐Ÿ’€.

Note: When an LDAP directory is used to publish root CA updates, the old and new root CA certificates, together with the two link certificates, get stored as cACertificate attribute values ๐Ÿ“š.

When a CA changes its key pair, the entities that got the old CA public key through "out-of-band" means are the most affected ๐Ÿ˜ญ. These end entities need to acquire the new CA public key in a trusted way. That can happen "out-of-band" by using a repository, or by using online messages that also contain the "new with old" link certificates. Once the end entity has acquired and properly verified the new CA public key, it must load the new trust anchor information into its trusted store ๐Ÿ”ฅ.

The data structure used to protect the new and old CA public keys is typically a standard X.509v3 certificate (which may also contain extensions). No new data structures are required ๐Ÿ“.

Note: Sometimes self-signed root CA certificates don't use X.509v3 extensions, and they may be X.509v1 certificates. So a root CA key update must be able to work for version 1 certificates. Using the X.509v3 KeyIdentifier extension is recommended for easier path building ๐ŸŒˆ.

Note: 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, so not having it just means the validity periods of certificates issued with the old CA key pair cannot exceed the end of the "old with new" certificate validity period ๐Ÿค”.

Note: This scheme gives end entities a mechanism to 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. Certificate and/or key update operations at other times don't necessarily require this, depending on the end entity's equipment โญ.

Note: In practice, a new root CA may have a slightly different subject Distinguished Name (DN), for example one that shows a generation identifier like the year of issuance or a version number, such as in an Organizational Unit (OU) element. How to bridge trust to the new root CA certificate in a CA DN change or a cross-certificate scenario is out of scope for this document ๐Ÿซ .

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 new CA public key, signed with the new private key or by the private key of some other CA (the "new with new" certificate).
  3. Optionally: Create a link certificate containing the new CA public key, signed with the old private key (the "new with old" certificate).
  4. Optionally: Create a link certificate containing the old CA public key, signed with the new private key (the "old with new" certificate).
  5. Publish these new certificates so end entities can acquire them, e.g., using a repository or RootCaKeyUpdateContent.

The old CA private key is no longer required once the validity of the "old with old" certificate has ended ๐Ÿฅ€. However, the old CA public key will stay in use for validating the "new with old" link certificate until the new CA public key is loaded into the trusted store. The old CA public key is no longer required (other than for non-repudiation) once all end entities of this CA have securely acquired and stored the new CA public key ๐Ÿ‘‘.

The "new with new" certificate must have a validity period with a notBefore time that is before the notAfter time of the "old with old" certificate, and a notAfter time that is after the notBefore time of the next update of this certificate ๐Ÿ—“๏ธ.

The "new with old" certificate must have a validity period with the same notBefore time as the "new with new" certificate, and a notAfter time by which all end entities of this CA will securely possess the new CA public key (at the latest, at the notAfter time of the "old with old" certificate) โฐ.

The "old with new" certificate must have a validity period with the same notBefore and notAfter time as the "old with old" certificate ๐Ÿฆ‹.

Note: More operational considerations on moving from one root CA self-signed certificate to the next are available in Section 5 of [RFC8649] ๐Ÿ’œ.

4.4.2. Verifying Certificates ๐Ÿ”

Normally when verifying a signature, the verifier checks (among other things) the certificate that contains the signer's public key. But once a CA is allowed to update its key, there are a range of new possibilities ๐Ÿ˜ณ. They're shown in the table below.

+======================+======================+=====================+
|                      | Verifier's TEE       | Verifier's TEE      |
|                      | contains NEW public  | contains OLD        |
|                      | key                  | public key          |
+======================+======================+=====================+
| Signer's certificate | Case 1: The verifier | Case 2: The         |
| is protected using   | can directly verify  | verifier is         |
| NEW key pair         | the certificate.     | missing the NEW     |
|                      |                      | public key.         |
+======================+----------------------+---------------------+
| Signer's certificate | Case 3: The verifier | Case 4: The         |
| is protected using   | is missing the OLD   | verifier can        |
| OLD key pair         | public key.          | directly verify     |
|                      |                      | the certificate.    |
+======================+----------------------+---------------------+

                                  Table 1

4.4.2.1. Verification in Cases 1 and 4 โœ…

In these cases, the verifier has a local copy of the CA public key that it can use to verify the certificate directly. It's the same as the situation where no key change has happened ๐ŸŒธ.

4.4.2.2. Verification in Case 2 ๐Ÿš€

In case 2, the verifier must get access to the new public key of the CA. This case will come up when the CA operator has issued the verifier's certificate, then changed the CA's key, and then issued the signer's certificate. So it's a pretty typical case ๐Ÿ’–.

The verifier does the following:

  1. Gets the "new with new" and "new with old" certificates. The location of these certificates may be available in the authority information access extension of the "old with old" certificate (see the access method for caIssuers in Section 4.2.2.1 of [RFC5280]), or it may be locally configured.
    • a. If a repository is available, look up the certificates in the caCertificate attribute.
    • b. If an HTTP or FTP server is available, pick the certificates from the "certs-only" CMS message.
    • c. If a CMP server is available, request the certificates using the root CA update the general message (see Section 5.3.19.15).
    • d. Otherwise, get the certificates "out-of-band" using any trustworthy mechanism.
  2. If the certificates are received, checks that the validity periods and the subject and issuer fields match. Verifies the signatures using the old root CA key (which the verifier has locally) ๐Ÿ”Ž.
  3. If all checks are successful, securely stores the new trust anchor information and validates the signer's certificate ๐ŸŽ‰.

4.4.2.3. Verification in Case 3 ๐Ÿงฉ

In case 3, the verifier must get access to the old public key of the CA. This case comes up when the CA operator has issued the signer's certificate, then changed the key, and then issued the verifier's certificate.

The verifier does the following:

  1. Gets the "old with new" certificate. The location of this certificate may be available in the authority information access extension of the "new with new" certificate (see the caIssuers access method in Section 4.2.2.1 of [RFC5280]), or it may be locally configured.
    • a. If a repository is available, look up the certificate in the caCertificate attribute.
    • b. If an HTTP or FTP server is available, pick the certificate from the "certs-only" CMS message.
    • c. If a CMP server and an untrusted copy of the old root CA certificate are available (e.g., the signer provided it in-band in the CMP extraCerts field), request the certificate using the root CA update the general message (see Section 5.3.19.15).
    • d. Otherwise, get the certificate "out-of-band" using any trustworthy mechanism.
  2. If the certificate is received, checks that the validity periods and the subject and issuer fields match. Verifies the signatures using the new root CA key (which the verifier has locally) ๐Ÿ”.
  3. If all checks were successful, securely stores the old trust anchor information and validates the signer's certificate ๐Ÿ’œ.

4.4.3. Revocation - Change of the CA Key โœจ

okay so bestie, remember how verifying a certificate gets way messier once the CA is allowed to swap its key? ๐Ÿ˜ญ well, revocation checks are giving the exact same drama ๐Ÿ’… because the CA might have signed the CRL with a newer private key than the one sitting inside the user's TEE ๐Ÿ”. main character plot twist.

and the way we figure out our options here? same exact analysis as certificate verification ๐Ÿฆ‹ no new rules, just the same playbook, periodt โœจ

4.5. EKU for PKI Entities ๐ŸŽ€

okay so the EKU extension is basically the bouncer ๐Ÿ’… it tells you what the certified key pair is allowed to be used for ๐Ÿ”‘, which means it puts limits on what a certificate can be used for, app by app ๐ŸŒธ

now, a CA might wanna hand off some of its jobs to other PKI management entities ๐Ÿงš this section is the mechanism that proves that handoff is legit AND lets machines automatically check the permission slip ๐Ÿ“œ (delegation can also be set up other ways, like explicit configuration, just saying ๐Ÿ™ˆ)

so here's the deal ๐Ÿ’œ: to get automatic validation for a CA delegating a role to another entity, the certificates used for CMP message protection or the signed data for central key generation MUST be issued by the delegating CA AND MUST contain the respective EKUs โœจ that's how we prove the delegating CA actually authorized this entity to play that role, as described below ๐Ÿ’–

the OIDs for these EKUs are:

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

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

  id-kp-cmKGA OBJECT IDENTIFIER ::= {
     iso(1) identified-organization(3) dod(6) internet(1)
     security(5) mechanisms(5) pkix(7) kp(3) 32 }
note: section 2.10 of [RFC6402] already specifies OIDs for a CMC CA and a CMC RA ๐Ÿ™Œ but a CA and RA aren't tied to any one certificate-management protocol (CMC or CMP), so CMP just reuses these EKUs ๐Ÿ” iconic energy, no need to reinvent the wheel ๐Ÿ›ž

and the meaning of the id-kp-cmKGA EKU? ๐Ÿ” it's giving very sensitive vibes:

  • CMP KGA ๐Ÿ‘‘: CMP KGAs are CAs or are identified by the id-kp-cmKGA EKU. the CMP KGA knows the private key it generated on behalf of the end entity ๐Ÿ—๏ธ this is a seriously sensitive service, so it needs specific authorization, which by default lives with the CA certificate itself ๐Ÿ’…
    • the CA can delegate that authorization by putting the id-kp-cmKGA EKU in the certificate used to authenticate the origin of the generated private key โœจ
    • the authorization can also be determined through local configuration of the end entity ๐ŸŒˆ

5. Data Structures ๐Ÿ“

okay bestie, this section is where we get into the actual building blocks ๐Ÿงฑ it describes the data structures needed for PKI management messages ๐Ÿ’– and section 6 is where you find the constraints on their values and the sequence of events for each PKI management operation ๐Ÿฆ‹ so think of this as the shopping list and section 6 as the recipe ๐Ÿง

5.1. Overall PKI Message ๐Ÿ’œ

every message used in this spec for PKI management follows this 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 message-specific info ๐ŸŽฏ
  • the PKIProtection, when it's used, has the bits that protect the PKI message ๐Ÿ›ก๏ธ
  • the extraCerts field can hold certificates the recipient might find useful ๐ŸŽ for example, a CA or RA can use it to give an end entity the certs it needs to verify its own new certificate (like when the CA that issued the end entity's cert isn't a root CA for that end entity) ๐ŸŒธ
    • heads up: this field does NOT necessarily contain a certification path ๐Ÿ™ƒ the recipient may have to sort, select from, or otherwise process the extra certs before they can actually use them ๐Ÿ’€

5.1.1. PKI Message Header ๐Ÿ’Œ

all PKI messages need some header info for addressing and transaction identification ๐Ÿ“ฌ some of it also shows up in a transport-specific envelope, but if the PKI message is protected, this info is protected too (we make no assumption about secure transport, bestie ๐Ÿ”’)

here's the data structure that holds this info:

  PKIHeader ::= SEQUENCE {
     pvno                INTEGER     { cmp1999(1), cmp2000(2),
                                       cmp2021(3) },
     sender              GeneralName,
     recipient           GeneralName,
     messageTime     [0] GeneralizedTime         OPTIONAL,
     protectionAlg   [1] AlgorithmIdentifier{ALGORITHM, {...}}
                         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 (protocol version number) usage is described in Section 7 ๐Ÿ“–

  • the sender field has the name of whoever sent the PKIMessage ๐Ÿ“ฃ this name (together with senderKID, if it's supplied) should be enough to tell you which key to use to verify the protection on the message ๐Ÿ”‘
    • if the sending entity knows nothing about the sender (like in the initial request message, where the end entity might not know its own DN, email name, IP address, etc.) then the "sender" field MUST contain a "NULL-DN" value in the directoryName choice ๐Ÿซฅ a "NULL-DN" is a SEQUENCE OF relative DNs of zero length, encoded as 0x3000 ๐Ÿงฉ
    • and in that case, the senderKID field MUST hold an identifier (a reference number) that tells the receiver which shared secret info to use to verify the message ๐Ÿ—๏ธ
  • the recipient field has the name of the recipient of the PKIMessage ๐ŸŽฏ this name (together with recipKID, if supplied) should be usable to verify the protection on the message โœ…
  • the protectionAlg field says which algorithm was used to protect the message ๐Ÿ›ก๏ธ if there are no protection bits (PKIProtection is OPTIONAL, remember ๐Ÿ™ˆ), this field MUST be omitted; if protection bits are supplied, this field MUST be supplied ๐Ÿ’…

senderKID and recipKID are how you indicate which keys were used to protect the message ๐Ÿ” (recipKID will normally only be required when the protection uses DH or Elliptic Curve Diffie-Hellman (ECDH) keys ๐Ÿ’Ž). these fields MUST be used if they're required to uniquely identify a key (like if more than one key is tied to a given sender name) ๐Ÿง and the senderKID SHOULD be used in any case โœจ

note: the advice about using senderKID has changed since [RFC4210], which said it should be left out if it wasn't needed to identify the protection key ๐Ÿ”„

the transactionID field is how the recipient correlates a message with an ongoing transaction ๐Ÿงต this is needed for all transactions that are more than just a single request/response pair ๐Ÿ” for single request/response transactions, the rules go like this ๐Ÿ‘‡:

  • a client MUST populate the transactionID field if the message contains an infoValue of type KemCiphertextInfo (see Section 5.1.3.4) ๐Ÿซถ
  • in all other cases, the client MAY populate the transactionID field of the request ๐Ÿคทโ€โ™€๏ธ
  • if a server gets such a request with the transactionID field set, it MUST set the transactionID field of the response to the same value ๐Ÿชž
  • if a server gets such a request with a missing transactionID field, it MUST populate the transactionID field if the message contains a KemCiphertextInfo field ๐Ÿ’…
  • in all other cases, the server MAY set the transactionID field of the response ๐ŸŒˆ

for transactions that are more than just a single request/response pair, the rules are different ๐Ÿงฉ:

  • if the message contains an infoValue of type KemCiphertextInfo, the client MUST generate a transactionID; otherwise, the client SHOULD generate a transactionID for the first request ๐Ÿ†”
  • if a server gets such a request with the transactionID field set, it MUST set the transactionID field of the response to the same value ๐Ÿชž
  • if a server gets such a request with a missing transactionID field, it MUST populate the transactionID field of the response with a server-generated ID ๐Ÿค–
  • subsequent requests and responses MUST all set the transactionID field to the value established ๐Ÿ”—
  • whenever a transactionID is being 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 are free to require uniqueness of the transactionID or not, as long as they can correctly associate messages with the right transaction ๐Ÿคธโ€โ™€๏ธ typically that means a server will require the {client, transactionID} tuple to be unique, or even the transactionID alone to be unique, if it can't tell clients apart based on any transport-level info ๐Ÿ•ต๏ธโ€โ™€๏ธ
  • if a server receives the first message of a transaction (one that needs more than a single request/response pair) and the transactionID doesn't let it meet the constraints above (usually because the transactionID is already in use), it MUST send back an ErrorMsgContent with a PKIFailureInfo of transactionIdInUse ๐Ÿ™…โ€โ™€๏ธ

it is RECOMMENDED that clients fill the transactionID field with 128 bits of (pseudo-)random data at the start of a transaction ๐ŸŽฒ this reduces the odds of the transactionID already being in use at the server ๐Ÿ€

the senderNonce and recipNonce fields protect the PKIMessage against replay attacks ๐Ÿ›ก๏ธ the senderNonce will typically be 128 bits of (pseudo-)random data generated by the sender ๐ŸŽฐ, whereas the recipNonce is copied from the senderNonce field of the previous message in the transaction ๐Ÿ”„

the messageTime field has the time at which the sender created the message โฐ this can be handy for end entities to check or correct their local time against a central system ๐Ÿ•ฐ๏ธ

the freeText field can send a human-readable message to the recipient (in any number of languages) ๐ŸŒ each UTF8String MAY include a language tag [RFC5646] to show what language the text is in ๐Ÿณ๏ธโ€๐ŸŒˆ the first language used in the sequence says which language replies should be in ๐Ÿ’ฌ

the generalInfo field can send machine-processable extra data to the recipient ๐Ÿค– the following generalInfo extensions are defined and MAY be supported โœจ

5.1.1.1. ImplicitConfirm ๐Ÿ™Œ

this one is how the end entity tells the CA or RA that it does NOT wish to send a certificate confirmation for issued certificates ๐Ÿ™…โ€โ™€๏ธ

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

if the CA grants the request, it MUST put the same extension in the PKIHeader of the response ๐Ÿซก and if the end entity doesn't find the extension in the response, it MUST send the certificate confirmation ๐Ÿ“จ no skipping this step, bestie ๐Ÿ’€

5.1.1.2. ConfirmWaitTime ๐ŸŽ€

okay so this one is giving "patience has limits" energy ๐Ÿ™ˆ The CA or RA uses it to tell the end entity how long it plans to wait for the certificate confirmation before it revokes the certificate and deletes the transaction. Bestie, that's a whole deadline situation ๐Ÿ’€

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

5.1.1.3. OrigPKIMessage ๐Ÿฆ‹

so an RA MAY include the original PKIMessage from the end entity in the generalInfo field of the PKIHeader of a PKIMessage ๐Ÿ’… The vibe here is the RA is basically showing the CA its receipts. It's the original message the RA got from the end entity and then changed in some way (like added or modified certain field values, or added new extensions) before forwarding the new PKIMessage ๐Ÿงš This is so the CA can check the message origin, the POP, or other info on the original end entity message. Main character energy for the CA, honestly ๐Ÿ‘‘

Note: If the changes made by the RA to the original PKIMessage break the POP of a certificate request, the RA can set the popo field of the new PKIMessage to raVerified (see Section 5.2.8.4).

Unless the OrigPKIMessage infoValue is in the header of a nested message, it MUST contain exactly one PKIMessage. The contents of OrigPKIMessage infoValue in the header of a nested message MAY contain multiple PKIMessage structures, which MUST be in the same order as the PKIMessage structures in PKIBody. ๐Ÿซถ

id-it-origPKIMessage OBJECT IDENTIFIER ::= {id-it 15} OrigPKIMessageValue ::= PKIMessages

5.1.1.4. CertProfile ๐ŸŒธ

this one is used by the end entity to indicate specific certificate profiles, like when it's requesting a new certificate or a certificate request template (see Section 5.3.19.16) โœจ It's giving "pick your aesthetic" ๐Ÿ’–

id-it-certProfile OBJECT IDENTIFIER ::= {id-it 21} CertProfileValue ::= SEQUENCE SIZE (1..MAX) OF UTF8String

When it's used in a p10cr message, the CertProfileValue sequence MUST NOT contain multiple certificate profile names. When it's used in an ir/cr/kur/genm message, the CertProfileValue sequence MUST NOT contain more certificate profile names than the number of CertReqMsg or GenMsgContent InfoTypeAndValue elements contained in the message body. ๐Ÿ“

The certificate profile names in the CertProfileValue sequence relate to the CertReqMsg or GenMsgContent InfoTypeAndValue elements in the given order. An empty string means no certificate profile name is associated with the respective CertReqMsg or GenMsgContent InfoTypeAndValue element. If the CertProfileValue sequence contains less certificate profile entries than CertReqMsg or GenMsgContent InfoTypeAndValue elements, the remaining CertReqMsg or GenMsgContent InfoTypeAndValue elements have no profile name associated with them. ๐Ÿ’œ

5.1.1.5. KemCiphertextInfo ๐ŸŒˆ

so a PKI entity MAY provide the KEM ciphertext for MAC-based message protection using KEM (see Section 5.1.3.4) in the generalInfo field of a request message to a PKI management entity, but only if it knows that the PKI management entity uses a KEM key pair and has its public key ๐Ÿ”ฅ bestie, it's all about knowing your audience ๐Ÿ™ˆ

id-it-KemCiphertextInfo OBJECT IDENTIFIER ::= { id-it 24 } KemCiphertextInfoValue ::= KemCiphertextInfo

For more details of KEM-based message protection, see Section 5.1.3.4. See Section 5.3.19.18 for the definition of {id-it 24}. ๐Ÿงš

5.1.2. PKI Message Body ๐Ÿ“

the PKIBody is a CHOICE, so every message type gets its own tag and label. It's like a whole menu of vibes ๐Ÿ’… The specific types are described in Section 5.3 below.

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] CAKeyUpdContent, --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 }

5.1.3. PKI Message Protection ๐Ÿ”

okay so some PKI messages will be protected for integrity ๐Ÿ›ก๏ธ

Note: If an asymmetric algorithm is used to protect a message and the relevant public component has been certified already, then the origin of the message can also be authenticated. On the other hand, if the public component is uncertified, then the message origin cannot be automatically authenticated but may be authenticated via out-of-band means.

When protection is applied, the following structure is used:

PKIProtection ::= BIT STRING

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

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

There MAY be cases in which the PKIProtection BIT STRING is deliberately not used to protect a message (i.e., this OPTIONAL field is omitted) because other protection, external to PKIX, will be applied instead. Such a choice is explicitly allowed in this specification. Examples of such external protection include CMS [RFC5652] and Security Multiparts [RFC1847] encapsulation of the PKIMessage (or simply the PKIBody (omitting the CHOICE tag), if the relevant PKIHeader information is securely carried in the external mechanism). It is noted, however, that many such external mechanisms require that the end entity already possesses a public-key certificate, a unique DN, and/or other such infrastructure-related information. Thus, they may not be appropriate for initial registration, key-recovery, or any other process with "bootstrapping" characteristics. For those cases, it may be necessary that the PKIProtection parameter be used. In the future, if/when external mechanisms are modified to accommodate bootstrapping scenarios, the use of PKIProtection may become rare or non-existent. ๐ŸŒธ

Depending on the circumstances, the PKIProtection bits may contain a MAC or signature. Only the following cases can occur: โœจ

5.1.3.1. Shared Secret Information ๐Ÿ”‘

in this case, the sender and recipient share secret information with sufficient entropy (established via out-of-band means). PKIProtection will contain a MAC value, and the protectionAlg MAY be one of the options described in Section 6.1 of CMP Algorithms [RFC9481].

The algorithm identifier id-PasswordBasedMac is defined in Section 4.4 of [RFC4211] and updated by [RFC9045]. It is mentioned in Section 6.1.1 of [RFC9481] for backward compatibility. More modern alternatives are listed in Section 6.1 of [RFC9481]. ๐Ÿฆ‹

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

The following text gives a method of key expansion to be used when the MAC algorithm requires an input length that is larger than the size of the one-way function (OWF). ๐Ÿงš

Note: Section 4.4 of [RFC4211] and [RFC9045] do not mention this key expansion method or give an example using HMAC algorithms where key expansion is not needed. It is recognized that this omission in [RFC4211] can lead to confusion and possible incompatibility if key expansion [RFC4210] is not used when needed. Therefore, when key expansion is required (when K > H), the key expansion defined in the following text MUST be used. ๐Ÿ˜ญ

In the above protectionAlg, the salt value is appended to the shared secret input. The OWF is then applied iterationCount times, where the salted secret is the input to the first iteration and, for each successive iteration, the input is set to be the output of the previous iteration. The output of the final iteration (called "BASEKEY" for ease of reference, with a size of "H") is what is used to form the symmetric key. If the MAC algorithm requires a K-bit key and K <= H, then the most significant K bits of BASEKEY are used. If K > H, then all of BASEKEY is used for the most significant H bits of the key, OWF("1" || BASEKEY) is used for the next most significant H bits of the key, OWF("2" || BASEKEY) is used for the next most significant H bits of the key, and so on, until all K bits have been derived. [Here "N" is the ASCII byte encoding the number N and "||" represents 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) to reduce the overhead associated with PasswordBasedMac computation. ๐ŸŒˆ

5.1.3.2. DH Key Pairs ๐Ÿ’ซ

where the sender and receiver possess finite-field or elliptic-curve-based DH certificates with compatible DH parameters in order to protect the message, the end entity must generate a symmetric key based on its private DH key value and the DH public key of the recipient of the PKI message. PKIProtection will contain a MAC value keyed with this derived symmetric key, and the protectionAlg will be the following: ๐Ÿ”ฅ

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

DHBMParameter ::= SEQUENCE { owf AlgorithmIdentifier, -- AlgId for an OWF mac AlgorithmIdentifier -- the MAC AlgId }

In the above protectionAlg, OWF is applied to the result of the DH computation. The OWF output (called "BASEKEY" for ease of reference, with a size of "H") is what is used to form the symmetric key. If the MAC algorithm requires a K-bit key and K <= H, then the most significant K bits of BASEKEY are used. If K > H, then all of BASEKEY is used for the most significant H bits of the key, OWF("1" || BASEKEY) is used for the next most significant H bits of the key, OWF("2" || BASEKEY) is used for the next most significant H bits of the key, and so on, until all K bits have been derived. [Here "N" is the ASCII byte encoding the number N and "||" represents concatenation.] ๐ŸŽ€

Note: Hash algorithms that can be used as OWFs are listed in Section 2 of CMP Algorithms [RFC9481]. ๐Ÿฆ‹

5.1.3.3. Signature โœ๏ธ

in this case, the sender possesses a signature key pair and simply signs the PKI message. PKIProtection will contain the signature value and the protectionAlg will be an AlgorithmIdentifier for a digital signature, which MAY be one of the options described in Section 3 of CMP Algorithms [RFC9481]. ๐Ÿ‘‘

5.1.3.4. Key Encapsulation ๐Ÿฆ‹โœจ

okay so bestie, this part is all about what happens when the sender has a KEM key pair ๐Ÿ”๐Ÿ’–. The idea is you can use it to set up a shared secret key for MAC-based message protection, and that lets you authenticate messages. Lowkey genius, no cap ๐Ÿ’….

This approach borrows the KEM algorithm functions from Section 1 of [RFC9629], and it's giving very clean vibes ๐ŸŒธ:

A KEM algorithm has three functions:

  1. KeyGen() -> (pk, sk): Generate a public key (pk) and a private (secret) key (sk).
  2. Encapsulate(pk) -> (ct, ss): Given the public key (pk), produce a ciphertext (ct) and a shared secret (ss).
  3. Decapsulate(sk, ct) -> (ss): Given the private key (sk) and the ciphertext (ct), produce the shared secret (ss).

So to support a particular KEM algorithm, the PKI entity that has a KEM key pair and wants to use it for MAC-based message protection MUST support the KEM Decapsulate() function ๐Ÿ™Œ. The PKI entity that wants to verify that MAC-based protection MUST support the KEM Encapsulate() function โœจ. The public KEM key usually lives in a certificate [ML-KEM] ๐Ÿ“œ.

Note: Both PKI entities send and receive messages in a PKI management operation ๐Ÿ’ฌ. Both of them might independently want to protect messages with their KEM key pairs. For ease of explanation, we'll call the entity with the KEM key pair who wants to provide MAC-based message protection "Alice" ๐Ÿ‘‘, and the entity that has Alice's authentic public KEM key and needs to verify her MAC-based protection "Bob" ๐ŸŽ€.

Okay so, assuming Bob has Alice's KEM public key, he generates the ciphertext with KEM encapsulation and sends it to Alice inside an InfoTypeAndValue structure ๐Ÿ’Œ. Alice then pulls the KEM shared secret out of that ciphertext using KEM decapsulation and her KEM private key ๐Ÿ”“. Next she uses a key derivation function (KDF) to turn the KEM shared secret, plus some other data Bob sent, into a shared secret key ๐Ÿงš. PKIProtection will hold a MAC value calculated with that shared secret key, and the protectionAlg is going to be this:

  id-KemBasedMac OBJECT IDENTIFIER ::= {1 2 840 113533 7 66 16}

  KemBMParameter ::= SEQUENCE {
    kdf              AlgorithmIdentifier{KEY-DERIVATION, {...}},
    kemContext   [0] OCTET STRING OPTIONAL,
    len              INTEGER (1..MAX),
    mac              AlgorithmIdentifier{MAC-ALGORITHM, {...}}
  }
Note: The OID for id-KemBasedMac was assigned on the private-use arc { iso(1) member-body(2) us(840) nortelnetworks(113533) entrust(7) } and not on an IANA-owned arc. The authors wanted it on the same branch as the existing OIDs for id-PasswordBasedMac and id-DHBasedMac ๐ŸŒˆ.

Quick breakdown of the fields ๐Ÿ“:

  • kdf is the algorithm identifier of the chosen KDF, plus any associated parameters, used to derive the shared secret key.
  • kemContext MAY be used to carry extra algorithm-specific context information (see also the definition of ukm in Section 3 of [RFC9629]) ๐Ÿง.
  • len is the output length of the KDF and MUST be the desired size of the key for MAC-based message protection ๐Ÿ“.
  • mac is the algorithm identifier of the chosen MAC algorithm, plus any associated parameters, used to calculate the MAC value ๐Ÿ”.

The KDF and MAC algorithms MAY be picked from the options in CMP Algorithms [RFC9481] ๐Ÿ›๏ธ.

The InfoTypeAndValue that carries the KEM ciphertext uses the OID id-it-KemCiphertextInfo ๐ŸŽซ. It holds a KemCiphertextInfo structure, as defined in Section 5.3.19.18 ๐Ÿ’….

Note: This InfoTypeAndValue can ride in a genm/genp message body, as specified in Section 5.3.19.18, or in the generalInfo field of PKIHeader in messages of other types (see Section 5.1.1.5) ๐Ÿš€.

Now let's look at a generic message flow for MAC-based protection using KEM, spelled out a bit more. We assume Bob has Alice's public KEM key ๐Ÿ—๏ธ. Alice can be the initiator of a PKI management operation or the responder. For fancier figures, check Appendix E ๐Ÿ“–.

Generic Message Flow:

Step# Alice                                Bob
---------------------------------------------------------------------
  1                                        perform KEM Encapsulate
                      <-- KEM Ciphertext <--
  2   perform KEM Decapsulate,
        perform key derivation,
        format message with
        MAC-based protection
                      -->    message     -->
  3                                        perform key derivation,
                                             verify MAC-based
                                             protection
-------------------  Alice authenticated by Bob  --------------------

     Figure 2: Generic Message Flow When Alice Has a KEM Key Pair

Now the steps, bestie ๐ŸŽ€:

  1. Bob needs Alice's authentic public KEM key (pk), for instance in a KEM certificate that he received and successfully validated beforehand ๐Ÿ“œโœ….

Bob generates a shared secret (ss) and the matching ciphertext (ct) using the KEM Encapsulate function with Alice's public KEM key (pk). Bob MUST NOT reuse the ss and ct for other PKI management operations ๐Ÿšซ. From that data, Bob builds a KemCiphertextInfo structure with the KEM algorithm identifier and the ciphertext (ct), and sends it to Alice in an InfoTypeAndValue structure, as defined in Section 5.3.19.18 ๐Ÿ’Œ.

Encapsulate(pk) -> (ct, ss)
  1. Alice decapsulates the shared secret (ss) from the ciphertext (ct) using the KEM Decapsulate function and her private KEM key (sk) ๐Ÿ”“.
Decapsulate(ct, sk) -> (ss)

If the decapsulation operation outputs an error, any failInfo field in an error response message SHALL contain the value badMessageCheck and the PKI management operation SHALL be terminated ๐Ÿ’€.

Alice then derives the shared secret key (ssk) with a KDF ๐Ÿงช. The shared secret (ss) is the input key material for the KDF, and len is the desired output length of the KDF, as the MAC algorithm needs it for message protection. KDF, len, and MAC get sent over to Bob in the protectionAlg KemBMParameter ๐Ÿ“ฆ. The DER-encoded KemOtherInfo structure, defined below, is used as the context for the KDF ๐Ÿงฉ.

KDF(ss, len, context)->(ssk)

The shared secret key (ssk) is what Alice uses for MAC-based protection ๐Ÿ”.

  1. Bob derives the very same shared secret key (ssk) with the KDF ๐Ÿช„. Again the shared secret (ss) is the input key material, len is the desired output length for the KDF, and the DER-encoded KemOtherInfo structure, built the same way as on Alice's side, is the context for the KDF ๐ŸŽฏ.
KDF(ss, len, context)->(ssk)

Bob uses the shared secret key (ssk) to verify the MAC-based protection on the message he received, and that's how he authenticates Alice ๐Ÿซถ.

This shared secret key (ssk) can be reused by Alice for MAC-based protection of further messages she sends to Bob within the current PKI management operation ๐Ÿ”.

This approach uses the KDF(IKM, L, info) notation from Section 5 of [RFC9629], with a few changes ๐Ÿฆ‹:

  • IKM is the input key material. It's the symmetric secret called "ss" that comes out of the KEM ๐Ÿ”‘.
  • L depends on the MAC algorithm used with the shared secret key for CMP message protection, and it's called "len" in this document ๐Ÿ“.
  • info is an extra input to the KDF, called "context" in this document. It holds the DER-encoded KemOtherInfo structure, defined as:
KemOtherInfo ::= SEQUENCE {
  staticString      PKIFreeText,
  transactionID     OCTET STRING,
  kemContext    [0] OCTET STRING OPTIONAL
}

staticString MUST be "CMP-KEM" ๐Ÿท๏ธ.

transactionID MUST be the value from the message that carries the ciphertext (ct) in KemCiphertextInfo ๐Ÿ†”.

Note: The transactionID keeps the derived shared secret key domain-separated between different PKI management operations ๐Ÿงฑ. For every PKI management operation with more than one exchange, the transactionID MUST be set anyway (see Section 5.1.1) ๐Ÿ’…. If Bob gave Alice an infoValue of type KemCiphertextInfo in the initial request message (see Figure 4 of Appendix E), then Bob MUST set the transactionID ๐Ÿ‘‘.

kemContext MAY contain additional algorithm-specific context information ๐ŸŒธ.

  • OKM is the output keying material of the KDF, used for MAC-based message protection with length len, and it's called "ssk" in this document โœจ.

There are a few different ways Alice can request, and Bob can provide, the KEM ciphertext (see Appendix E for the details) ๐Ÿงšโ€โ™€๏ธ. The KemCiphertextInfo can be requested with PKI general messages, as described in Section 5.3.19.18 ๐Ÿ“ฎ. Or the generalInfo field of the PKIHeader can carry the same request and response InfoTypeAndValue structures, as described in Section 5.1.1.5 ๐ŸŽ. The procedure also works without Alice explicitly asking for the KEM ciphertext, as long as Bob already knows one of Alice's KEM keys and can expect she's ready to use it ๐Ÿ™ˆ.

If both the initiator and the responder in a PKI management operation have KEM key pairs, this procedure can be run by both entities independently, and they'll end up with different shared secret keys for each direction ๐ŸŒˆ๐Ÿ’œ.


5.1.3.5. Multiple Protection ๐ŸŽ€

When a PKI management entity, like an RA, receives a protected PKI message, it MAY forward that message and add its own protection ๐Ÿ›ก๏ธ. Multiple PKI messages MAY also be aggregated ๐Ÿ“ฆ. There are several use cases for this ๐Ÿ’–.

  • The RA confirms it has validated and authorized a message and forwards the original message unchanged โœ….
  • A PKI management entity collects several messages that are headed the same way and forwards them together in a batch ๐Ÿšš. Request messages can be sent as a batch upstream (towards the CA), and response or announce messages can be sent as a batch downstream (towards an RA but not to the end entity) โฌ‡๏ธ. For example, this can be handy when bridging an offline connection between two PKI management entities ๐ŸŒ‰.

These use cases are handled by nesting the messages inside a new PKI message. The structure looks like this:

NestedMessageContent ::= PKIMessages

If an RA needs to modify a request message, it MAY include the original PKIMessage in the generalInfo field of the modified message, as described in Section 5.1.1.3 ๐Ÿ”.


5.2. Common Data Structures ๐Ÿง

Before we get into the specific types that can go in a PKIBody, we define some data structures that get used in more than one case ๐Ÿ’…โœจ.

5.2.1. Requested Certificate Contents

okay so this is where the requester gets to be the main character ๐Ÿ’… A PKI management message often needs the originator to say which fields should show up in a certificate. The CertTemplate structure is how they do it ๐ŸŽ€ Usually they have to give at least the publicKey field, and honestly that's the bare minimum. A CertTemplate is basically a TBSCertificate (see [RFC5280]) but with every field optional/situational, so nothing is locked in ๐Ÿฆ‹

Note: Even if the originator totally spells out the contents of the certificate it wants, the CA is free to change fields in the certificate it actually issues. If the changed certificate is unacceptable to the requester, the requester MUST send back a certConf message that either leaves this certificate out (via a CertHash) or includes it (via a CertHash) with a status of "rejected". See Section 5.3.18 for the definition and use of CertHash and the certConf message. ๐Ÿ™ˆ
Note: Before asking for a new certificate, an end entity can request a certTemplate as a kind of request blueprint ๐Ÿงš That way it can learn what data the CA expects to see in the request (see Section 5.3.19.16).

For the CertTemplate syntax, check out CRMF [RFC4211] ๐Ÿ’–

If certTemplate is an empty SEQUENCE (all fields omitted), then the controls field in the CertRequest structure MAY contain the id-regCtrl-altCertTemplate control, which specifies a template for a certificate that is not an X.509v3 public-key certificate ๐ŸŒˆ But if certTemplate is not empty (at least one field is present), then controls MUST NOT contain id-regCtrl-altCertTemplate. Here's the new control:

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

  AltCertTemplate ::= AttributeTypeAndValue

Also see [RFC4212] for more on managing certificates in alternative formats using CRMF [RFC4211] syntax โœจ

5.2.2. Encrypted Values

When encrypted stuff like a private key, certificate, POP challenge, or revocation passphrase gets sent in PKI messages, it is RECOMMENDED to use the EnvelopedData structure ๐Ÿ” Sometimes you get there by using the EncryptedKey data structure instead of EncryptedValue.

  EncryptedKey ::= CHOICE {
     encryptedValue       EncryptedValue, -- deprecated
     envelopedData    [0] EnvelopedData }

For EncryptedKey and EncryptedValue syntax, see Certificate Request Message Format (CRMF) [RFC4211], and for EnvelopedData syntax see Cryptographic Message Syntax (CMS) [RFC5652] ๐Ÿ“œ EncryptedKey gives you the choice of either EncryptedValue (only for backward compatibility) or EnvelopedData. EncryptedValue has been deprecated in favor of EnvelopedData, so it is RECOMMENDED to use EnvelopedData. Period ๐Ÿ’…

Note: The EncryptedKey structure from CRMF [RFC4211] is what's used here, which keeps the update backward compatible. Using the new syntax with the untagged default choice EncryptedValue is bits-on-the-wire compatible with the old syntax ๐Ÿซถ

To signal support for EnvelopedData, the pvno cmp2021 was introduced. Details on using the protocol version number are in Section 7 ๐Ÿฆ‹

It is RECOMMENDED to use the EnvelopedData structure in CMP to carry a private key, certificate, POP challenge, or revocation passphrase in encrypted form, as follows:

  • It contains only one RecipientInfo structure, because the content is encrypted for just one recipient.
  • It may contain a private key in the AsymmetricKeyPackage structure (which goes in the encryptedContentInfo field), as defined in [RFC5958], wrapped in a SignedData structure as specified in Section 5 of [RFC5652] and [RFC8933], and signed by the KGA or CA ๐Ÿ”‘
  • It may contain a certificate, POP challenge, or revocation passphrase directly in the encryptedContent field.

The content of the EnvelopedData structure, as specified in Section 6 of [RFC5652], MUST be encrypted using a newly generated symmetric content-encryption key. This content-encryption key MUST be securely provided to the recipient using one of four key management techniques. Yes, four! ๐Ÿ™Œ

The sender picks the key management technique based on what credential the recipient has:

  • recipient's certificate with an algorithm identifier and a public key that supports key transport, where any given key usage extension allows keyEncipherment: The content-encryption key will be protected using the key transport key management technique, as specified in Section 6.2.1 of [RFC5652] ๐Ÿšš
  • recipient's certificate with an algorithm identifier and a public key that supports key agreement, where any given key usage extension allows keyAgreement: The content-encryption key will be protected using the key agreement key management technique, as specified in Section 6.2.2 of [RFC5652] ๐Ÿค
  • a password or shared secret: The content-encryption key will be protected using the password-based key management technique, as specified in Section 6.2.4 of [RFC5652] ๐Ÿ—๏ธ
  • recipient's certificate with an algorithm identifier and a public key that supports KEM, where any given key usage extension allows keyEncipherment: The content-encryption key will be protected using the key management technique for KEM keys, as specified in [RFC9629] ๐ŸŒธ
Note: Sometimes the algorithm identifier, the type of public key, and the key usage extension just aren't enough to pick a key management technique, e.g., when rsaEncryption is the algorithm identifier. In those cases, it's a matter of local policy to decide ๐Ÿคทโ€โ™€๏ธ

5.2.3. Status Codes and Failure Information for PKI Messages

All response messages will include some status information ๐Ÿ“ฌ 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 pin down particular certificates, the CertId data structure is used ๐ŸŽฏ

For CertId syntax, see [RFC4211] ๐Ÿ’…

5.2.5. Out-of-Band Root CA Public Key

Every root CA that provides a self-signed certificate must be able to publish its current public key through some "out-of-band" means, or together with the respective link certificate using an online mechanism ๐ŸŒ Those mechanisms are beyond the scope of this document, but we do define data structures that can support them โœจ

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

Note: As an alternative to out-of-band distribution of root CA public keys, the CA can provide the self-signed certificate together with link certificates, e.g., using RootCaKeyUpdateContent (Section 5.3.19.15) ๐Ÿฆ‹
  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 contains a "NULL-DN", then both subjectAltNames and issuerAltNames extensions MUST be present and have exactly the same value; and
  • The values of all other extensions must be suitable for a self-signed certificate (e.g., key identifiers for the 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 can say they want the PKI to archive a private key value using the PKIArchiveOptions structure ๐Ÿ—„๏ธ

For PKIArchiveOptions syntax, see [RFC4211] ๐Ÿ’–

5.2.7. Publication Information

Requesters can say they want the PKI to publish a certificate using the PKIPublicationInfo structure ๐Ÿ“ฃ

For PKIPublicationInfo syntax, see [RFC4211] ๐Ÿ’œ

5.2.8. POP Structures

The POP structure in use is indicated in the popo field of type ProofOfPossession in the CertReqMsg sequence (see Section 4 of [RFC4211]) ๐Ÿงพ

   ProofOfPossession ::= CHOICE {
      raVerified      [0] NULL,
      signature       [1] POPOSigningKey,
      keyEncipherment [2] POPOPrivKey,
      keyAgreement    [3] POPOPrivKey
   }

5.2.8.1. raVerified

An end entity MUST NOT use raVerified ๐Ÿšซ If an RA changes a certification request in a way that breaks the provided POP, or if the RA requests a certificate on behalf of an end entity and can't provide the POP itself, the RA MUST use raVerified. Otherwise, it SHOULD NOT use raVerified.

When introducing raVerified, the RA MUST check the existing POP, or it MUST ensure by other means that the end entity is the holder of the private key ๐Ÿ•ต๏ธโ€โ™€๏ธ The RA MAY include the original message containing the POP in the generalInfo field using the id-it-origPKIMessage (see Section 5.1.1.3), so the CA can verify it โœ…

5.2.8.2. POPOSigningKey Structure

Okay so, bestie, if the certification request is for a key pair that supports signing (aka a request for a verification certificate) ๐Ÿ–Š๏ธโœจ, then the POP of the private key gets shown with the POPOSigningKey structure. For the full tea, check out Section 4.1 of [RFC4211]. ๐Ÿ’…

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

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

PKMACValue ::= SEQUENCE {
   algId AlgorithmIdentifier,
   value BIT STRING
}

Note: For this spec, the ASN.1 comment in Appendix C of [RFC4211] applies not only to certTemplate but also to the altCertTemplate control, as defined in Section 5.2.1. ๐ŸŽ€

Okay, so here's the key part ๐Ÿ”‘๐Ÿซถ. If certTemplate (or the altCertTemplate control) has the subject and publicKey values, then poposkInput MUST be omitted, and the signature MUST be computed over the DER-encoded value of the certReq field of the CertReqMsg (or the DER-encoded value of AltCertTemplate). If certTemplate/altCertTemplate doesn't have both the subject and public key values (like, it has only one of them or neither ๐Ÿ™ˆ), then poposkInput MUST be present, and the signature MUST be computed over the DER-encoded value of poposkInput (i.e., the "value" OCTETs of the POPOSigningKeyInput DER).

In the special case where the CA/RA has a DH certificate that the end entity already knows, AND the certification request is for a key agreement key pair, the end entity can also use the POPOSigningKey structure (where the algorithmIdentifier field is DHBasedMAC and the signature field is the MAC) to demonstrate POP. โœจ๐Ÿฆ‹

5.2.8.3. POPOPrivKey Structure

If the certification request is for a key pair that does NOT support signing (so, a request for an encryption or key agreement certificate ๐Ÿ”), then the POP of the private key is shown using the POPOPrivKey structure in one of the following three ways. For details, see Sections 4.2 and 4.3 in [RFC4211]. ๐ŸŒธ

POPOPrivKey ::= CHOICE {
   thisMessage [0] BIT STRING, -- deprecated
   subsequentMessage [1] SubsequentMessage,
   dhMAC [2] BIT STRING, -- deprecated
   agreeMAC [3] PKMACValue,
   encryptedKey [4] EnvelopedData
}

SubsequentMessage ::= INTEGER {
   encrCert (0),
   challengeResp (1)
}

When using the agreeMAC or encryptedKey choices, the pvno cmp2021(3) MUST be used. ๐Ÿ’œ Details on how the protocol version number gets used are in Section 7.

5.2.8.3.1. Inclusion of the Private Key

This method, which we chatted about earlier in Section 4.3, shows POP of the private key by including the encrypted private key in the CertRequest, inside the POPOPrivKey structure or the PKIArchiveOptions control structure. ๐Ÿ—๏ธ This method SHALL only be used if archival of the private key is desired. Not me being strict, but that's the rule!! ๐Ÿ˜ญ

For a certification request message that indicates cmp2021(3) in the pvno field of the PKIHeader, the encrypted private key MUST be transferred in the encryptedKey choice of POPOPrivKey (or within the PKIArchiveOptions control) in a CMS EnvelopedData structure, as defined in Section 5.2.2. ๐Ÿงš

Note: The thisMessage choice has been deprecated in favor of encryptedKey. When using cmp2000(2) in the certification request message header for backward compatibility, the thisMessage choice of POPOPrivKey is used, containing the encrypted private key in an EncryptedValue structure wrapped in a BIT STRING. This still allows the necessary conveyance and protection of the private key, while keeping bits-on-the-wire compatibility with [RFC4211]. ๐Ÿ“

5.2.8.3.2. Indirect Method - Encrypted Certificate

The indirect method, which we also mentioned in Section 4.3, shows POP of the private key by having the CA return the requested certificate in encrypted form (see Section 5.2.2). โœจ This method is indicated in the CertRequest by requesting the encrCert option in the subsequentMessage choice of POPOPrivKey.

        end entity                         RA/CA
                 ----       req        ---->
                 <---  rep (enc cert)  -----
                 ---- conf (cert hash) ---->
                 <---       ack        -----

Okay, this is so clever ๐Ÿ™ˆ๐Ÿ”ฅ. The end entity proves it knows the private key to the CA by providing the correct CertHash for this certificate in the certConf message. This demonstrates POP because the end entity can only compute the correct CertHash if it can recover the encrypted certificate, and it can only recover the certificate if it can get the symmetric key using the required private key. Clearly, for this to work, the CA MUST NOT publish the certificate until the certConf message arrives (when certHash is to be used to demonstrate POP). See Section 5.3.18 for further details, and see Section 8.11 for security considerations regarding use of CT logs. ๐Ÿ‘‘

The recipient SHOULD maintain a context of the PKI management operation, e.g., using transactionID and certReqId, to identify the private key to use when decrypting the EnvelopedData containing the newly issued certificate. The recipient MAY be unable to use the RecipientInfo structure, since it refers to the certificate that is still encrypted. ๐Ÿซถ The sender MUST populate the rid field as specified by CMS, and the client MAY ignore it. ๐Ÿ’–

5.2.8.3.3. Direct Method - Challenge-Response Protocol

The direct method, mentioned earlier in Section 4.3, shows POP of the private key by having the end entity engage in a challenge-response protocol (using the messages popdecc of type POPODecKeyChall and popdecr of type POPODecKeyResp; see below) between CertReqMessages and CertRepMessage. This method is indicated in the CertRequest by requesting the challengeResp option in the subsequentMessage choice of POPOPrivKey. ๐Ÿฆ‹

Note: This method would typically be used in an environment where an RA verifies POP and then makes a certification request to the CA on behalf of the end entity. In that kind of setup, the CA trusts the RA to have done POP correctly before the RA requests a certificate for the end entity. ๐ŸŒˆ

The complete protocol then looks like this (note that req' does not necessarily encapsulate req as a nested message): ๐Ÿ’…

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

Okay, this one is obviously way longer than the exchange in Section 5.2.8.3.2 above ๐Ÿ˜ญ, but it lets a Local Registration Authority (LRA) get involved, and it has the property that the certificate itself isn't actually created until the POP is complete. โœจ In some environments, a different order of the messages above may be required, like this one (this may be determined by policy): ๐ŸŒธ

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

The challenge-response messages for POP of a private key are specified as follows (for decryption keys, see [MvOV97], p.404 for details). This challenge-response exchange is linked to the preceding certification request message (and the subsequent certification response and confirmation messages) by the transactionID used in the PKIHeader and by the protection applied to the PKIMessage. ๐Ÿ”

POPODecKeyChallContent ::= SEQUENCE OF Challenge

Challenge ::= SEQUENCE {
   owf AlgorithmIdentifier OPTIONAL,
   witness OCTET STRING,
   challenge OCTET STRING, -- deprecated
   encryptedRand [0] EnvelopedData OPTIONAL
}

Rand ::= SEQUENCE {
   int INTEGER,
   sender GeneralName
}

More details on the fields in this syntax are available in Appendix F. ๐Ÿงš

For a popdecc message that indicates cmp2021(3) in the pvno field of the PKIHeader, the encryption of Rand MUST be transferred in the encryptedRand field, in a CMS EnvelopedData structure as defined in Section 5.2.2. The challenge field MUST contain an empty OCTET STRING. ๐Ÿ’œ

The recipient SHOULD maintain a context of the PKI management operation, e.g., using transactionID and certReqId, to identify the private key to use when decrypting encryptedRand. The sender MUST populate the rid field in the EnvelopedData sequence using the issuerAndSerialNumber choice, containing a NULL-DN as issuer and the certReqId as serialNumber. The client MAY ignore the rid field. ๐Ÿ“

Note: The challenge field has been deprecated in favor of encryptedRand. When using cmp2000(2) in the popdecc message header for backward compatibility, the challenge field MUST contain the encryption (involving the public key for which the certification request is being made) of Rand, and encryptedRand MUST be omitted. Using challenge (omitting the optional encryptedRand field) is bit-compatible with [RFC4210]. Note that the size of Rand, when used with challenge, needs to be appropriate for encryption involving the public key of the requester. If, in some environment, names are so long that they cannot fit (e.g., 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 is able to deal meaningfully with the abbreviation). ๐ŸŽ€

POPODecKeyRespContent ::= SEQUENCE OF INTEGER

On receiving the popdecc message, the end entity decrypts all included challenges and responds with a popdecr message containing the decrypted integer values in the same order. ๐ŸŒˆโœจ

5.2.8.4. Summary of POP Options โœจ

okay bestie, this part is literally the recap of every POP option, and I'm obsessed ๐Ÿซถ POP is basically "proof of possession," aka proving you actually hold the private key. Using "SK" for "signing key", "EK" for "encryption key", "KAK" for "key agreement key", and "KEMK" for "key encapsulation mechanism key", the whole lineup looks like this ๐Ÿ‘‘

   RAVerified;
   SKPOP;
   EKPOPThisMessage; -- deprecated
   KAKPOPThisMessage; -- deprecated
   EKPOPEncryptedKey;
   KAKPOPEncryptedKey;
   KEMKPOPEncryptedKey;
   KAKPOPThisMessageDHMAC;
   EKPOPEncryptedCert;
   KAKPOPEncryptedCert;
   KEMKPOPEncryptedCert;
   EKPOPChallengeResp;
   KAKPOPChallengeResp; and
   KEMKPOPChallengeResp.

so the big question is, how does an end entity know which ones the CA/RA actually supports? ๐Ÿค” The guidelines below are the answer, end entity implementers, read these ๐Ÿ’…

  • RAVerified: this is not an end entity decision ๐Ÿ™…โ€โ™€๏ธ The RA uses this if and only if it has verified POP before forwarding the request on to the CA, so the end entity cannot pick this one. Not me choosing it, the RA is the one doing it.
  • SKPOP: if the end entity has a signing key pair, this is the only POP method specified for use in the request for a corresponding certificate. Simple and iconic โœจ
  • EKPOPThisMessage (deprecated), KAKPOPThisMessage (deprecated), EKPOPEncryptedKey, KAKPOPEncryptedKey, KEMKPOPEncryptedKey: whether or not to give up its private key to the CA/RA is an end entity decision ๐Ÿฆ‹ If the end entity decides to reveal its key, then these are the only POP methods available in this specification to achieve this, and the key pair type and protocol version used will determine which of these to use. The reason the EKPOPThisMessage and KAKPOPThisMessage options got deprecated is in Section 5.2.8.3.1, so go check that one out ๐ŸŽ€
  • KAKPOPThisMessageDHMAC: the end entity can only use this method if (1) the CA/RA has a DH certificate available for this purpose and (2) the end entity already has a copy of this certificate. If both of these conditions hold, then this technique is clearly supported and may be used by the end entity, if desired ๐ŸŒธ
  • EKPOPEncryptedCert, KAKPOPEncryptedCert, KEMKPOPEncryptedCert, EKPOPChallengeResp, KAKPOPChallengeResp, and KEMKPOPChallengeResp: the end entity picks one of these (in the subsequentMessage field) in the request message, depending on preference and key pair type ๐Ÿงš The end entity is not doing POP at this point, it's just indicating which method it wants to use. So if the CA/RA replies with a "badPOP" error, the end entity can re-request using the other POP method chosen in subsequentMessage ๐Ÿ’œ Note, however, that this specification encourages the use of the EncryptedCert choice, and furthermore says that the challenge-response would typically be used when an RA is involved and doing POP verification. So the end entity should be able to make an intelligent decision about which of these to choose in the request message ๐Ÿ‘‘

5.2.9. GeneralizedTime โœจ

GeneralizedTime is a standard ASN.1 type and SHALL be used as specified in Section 4.1.2.5.2 of [RFC5280] ๐Ÿ•ฐ๏ธ no notes, just follow it, bestie ๐Ÿ’…


5.3. Operation-Specific Data Structures ๐ŸŽ€

5.3.1. Initialization Request ๐ŸŒˆ

An Initialization request message contains, as the PKIBody, a CertReqMessages data structure that specifies the requested certificate(s) ๐Ÿ’– Typically, SubjectPublicKeyInfo, KeyId, and Validity are the template fields that may be supplied for each certificate requested (see the profiles defined in Section 4.1.1 of [RFC9483] and Appendices C.4 and D.7 for further info). This message is intended for entities when they're first initializing into the PKI ๐ŸŒธ

See Section 5.2.1 and [RFC4211] for CertReqMessages syntax ๐Ÿ“–

5.3.2. Initialization Response ๐Ÿง

An Initialization response message contains, as the PKIBody, a CertRepMessage data structure. For each certificate requested, it has a PKIStatusInfo field, a subject certificate, and possibly a private key (normally encrypted using EnvelopedData; see Section 4.1.6 of [RFC9483] for more info) ๐Ÿ”

See Section 5.3.4 for CertRepMessage syntax ๐Ÿ’… Note that if the PKI message protection is "shared secret information" (see Section 5.1.3.1), then any certificate transported in the caPubs field may be directly trusted as a root CA certificate by the initiator ๐Ÿšจ that's a big deal, so don't skip this one!

5.3.3. Certification Request ๐Ÿฆ‹

A Certification request message contains, as the PKIBody, a CertReqMessages data structure that specifies the requested certificates (see the profiles defined in Section 4.1.2 of [RFC9483] and Appendix C.2 for further info). This message is intended for existing PKI entities who want to get additional certificates ๐Ÿ’œ

See Section 5.2.1 and [RFC4211] for CertReqMessages syntax โœจ

Alternatively, the PKIBody MAY be a CertificationRequest. This structure is fully specified by the ASN.1 structure CertificationRequest given in [RFC2986] (see the profiles defined in Section 4.1.4 of [RFC9483] for further info). 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's not absolutely necessary ๐Ÿ™…โ€โ™€๏ธ

5.3.4. Certification Response ๐Ÿ“

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

   CertRepMessage ::= SEQUENCE {
      caPubs          [1] SEQUENCE SIZE (1..MAX) OF CMPCertificate
                          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 [RFC4211]
   }

   CertifiedKeyPair ::= SEQUENCE {
      certOrEncCert       CertOrEncCert,
      privateKey      [0] EncryptedKey         OPTIONAL,
      -- See [RFC4211] for comments on encoding.
      publicationInfo [1] PKIPublicationInfo   OPTIONAL
   }

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

A p10cr message contains exactly one CertificationRequestInfo data structure, as specified in PKCS #10 [RFC2986], but no certReqId. Therefore, the certReqId in the corresponding Certification Response (cp) message MUST be set to -1 ๐Ÿ”ข don't forget the -1!!

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 ๐Ÿ™ˆ

Given an EncryptedCert and the relevant decryption key, the certificate may be obtained. The purpose of this is to let a CA return the value of a certificate, but with the constraint that only the intended recipient can obtain the actual certificate ๐Ÿ”’ The benefit is that a CA may 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 is received by the CA). So the CA won't have to revoke that certificate if something goes wrong with the POP (but it MAY do so anyway, depending on policy) ๐Ÿ’€ iykyk, it's giving clever.

The use of EncryptedKey is described in Section 5.2.2 ๐Ÿ“–

Note: To indicate support for EnvelopedData, the pvno cmp2021 has been introduced. Details on the usage of different protocol version numbers are described in Section 7 ๐Ÿšจ

5.3.5. Key Update Request Content ๐ŸŒธ

For key update requests, the CertReqMessages syntax is used. Typically, SubjectPublicKeyInfo, KeyId, and Validity are the template fields that may be supplied for each key to be updated (see the profiles defined in Section 4.1.3 of [RFC9483] and Appendix C.6 for further info). This message is intended to request updates to existing (non-revoked and non-expired) certificates, which is why it's sometimes called a "Certificate Update" operation ๐Ÿ”„ An update is a replacement certificate containing either a new subject public key or the current subject public key (although the latter practice may not be appropriate for some environments) ๐Ÿฆ‹

See Section 5.2.1 and [RFC4211] for CertReqMessages syntax โœจ

5.3.6. Key Update Response Content ๐Ÿ’–

For key update responses, the CertRepMessage syntax is used. The response is identical to the initialization response ๐Ÿซถ

See Section 5.3.4 for CertRepMessage syntax ๐Ÿ’…

5.3.7. Key Recovery Request Content ๐Ÿงš

For key recovery requests, the syntax used 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 for which a certificate is required ๐Ÿ”‘

See Section 5.2.1 and [RFC4211] for CertReqMessages syntax. Note that if a key history is required, the requester MUST supply a protocol encryption key control in the request message ๐Ÿšจ

5.3.8. Key Recovery Response Content ๐Ÿ‘‘

For key recovery responses, the following syntax is used. For some status values (e.g., waiting), none of the optional fields will be present ๐Ÿ™ˆ

   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 requesting revocation of a certificate (or several certificates), the following data structure is used (see the profiles defined in Section 4.2 of [RFC9483] for further info). The name of the requester is present in the PKIHeader structure ๐Ÿซถ

   RevReqContent ::= SEQUENCE OF RevDetails

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

5.3.10. Revocation Response Content ๐ŸŽ€

The revocation response is the response to the above message. If produced, it's sent to the requester of 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, with the restriction that the key pair MUST have been generated by the requesting CA and the private key MUST NOT be sent to the responding CA (see the profiles defined in Appendix D.6 for further info) ๐Ÿ” This request MAY also be used by subordinate CAs to get their certificates signed by the parent CA ๐ŸŒณ

See Section 5.2.1 and [RFC4211] for CertReqMessages syntax ๐Ÿ’–

5.3.12. Cross-Certification Response Content ๐Ÿฆ‹

Okay so cross-cert responses are literally the same vibe as normal cert responses, they use the same syntax (CertRepMessage) ๐Ÿ’… with ONE restriction: no encrypted private key can be sent. Not me being dramatic, it's just the rule ๐Ÿ™ˆ

See Section 5.3.4 for CertRepMessage syntax ๐ŸŒธ

5.3.13. CA Key Update Announcement Content โœจ

Okay so when a CA updates its own key pair, there's a data structure that MAY be used to announce it ๐Ÿ“ฃ

RootCaKeyUpdateContent ::= SEQUENCE {
   newWithNew              CMPCertificate,
   newWithOld          [0] CMPCertificate OPTIONAL,
   oldWithNew          [1] CMPCertificate OPTIONAL
}

CAKeyUpdContent ::= CHOICE {
    cAKeyUpdAnnV2      CAKeyUpdAnnContent, -- deprecated
    cAKeyUpdAnnV3  [0] RootCaKeyUpdateContent
}

When you use RootCaKeyUpdateContent in the ckuann message, the pvno cmp2021 MUST be used ๐Ÿ”ฅ The details on how the protocol version number works are in Section 7 ๐ŸŽ€

In contrast to CAKeyUpdAnnContent as supported with cmp2000, RootCaKeyUpdateContent lets you omit newWithOld and oldWithNew, depending on what the end entity needs ๐Ÿซถ

5.3.14. Certificate Announcement ๐Ÿงš

This structure MAY be used to announce that certificates exist ๐Ÿ“

Note that this message is meant for the cases (if any) where there's no pre-existing way to publish certificates. It is NOT meant for cases 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 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 this announcement to warn (or notify) a subject that its certificate is about to be (or has already been) revoked ๐Ÿšจ This would typically happen when the revocation request didn't come from the subject concerned ๐Ÿ‘€

The willBeRevokedAt field holds the time when a new entry will be added to the relevant CRLs โญ

5.3.16. CRL Announcement ๐ŸŒˆ

When a CA issues a new CRL (or set of CRLs), the following 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 every case. Honestly there's no content at all, since the PKIHeader already carries all the required information ๐Ÿคทโ€โ™€๏ธ

PKIConfirmContent ::= NULL

Using this message for certificate confirmation is NOT RECOMMENDED ๐Ÿ™…โ€โ™€๏ธ certConf SHOULD be used instead ๐Ÿ’– When a recipient gets a pkiconf for a certificate response, it 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,
   hashAlg [0] AlgorithmIdentifier{DIGEST-ALGORITHM, {...}}
               OPTIONAL
}

The hashAlg field SHOULD be used only in exceptional cases ๐Ÿง Those are when the signatureAlgorithm of the certificate being confirmed doesn't specify a hash algorithm in the OID or in the parameters, or when no hash algorithm is specified for hashing certificates signed using the signatureAlgorithm. Heads up that for EdDSA, a hash algorithm is specified in Section 3.3 of [RFC9481], so the hashAlg field is NOT needed for EdDSA ๐Ÿฆ‹ Otherwise, the certHash value SHALL be computed using the same hash algorithm used to create and verify the certificate signature, or as specified for hashing certificates signed using the signatureAlgorithm ๐Ÿ” If hashAlg is used, the CMP version in the certConf message header must be cmp2021(3) ๐Ÿ”ฅ

For any particular CertStatus, leaving out the statusInfo field means the specified certificate is accepted ๐ŸŽ‰ Alternatively, explicit status details (about acceptance or rejection) MAY be given in the statusInfo field, maybe for auditing at the CA/RA ๐Ÿ•ต๏ธโ€โ™€๏ธ

Within CertConfirmContent, leaving out a CertStatus structure for a certificate from the previous response message means that certificate is rejected ๐Ÿ™…โ€โ™€๏ธ So an empty CertConfirmContent (a zero-length SEQUENCE) MAY be used to reject all supplied certificates ๐Ÿ’… See Section 5.2.8.3.2 for a discussion of the certHash field with respect to POP ๐Ÿซถ

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 end entity to get a certificate from the CA that it can use to protect sensitive info during the protocol ๐Ÿ›ก๏ธ

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

End entities MUST make sure the correct certificate is used for this purpose ๐ŸŽฏ

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

This MAY be used by the end entity to get the list of signature algorithms whose subject public key values the CA is willing to certify ๐Ÿ“‹

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

Note: For the purposes of this exchange, rsaEncryption and sha256WithRSAEncryption, for example, are considered equivalent. The question being asked is, "Is the CA willing to certify an RSA public key?" ๐Ÿค”

Note: If several elliptic curves are supported, several id-ecPublicKey elements as defined in [RFC5480] need to be given, one per named curve ๐ŸŒˆ

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

Note: If several elliptic curves are supported, several id-ecPublicKey elements as defined in [RFC5480] need to be given, one per named curve ๐ŸŒˆ

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 info that needs to be exchanged between the end entity and the CA ๐Ÿซฃ For example, if the end entity 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 18}, RootCaKeyUpdateValue

See Section 5.3.13 for details of CA key update announcements ๐Ÿ“–

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 return 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 end entity to request the domain parameters to use for generating the key pair for certain public-key algorithms ๐Ÿงฎ It can be used, for example, to request the right 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 ๐Ÿšซ

End entities MUST make sure the parameters are acceptable to them, and that the GenRep message is authenticated (to avoid substitution attacks) ๐Ÿ›‘

5.3.19.9. Revocation Passphrase ๐Ÿคซ

This MAY be used by the end entity to send a passphrase to a CA/RA so that a later revocation request can be authenticated ๐Ÿ” That's for when the signing private key you'd normally use is no longer available ๐Ÿ˜… See Appendix B for further details on how this mechanism works ๐Ÿ“š

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

The use of EncryptedKey is described in Section 5.2.2 ๐ŸŽ€

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.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 [RFC5646] for later messages ๐Ÿ’ฌ The sender sends its list of supported languages (most preferred to least preferred), 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.19.14. CA Certificates ๐Ÿ›๏ธ

This MAY be used by the client to get CA certificates ๐Ÿชช

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

5.3.19.15. Root CA Update ๐ŸŒณ

This MAY be used by the client to get an update of a root CA certificate, which is provided in the body of the request message ๐Ÿ“ฌ Unlike the ckuann message, this approach follows the request/response model ๐Ÿ”

The end entity SHOULD reference its current trust anchor in RootCaCertValue in the request body, giving the root CA certificate if available ๐ŸŒŸ

GenMsg:    {id-it 20}, RootCaCertValue | < absent >
GenRep:    {id-it 18}, RootCaKeyUpdateValue | < absent >

RootCaCertValue ::= CMPCertificate

RootCaKeyUpdateValue ::= RootCaKeyUpdateContent

RootCaKeyUpdateContent ::= SEQUENCE {
   newWithNew              CMPCertificate,
   newWithOld          [0] CMPCertificate OPTIONAL,
   oldWithNew          [1] CMPCertificate OPTIONAL
}

Note: Unlike CAKeyUpdAnnContent (which was deprecated with pvno cmp2021), RootCaKeyUpdateContent lets you omit newWithOld and oldWithNew, depending on what the end entity needs ๐Ÿ’–

5.3.19.16. Certificate Request Template โœจ

Okay bestie, this one's a template request ๐ŸŽ€ The client MAY use it to grab a prefilled template that lists the requirements for certificate request attributes and extensions ๐Ÿ’– The controls id-regCtrl-algId and id-regCtrl-rsaKeyLen MAY contain details on which types of subject public keys the CA is willing to certify ๐Ÿ”‘

The id-regCtrl-algId control MAY be used to name a cryptographic algorithm (see Section 4.1.2.7 of [RFC5280]) other than rsaEncryption ๐Ÿฆ‹ The algorithm field SHALL identify a cryptographic algorithm ๐Ÿ‘‘ The optional parameters field changes depending on which algorithm is picked. For example, if the algorithm is id-ecPublicKey, the parameters name the elliptic curve to use. See [RFC5480] ๐Ÿงš

Note: The client may specify a profile name in the certProfile field (see Section 5.1.1.4). ๐ŸŒธ

The id-regCtrl-rsaKeyLen control SHALL be used for algorithm rsaEncryption and SHALL contain the intended modulus bit length of the RSA key ๐Ÿ”ฅ

  GenMsg:    {id-it 19}, < absent >
  GenRep:    {id-it 19}, CertReqTemplateContent | < absent >

  CertReqTemplateValue  ::= CertReqTemplateContent

  CertReqTemplateContent ::= SEQUENCE {
     certTemplate           CertTemplate,
     keySpec                Controls OPTIONAL }

  Controls  ::= SEQUENCE SIZE (1..MAX) OF AttributeTypeAndValue

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

  AlgIdCtrl ::= AlgorithmIdentifier{ALGORITHM, {...}}

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

  RsaKeyLenCtrl ::= INTEGER (1..MAX)

The CertReqTemplateValue holds the prefilled certTemplate for a future certificate request ๐Ÿ“ The publicKey field in the certTemplate MUST NOT be used ๐Ÿ™…โ€โ™€๏ธ If the PKI management entity wants to list supported public-key algorithms, the keySpec field MUST be used ๐Ÿ’… You MUST use one AttributeTypeAndValue per supported algorithm or RSA key length โœจ

Note: The controls for an ASN.1 type are defined in Section 6 of CRMF [RFC4211]. ๐ŸŽ€


5.3.19.17. CRL Update Retrieval ๐Ÿฆ‹

This MAY be used by the client to fetch new CRLs. The client tells the server where the CRLs come from and the thisUpdate value of the latest CRL it already has, if it has one ๐Ÿ“œ A CRL source is either a DistributionPointName or the GeneralNames of the issuing CA ๐Ÿ  The DistributionPointName should be treated as an internal pointer that helps identify a CRL the server already has. It is not a way to make the server go fetch CRLs from outside places ๐Ÿ™…โ€โ™€๏ธ The server SHALL only provide CRLs that are more recent than the ones the client named ๐Ÿ’–

  GenMsg:    {id-it 22}, SEQUENCE SIZE (1..MAX) OF CRLStatus
  GenRep:    {id-it 23}, SEQUENCE SIZE (1..MAX) OF
                           CertificateList  |  < absent >

  CRLSource ::= CHOICE {
     dpn          [0] DistributionPointName,
     issuer       [1] GeneralNames }

  CRLStatus ::= SEQUENCE {
     source       CRLSource,
     thisUpdate   Time OPTIONAL }

5.3.19.18. KEM Ciphertext ๐Ÿงš

This MAY be used by a PKI entity to get the KEM ciphertext for MAC-based message protection using KEM (see Section 5.1.3.4) ๐Ÿ”

A PKI entity that has a KEM key pair can ask for the ciphertext by sending an InfoTypeAndValue structure of type KemCiphertextInfo, with the infoValue absent ๐Ÿ™Œ The ciphertext then comes back in the following genp message, using an InfoTypeAndValue structure of the same type ๐Ÿ“ฌ

  GenMsg:    {id-it 24}, < absent >
  GenRep:    {id-it 24}, KemCiphertextInfo

  KemCiphertextInfo ::= SEQUENCE {
    kem              AlgorithmIdentifier{KEM-ALGORITHM, {...}},
    ct               OCTET STRING
  }

kem is the algorithm identifier of the KEM algorithm, plus any associated parameters, that was used to generate the ciphertext (ct) ๐Ÿ“

ct is the ciphertext output from the KEM Encapsulate function โœจ

Note: These InfoTypeAndValue structures can also be transferred in the generalInfo field of the PKIHeader in messages of other types (see Section 5.1.1.5). ๐Ÿ’œ


5.3.20. PKI General Response Content ๐ŸŒˆ

  GenRepContent ::= SEQUENCE OF InfoTypeAndValue

Examples of GenReps that MAY be supported include the ones listed in the subsections of Section 5.3.19 ๐ŸŽ€


5.3.21. Error Message Content ๐Ÿ’€

This data structure MAY be used by an end entity, CA, or RA to convey error information, and by a PKI management entity to start delayed delivery of responses ๐Ÿ˜ญ

  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 pkiconf response, or another error message if any part of the header is not valid ๐Ÿ™ˆ

If a PKI management entity sends an error message to the end entity with the pKIStatusInfo field set to the status "waiting", the end entity SHOULD start polling as described in Section 5.3.22 ๐Ÿ”„ If the end entity doesn't start polling, both sides MUST treat this message as the end of the transaction (if one is in progress) ๐Ÿ›‘

If protection is wanted on the message, the client MUST protect it with the same technique (signature or MAC) as the starting message of the transaction. The CA MUST always sign it with a signature key. ๐Ÿ”๐Ÿ‘‘

5.3.22. Polling Request and Response โœจ

okay so this pair of messages is for when the client needs to keep checking on the server ๐Ÿซถ like "did my cert get approved yet??" ๐Ÿ˜ญ that's the whole vibe. it's for when the server already sent back the "waiting" PKIStatus and the client is just sitting there waiting for its answer ๐Ÿ’…

   PollReqContent ::= SEQUENCE OF SEQUENCE {
      certReqId    INTEGER }

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

bestie, here's the tea ๐Ÿต unless implicit confirmation was asked for and granted, an ir, cr, p10cr, kur, krr, or ccr request message gets answered with an ip, cp, kup, krp, or ccp response message that has status "waiting", and that's when polling kicks off ๐Ÿฆ‹ for ANY type of request message, polling can also start from an error response message with status "waiting" ๐Ÿ™ˆ the clauses below explain how the polling messages get used. also, multiple certConf messages can be sent during a transaction. there will be one for each ip, cp, kup, krp, or ccp that has a CertStatus for an issued certificate ๐ŸŽ€

  1. when an ip, cp, kup, krp, or ccp message shows up, the end entity sends a certConf for all the issued certificates and expects a pkiconf for each certConf ๐Ÿ’Œ the end entity also sends a pollReq in response to each CertResponse element of an ip, cp, or kup message with status "waiting", and in response to an error message with status "waiting" โœจ its certReqId MUST be either the index of a CertResponse data structure with status "waiting" or -1 referring to the complete response ๐Ÿ’œ
  2. when a pollReq comes in, the CA/RA returns an ip, cp, kup, krp, or ccp if one or more of the still pending requested certificates are ready, or if the final response to some other type of request is available ๐ŸŒธ otherwise, it returns a pollRep ๐Ÿ“
  3. if the end entity gets a pollRep, it waits for at least the number of seconds given in the checkAfter field before sending another pollReq โฐ
Note that the checkAfter value heavily depends on the certificate management environment ๐Ÿ’€ there are different possible reasons for a delayed delivery of response messages, e.g., high load on the server's backend, offline transfer of messages between two PKI management entities, or required RA operator approval ๐Ÿ˜ญ so the checkAfter time can vary greatly. this should also be considered by the transfer protocol ๐ŸŒˆ
  1. if the end entity gets an ip, cp, kup, krp, or ccp, it's treated the same way as the initial response ๐Ÿ‘‘ if it gets any other response, that counts as the final response to the original request ๐Ÿงš

ok the next state machine shows polling for individual CertResponse elements, using an ir request message as the example ๐Ÿฆ‹

                             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   |
                              / \                              |
                             /   \  (empty conf list)          |
                (conf list) /     \                            |
                           /       \              ip           |
                          /         \        +-----------------+
    (empty pending list) V           V       |    pollRep
      END <---- Send certConf        Send pollReq---------->Wait
                       |                 ^   ^               |
                       |                 |   |               |
                       +-----------------+   +---------------+
                          (pending list)

in this exchange, the end entity is enrolling for two certificates in one request ๐ŸŽ€

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 pollReq
  8                   --> pollReq  -->
  9                                    check status of cert requests,
                                          certificates not ready
 10                                    format pollRep
 11                   <-- pollRep  <--
 12   wait
 13   format pollReq
 14                   --> pollReq  -->
 15                                    check status of cert requests,
                                          one certificate is ready
 16                                    format ip
 17                   <-- ip       <--
 18   handle ip
 19   format certConf
 20                   --> certConf -->
 21                                    handle certConf
 22                                    format ack
 23                   <-- pkiconf  <--
 24   format pollReq
 25                   --> pollReq  -->
 26                                    check status of certificate,
                                          certificate is ready
 27                                    format ip
 28                   <-- ip       <--
 29   handle ip
 30   format certConf
 31                   --> certConf -->
 32                                    handle certConf
 33                                    format ack
 34                   <-- pkiconf  <--

next up is the client-side state machine for polling a complete response message ๐ŸŒท

                                 Start
                                   |
                                   | Send request
                                   v
              +----------- Receive response ------------+
              |                                         |
              | ip/cp/kup/krp/ccp/error with            | other
              | status "waiting"                        | response
              |                                         |
              v                                         |
  +------> Polling                                      |
  |           |                                         |
  |           | Send pollReq                            |
  |           | Receive response                        |
  |           |                                         |
  |           v                                         |
  +-----------+------------------->+<-------------------+
      pollRep   other response     |
                                   v
                             Handle response
                                   |
                                   v
                                  End

and last but not least, the end entity sends a general message request, and the server takes its sweet time responding ๐Ÿ•ฐ๏ธ this is the exchange for that ๐Ÿซถ

Step# End entity                       PKI
---------------------------------------------------------------------
  1   format genm
  2                  --> genm    -->
  3                                 handle genm
  4                                 delay in response is necessary
  5                                 format error message "waiting"
                                       with certReqId set to -1
  6                  <-- error   <--
  7   process error
  8   format pollReq
  9                  --> pollReq -->
 10                                 check status of original request,
                                       general message response not
                                       ready
 11                                 format pollRep
 12                  <-- pollRep <--
 13   wait
 14   format pollReq
 15                  --> pollReq -->
 16                                 check status of original request,
                                       general message response is
                                       ready
 17                                 format genp
 18                  <-- genp    <--
 19   handle genp

6. Mandatory PKI Management Functions ๐Ÿ‘‘

okay now we're in the "must-have" section ๐ŸŽ€ some of the PKI management functions from Section 3.1 get described right here.

this section is about functions that are "mandatory", which means that all end entity and CA/RA implementations MUST be able to provide the functionality described ๐Ÿ’… basically this part is the profile of the PKI management functionality that MUST be supported ๐Ÿ”ฅ but heads up, the management functions in this section don't have to use the PKI messages from Section 5 if some other means work better for a given environment ๐Ÿฆ‹ see Section 7 of [RFC9483] and Appendix C for profiles of the PKIMessage structures that MUST be supported for specific use cases ๐ŸŒˆ

6.1. Root CA Initialization โœจ

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

if a newly created root CA sits at the top of a PKI hierarchy, it usually produces a "self-certificate" ๐ŸŒธ that's a certificate structure with the profile defined for the "newWithNew" certificate issued after a root CA key update ๐Ÿ’–

so, in order to make the CA's self-certificate 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 get this fingerprint securely through some "out-of-band" means can then verify the CA's self-certificate, and therefore the other attributes inside it ๐Ÿ”

the data structure used to carry the fingerprint may be the OOBCertHash (see Section 5.2.5) ๐Ÿ“

6.2. Root CA Key Update ๐Ÿฆ‹

CA keys (like all other keys) have a finite lifetime and need to be updated 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 root CA certificate (OldWithOld) move securely to the new root CA certificate (NewWithNew) ๐Ÿ’œ they also help new end entities who will hold NewWithNew get OldWithOld securely, so they can verify existing data ๐Ÿซถ

6.3. Subordinate CA Initialization ๐ŸŒท

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

from the point of view of PKI management protocols, starting up a subordinate CA is the same as starting up 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, which are to be periodically produced ๐ŸŽ€

6.5. PKI Information Request ๐Ÿ’โ€โ™€๏ธ

Okay so when a PKI entity (CA, RA, or end entity) wants to find out the current status of a CA, it MAY send that CA a request asking for the info. ๐Ÿงš

The CA MUST respond to the request by providing (at least) everything the requester asked for. If some of the info 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 (e.g., password-based MAC; see Section 6.1 of "CMP Algorithms" [RFC9481]) or using any asymmetric authentication means such as a signature (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

Cross-certification is basically a one-way operation, bestie. ๐Ÿฆ‹ When it succeeds, it creates exactly one new cross-certificate. If you need cross-certificates "in both directions," then each CA has to start its own cross-certification operation (or use another scheme). Main character energy from both sides, lol. ๐Ÿ‘‘

This scheme is suitable where the two CAs in question can already verify each other's signatures (they have some common points of trust) or where there is an out-of-band verification of the origin of the certification request. ๐ŸŒธ

Detailed Description:

Cross-certification is initiated at one CA known as the responder. The CA administrator for the responder identifies the CA it wants to cross-certify, and the responder CA equipment generates an authorization code. The responder CA administrator passes this authorization code by out-of-band means to the requester CA administrator. The requester CA administrator enters the authorization code at the requester CA in order to initiate the online exchange. ๐ŸŽ€

The authorization code is used for authentication and integrity purposes. This is done by generating a symmetric key based on the authorization code and using the symmetric key for generating MACs on all messages exchanged. (Authentication may alternatively be done using signatures instead of MACs, if the CAs are able to retrieve and validate the required public keys by some means, such as an out-of-band hash comparison.) ๐Ÿ”‘

The requester CA initiates the exchange by generating a cross-certification request (ccr) with a fresh random number (requester random number). The requester CA then sends the ccr message to the responder CA. The fields in this message are protected from modification with a MAC based on the authorization code. ๐Ÿ’Œ

Upon receipt of the ccr message, the responder CA validates the message and the MAC, saves the requester random number, and generates its own random number (responder random number). It then generates (and archives, if desired) a new requester certificate that contains the requester CA public key and is signed with the responder CA signature private key. The responder CA responds with the cross-certification response (ccp) message. The fields in this message are protected from modification with a MAC based on the authorization code. ๐Ÿซถ

Upon receipt of the ccp message, the requester CA validates the message (including the received random numbers) and the MAC. The requester CA 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. ๐Ÿ“š

Upon receipt of the certConf message, the responder CA validates the message and the MAC and sends back an acknowledgement using the pkiconf 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; that is, 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 present, 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 must be initialized. Initialization of end entities requires 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 required (e.g., supported extensions or CA policy information) in order to produce a certification request that will be successful. However, for simplicity, we do not mandate that the end entity acquires this information via the PKI messages. The end result is simply 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 the Root CA Key

An end entity must securely possess the public key of its root CA. One method to achieve this is to provide the end entity with the CA's self-certificate fingerprint via some secure "out-of-band" means. The end entity can then 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 will be made using the certification request (cr) message. If the end entity already possesses 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 is successful) in a CertRepMessage. ๐Ÿ’…

6.9. Key Update ๐Ÿ”„

When a key pair is due to expire, the relevant end entity MAY request a key update; that is, 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 (referred to, in some environments, as a "Certificate Update" operation). If the end entity already possesses 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 is successful) 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 clients and servers. ๐Ÿงš

If a client knows the protocol version(s) supported by the server (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 does not know what version(s) the server supports, then it MUST send a PKIMessage using the highest version it supports with the following exception: Version cmp2021 SHOULD only be used if cmp2021 syntax is needed for the request being sent or for the expected response. ๐Ÿค”

Note: Using cmp2000 as the default pvno value is done to avoid extra message exchanges for version negotiation and to foster compatibility with cmp2000 implementations. Version cmp2021 syntax is only needed if a message exchange uses EnvelopedData, hashAlg (in CertStatus), POPOPrivKey with agreeMAC, or ckuann with RootCaKeyUpdateContent. ๐Ÿ“

If a server receives a message with a version that 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 ๐ŸŒธ

[RFC2510] did not specify the behavior of implementations receiving versions they did not understand since there was only one version in existence. With the introduction of the revision in [RFC4210], the following versioning behavior is recommended. ๐Ÿ“–

7.1.1. Clients Talking to RFC 2510 Servers ๐Ÿ—ฃ๏ธ

If, after sending a message with a pvno value higher than cmp1999, a client receives an ErrorMsgContent with a version of cmp1999, then it MUST abort the current transaction.

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 the semantics described in [RFC2510]. If it does not choose to do so and the transaction is not 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 the behavior described in [RFC2510] and respond with version cmp1999 messages. If it does not choose to do so, then it MUST send back an ErrorMsgContent as described above in Section 7. ๐Ÿ’€

8. Security Considerations ๐Ÿ”

8.1. On the Necessity of POP โœจ

okay so, it's well established that a CA's whole job is to verify that the name and public key belong to the end entity before it issues a certificate ๐Ÿ’…. If an entity holding a private key gets a certificate with the matching public key issued for a different entity, it can authenticate as the entity named in that certificate. that's masquerading, bestie ๐Ÿ’€. It is not entirely clear what security guarantees are lost if an end entity can get a certificate containing a public key they don't have the corresponding private key for ๐Ÿค”. There are some scenarios called "forwarding attacks" (see Appendix A of [Gueneysu]) where this can lead to protocol attacks against a naively implemented sign-then-encrypt protocol, but in general it just means the end entity ends up with a certificate they cannot use ๐Ÿซถ.

8.2. POP with a Decryption Key ๐Ÿ”

some crypto considerations are worth spelling out, so let's do it ๐Ÿง . In the protocols above, when an end entity has to prove it holds a decryption key, it's basically being challenged to decrypt something (its own certificate). This scheme (and many others!) could be vulnerable to an attack if the holder of the decryption key could be tricked into decrypting an arbitrary challenge and handing the cleartext back to an attacker ๐Ÿ˜ฑ. This specification needs a bunch of other security failures to happen before this attack can work, but it's conceivable that some future services (e.g., notary, trusted time) could be vulnerable ๐Ÿ™ˆ. So we're reiterating the general rule: implementations should be very careful about decrypting arbitrary "ciphertext" and revealing recovered "plaintext", because that can lead to serious security vulnerabilities ๐Ÿšจ.

The client MUST return the decrypted values only if they match the expected content type. In an indirect method, the decrypted value MUST be a valid certificate, and in a direct method, the decrypted value MUST be a Rand as defined in Section 5.2.8.3.3. ๐Ÿ“œ

8.3. POP by Exposing the Private Key ๐Ÿ—๏ธ

heads up, though: exposing a private key to the CA/RA as a POP 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. ๐Ÿง
  • Only use this POP mechanism if archival of the private key is desired. ๐Ÿ—„๏ธ
  • 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.4. Attack Against DH Key Exchange ๐Ÿงจ

a small subgroup attack during a DH key exchange can be carried out like this. A malicious end entity deliberately picks DH parameters that let it derive (a significant number of bits of) the DH private key of the CA during a key archival or key recovery operation ๐Ÿ˜ˆ. Armed with that, the end entity could retrieve the decryption private key of another unsuspecting end entity, EE2, during EE2's legitimate key archival or key recovery operation with that CA. Main villain energy ๐Ÿ’€. To avoid this, there are two courses of action. (1) The CA may generate a fresh DH key pair to be used as a protocol encryption key pair for each end entity 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 the end entity's protocol encryption key pair won't facilitate this attack. Option (1) is clearly simpler (no extra protocol exchanges from either party), so it is RECOMMENDED ๐Ÿ‘‘.

8.5. Perfect Forward Secrecy ๐ŸŒธ

long-term security typically requires perfect forward secrecy (pfs) โœจ. When you're transferring encrypted long-term confidential values, like centrally generated private keys or revocation passphrases, pfs is likely important. Yet it's not needed for CMP message protection that provides integrity and authenticity, because transfer of PKI messages is usually done in a very limited time โฑ๏ธ. For the same reason, it's not typically required for the indirect method to provide a POP (Section 5.2.8.3.2) that delivers the newly issued certificate in encrypted form.

Encrypted values (Section 5.2.2) are transferred using CMS EnvelopedData [RFC5652], which does not offer pfs ๐Ÿ™ƒ. In cases where long-term security is needed, CMP messages SHOULD be transferred over a mechanism that provides pfs, such as TLS with appropriate cipher suites selected ๐Ÿ”’.

8.6. Private Keys for Certificate Signing and CMP Message Protection ๐Ÿ”‘

a CA should not reuse its certificate signing key for other purposes, like protecting CMP responses and TLS connections ๐Ÿ™…โ€โ™€๏ธ. That way, exposure to other parts of the system and the number of uses of this super critical key get reduced to a minimum ๐Ÿ›ก๏ธ.

8.7. Entropy of Random Numbers, Key Pairs, and Shared Secret Information ๐ŸŽฒ

implementations must generate nonces and private keys from random input ๐ŸŽฐ. Using inadequate pseudorandom number generators (PRNGs) to generate cryptographic keys can result in little or no security ๐Ÿ’€. An attacker may find it way easier to reproduce the PRNG environment that produced the keys and search the resulting small set of possibilities than to brute-force the whole key space. For an example of predictable random numbers, see [CVE-2008-0166]; consequences of low-entropy random numbers are discussed in Mining Your Ps and Qs [MiningPsQs]. Generating quality random numbers is genuinely difficult ๐Ÿฅฒ. ISO/IEC 20543:2019 [ISO.20543-2019], NIST SP 800-90A Rev.1 [NIST.SP.800_90Ar1], BSI AIS 31 V2.0 [AIS31], and other specifications offer valuable guidance in this area ๐Ÿ“š.

If shared secret information is generated by a cryptographically secure random number generator (CSRNG), it is safe to assume that the entropy of the shared secret information equals its bit length ๐Ÿ’ฏ. If no CSRNG is used, the entropy of shared secret information depends on the details of the generation process and cannot be measured securely after it has been generated. If user-generated passwords are used as shared secret information, their entropy cannot be measured. Passwords generated from user-supplied entropy are typically insufficient for protected delivery of centrally generated keys or trust anchors ๐Ÿ™ˆ.

If the entropy of shared secret information protecting the delivery of a centrally generated key pair is known, it should not be less than the security strength of that key pair. If the shared secret information is reused for different key pairs, the security of the shared secret information should exceed the security strength of each individual key pair ๐Ÿ’ช.

For a PKI management operation that delivers a new trust anchor (e.g., a root CA certificate), using caPubs or genp that is (a) not concluded in a timely manner or (b) where the shared secret information is reused for several key management operations, the entropy of the shared secret information, if known, should not be less than the security strength of the trust anchor being managed by the operation. The shared secret information should have an entropy that at least matches the security strength of the key material being managed by the operation. Certain use cases may require shared secret information of a low security strength, e.g., a human-generated password ๐Ÿซ . It is RECOMMENDED that such secret information be limited to a single PKI management operation ๐ŸŒˆ.

Importantly for this section, more info on algorithm use profiles and their security strength is in Section 7 of CMP Algorithms [RFC9481] ๐Ÿ“–.

8.8. Recurring Usage of KEM Keys for Message Protection ๐Ÿฆ‹

for each PKI management operation using MAC-based message protection involving KEM (see Section 5.1.3.4), the KEM Encapsulate() function MUST be invoked, providing a fresh KEM ciphertext (ct) and shared secret (ss) ๐Ÿ”.

It's assumed that the overall data size of the CMP messages in a PKI management operation protected by a single shared secret key is small enough not to introduce extra security risks ๐Ÿ“.

To be appropriate for use with this specification, the KEM algorithm MUST explicitly be designed to be secure when the public key is used many times ๐Ÿ”„. For example, a KEM algorithm with a single-use public key is not appropriate, because the public key is expected to be carried in a long-lived certificate [RFC5280] and used over and over. So KEM algorithms that offer indistinguishability under adaptive chosen ciphertext attack (IND-CCA2) security are appropriate โœ…. A common design pattern for getting IND-CCA2 security with public key reuse is to apply the Fujisaki-Okamoto (FO) transform [Fujisaki] or a variant of the FO transform [Hofheinz] ๐Ÿงฉ.

So, given a long-term public key using an IND-CCA2-secure KEM algorithm, there is no limit to the number of CMP messages that can be authenticated using KEM keys for MAC-based message protection ๐ŸŽ‰.

8.9. Trust Anchor Provisioning Using CMP Messages ๐Ÿฐ

a provider of trust anchors (which may be an RA involved in configuration management of its clients) MUST NOT include to-be-trusted CA certificates in a CMP message, unless the specific deployment scenario can ensure that it's adequate for the receiving end entity to trust these certificates, e.g., by loading them into its trust store ๐Ÿšซ.

Whenever an end entity receives a CA certificate in a CMP message to be used as a trust anchor (for example, in the caPubs field of a certificate response or in a general response), it MUST properly authenticate the message sender with existing trust anchors, without requiring new trust anchor information included in the message ๐Ÿ•ต๏ธโ€โ™€๏ธ.

Additionally, the end entity MUST verify that the sender is an authorized source of trust anchors. This authorization is governed by local policy and is typically indicated using shared secret information or with a signature-based message protection using a certificate issued by a PKI that is explicitly authorized for this purpose ๐Ÿชช.

8.10. Authorizing Requests for Certificates with Specific EKUs ๐Ÿ‘‘

when a CA issues a certificate containing EKU extensions as defined in Section 4.5, that expresses delegation of an authorization that originally only belonged to the CA certificate itself ๐Ÿซข. Delegation like that is a very sensitive action in a PKI, so special care must be taken when approving such certificate requests, to make sure only legitimate entities receive a certificate containing such an EKU ๐Ÿ”.

8.11. Usage of CT Logs ๐Ÿ“’

CAs that support indirect POP MUST NOT also publish final certificates to CT logs [RFC9162] before they've received the certConf message containing the certHash of that certificate to complete the POP ๐Ÿ™…โ€โ™€๏ธ. The risk is that a malicious actor could fetch the final certificate from the CT log and use it to spoof a response to the implicit POP challenge via a certConf response ๐Ÿ˜ฑ. This risk doesn't apply to CT precertificates, so those are okay to publish โœจ.

If a certificate or its precertificate was published in a CT log, it must be revoked if a required certConf message could not be verified, especially when the implicit POP was used ๐Ÿšจ.

9. IANA Considerations โœจ

Okay bestie, so this document updates the ASN.1 modules in Appendix A.2 of CMP Updates [RFC9480] ๐ŸŽ€ The OID 116 (id-mod-cmp2023-02) got registered in the "SMI Security for PKIX Module Identifier" registry so the updated ASN.1 module has its own ID. Iconic ๐Ÿ’…

IANA also added a new entry to the "SMI Security for PKIX CMP Information Types" registry, which lives inside the SMI Numbers registry group (see <https://www.iana.org/assignments/smi-numbers>) [RFC7299]. Here's the entry:

Decimal:  24
Description:  id-it-KemCiphertextInfo
Reference:  RFC 9810

Now, ngl, this next bit is a little plot twist ๐Ÿฆ‹ The new OID 1.2.840.113533.7.66.16 was registered by Entrust, not by IANA, for id-KemBasedMac in the arc 1.2.840.113533.7.66. They did it to match the earlier registrations for id-PasswordBasedMac and id-DHBasedMac, which also sit on the Entrust private arc. Main character energy for consistency ๐Ÿงš

Last thing: every existing reference to [RFC2510], [RFC4210], and [RFC9480] at <https://www.iana.org/assignments/smi-numbers> has been swapped over to this document, except the ones in the "SMI Security for PKIX Module Identifier" registry. Those stayed the way they were ๐Ÿ’œ


10. References ๐Ÿ“š

10.1. Normative References

10.2. Informative References ๐Ÿ“š

okay bestie, here are the receipts ๐Ÿงพ๐Ÿ’… these are the informative refs, the extra reading that backs everything up. no pressure to read them all rn ๐Ÿซถ


Appendix A. Reasons for the Presence of RAs โœจ

okay so why even have an RA? ๐Ÿค” there are technical reasons and organizational reasons, and both are lowkey iconic ๐Ÿ’œ

Technical reasons include the following.

  • If hardware tokens are in use, then not all end entities will have the equipment needed to initialize these; the RA equipment can include the necessary functionality (this may also be a matter of policy).
  • Some end entities may not have the capability 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 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 the presence of an RA are the following. ๐ŸŒธ

  • 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 that candidates for the role of RA are easy to find (which may not be true of the CA).

Further reasons relevant for automated machine-to-machine certificate lifecycle management are available in the Lightweight CMP Profile [RFC9483]. ๐Ÿค–๐ŸŽ€

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

okay so bestie, revocation requests are a big deal ๐Ÿ˜ญ. they need proper authentication or else some random troll can send a denial-of-service attack ๐Ÿ’€. a digital signature or DH/KEM-based message protection on the request is the usual way to get that authentication, and it's REQUIRED to support in this spec depending on the key type, if revocation requests are supported at all ๐Ÿซถ.

but there are times when that's not an option, like when the private key is gone ๐Ÿฅฒ and the entity wants to revoke before re-certifying another key pair. so a password-based MAC (see Section 6.1 of CMP Algorithms [RFC9481]) on the request is also REQUIRED to support here ๐ŸŽ€, subject to local security policy for a given environment, and only if revocation requests are supported and shared secret info can be set up between requester and responder before revocation is needed ๐Ÿ’….

a technique that's been used in some places is the "revocation passphrase" ๐Ÿฆ‹. it's a value with sufficient entropy (so a long passphrase, not a short password) that's shared between (only) the entity and the CA/RA ahead of time, and it gets used later to authenticate the revocation request ๐ŸŒธ.

in this spec, establishing that shared secret (aka the revocation passphrase) is OPTIONAL to support ๐Ÿ“. here's how it works in CMP messages:

  • the OID and value from Section 5.3.19.9 MAY be sent in a GenMsg at any time, OR MAY be sent in the generalInfo field of the PKIHeader of any PKIMessage at any time. (fun fact: the EncryptedKey structure from Section 5.2.2 can ride along in the header of the certConf message that confirms the certs from an initialization request or certificate request ๐Ÿงš.) this conveys a revocation passphrase the entity picked, to the relevant CA/RA. with EnvelopedData it lives in the decrypted bytes of encryptedContent, and with EncryptedValue it lives in the decrypted bytes of encValue. and the transfer has to happen with appropriate confidentiality characteristics ๐Ÿ”’.
  • if a CA/RA gets the revocation passphrase (OID and value from Section 5.3.19.9) in a GenMsg, it MUST construct and send a GenRep message that includes the OID (with absent value) from Section 5.3.19.9. if it gets the passphrase in the generalInfo field of a PKIHeader, it MUST include the OID (with absent value) in the generalInfo field of the PKIHeader of the corresponding response. if the CA/RA can't return the right response for any reason, it MUST send an error message with a status of "rejection" and, optionally, a failInfo reason set ๐Ÿ™ˆ.
  • either the localKeyId attribute of EnvelopedData (from [RFC2985]) or the valueHint field of EncryptedValue MAY hold a key identifier, which the entity picks along with the passphrase itself ๐ŸŒˆ. this helps find the right passphrase later, like when the end entity builds the revocation request and the CA/RA receives it.
  • the revocation request is protected by a password-based MAC (see Section 6.1 of "CMP Algorithms" [RFC9481]) using the revocation passphrase as the key. if it makes sense, the senderKID field in the PKIHeader MAY contain the value that was previously sent in localKeyId or valueHint โœจ.
Note: for a message carrying a revocation passphrase with cmp2021(3) in the pvno field of the PKIHeader, the encrypted passphrase MUST be sent in the envelopedData choice of EncryptedKey as defined in Section 5.2.2. when cmp2000(2) is used in the message header for backward compatibility, the encryptedValue is used instead. this keeps the passphrase conveyed and protected properly while staying bits-on-the-wire compatible with [RFC4210]. the encryptedValue choice has been deprecated in favor of encryptedData ๐Ÿ’€.

using this technique, the revocation passphrase can be set up and updated at any time with no extra messages or out-of-band exchanges ๐ŸŽ‰. for example, the revocation request itself (protected by a MAC keyed with the revocation passphrase) can carry a new revocation passphrase in the PKIHeader, to be used for future revocation requests on the entity's other certs ๐Ÿ’–. some environments like this more than mechanisms that reveal the passphrase in the request, because a revealed passphrase can enable a denial-of-service attack where an unauthorized third party uses it to request revocation of the entity's other certificates ๐Ÿ˜ฑ. and since the passphrase isn't revealed in the request, there's no requirement that it must always be updated when a revocation request is made. the same passphrase MAY be used to authenticate revocation requests for different certificates at different times ๐Ÿฆ‹.

also, this technique can give strong cryptographic protection over the entire revocation request, even when no digital signature is used ๐Ÿ›ก๏ธ. techniques that authenticate a revocation request by just revealing the passphrase usually don't protect the fields of the request, so a request to revoke one certificate could be changed by an unauthorized third party into a request to revoke a different certificate for that entity ๐Ÿ˜ญ๐Ÿ’….


Appendix C. PKI Management Message Profiles (REQUIRED) ๐ŸŽ€

this appendix has the detailed profiles for the PKIMessages that MUST be supported by conforming implementations (see Section 6) ๐ŸŒธ.

Note: Appendices C and D focus on PKI management operations for managing certificates for human end entities ๐Ÿง‘. in contrast, the Lightweight CMP Profile [RFC9483] focuses on typical use cases in industrial and IoT scenarios that need highly automated certificate lifecycle management ๐Ÿค–โšก.

the profiles cover PKIMessages used in these PKI management operations:

  • initial registration/certification
  • basic authenticated scheme
  • certificate request
  • key update

C.1. General Rules for Interpretation of These Profiles

  1. where OPTIONAL or DEFAULT fields are not mentioned in individual profiles, they SHOULD be absent from the relevant message (so a receiver can validly reject a message with such fields as syntactically incorrect ๐Ÿ™…). mandatory fields aren't mentioned if they have an obvious value. the protocol version number MUST be set as specified in Section 7).
  2. where structures occur in more than one message, they're profiled separately as appropriate ๐Ÿงฉ.
  3. the algorithmIdentifiers from PKIMessage structures are profiled separately ๐Ÿ”‘.
  4. a "special" X.500 DN is called the "NULL-DN"; it's a DN with 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 (like when an end entity makes a request before knowing its name), the GeneralName is an X.500 NULL-DN (so the Name field of the CHOICE contains a NULL-DN) ๐Ÿซ .
  6. where a profile doesn't specify the value for a GeneralName, the NULL-DN value is present in the relevant PKIMessage field. this happens with the sender field of the PKIHeader for some messages ๐Ÿ’œ.
  7. where naming of fields could be ambiguous, the profile uses "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, zero-based array notation describes fields within the SEQUENCE OF (e.g., crm[0].certReq.certTemplate.subject refers to a subfield of the first CertReqMsg in a request message) ๐Ÿญ.
  9. all PKI message exchanges in Appendices C.4 to C.6 require a certConf message to be sent by the initiating entity and a pkiconf message to be sent by the responding entity. the pkiconf isn't included in some profiles since its body is NULL and its header contents are clear from context. any authenticated means can be used for the protectionAlg (e.g., password-based MAC if shared secret info is known, or signature) ๐Ÿซถ.

C.2. Algorithm Use Profile

for algorithm identifiers and the conventions conforming implementations should follow, check Section 7.1 of CMP Algorithms [RFC9481] ๐Ÿง โœจ.

C.3. POP Profile

the table below describes the POP fields to use (in the signature field of the pop field of a ProofOfPossession structure) when proving possession of a private signing key that corresponds to a public verification key for which a certificate has been requested ๐Ÿ’–.

  +=====================+=============+===========================+
  | Field               | Value       | Comment                   |
  +=====================+=============+===========================+
  | algorithmIdentifier | MSG_SIG_ALG | only signature protection |
  |                     |             | is allowed for this proof |
  +---------------------+-------------+---------------------------+
  | signature           | present     | bits calculated using     |
  |                     |             | MSG_SIG_ALG               |
  +---------------------+-------------+---------------------------+

                               Table 2

Note: for examples of MSG_SIG_ALG OIDs, see Section 3 of CMP Algorithms [RFC9481] ๐Ÿ”.

POP of a private decryption key that corresponds to a public encryption key for which a certificate has been requested does NOT use this profile. the CertHash field of the certConf message is used instead ๐Ÿ™ƒ.

not every CA/RA will do POP (of signing key, decryption key, or key agreement key) in the PKIX-CMP in-band certification request protocol. how POP is done MAY ultimately be a policy issue, made explicit for any given CA in its publicized Policy OID and Certification Practice Statement ๐Ÿ“œ. however, this specification mandates that CA/RA entities MUST do POP (by some means) as part of the certification process ๐Ÿ™Œ. all end entities MUST be prepared to provide POP (so these parts of the PKIX-CMP protocol MUST be supported) ๐Ÿ’…๐Ÿ”ฅ.

C.4. Initial Registration/Certification (Basic Authenticated Scheme) ๐ŸŽ€

Okay bestie, this is the first-time signup flow ๐Ÿ’– An uninitialized end entity asks a CA for its very first certificate. The CA sends back a message with the certificate, the end entity replies with a certificate confirmation, and then the CA sends a pkiconf to close the transaction ๐Ÿฆ‹ Every message in here is authenticated, no cap.

This scheme lets the end entity get a locally generated public key certified, which is usually a signature key โœจ The end entity MAY also choose to ask for centralized generation and certification of another key pair, usually an encryption key pair ๐Ÿ”

Only one locally generated public key can be certified per request. If you need more, send separate PKIMessages ๐Ÿ’… The end entity MUST support POP (proof of possession) of the private key that goes with that locally generated public key ๐Ÿ”‘

Preconditions

Two things need to be true before this flow starts ๐Ÿ‘€

  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

Here's the whole back-and-forth at a glance ๐Ÿงš

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 making some strict rules ๐Ÿ˜ค The end entity MUST include all (that's one or two) CertReqMsg in a single PKIMessage. The PKI (CA) MUST produce a single response PKIMessage that holds the complete response, including the OPTIONAL second key pair if it was requested and centralized key generation is supported. To keep things simple, this message MUST be the final one too, so there's no "waiting" status value ๐Ÿ™ˆ

The end entity does an out-of-band interaction with the CA/RA first. That's where the shared secret, the referenceNumber, and optionally the DN (used for both the sender and subject name in the certificate template) get set up ๐Ÿค Check out Section 8.7 for security considerations on how good that shared secret information needs to be. It's giving serious, so read it!

Initialization Request -- ir

This is the opening message, the ir. Here's what each field needs โœจ

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

The crm[0] request is the main one, and it's the one that always has to show up ๐Ÿ’– The crm[1] request is the optional bonus, the one you use if you want the CA to generate the key for you ๐ŸŽ When you use it, the protocolEncrKey is the short-term encryption key that lets the CA protect the key it makes, so you know it's kept safe ๐Ÿ”’

Initialization Response -- ip

Now the CA replies with the ip. Every response field is set like this ๐ŸŒธ

Field                Value

sender               CA name
  -- the name of the CA who produced the message
messageTime          present
  -- time at which CA produced message
protectionAlg        MSG_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
  -- Use EnvelopedData; if backward compatibility is required,
  -- use EncryptedValue, see Section 5.2.2
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

The crc[0] answer is the response to your first request, and it always shows up ๐Ÿ’… The crc[1] answer only appears if your ir had two requests and the CA supports centralized key generation ๐ŸŽ€ If you're using a symmetric-style key for the private key, go with EnvelopedData, but if you need backward compatibility, EncryptedValue is the move, so check Section 5.2.2 ๐Ÿ” The CA MAY also add extra certificates, so don't be shocked if extraCerts shows up ๐ŸŒˆ

Certificate confirm -- certConf

Next up is the certConf, where the end entity says "yep, got it" ๐Ÿ’œ

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 end entity and the CA.

senderKID            referenceNum
  -- the reference number that 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

If both an encryption cert and a signing cert got sent, you'll need two CertStatus structures in here, so don't forget one ๐Ÿ™ˆ For what goes in the certConf fields, the PKI Confirmation Content section is where to look ๐Ÿฆ‹

Confirmation -- pkiconf

Last but not least, the CA sends the pkiconf to close the whole transaction ๐ŸŽ‰

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

And that's the whole basic signup flow, all wrapped up with a bow ๐ŸŽ€ Every message is MAC-protected with the initial authentication key, so it's secure and cute at the same time ๐Ÿ’–

C.5. Certificate Request ๐Ÿ’Œ

Okay, so an initialized end entity ๐Ÿ’… asks a CA for a certificate, for any reason at all! When the CA sends back a message with a certificate, the end entity replies with a certificate confirmation. Then the CA sends a pkiconf message to close the transaction. ngl, every single message is authenticated ๐Ÿ”.

The profile for this exchange is identical to the one in Appendix C.4, with a few glow-ups:

  • The sender name SHOULD be present ๐ŸŽ€;
  • protectionAlg of MSG_SIG_ALG MUST be supported (MSG_MAC_ALG MAY also be supported) in request, response, certConf, and pkiconf messages ๐Ÿ”ฅ;
  • senderKID and recipKID are only present if they're required for message verification ๐Ÿซถ;
  • the body is cr or cp ๐Ÿ’–;
  • the body may contain one or two CertReqMsg structures, and either one can be used to request certification of a locally generated public key or a centrally generated public key. So the position-dependence requirement of Appendix C.4 is removed. Iconic ๐Ÿ‘‘; and
  • protection bits are calculated according to the protectionAlg field ๐Ÿฆ‹.

C.6. Key Update Request ๐ŸŒธ

Same energy here! An initialized end entity asks a CA for a certificate, this time to update the key pair and/or the corresponding certificate it already has. When the CA responds with a message containing a certificate, the end entity replies with a certificate confirmation. The CA then replies with a PKIConfirm to close the transaction. Again, all messages are authenticated ๐Ÿ”โœจ.

The profile for this exchange is identical to the one in Appendix C.4, with these exceptions:

  • The sender name SHOULD be present ๐ŸŽ€;
  • protectionAlg of 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 required for message verification ๐Ÿซถ;
  • the body is kur or kup ๐Ÿ’–;
  • the body may contain one or two CertReqMsg structures, and either one can be used to request certification of a locally generated public key or a centrally generated public key. The position-dependence requirement of Appendix C.4 is removed here too ๐Ÿ‘‘;
  • protection bits are calculated according to the protectionAlg field; and ๐Ÿฆ‹
  • regCtrl OldCertId SHOULD be used, unless it's clear to both the sender and receiver (by means not specified in this document) that it's not needed ๐ŸŒˆ.

Appendix D. PKI Management Message Profiles (OPTIONAL) ๐Ÿงš

This appendix is the home of the detailed profiles for those PKIMessages that MAY be supported by implementations. Think of it as the optional extras menu ๐Ÿ“.

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

Future versions of this document may extend the list above to include profiles for the operations below (along with other operations, if desired). Those are:

  • revocation request
  • certificate publication
  • CRL publication

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

Identical to Appendix C.1. No new rules, bestie ๐Ÿ’€.

D.2. Algorithm Use Profile ๐Ÿงฎ

Identical to Appendix C.2. Same vibes, same algorithms โœจ.

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

Okay, this table is a profile of how a certificate structure may be "self-signed". These structures get used for distributing new root CA public keys, and that can happen in one of three ways. (Check out Section 4.4 above for how these structures get used.) Here's the tea:

+============+=============================================+
| Type       | Function                                    |
+============+=============================================+
| newWithNew | a "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                                 |
+------------+---------------------------------------------+

                             Table 3

A newWithNew certificate (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. Be sensible, friend ๐Ÿ™ˆ.

D.4. Root CA Key Update ๐Ÿ”‘

A root CA updates its key pair. Then it produces a CA key update announcement message that can be made available (via some transport mechanism) to the relevant entities. A confirmation message is not required from the end entities, so no awkward replies needed ๐ŸŒธ.

ckuann message:

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

                                Table 4

D.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. The RA/CA responds with a general response. If an RA generates the response, it simply forwards the equivalent message it previously received from the CA, maybe adding certificates to the extraCerts fields of the PKIMessage. A confirmation message isn't required from the end entity. Easy peasy ๐Ÿ’.

Here's the message flow, step by step:

Step# End entity                        PKI
---------------------------------------------------------------------
  1   format genm
  2                -->   genm   -->
  3                                     handle genm
  4                                     produce genp
  5                <--   genp   <--
  6   handle genp

The genM message looks like this:

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

And the genP message looks like this:

genP:

Field                Value

sender               CA name
  -- name of the CA that 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)
RootCaKeyUpdate      optionally present, with
                     relevant value
  -- Use RootCaKeyUpdate; if backward compatibility with cmp2000 is
  -- required, use CAKeyUpdateInfo.
  -- 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.

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

okay so this section is all about making ONE cross-certificate at a time (not two at once, bestie ๐Ÿ™…โ€โ™€๏ธ). the requesting CA MAY choose who is responsible for publishing the cross-certificate that the responding CA makes, using the PKIPublicationInfo control ๐Ÿ’…

Preconditions:

  1. Responding CA can verify the origin of the request (possibly requiring out-of-band means) before processing the request. ๐Ÿ”
  2. Requesting CA can authenticate the authenticity of the origin of the response (possibly requiring out-of-band means) before processing the response. ๐Ÿซถ

the use of certificate confirmation and the matching server confirmation is decided by the generalInfo field in the PKIHeader (see Section 5.1.1) ๐ŸŽ€. the following profile does NOT mandate support for either confirmation, so no pressure ๐ŸŒธ

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 Appendix C.3: POP 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

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

okay so picture this: an end entity (totally uninitialized, no PKI friends yet ๐Ÿฅบ) wants to join the PKI with a CA called CA-1. for authentication it uses an identity certificate that was already issued by a different, external CA, called CA-X ๐ŸŒˆ. before any of this works, CA-1 and CA-X have to already trust each other, so CA-1 can validate the end entity's identity certificate signed by CA-X ๐Ÿ’œ. ALSO, the end entity's TEE (aka PSE) already needs some setup so it can authenticate and verify PKIMessages signed by CA-1. as one example, the TEE might hold a certificate for CA-1's public key, signed by some other CA the end entity trusts based on out-of-band authentication techniques ๐Ÿ”

the end entity 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 pkiconf message to close the transaction ๐Ÿ’…. every message is signed (the end entity signs with the private key matching the public key in its external identity certificate, and CA-1 signs with the private key matching the public key in a certificate that chains to a trust anchor in the end entity's TEE) ๐Ÿ”

the profile for this exchange is identical to Appendix C.4, with the following exceptions ๐ŸŽ€:

  • the end entity and CA-1 do NOT share a symmetric MACing key (so there is no out-of-band shared secret between these entities) ๐Ÿ™…โ€โ™€๏ธ
  • 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 certificate MUST be carried in ir extraCerts field ๐Ÿ’–
  • senderKID and recipKID are NOT used ๐Ÿ™ˆ
  • body is ir or ip; and ๐Ÿฆ‹
  • protection bits are calculated according to the protectionAlg field. ๐Ÿ‘‘

Appendix E. Variants of Using KEM Keys for PKI Message Protection โœจ

As described in Section 5.1.3.4, any party in a PKI management operation may wish to use a KEM key pair for message protection ๐Ÿ”. Possible cases are described below ๐Ÿ’….

For any PKI management operation started by a PKI entity with any type of request message, the following message flows describe the use of a KEM key ๐Ÿฆ‹. There are two cases to distinguish, namely whether the PKI entity or the PKI management entity owns a KEM key pair ๐ŸŒธ. If both sides own KEM key pairs, the flows need to be combined such that for each direction a shared secret key is established ๐Ÿซถ.

In the following message flows, Alice indicates the PKI entity that uses a KEM key pair for message authentication and Bob provides the KEM ciphertext using Alice's public KEM key, as described in Section 5.1.3.4 ๐Ÿงš.

Step# PKI entity                           PKI management entity
      (Alice)                              (Bob)
---------------------------------------------------------------------
  1   format unprotected genm
        of type
        KemCiphertextInfo
        without value, and
        KEM certificate in
        extraCerts
  2                     -->   genm    -->
  3                                        validate KEM certificate
  4                                        perform KEM Encapsulate
  5                                        format unprotected genp
                                             of type
                                             KemCiphertextInfo
                                             providing KEM ciphertext
  6                     <--   genp    <--
  7   perform KEM Decapsulate
  8   perform key derivation
        to get ssk
  9   format request with
        MAC-based protection
 10                     -->  request  -->
 11                                        perform key derivation
                                             to get ssk
 12                                        verify MAC-based
                                             protection

--------  PKI entity authenticated by PKI management entity  --------

 13                                        format response with
                                             protection depending on
                                             available key material
 14                     <-- response  <--
 15   verify protection
        provided by the
        PKI management entity

 16       Further messages of this PKI management operation
        can be exchanged with MAC-based protection by the PKI
         entity using the established shared secret key (ssk)

  Figure 3: Message Flow When the PKI Entity Has a KEM Key Pair and
                             Certificate
Step# PKI entity                           PKI management entity
      (Bob)                                (Alice)
---------------------------------------------------------------------
  1   perform KEM Encapsulate
  2   format request providing
        KEM ciphertext in
        generalInfo of type
        KemCiphertextInfo,
        and with protection
        depending on available
        key material
  3                     -->  request  -->
  4                                        perform KEM Decapsulate
  5                                        perform key derivation
                                             to get ssk
  6                                        format response with
                                             MAC-based protection
  7                     <-- response  <--
  8   perform key derivation
        to get ssk
  9   verify MAC-based
        protection

--------  PKI management entity authenticated by PKI entity  --------

 10       Further messages of this PKI management operation
          can be exchanged with MAC-based protection by the
             PKI management entity using the established
                        shared secret key (ssk)

    Figure 4: Message Flow When the PKI Entity Knows That the PKI
     Management Entity Uses a KEM Key Pair and Has the Authentic
                              Public Key

Note: Figure 4 describes the situation where KEM-based message protection may not require more than one message exchange. In this case, the transactionID MUST also be used by the PKI entity (Bob) to ensure domain separation between different PKI management operations ๐Ÿ™ˆ.

Step# PKI entity                           PKI management entity
      (Bob)                                (Alice)
---------------------------------------------------------------------
  1   format request with
        protection depending
        on available key
        material
  2                     -->  request  -->
  3                                        format unprotected error
                                             with status "rejection"
                                             and failInfo
                                             "wrongIntegrity" and KEM
                                             certificate in
                                             extraCerts
  4                     <--   error   <--
  5   validate KEM certificate

  6              proceed as shown in the figure before

Figure 5: Message Flow When the PKI Entity Does Not Know That the PKI
                Management Entity Uses a KEM Key Pair

Appendix F. Compilable ASN.1 Definitions ๐Ÿ’œ

This section contains the updated 2002 ASN.1 module from [RFC5912], which was updated in [RFC9480]. This module replaces the module in Section 9 of [RFC5912]. The module contains those changes to the normative ASN.1 module from Appendix F of [RFC4210] that were specified in [RFC9480], as well as changes made in this document. This module makes reference to ASN.1 structures defined in [RFC6268], as well as the UTF-8 encoding defined in [RFC3629] โœจ.

PKIXCMP-2023
    { iso(1) identified-organization(3) dod(6) internet(1)
    security(5) mechanisms(5) pkix(7) id-mod(0)
    id-mod-cmp2023-02(116) }
DEFINITIONS EXPLICIT TAGS ::=
BEGIN
IMPORTS

AttributeSet{}, SingleAttribute{}, Extensions{}, EXTENSION, ATTRIBUTE
FROM PKIX-CommonTypes-2009
    {iso(1) identified-organization(3) dod(6) internet(1) security(5)
    mechanisms(5) pkix(7) id-mod(0) id-mod-pkixCommon-02(57)}

AlgorithmIdentifier{}, SIGNATURE-ALGORITHM, ALGORITHM,
    DIGEST-ALGORITHM, MAC-ALGORITHM, KEY-DERIVATION
FROM AlgorithmInformation-2009
    {iso(1) identified-organization(3) dod(6) internet(1) security(5)
    mechanisms(5) pkix(7) id-mod(0)
    id-mod-algorithmInformation-02(58)}

Certificate, CertificateList, Time, id-kp
FROM PKIX1Explicit-2009
    {iso(1) identified-organization(3) dod(6) internet(1) security(5)
    mechanisms(5) pkix(7) id-mod(0) id-mod-pkix1-explicit-02(51)}

DistributionPointName, GeneralNames, GeneralName, KeyIdentifier
FROM PKIX1Implicit-2009
    {iso(1) identified-organization(3) dod(6) internet(1) security(5)
    mechanisms(5) pkix(7) id-mod(0) id-mod-pkix1-implicit-02(59)}

CertTemplate, PKIPublicationInfo, EncryptedKey, CertId,
    CertReqMessages, Controls, RegControlSet, id-regCtrl
FROM PKIXCRMF-2009
    { iso(1) identified-organization(3) dod(6) internet(1)
    security(5) mechanisms(5) pkix(7) id-mod(0)
    id-mod-crmf2005-02(55) }
    -- The import of EncryptedKey is added due to the updates made
    -- in [RFC9480]. EncryptedValue does not need to be imported
    -- anymore and is therefore removed here.

CertificationRequest
FROM PKCS-10
    {iso(1) identified-organization(3) dod(6) internet(1) security(5)
    mechanisms(5) pkix(7) id-mod(0) id-mod-pkcs10-2009(69)}
-- (specified in [RFC2986] with 1993 ASN.1 syntax and IMPLICIT
-- tags).  Alternatively, implementers may directly include
-- the syntax of [RFC2986] in this module.

localKeyId
FROM PKCS-9
    {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9)
    modules(0) pkcs-9(1)}
    -- The import of localKeyId is added due to the updates made in
    -- [RFC9480]

EnvelopedData, SignedData
FROM CryptographicMessageSyntax-2010
    {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9)
    smime(16) modules(0) id-mod-cms-2009(58)}
    -- The import of EnvelopedData and SignedData from [RFC6268] is
    -- added due to the updates made in CMP Updates [RFC9480]

KEM-ALGORITHM
FROM KEMAlgorithmInformation-2023  -- [RFC9629]
    { iso(1) identified-organization(3) dod(6) internet(1)
    security(5) mechanisms(5) pkix(7) id-mod(0)
    id-mod-kemAlgorithmInformation-2023(109) }
    -- The import of KEM-ALGORITHM was added due to the updates made
    -- in [RFC9810]
;

-- History of the PKIXCMP ASN.1 modules
-- [RFC2510]
--    1988 Syntax, PKIXCMP, 1.3.6.1.5.5.7.0.9 (id-mod-cmp)
--    Obsoleted by RFC 4210 PKIXCMP, 1.3.6.1.5.5.7.0.16
--                                   (id-mod-cmp2000)
-- [RFC4210]
--    1988 Syntax, PKIXCMP, 1.3.6.1.5.5.7.0.16 (id-mod-cmp2000)
--    Replaced by RFC 9480 PKIXCMP, 1.3.6.1.5.5.7.0.99
--                                  (id-mod-cmp2021-88)
-- [RFC5912]
--    2002 Syntax, PKIXCMP-2009, 1.3.6.1.5.5.7.0.50
--                               (id-mod-cmp2000-02)
--    Replaced by RFC 9480 PKIXCMP-2021, 1.3.6.1.5.5.7.0.100
--                                       (id-mod-cmp2021-02)
-- [RFC9480]
--    1988 Syntax, PKIXCMP, 1.3.6.1.5.5.7.0.99 (id-mod-cmp2021-88)
--    2002 Syntax, PKIXCMP-2021, 1.3.6.1.5.5.7.0.100
--                               (id-mod-cmp2021-02)
--    Obsoleted by [RFC9810] PKIXCMP-2023, 1.3.6.1.5.5.7.0.116
--                                         (id-mod-cmp2023-02)
-- [RFC9810]
--    2002 Syntax, PKIXCMP-2023, 1.3.6.1.5.5.7.0.116
--                               (id-mod-cmp2023-02)


-- 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, card-verifiable 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 "uncomment" 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, the ASN.1 module keeps going and it's giving structure ๐ŸŽ€โœจ

   PKIHeader ::= SEQUENCE {
       pvno                INTEGER     { cmp1999(1), cmp2000(2),
                                         cmp2021(3) },
       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{ALGORITHM, {...}}
                               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 is not primarily intended for human consumption)
   }

   PKIFreeText ::= SEQUENCE SIZE (1..MAX) OF UTF8String
       -- text encoded as UTF-8 string [RFC3629]

   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 [RFC2986]
       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] CAKeyUpdContent,        --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 ::= { iso(1) member-body(2)
       usa(840) nt(113533) nsn(7) algorithms(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{DIGEST-ALGORITHM, {...}},
       -- AlgId for the OWF
       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{MAC-ALGORITHM, {...}}
       -- AlgId of the MAC algorithm
   }

   id-DHBasedMac OBJECT IDENTIFIER ::= { iso(1) member-body(2)
       usa(840) nt(113533) nsn(7) algorithms(66) 30 }
   DHBMParameter ::= SEQUENCE {
       owf                 AlgorithmIdentifier{DIGEST-ALGORITHM, {...}},
       -- AlgId for an OWF
       mac                 AlgorithmIdentifier{MAC-ALGORITHM, {...}}
       -- AlgId of the MAC algorithm
   }

   -- id-KemBasedMac and KemBMParameter were added in [RFC9810]

   id-KemBasedMac OBJECT IDENTIFIER ::= { iso(1) member-body(2)
       usa(840) nt(113533) nsn(7) algorithms(66) 16 }
   KemBMParameter ::= SEQUENCE {
       kdf              AlgorithmIdentifier{KEY-DERIVATION, {...}},
       -- AlgId of the Key Derivation Function algorithm
       kemContext   [0] OCTET STRING OPTIONAL,
       -- MAY contain additional algorithm-specific context information
       len              INTEGER (1..MAX),
       -- Defines the length of the keying material output of the KDF
       -- SHOULD be the maximum key length of the MAC function
       mac              AlgorithmIdentifier{MAC-ALGORITHM, {...}}
       -- AlgId of the MAC algorithm
   }

   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 POP failed
       certRevoked         (10),
       -- the certificate has already been revoked
       certConfirmed       (11),
       -- the certificate has already been confirmed
       wrongIntegrity      (12),
       -- KEM ciphertext missing for MAC-based protection of response,
       -- or not valid integrity of message received (password based
       -- instead of signature or vice versa)
       badRecipientNonce   (13),
       -- not valid 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),
       -- not valid sender nonce, either missing or wrong size
       badCertTemplate     (19),
       -- not valid 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{DIGEST-ALGORITHM, {...}}
                           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 or key agreement key certification
   -- request (in the same order as these requests appear in
   -- CertReqMessages).

   -- encryptedRand was added in [RFC9810]

that's the module so far, and the vibes are immaculate ๐Ÿฆ‹๐Ÿ’œ more to come, stay with me ๐Ÿซถ

okay bestie, picking up right where we left off in Appendix F ๐Ÿ’… this is the compilable ASN.1 zone, so the whole block stays exact, comments and all ๐ŸŽ€

   Challenge ::= SEQUENCE {
      owf                 AlgorithmIdentifier{DIGEST-ALGORITHM, {...}}
                               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 OWF to a
      -- randomly generated INTEGER, A. (Note that a different
      -- INTEGER MUST be used for each Challenge.)
      challenge           OCTET STRING,
      -- MUST be used for cmp2000(2) popdecc messages and MUST be
      -- the encryption of Rand (using a mechanism depending on the
      -- private key type).
      -- MUST be an empty OCTET STRING for cmp2021(3) popdecc messages.
      -- Note: Using challenge omitting the optional encryptedRand is
      -- bit-compatible to the syntax without adding this optional
      -- field.
      encryptedRand   [0] EnvelopedData OPTIONAL
      -- MUST be omitted for cmp2000(2) popdecc messages.
      -- MUST be used for cmp2021(3) popdecc messages and MUST contain
      -- the encrypted value of Rand using CMS EnvelopedData using the
      -- key management technique depending on the private key type as
      -- defined in Section 5.2.2.
   }

   -- Rand was added in [RFC9480]

   Rand ::= SEQUENCE {
   -- Rand is encrypted involving the public key to form the content of
   -- challenge or encryptedRand in POPODecKeyChallContent
      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 or key agreement 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 }

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

   CertifiedKeyPair ::= SEQUENCE {
       certOrEncCert       CertOrEncCert,
       privateKey      [0] EncryptedKey      OPTIONAL,
       -- See [RFC4211] for comments on encoding.
       -- Changed from EncryptedValue to EncryptedKey as a CHOICE of
       -- EncryptedValue and EnvelopedData due to the changes made in
       -- [RFC9480].
       -- Using the choice EncryptedValue is bit-compatible to the
       -- syntax without this change.
       publicationInfo [1] PKIPublicationInfo  OPTIONAL }

   CertOrEncCert ::= CHOICE {
       certificate     [0] CMPCertificate,
       encryptedCert   [1] EncryptedKey
       -- Changed from Encrypted Value to EncryptedKey as a CHOICE of
       -- EncryptedValue and EnvelopedData due to the changes made in
       -- [RFC9480].
       -- Using the choice EncryptedValue is bit-compatible to the
       -- syntax without this change.
   }

   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
   }

   -- CAKeyUpdContent was added in [RFC9810]
   CAKeyUpdContent ::= CHOICE {
       cAKeyUpdAnnV2      CAKeyUpdAnnContent, -- deprecated
       cAKeyUpdAnnV3  [0] RootCaKeyUpdateContent
   }
   -- With cmp2021, the use of CAKeyUpdAnnContent is deprecated, use
   -- RootCaKeyUpdateContent instead.

   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

   PKIConfirmContent ::= NULL

   NestedMessageContent ::= PKIMessages

   -- CertReqTemplateContent, AttributeTypeAndValue,
   -- ExpandedRegControlSet, id-regCtrl-altCertTemplate,
   -- AltCertTemplate, regCtrl-algId, id-regCtrl-algId, AlgIdCtrl,
   -- regCtrl-rsaKeyLen, id-regCtrl-rsaKeyLen, and RsaKeyLenCtrl
   -- were added in [RFC9480]

   CertReqTemplateContent ::= SEQUENCE {
      certTemplate           CertTemplate,
      -- prefilled certTemplate structure elements
      -- The SubjectPublicKeyInfo field in the certTemplate MUST NOT
      -- be used.
      keySpec                Controls OPTIONAL
      -- MAY be used to specify supported algorithms
      -- Controls  ::= SEQUENCE SIZE (1..MAX) OF AttributeTypeAndValue
      -- as specified in CRMF [RFC4211]
      }

   AttributeTypeAndValue ::= SingleAttribute{{ ... }}

   ExpandedRegControlSet ATTRIBUTE ::= { RegControlSet |
      regCtrl-altCertTemplate | regCtrl-algId | regCtrl-rsaKeyLen, ... }

   regCtrl-altCertTemplate ATTRIBUTE ::=
      { TYPE AltCertTemplate IDENTIFIED BY id-regCtrl-altCertTemplate }

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

   AltCertTemplate ::= AttributeTypeAndValue
      -- specifies a template for a certificate other than an X.509v3
      -- public key certificate

   regCtrl-algId ATTRIBUTE ::=
      { TYPE AlgIdCtrl IDENTIFIED BY id-regCtrl-algId }

   id-regCtrl-algId OBJECT IDENTIFIER ::= { id-regCtrl 11 }

   AlgIdCtrl ::= AlgorithmIdentifier{ALGORITHM, {...}}
      -- SHALL be used to specify supported algorithms other than RSA

   regCtrl-rsaKeyLen ATTRIBUTE ::=
      { TYPE RsaKeyLenCtrl IDENTIFIED BY id-regCtrl-rsaKeyLen }

   id-regCtrl-rsaKeyLen OBJECT IDENTIFIER ::= { id-regCtrl 12 }

   RsaKeyLenCtrl ::= INTEGER (1..MAX)
      -- SHALL be used to specify supported RSA key lengths

   -- RootCaKeyUpdateContent, CRLSource, and CRLStatus were added in
   -- [RFC9480]

   RootCaKeyUpdateContent ::= SEQUENCE {
      newWithNew       CMPCertificate,
      -- new root CA certificate
      newWithOld   [0] CMPCertificate OPTIONAL,
      -- X.509 certificate containing the new public root CA key
      -- signed with the old private root CA key
      oldWithNew   [1] CMPCertificate OPTIONAL
      -- X.509 certificate containing the old public root CA key
      -- signed with the new private root CA key
      }

   CRLSource ::= CHOICE {
      dpn          [0] DistributionPointName,
      issuer       [1] GeneralNames }

   CRLStatus ::= SEQUENCE {
      source       CRLSource,
      thisUpdate   Time OPTIONAL }

   -- KemCiphertextInfo and KemOtherInfo were added in [RFC9810]

   KemCiphertextInfo ::= SEQUENCE {
      kem              AlgorithmIdentifier{KEM-ALGORITHM, {...}},
      -- AlgId of the KEM algorithm
      ct               OCTET STRING
      -- Ciphertext output from the Encapsulate function
      }

   KemOtherInfo ::= SEQUENCE {
      staticString     PKIFreeText,
      -- MUST be "CMP-KEM"
      transactionID    OCTET STRING,
      -- MUST contain the values from the message previously received
      -- containing the ciphertext (ct) in KemCiphertextInfo
      kemContext   [0] OCTET STRING OPTIONAL
      -- MAY contain additional algorithm-specific context information
     }

   INFO-TYPE-AND-VALUE ::= TYPE-IDENTIFIER

   InfoTypeAndValue ::= SEQUENCE {
       infoType    INFO-TYPE-AND-VALUE.
                       &id({SupportedInfoSet}),
       infoValue   INFO-TYPE-AND-VALUE.
                       &Type({SupportedInfoSet}{@infoType}) }

   SupportedInfoSet INFO-TYPE-AND-VALUE ::= { ... }

that's the whole ASN.1 module chunk, the structures for challenges, cert responses, revocation, CA key updates, and KEM info ๐Ÿงš๐Ÿ’œ

   -- Example InfoTypeAndValue contents include, but are not limited
   -- to, the following (uncomment 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 SIZE (1..MAX) OF
   --                                      AlgorithmIdentifier{{...}}
   --   id-it-encKeyPairTypes  OBJECT IDENTIFIER ::= {id-it 3}
   --      EncKeyPairTypesValue    ::= SEQUENCE SIZE (1..MAX) OF
   --                                      AlgorithmIdentifier{{...}}
   --   id-it-preferredSymmAlg OBJECT IDENTIFIER ::= {id-it 4}
   --      PreferredSymmAlgValue   ::= AlgorithmIdentifier{{...}}
   --   id-it-caKeyUpdateInfo  OBJECT IDENTIFIER ::= {id-it 5}
   --      CAKeyUpdateInfoValue    ::= CAKeyUpdAnnContent
   --      - id-it-caKeyUpdateInfo was deprecated with cmp2021
   --   id-it-currentCRL       OBJECT IDENTIFIER ::= {id-it 6}
   --      CurrentCRLValue         ::= CertificateList
   --   id-it-unsupportedOIDs  OBJECT IDENTIFIER ::= {id-it 7}
   --      UnsupportedOIDsValue    ::= SEQUENCE SIZE (1..MAX) OF
   --                                          OBJECT IDENTIFIER
   --   id-it-keyPairParamReq  OBJECT IDENTIFIER ::= {id-it 10}
   --      KeyPairParamReqValue    ::= OBJECT IDENTIFIER
   --   id-it-keyPairParamRep  OBJECT IDENTIFIER ::= {id-it 11}
   --      KeyPairParamRepValue    ::= AlgorithmIdentifier{{...}}
   --   id-it-revPassphrase    OBJECT IDENTIFIER ::= {id-it 12}
   --      RevPassphraseValue      ::= EncryptedKey
   --      - Changed from Encrypted Value to EncryptedKey as a CHOICE
   --      - of EncryptedValue and EnvelopedData due to the changes
   --      - made in [RFC9480]
   --      - Using the choice EncryptedValue is bit-compatible to
   --      - the syntax without this change
   --   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
   --   id-it-caCerts          OBJECT IDENTIFIER ::= {id-it 17}
   --      CaCertsValue            ::= SEQUENCE SIZE (1..MAX) OF
   --                                             CMPCertificate
   --      - id-it-caCerts added in [RFC9480]
   --   id-it-rootCaKeyUpdate  OBJECT IDENTIFIER ::= {id-it 18}
   --      RootCaKeyUpdateValue    ::= RootCaKeyUpdateContent
   --      - id-it-rootCaKeyUpdate added in [RFC9480]
   --   id-it-certReqTemplate  OBJECT IDENTIFIER ::= {id-it 19}
   --      CertReqTemplateValue    ::= CertReqTemplateContent
   --      - id-it-certReqTemplate added in [RFC9480]
   --   id-it-rootCaCert       OBJECT IDENTIFIER ::= {id-it 20}
   --      RootCaCertValue         ::= CMPCertificate
   --      - id-it-rootCaCert added in [RFC9480]
   --   id-it-certProfile      OBJECT IDENTIFIER ::= {id-it 21}
   --      CertProfileValue        ::= SEQUENCE SIZE (1..MAX) OF
   --                                                 UTF8String
   --      - id-it-certProfile added in [RFC9480]
   --   id-it-crlStatusList    OBJECT IDENTIFIER ::= {id-it 22}
   --      CRLStatusListValue      ::= SEQUENCE SIZE (1..MAX) OF
   --                                                  CRLStatus
   --      - id-it-crlStatusList added in [RFC9480]
   --   id-it-crls             OBJECT IDENTIFIER ::= {id-it 23}
   --      CRLsValue               ::= SEQUENCE SIZE (1..MAX) OF
   --                                            CertificateList
   --      - id-it-crls added in [RFC9480]
   --   id-it-KemCiphertextInfo    OBJECT IDENTIFIER ::= {id-it 24}
   --      KemCiphertextInfoValue  ::= KemCiphertextInfo
   --      - id-it-KemCiphertextInfo was added in [RFC9810]
   --
   -- 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 end entity, 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 OIDs that it
   -- does not recognize.  If sent from end entity to CA, the empty set
   -- indicates that the CA may send
   -- any/all information that it wishes.

   GenRepContent ::= SEQUENCE OF InfoTypeAndValue
   -- The 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
   }

   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,
       hashAlg [0] AlgorithmIdentifier{DIGEST-ALGORITHM, {...}} OPTIONAL
       -- the hash algorithm to use for calculating certHash
       -- SHOULD NOT be used in all cases where the AlgorithmIdentifier
       -- of the certificate signature specifies a hash algorithm
      }

   PollReqContent ::= SEQUENCE OF SEQUENCE {
       certReqId              INTEGER }

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

   --
   -- EKU extension for PKI entities used in CMP
   -- operations, added due to the changes made in [RFC9480]
   -- The EKUs for the CA and RA are reused from CMC, as defined in
   -- [RFC6402]
   --

   -- id-kp-cmcCA OBJECT IDENTIFIER ::= { id-kp 27 }
   -- id-kp-cmcRA OBJECT IDENTIFIER ::= { id-kp 28 }
   id-kp-cmKGA OBJECT IDENTIFIER ::= { id-kp 32 }

   END

Acknowledgements ๐Ÿ™โœจ

Okay, big shoutout time! ๐Ÿซถ The authors wanna thank Carlisle Adams, Stephen Farrell, Tomi Kause, and Tero Mononen, the original authors of [RFC4210], for all their work. They literally built the foundation we're still vibing on ๐Ÿ‘‘

We also thank every single reviewer of this document for their valuable feedback. You all made this so much better ๐Ÿ’–

Adding KEM support to this document was partly funded by the German Federal Ministry of Education and Research in the project Quoryptan, through grant number 16KIS2033. Funded and slaying ๐Ÿ’…๐ŸŒˆ

Authors' Addresses ๐ŸŽ€

Here's where you can find the people who wrote this thing, bestie ๐Ÿฆ‹

Hendrik Brockhaus
Siemens
Werner-von-Siemens-Strasse 1
80333 Munich
Germany
Email: hendrik.brockhaus@siemens.com
URI:   https://www.siemens.com


David von Oheimb
Siemens
Werner-von-Siemens-Strasse 1
80333 Munich
Germany
Email: david.von.oheimb@siemens.com
URI:   https://www.siemens.com


Mike Ounsworth
Entrust
1187 Park Place
Minneapolis, MN 55379
United States of America
Email: mike.ounsworth@entrust.com
URI:   https://www.entrust.com


John Gray
Entrust
1187 Park Place
Minneapolis, MN 55379
United States of America
Email: john.gray@entrust.com
URI:   https://www.entrust.com
๐Ÿ“ฆ where this page comes from