OSSL_CMP_MSG_GET0_HEADER(3ossl)

πŸ’– OSSL_CMP_MSG_GET0_HEADER β€” the 3ossl manual, but make it make sense πŸ’–

okay bestie, gather round 🫢 this is the OpenSSL manual page for a whole lil squad of functions that manipulate CMP messages. yes, all ten of them. yes, we're doing all ten. slay.


✨ NAME ✨

OSSL_CMP_MSG_get0_header, OSSL_CMP_MSG_get_bodytype, OSSL_CMP_MSG_get0_certreq_publickey, OSSL_CMP_MSG_update_transactionID, OSSL_CMP_MSG_update_recipNonce, OSSL_CMP_CTX_setup_CRM, OSSL_CMP_MSG_read, OSSL_CMP_MSG_write, d2i_OSSL_CMP_MSG_bio, i2d_OSSL_CMP_MSG_bio β€” literally just functions for manipulating CMP messages πŸ’…


🌸 SYNOPSIS 🌸

#include <openssl/cmp.h>

OSSL_CMP_PKIHEADER *OSSL_CMP_MSG_get0_header(const OSSL_CMP_MSG *msg);
int OSSL_CMP_MSG_get_bodytype(const OSSL_CMP_MSG *msg);
X509_PUBKEY *OSSL_CMP_MSG_get0_certreq_publickey(const OSSL_CMP_MSG *msg);
int OSSL_CMP_MSG_update_transactionID(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg);
int OSSL_CMP_MSG_update_recipNonce(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg);
OSSL_CRMF_MSG *OSSL_CMP_CTX_setup_CRM(OSSL_CMP_CTX *ctx, int for_KUR, int rid);
OSSL_CMP_MSG *OSSL_CMP_MSG_read(const char *file, OSSL_LIB_CTX *libctx, const char *propq);
int OSSL_CMP_MSG_write(const char *file, const OSSL_CMP_MSG *msg);
OSSL_CMP_MSG *d2i_OSSL_CMP_MSG_bio(BIO *bio, OSSL_CMP_MSG **msg);
int i2d_OSSL_CMP_MSG_bio(BIO *bio, const OSSL_CMP_MSG *msg);

πŸ¦‹ DESCRIPTION πŸ¦‹

okay so, function by function, no cap:

  • OSSL_CMP_MSG_get0_header() β€” hands you back the header of the CMP message you passed in. that's it, that's the whole job πŸ‘‘
  • OSSL_CMP_MSG_get_bodytype() β€” gives you the body type of the given CMP message.
  • OSSL_CMP_MSG_get0_certreq_publickey() β€” expects msg to be a certificate request message, and if there's a public key chilling in its certificate template, it returns that key. if not, no key, no drama πŸ™ˆ
  • OSSL_CMP_MSG_update_transactionID() β€” updates the transactionID field in the header of the given message, following whatever the CMP_CTX says. and listen: if ctx doesn't already have a transaction ID, a fresh one gets created first ✨. then the message gets re-protected β€” but only if protecting requests is required. iykyk.
  • OSSL_CMP_MSG_update_recipNonce() β€” same energy, different field: it updates the recipNonce field in the header of the given message according to the CMP_CTX. and yep, the message gets re-protected too (if protecting requests is required).
  • OSSL_CMP_CTX_setup_CRM() β€” this one's the main character fr. it creates a CRMF certificate request message out of all the various info provided in the CMP context argument ctx, so it can go into a CMP request message based on the details contained in ctx. the rid argument defines the request identifier to use β€” and typically that's just 0.

πŸŽ€ the subject DN tea πŸŽ€

the subject DN that ends up in the certificate template is the first available</> value from this list, in order:

  1. any subject name in ctx that was set via OSSL_CMP_CTX_set1_subjectName(3) β€” but lowkey if it's the NULL-DN (i.e., any empty sequence of RDNs), then no subject is included at all πŸ’€
  2. the subject field of any PKCS#10 CSR set in ctx via OSSL_CMP_CTX_set1_p10CSR(3)
  3. the subject field of any reference certificate given in ctx (see OSSL_CMP_CTX_set1_oldCert(3)) β€” but only if for_KUR is nonzero, or if ctx doesn't include a Subject Alternative Name

🧚 the public key tea 🧚

and the public key that gets included? also the first available value from this list:

  1. the public key derived from any key set via OSSL_CMP_CTX_set0_newPkey(3)
  2. the public key of any PKCS#10 CSR given in ctx
  3. the public key of any reference certificate given in ctx (see OSSL_CMP_CTX_set1_oldCert(3))
  4. the public key derived from any client's private key set via OSSL_CMP_CTX_set1_pkey(3)

🌈 the extensions tea 🌈

the set of X.509 extensions to include is computed like this, bestie, follow along:

  • if a PKCS#10 CSR is present in ctx, the default extensions are taken from there. otherwise, the empty set is the initial value.
  • if there's a reference certificate in ctx and it contains Subject Alternative Names (SANs) and OSSL_CMP_OPT_SUBJECTALTNAME_NODEFAULT is not set, those SANs override any SANs from the PKCS#10 CSR.
  • the extensions are further augmented or overridden by any extensions with the same OIDs included in ctx via OSSL_CMP_CTX_set0_reqExtensions(3).
  • the SANs are further overridden by any SANs included in ctx via OSSL_CMP_CTX_push1_subjectAltName(3).
  • and finally, policies are overridden by any policies included in ctx via OSSL_CMP_CTX_push0_policy(3).

also, OSSL_CMP_CTX_setup_CRM() sets the regToken control oldCertID for KUR messages using the issuer name and serial number of the reference certificate β€” if present. periodt.


  • OSSL_CMP_MSG_read() β€” loads a DER-encoded OSSL_CMP_MSG from file.
  • OSSL_CMP_MSG_write() β€” stores the given OSSL_CMP_MSG to file in DER encoding.
  • d2i_OSSL_CMP_MSG_bio() β€” parses an ASN.1-encoded OSSL_CMP_MSG from the BIO bio. and if msg is not NULL, it assigns a pointer to the new structure to *msg ✨
  • i2d_OSSL_CMP_MSG_bio() β€” writes the OSSL_CMP_MSG msg in ASN.1 encoding to the BIO bio.

πŸ“ NOTES πŸ“

CMP is defined in RFC 9810. that's the vibe check, that's the source of truth πŸ’œ


πŸ‘‘ RETURN VALUES πŸ‘‘

  • OSSL_CMP_MSG_get0_header() β€” returns the intended pointer value as described above, or NULL if the respective entry doesn't exist, and on error.
  • OSSL_CMP_MSG_get_bodytype() β€” returns the body type, or -1 on error.
  • OSSL_CMP_MSG_get0_certreq_publickey() β€” returns a public key, or NULL on error.
  • OSSL_CMP_CTX_setup_CRM() β€” returns a pointer to an OSSL_CRMF_MSG on success, NULL on error.
  • d2i_OSSL_CMP_MSG_bio() β€” returns the parsed message, or NULL on error.
  • OSSL_CMP_MSG_read() and d2i_OSSL_CMP_MSG_bio() β€” return the parsed CMP message, or NULL on error.
  • OSSL_CMP_MSG_write() β€” returns the number of bytes successfully encoded, or a negative value if an error occurs.
  • i2d_OSSL_CMP_MSG_bio(), OSSL_CMP_MSG_update_transactionID(), and OSSL_CMP_MSG_update_recipNonce() β€” return 1 on success, 0 on error.

πŸ”— SEE ALSO πŸ”—

OSSL_CMP_CTX_set1_subjectName(3), OSSL_CMP_CTX_set1_p10CSR(3), OSSL_CMP_CTX_set1_oldCert(3), OSSL_CMP_CTX_set0_newPkey(3), OSSL_CMP_CTX_set1_pkey(3), OSSL_CMP_CTX_set0_reqExtensions(3), OSSL_CMP_CTX_push1_subjectAltName(3), OSSL_CMP_CTX_push0_policy(3)


⭐ HISTORY ⭐

  • the OpenSSL CMP support was added in OpenSSL 3.0.
  • OSSL_CMP_MSG_update_recipNonce() was added in OpenSSL 3.0.9.
  • OSSL_CMP_MSG_get0_certreq_publickey() was added in OpenSSL 3.3.

Copyright 2007-2024 The OpenSSL Project Authors. All Rights Reserved.

Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy in the file LICENSE in the source distribution or at <https://www.openssl.org/source/license.html>.


🫢 that's the whole page, bestie. go forth and manipulate some CMP messages responsibly πŸ’…βœ¨

and that's a wrap on the 3.5.9 version, dated 2026-09-29 β€” OpenSSL gang, we ate πŸ“πŸ‘‘

πŸ“¦ where this page comes from