X509_GET0_SIGNATURE(3)

πŸ“¦ version 4.4.0, in alpine 3.24, arch rolling

πŸ’… X509_GET0_SIGNATURE(3) β€” signature information πŸ’…

okay so this is a page from the Library Functions Manual and it's all about peeking at signatures on certificates, requests, and CRLs. yes bestie, we're going deep into the crypto guts today. buckle up πŸŽ€


✨ NAME ✨

X509_get0_signature, X509_REQ_get0_signature, X509_CRL_get0_signature, X509_get0_tbs_sigalg, X509_CRL_get0_tbs_sigalg, X509_get_signature_type, X509_get_signature_nid, X509_REQ_get_signature_nid, X509_CRL_get_signature_nid, X509_get_signature_info β€” signature information πŸ¦‹

🌸 SYNOPSIS 🌸

library β€œlibcrypto” #include <openssl/x509.h>

void
X509_get0_signature(const ASN1_BIT_STRING **psig,
    const X509_ALGOR **palg, const X509 *x);

void
X509_REQ_get0_signature(const X509_REQ *req,
    const ASN1_BIT_STRING **psig, const X509_ALGOR **palg);

void
X509_CRL_get0_signature(const X509_CRL *crl,
    const ASN1_BIT_STRING **psig, const X509_ALGOR **palg);

const X509_ALGOR *
X509_get0_tbs_sigalg(const X509 *x);

const X509_ALGOR *
X509_CRL_get0_tbs_sigalg(const X509_CRL *crl);

int
X509_get_signature_type(const X509 *x);

int
X509_get_signature_nid(const X509 *x);

int
X509_REQ_get_signature_nid(const X509_REQ *req);

int
X509_CRL_get_signature_nid(const X509_CRL *crl);

int
X509_get_signature_info(X509 *x, int *md_nid, int *pkey_nid,
    int *security_bits, uint32_t *flags);

πŸ‘‘ DESCRIPTION πŸ‘‘

🫢 the get0 crew

X509_get0_signature(), X509_REQ_get0_signature(), and X509_CRL_get0_signature() set *psig to the signature and *palg to the signature algorithm of x, req, or crl, respectively. slay, now you know where the goods live πŸ’–

X509_get0_tbs_sigalg() and X509_CRL_get0_tbs_sigalg() return the signature algorithm in the signed portion of x or crl, respectively. (yes, the tbs part δΈ€ that's the "to be signed" bit, iykyk.)

⚠️ bestie listen to me: the values returned are internal pointers that must not be freed by the caller. not you, not your cleanup handler, nobody. leave them alone fr fr. πŸ’€

πŸ¦‹ the type / nid girlies

X509_get_signature_type() returns the base NID corresponding to the signature algorithm of x, just like EVP_PKEY_base_id(3) does.

X509_get_signature_nid(), X509_REQ_get_signature_nid(), and X509_CRL_get_signature_nid() return the NID corresponding to the signature algorithm of x, req, or crl, respectively, just like EVP_PKEY_id(3) does. same energy, different call πŸ’…

🌈 X509_get_signature_info() β€” the main character

X509_get_signature_info() retrieves information about the signature of certificate x. here's the tea on where everything goes:

  • the NID of the digest algorithm is written to *md_nid
  • the public key algorithm goes to *pkey_nid
  • the effective security bits land in *security_bits
  • and flag details get written to *flags

any of the output parameters can be set to NULL if you don't need that info. lowkey convenient ngl 🫢

if flags is not a NULL pointer, *flags is set to the bitwise OR of these bad boys:

  • X509_SIG_INFO_VALID β€” no error occurred ✨ this flag is set if X509_get_signature_info() returns 1.
  • X509_SIG_INFO_TLS β€” the signature algorithm is appropriate for use in TLS πŸ”₯
    • For a supported EdDSA algorithm (in LibreSSL this is Ed25519) this flag is always set.
    • For an RSASSA-PSS PSS algorithm this flag is set if all of these hold: the parameters are DER encoded, the digest algorithm is one of SHA-256, SHA-384, or SHA-512, the same digest algorithm is used in the mask generation function, and the salt length is equal to the digest algorithm's output length.
    • For all other signature algorithms this flag is set if the digest algorithm is one of SHA-1, SHA-256, SHA-384, or SHA-512.

X509_get_signature_info() returns 1 on success and 0 on failure. failure conditions include unsupported signature algorithms, certificate parsing errors and memory allocation failure 😭 (yes, three separate ways to fail, iconic of her honestly.)

🧚 why would you even need this

these functions provide lower level access to the signature for cases where an application wishes to analyse or generate a signature in a form where X509_sign(3) is not appropriate β€” for example in a non-standard or unsupported format. like when the normal path just isn't giving what you need πŸŽ€

πŸ’œ SEE ALSO πŸ’œ

EVP_PKEY_base_id(3), OBJ_obj2nid(3), X509_ALGOR_new(3), X509_CRL_get0_by_serial(3), X509_CRL_new(3), X509_get_pubkey(3), X509_get_subject_name(3), X509_get_version(3), X509_new(3), X509_REQ_new(3), X509_sign(3), X509_signature_dump(3), X509_verify_cert(3)

⭐ HISTORY ⭐

X509_get_signature_type() first appeared in SSLeay 0.8.0 and has been available since OpenBSD 2.4. ancient. a true elder 🫑

X509_get0_signature() and X509_get_signature_nid() first appeared in OpenSSL 1.0.2. then X509_REQ_get0_signature(), X509_CRL_get0_signature(), X509_get0_tbs_sigalg(), X509_REQ_get_signature_nid(), and X509_CRL_get_signature_nid() all showed up in OpenSSL 1.1.0. all these functions have been available since OpenBSD 6.3 🌸

X509_CRL_get0_tbs_sigalg() first appeared in LibreSSL 3.7.1 and has been available since OpenBSD 7.3. new-ish girlie ✨

X509_get_signature_info() first appeared in OpenSSL 1.1.1 and has been available since OpenBSD 7.6. freshest of the bunch πŸŽ€

πŸ™ˆ CAVEATS πŸ™ˆ

the security bits returned by X509_get_signature_info() refer to the information available from the certificate signature (such as the signing digest). but heads up: in some cases the actual security of the signature is smaller because the signing key is less secure. for example in a certificate signed using SHA-512 and a 1024-bit RSA key. so like... the digest is doing great and the key is doing... not that πŸ’€ don't let the number fool you.

😭 BUGS 😭

the signatures of X509_get0_signature(), X509_REQ_get0_signature(), and X509_CRL_get0_signature() are inconsistent. that's it. that's the bug. not me side-eying the API design πŸ’…


and that's the whole page bestie!! πŸ’– this one came out of Debian, dated July 6, 2025, and it's X509_GET0_SIGNATURE(3) β€” go forth and inspect those signatures responsibly πŸ¦‹βœ¨

πŸ“¦ where this page comes from