Open-Source Wikis

/

OpenSSL

/

Features

/

CMP (Certificate Management Protocol)

openssl/openssl

CMP (Certificate Management Protocol)

Active contributors: Dr. David von Oheimb, Tomas Mraz

Purpose

OpenSSL implements the Certificate Management Protocol (RFC 4210, RFC 9480, RFC 9481) and CRMF (Certificate Request Message Format, RFC 4211). This is the IETF protocol used by EJBCA, Insta-CertifierCA, RFC 4210-conforming product suites, and various industrial automation deployments to enroll, renew, revoke, and confirm certificates over HTTP/HTTPS or files.

CMP support landed in 3.0 (Sept 2021). The implementation comprises:

  • Library: crypto/cmp/ (a CMP client and a server-side helper) and crypto/crmf/ (CRMF message types).
  • HTTP transport in crypto/http/.
  • CLI in apps/cmp.c, exposed as openssl cmp.

Directory layout

crypto/cmp/
├── cmp_asn.c             37 KB  -- the CMP/PKIMessage ASN.1 schema
├── cmp_client.c          38 KB  -- the high-level client (ir/cr/p10cr/kur/rr/genm)
├── cmp_server.c          25 KB  -- the server-side dispatcher hooks
├── cmp_ctx.c             37 KB  -- OSSL_CMP_CTX configuration and state
├── cmp_msg.c             39 KB  -- message construction (every PKIBody type)
├── cmp_vfy.c             34 KB  -- message verification (signature/MAC, content rules)
├── cmp_protect.c         11 KB  -- protection algorithm selection (PBM, signature)
├── cmp_hdr.c             10 KB  -- PKIHeader handling
├── cmp_genm.c            14 KB  -- General Message types (rootCaCert, certReqTemplate, …)
├── cmp_status.c          10 KB  -- PKIStatusInfo helpers
├── cmp_util.c             9 KB  -- assorted helpers
├── cmp_http.c             4 KB  -- glue to crypto/http/
├── cmp_err.c             10 KB  -- CMP_R_* reasons
└── cmp_local.h           42 KB

crypto/crmf/
├── crmf_asn.c            -- CRMF ASN.1 schema (CertReqMsg, CertTemplate, ...)
├── crmf_lib.c            -- CRMF builders
├── crmf_pbm.c            -- PBM-based proof-of-possession
└── crmf_local.h, crmf_err.c

Concepts

CMP defines a transaction between a client (the EE — End Entity, or an RA) and a server (the CA). Every message is a PKIMessage:

PKIMessage ::= SEQUENCE {
    header     PKIHeader,
    body       PKIBody,    -- one of ir, ip, cr, cp, p10cr, kur, kup, rr, rp, ccp, ccr, certConf, pollReq, pollRep, error, genm, genp, ...
    protection [0] PKIProtection OPTIONAL,
    extraCerts [1] SEQUENCE OF CMPCertificate OPTIONAL
}

The PKIBody one-of carries the operation. A typical exchange is two messages: request (ir) → response (ip), then a third confirmation (certConf) → ack (pkiconf). Polling messages (pollReq / pollRep) handle slow CAs.

High-level operations

openssl cmp and the OSSL_CMP_exec_*_ses functions in cmp_client.c cover:

Operation RFC term OpenSSL helper
Initial enrollment IR (ir/ip) OSSL_CMP_exec_IR_ses
Certification request (subsequent) CR (cr/cp) OSSL_CMP_exec_CR_ses
Key update KUR (kur/kup) OSSL_CMP_exec_KUR_ses
PKCS#10-based request P10CR OSSL_CMP_exec_P10CR_ses
Revocation RR (rr/rp) OSSL_CMP_exec_RR_ses
General message genm/genp OSSL_CMP_exec_GENM_ses
Cert confirm certConf/pkiconf sent automatically as part of IR/CR/KUR if cert acceptance succeeded

Each helper takes an OSSL_CMP_CTX * and returns the issued cert (or, for revocation, a status).

Configuration

OSSL_CMP_CTX (in cmp_ctx.c) is a large state object with many setters. The most-used:

Setter Purpose
OSSL_CMP_CTX_set1_serverPath / set1_server / set1_proxy / set1_no_proxy HTTP endpoints.
OSSL_CMP_CTX_set1_subjectName Subject for the cert template.
OSSL_CMP_CTX_set0_newPkey New keypair to enroll.
OSSL_CMP_CTX_set1_oldCert / set1_oldClCert Cert being renewed (KUR) or revoked (RR).
OSSL_CMP_CTX_set1_p10CSR PKCS#10 CSR for P10CR.
OSSL_CMP_CTX_set1_secretValue Shared secret for PBM-based protection.
OSSL_CMP_CTX_set1_referenceValue KEK identifier matching secretValue.
OSSL_CMP_CTX_set1_cert / set1_pkey Existing cert+key for signature-based protection.
OSSL_CMP_CTX_set0_trustedStore / set1_untrusted Verification material.
OSSL_CMP_CTX_set1_recipient / set1_expected_sender Header overrides.

The full list is in doc/man3/OSSL_CMP_CTX_new.pod plus the related man pages.

Message protection

CMP messages are protected by either:

  • Signature (preferred): the sender's certificate signs the protectedPart using a KeyMgmt-fetched EVP_PKEY. cmp_protect.c selects the algorithm (RSA/ECDSA/EdDSA). cmp_vfy.c validates.
  • PBM (Password-Based MAC): a shared secret is derived through PKCS#5 PBKDF2 (or the older RFC 4210 PBM) into a HMAC key. Used during initial enrollment when the EE has no signing key yet.

The protection algorithm goes into the PKIHeader.protectionAlg field, and the protection bytes into PKIMessage.protection.

Verification

cmp_vfy.c verifies a received message:

  1. Header sanity (transaction id matches, sender nonce echoed, recipient nonce stored).
  2. Protection check: signature or PBM.
  3. Content-specific checks (e.g. ip's certifiedKeyPair must match the requested template).
  4. Optional OSSL_CMP_certConf_cb callback to let the application accept or reject the issued cert.

The verifier uses the regular crypto/x509/ machinery for signature trust (features/x509-pki).

Server side

cmp_server.c is a server helper, not a full CA. It dispatches incoming PKIMessages to per-PKIBody handlers that the application supplies via the OSSL_CMP_SRV_CTX callback table:

  • OSSL_CMP_SRV_set_process_cert_request_cb
  • OSSL_CMP_SRV_set_process_rr_cb
  • OSSL_CMP_SRV_set_process_genm_cb
  • OSSL_CMP_SRV_set_process_error_cb
  • OSSL_CMP_SRV_set_process_certConf_cb
  • OSSL_CMP_SRV_set_process_pollReq_cb

The application implements the actual issuance logic (signing the cert with its CA key) inside those callbacks.

CRMF

CRMF (RFC 4211) defines CertReqMsg, the carrier for certificate-request bodies inside CMP. crypto/crmf/:

  • Builds CertReqMsg with template, regInfo, and proof-of-possession.
  • Implements PoP variants: signature, encrypted cert (RaVerified), key-agreement.
  • Validates received CertReqMsg.

CLI

apps/openssl cmp exposes most of the library's surface. Examples:

openssl cmp -cmd ir -server localhost:8085 -path /pkix/ \
    -secret pass:1234 -ref MyKEK \
    -newkey new.pem -subject "/CN=test" -certout new.crt

openssl cmp -cmd kur -server ca.example.com -path /pkix/ \
    -cert old.crt -key old.key -newkey newer.pem \
    -trusted ca-bundle.pem -certout newer.crt

openssl cmp -cmd rr -server ca.example.com -path /pkix/ \
    -cert revoked.crt -key revoked.key -trusted ca-bundle.pem

apps/openssl cmp uses apps/cmp.c (one of the bigger CLI files; it delegates back to OSSL_CMP_* for almost everything).

Integration points

  • HTTP transport: crypto/http/ is the minimal client. CMP can also operate over files (request/response read from / written to disk) via -rspin / -rspout, useful when the channel is a regulated air-gapped exchange.
  • X.509: every issued cert and the trust path use the regular X509/X509_STORE_CTX stack.
  • CMS / ESS: not used directly — CMP has its own protection mechanism. (CMS is used elsewhere; see features/cms.)

Entry points for modification

  • New PKIBody type: extend cmp_asn.c, cmp_msg.c, cmp_vfy.c, and the dispatcher in cmp_client.c/cmp_server.c.
  • New genm/genp InfoType: extend cmp_genm.c (and the corresponding ASN.1 if needed).
  • New PoP method in CRMF: crypto/crmf/crmf_lib.c.
  • New protection algorithm: registration in cmp_protect.c; the implementation comes from a provider via EVP.

Documentation

  • doc/man1/openssl-cmp.pod.in — the CLI.
  • doc/man3/OSSL_CMP_*.pod (a couple of dozen pages).
  • doc/man3/OSSL_CRMF_*.pod.
  • doc/man7/openssl-cmp.pod — concepts.
  • doc/designs/cmp_*.md for design notes (where present).

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

CMP (Certificate Management Protocol) – OpenSSL wiki | Factory