OSSL_CMP_MSG_GET0_HEADER(3ossl)

πŸ“¦ version 3.5.0, in opensuse-leap 16.0

πŸ’… OSSL_CMP_MSG_GET0_HEADER β€” like, the whole CMP message glow-up toolkit (that's the 3ossl manual, bestie)

Okay so real talk: this page is the group chat for all the little functions that poke at CMP messages β€” grabbing their headers, reading them off disk, writing them back out, updating transaction IDs and nonces, and building CRMF cert requests from your context. It's giving "backstage pass to the certificate management protocol" energy. πŸ’–


✨ 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 πŸ¦‹

The little getters πŸŽ€

  • OSSL_CMP_MSG_get0_header() β€” hands you the header of the CMP message you passed in. That's it, that's the whole job. Iconic.
  • OSSL_CMP_MSG_get_bodytype() β€” tells you the body type of the given CMP message. Vibe check for the payload. πŸ’…
  • OSSL_CMP_MSG_get0_certreq_publickey() β€” expects msg to be a certificate request message, and returns the public key sitting in its certificate template, if it's there. No key? No drama, you get nothing back.

Updating stuff (re-protection era) 🌸

  • OSSL_CMP_MSG_update_transactionID() β€” updates the transactionID field in the header of msg, following whatever the CMP_CTX says. If ctx doesn't have a transaction ID yet, a fresh one gets created first. Then the message gets re-protected (if protecting requests is required). Main character behavior tbh. πŸ‘‘
  • OSSL_CMP_MSG_update_recipNonce() β€” same deal but for the recipNonce field in the header of msg, according to the CMP_CTX. Message gets re-protected too (again, if protecting requests is required).

OSSL_CMP_CTX_setup_CRM() β€” the big one 🫢

This one builds a CRMF certificate request message out of all the assorted info living in the CMP context argument ctx, so it can get tucked into a CMP request message. The rid argument is the request identifier to use β€” typically it's 0. Ngl, 0 is the moment.

Now let's talk about what actually goes into it, because the priority order is everything:

The subject DN (first available wins) ⭐

The subject DN put in the certificate template is the first available value of these, in order:

  1. Any subject name in ctx set via OSSL_CMP_CTX_set1_subjectName(3) β€” but heads up, if it's the NULL-DN (i.e., any empty sequence of RDNs), no subject is included.
  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 the ctx does not include a Subject Alternative Name. Conditional queen. πŸ’…

The public key (also first available wins) πŸ”‘

The public key included is the first available value of these, in order:

  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 X.509 extensions (this is a whole saga) 🌈

The set of X.509 extensions to include is computed like this:

  • If a PKCS#10 CSR is present in ctx, 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 get further augmented or overridden by any extensions with the same OIDs included in ctx via OSSL_CMP_CTX_set0_reqExtensions(3).
  • The SANs get further overridden by any SANs included in ctx via OSSL_CMP_CTX_push1_subjectAltName(3).
  • Finally, policies are overridden by any policies included in ctx via OSSL_CMP_CTX_push0_policy(3).

Layer upon layer upon layer. It's giving onion, honestly. πŸ§…βœ¨

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.

Reading & writing πŸ’Ύ

  • 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. It assigns a pointer to the new structure to *msg if msg is not NULL. (Don't be the person who passes garbage there, kay? 😭)
  • i2d_OSSL_CMP_MSG_bio() β€” writes the OSSL_CMP_MSG msg in ASN.1 encoding to BIO bio.

πŸ“Œ NOTES πŸ“Œ

CMP is defined in RFC 4210. That's the receipts, bestie. πŸŽ€


πŸ”₯ 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.
fr fr, 0 vs -1 vs NULL β€” three different flavors of "nope". Read the list carefully or you'll be debugging at 3am. πŸ’€

πŸ‘€ SEE ALSO πŸ‘€

Go read those too, iykyk. πŸ¦‹


πŸ•°οΈ HISTORY πŸ•°οΈ

  • 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.

A whole glow-up timeline. ⭐


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>.


Okay that's the whole page, bestie β€” no cap, every last detail preserved. This one's from OpenSSL 3.5.0, dated 2026-09-25, and it's the 3ossl manual page, mwah πŸ’‹πŸ«ΆπŸŽ€

πŸ“¦ where this page comes from