X509_GET_PUBKEY(3)

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

πŸ’… X509_GET_PUBKEY(3) β€” the libcrypto glow-up

okay so bestie, this is the manual page for the public-key getters and setters in the libcrypto library (that's the crypto half of OpenSSL, iykyk). We're talking certificates πŸŽ€ and certificate requests πŸ¦‹ and the whole "where is the public key, and can I have it please" situation. Ten functions, one page, let's go ✨


✨ SYNOPSIS ✨

Like, here's the whole cast list, and yes they all live in <openssl/x509.h>:

#include <openssl/x509.h>

EVP_PKEY *
X509_get_pubkey(X509 *x);

EVP_PKEY *
X509_get0_pubkey(const X509 *x);

int
X509_set_pubkey(X509 *x, EVP_PKEY *pkey);

X509_PUBKEY *
X509_get_X509_PUBKEY(const X509 *x);

ASN1_BIT_STRING *
X509_get0_pubkey_bitstr(const X509 *x);

EVP_PKEY *
X509_REQ_get_pubkey(X509_REQ *req);

EVP_PKEY *
X509_REQ_get0_pubkey(X509_REQ *req);

int
X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey);

EVP_PKEY *
X509_extract_key(X509 *x);

EVP_PKEY *
X509_REQ_extract_key(X509_REQ *req);

🌸 DESCRIPTION 🌸

So the whole vibe of this page is: get a public key out of a cert, or put one in, and be very careful about who owns the memory afterwards 😭 because that's literally the entire plot.

  • X509_get_pubkey() β€” tries to decode the public key out of certificate x. If it works, you get it back as an EVP_PKEY pointer with its reference count incremented πŸ”₯ which means: you have to free it after use. It's yours now, congrats, it's a whole responsibility.
  • X509_get0_pubkey() β€” same idea, except it does not increment the reference count of the EVP_PKEY it hands back, so you must not free it after use. Look at it, admire it, but do not touch. πŸ™ˆ
  • X509_get_X509_PUBKEY() β€” returns an internal pointer to the SubjectPublicKeyInfo structure inside x. Again: must not be freed up after use. It's a peek, not a gift πŸŽ€
  • X509_get0_pubkey_bitstr() β€” returns an internal pointer to just the public key part inside that SubjectPublicKeyInfo structure, without the info about which algorithm was used. Like, the key itself, stripped of its little algorithm label πŸ’…
  • X509_set_pubkey() β€” tries to set the public key for certificate x to pkey. And, bestie, note this well: pkey should be freed up after use.
  • X509_REQ_get_pubkey(), X509_REQ_get0_pubkey(), and X509_REQ_set_pubkey() β€” literally the same energy but they operate on certificate request req ✨

Now for the performance tea β˜•: the first time a public key gets decoded, the EVP_PKEY structure is cached in the certificate or certificate request itself. So subsequent calls just return the cached structure with its reference count incremented β€” faster, slay, iconic πŸ‘‘

Also important: X509_extract_key() and X509_REQ_extract_key() are deprecated aliases for X509_get_pubkey() and X509_REQ_get_pubkey(), respectively, and they're implemented as macros. Deprecated, okay? Noted. πŸ“

πŸ’– RETURN VALUES πŸ’–

  • X509_get_pubkey(), X509_get0_pubkey(), X509_get_X509_PUBKEY(), X509_get0_pubkey_bitstr(), X509_REQ_get_pubkey(), X509_REQ_get0_pubkey(), X509_extract_key(), and X509_REQ_extract_key() β€” return a public key, or NULL if an error occurred 😭
  • X509_set_pubkey() and X509_REQ_set_pubkey() β€” return 1 for success or 0 for failure.
  • In some cases of failure of X509_get0_pubkey(), X509_set_pubkey(), X509_REQ_get_pubkey(), X509_REQ_get0_pubkey(), and X509_REQ_set_pubkey(), the reason can be determined with ERR_get_error(3) πŸ•΅οΈβ€β™€οΈ

πŸ”₯ ERRORS πŸ”₯

  • X509_get_pubkey(), X509_get0_pubkey(), X509_REQ_get_pubkey(), X509_extract_key(), and X509_REQ_extract_key() provide diagnostics as documented for X509_PUBKEY_get(3). If x or req is NULL or contains no certificate information, they fail without pushing an error onto the stack.
  • X509_get_X509_PUBKEY() provides no diagnostics and crashes by accessing a NULL pointer if x is NULL or contains no certificate information πŸ’€
  • X509_get0_pubkey_bitstr() provides no diagnostics and fails without pushing an error onto the stack if x is NULL β€” but it crashes by accessing a NULL pointer if x contains no certificate information πŸ’€πŸ’€
fr fr, do the vibe check before you call these. A NULL check is cheaper than a segfault, bestie. 🫢

πŸ¦‹ SEE ALSO πŸ¦‹

d2i_X509(3), X509_CRL_get0_by_serial(3), X509_NAME_add_entry_by_txt(3), X509_NAME_ENTRY_get_object(3), X509_NAME_get_index_by_NID(3), X509_NAME_print_ex(3), X509_new(3), X509_PUBKEY_new(3), X509_REQ_new(3), X509_sign(3), X509_verify_cert(3), X509V3_get_d2i(3)


⭐ STANDARDS ⭐

  • RFC 5280, Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile, section 4.1 Basic Certificate Fields
  • RFC 2986: PKCS #10: Certification Request Syntax Specification, section 4.1 CertificationRequestInfo

🧚 HISTORY 🧚

  • X509_extract_key() and X509_REQ_extract_key() first appeared in SSLeay 0.5.1 β€” but, plot twist 😳, they returned a pointer to an RSA object before SSLeay 0.6.0.
  • X509_get_pubkey(), X509_set_pubkey(), X509_REQ_get_pubkey(), and X509_REQ_set_pubkey() first appeared in SSLeay 0.6.5.
  • X509_get_X509_PUBKEY() first appeared in SSLeay 0.8.0.
  • These functions have been available since OpenBSD 2.4.
  • X509_get0_pubkey_bitstr() first appeared in OpenSSL 0.9.7 and has been available since OpenBSD 3.4.
  • X509_get0_pubkey() first appeared in OpenSSL 1.1.0 and has been available since OpenBSD 6.3.
  • X509_REQ_get0_pubkey() first appeared in OpenSSL 1.1.0 and has been available since OpenBSD 7.1.

and that's the whole page, bestie β€” historical lore and all πŸ‘‘ This lovely piece of documentation is from Debian, dated June 8, 2025. Go forth and increment those reference counts responsibly πŸ’œπŸ«Άβœ¨

πŸ“¦ where this page comes from