OpenSSL CMP enrolment with trusted configuration
You will prepare an OpenSSL Certificate Management Protocol (CMP) client command for an initial certificate enrolment, save the returned certificate and CA certificates, and understand which settings protect the exchange. Allow 20 to 30 minutes for a first pass, assuming the CA operator has already supplied its CMP URL, recipient DN, authentication method and trust material.
The route
Jump straight to the step you need, or tick off Done means at the end.
Before you start
You need the openssl package, a private key that may be used for the requested certificate, and details from the CA. You also need either a pre-shared secret and reference value or a client certificate and private key for signature-based CMP protection. CMP is a protocol exchange with a CA, not a local certificate generator. Do not invent the server URL, recipient DN, secret, or trust anchor.
On this machine the executable reports OpenSSL 3.6.1, while the installed openssl-cmp(1ssl) page has a 3.0.13 header. Check both when diagnosing a difference:
$ openssl version
OpenSSL 3.6.1 27 Jan 2026
$ man -w openssl-cmp
/home/linuxbrew/.linuxbrew/Cellar/openssl@3/3.6.1/share/man/man1/openssl-cmp.1ssl
The examples below use options documented by that local manual. The executable's help is the final check for the installed build.
1. Inspect the installed client
Run the help command before building a transaction. This is harmless and does not contact a CA:
$ openssl cmp -help
Usage: cmp [options]
-config val Configuration file to use
-section val Section(s) in config file to get options from
-cmd val CMP request to send: ir/cr/kur/p10cr/rr/genm
The request types have distinct jobs. ir is an initial request, cr requests another certificate, kur updates an existing key or certificate, rr requests revocation, p10cr uses a legacy PKCS#10 request, and genm requests information. Start with ir only when the CA says this is a first enrolment.
2. Put repeatable settings in an OpenSSL configuration
Long CMP commands are easy to misread, especially when a passphrase or DN contains shell metacharacters. Create a private configuration file with a general section and an initial-enrolment section. The values below are placeholders, not working credentials:
[cmp]
server = cmp.example.invalid:80
path = /pkix/
[initial]
cmd = ir
recipient = /CN=CMP-CA
ref = REPLACE_WITH_REFERENCE
secret = pass:REPLACE_WITH_SECRET
newkey = client-key.pem
subject = /CN=client.example.invalid
cacertsout = ca-certs.pem
certout = client-cert.pem
Save it with permissions that exclude other users:
$ chmod 600 cmp-client.cnf
$ openssl cmp -config cmp-client.cnf -section cmp,initial -help > /tmp/cmp-help.txt
$ head -n 4 /tmp/cmp-help.txt
Usage: cmp [options]
The -section argument can load several sections, separated by commas or whitespace. Later sections and command-line options can override earlier values. The default section name is cmp; using an explicit section makes the transaction easier to review.
3. Choose authentication and trust deliberately
The example uses MAC-based protection with ref and secret. Treat the secret as a credential: do not put a real value in a shared shell history, paste it into a ticket, or commit the configuration. The pass: form is convenient for a throwaway test but exposes the value to anyone who can read the file or command line. Use an OpenSSL passphrase source suitable for your deployment, and test its behaviour with the CA operator.
For signature-based protection, the client needs cert, key, and a trust anchor in trusted, with any intermediate certificates in untrusted. A pinned srvcert directly trusts the specified CMP server certificate and takes precedence over trusted. That is a security boundary, not a cosmetic option. Confirm the certificate fingerprint through a trusted channel before pinning it.
If the CA uses HTTPS, add tls_used = 1 and configure tls_trusted. The manual says HTTPS in -server is valid only when TLS is enabled. tls_trusted also enables hostname validation, so use the CA's DNS name rather than an address that is not covered by its certificate.
4. Review the transaction, then contact the CA
Before sending anything, check the output paths and ask whether the CA expects a different subject, SAN, port or CMP alias. The command creates or overwrites the files named by certout and cacertsout; keep any existing files under a backup name first. This is the point where a wrong recipient or trust anchor can result in a failed or misdirected request.
Once the values have been confirmed, run:
$ openssl cmp -config cmp-client.cnf -section cmp,initial -verbosity 6
cmp_main:apps/cmp.c:...:CMP info: using section(s) 'cmp,initial'
The exact diagnostic lines vary by build and transaction. A successful enrolment should leave the new certificate and CA output files named in the configuration. Do not treat an informational log line as proof of enrolment; inspect the exit status and files.
$ test -s client-cert.pem && echo 'certificate saved'
certificate saved
$ openssl x509 -in client-cert.pem -noout -subject -issuer -dates
subject=CN = client.example.invalid
issuer=CN = CMP-CA
Reading a certificate is normally unprivileged. Do not use sudo unless your chosen file location genuinely requires it.
5. Use saved messages for troubleshooting
When the CA operator needs a reproducible request without another live exchange, add reqout to save the generated request sequence. rspout saves responses that were actually used. The rspin option can process saved responses without contacting the server while enough response files are available. These files can contain certificate material and protocol metadata, so protect them like operational logs.
For a dry local protocol test, use_mock_srv uses the internal API-level mock server and excludes server and port. It is useful for checking client-side configuration, but it does not prove that the production CA accepts your policy, credentials or certificate chain.
If a server returns an unprotected negative response, the manual documents unprotected_errors as a diagnostic workaround. Use it only when the CA operator has confirmed that this is the failure mode. It weakens protection checks and must not become a routine production setting.
6. Keep update and revocation separate
For a key update, generate a new key, set cmd = kur, provide the existing certificate and key, and use newkey for the replacement. Write the new certificate to a temporary name until it has been checked, then replace the active files as one deliberate change. For revocation, use cmd = rr and oldcert. Revocation can disrupt services and is difficult to undo, so confirm the certificate and reason with the CA operator before sending it.
Done means
openssl cmp -helpandopenssl versionwere checked on the target machine.- The CMP URL, recipient DN, authentication details and trust material came from the CA operator.
- The configuration file is private and real secrets are not committed or exposed in shell history.
- The enrolment command exited successfully and
openssl x509shows the expected subject, issuer and validity dates. - Saved request, response and CA files are protected, and update or revocation commands have not been run accidentally.