X509_PUBKEY_NEW(3SSL)

🌸 X509_PUBKEY_NEW ✨ (that's the 3SSL manual, bestie)

okay so. welcome to the OpenSSL group chat, section 3SSL. today's main character: SubjectPublicKeyInfo public key functions πŸ’… β€” the ones that hold, encode, decode and vibe-check the public keys inside certificates and certificate requests. there's like twenty of them and yes we're doing all twenty, no skips, no shortcuts. sit down, hydrate, let's go 🫢

✨ NAME ✨

X509_PUBKEY_new_ex, X509_PUBKEY_new, X509_PUBKEY_free, X509_PUBKEY_dup, X509_PUBKEY_set, X509_PUBKEY_get0, X509_PUBKEY_get, d2i_PUBKEY_ex, d2i_PUBKEY, i2d_PUBKEY, d2i_PUBKEY_ex_bio, d2i_PUBKEY_bio, d2i_PUBKEY_ex_fp, d2i_PUBKEY_fp, i2d_PUBKEY_fp, i2d_PUBKEY_bio, X509_PUBKEY_set0_public_key, X509_PUBKEY_set0_param, X509_PUBKEY_get0_param, X509_PUBKEY_eq β€” SubjectPublicKeyInfo public key functions 🌈


πŸŽ€ SYNOPSIS πŸŽ€

#include <openssl/x509.h>

X509_PUBKEY *X509_PUBKEY_new_ex(OSSL_LIB_CTX *libctx, const char *propq);
X509_PUBKEY *X509_PUBKEY_new(void);
void X509_PUBKEY_free(X509_PUBKEY *a);
X509_PUBKEY *X509_PUBKEY_dup(const X509_PUBKEY *a);

int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey);
EVP_PKEY *X509_PUBKEY_get0(const X509_PUBKEY *key);
EVP_PKEY *X509_PUBKEY_get(const X509_PUBKEY *key);

EVP_PKEY *d2i_PUBKEY_ex(EVP_PKEY **a, const unsigned char **pp, long length,
                        OSSL_LIB_CTX *libctx, const char *propq);
EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length);
int i2d_PUBKEY(const EVP_PKEY *a, unsigned char **pp);

EVP_PKEY *d2i_PUBKEY_ex_bio(BIO *bp, EVP_PKEY **a, OSSL_LIB_CTX *libctx,
                            const char *propq);
EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a);

EVP_PKEY *d2i_PUBKEY_ex_fp(FILE *fp, EVP_PKEY **a, OSSL_LIB_CTX *libctx,
                           const char *propq);
EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a);

int i2d_PUBKEY_fp(const FILE *fp, EVP_PKEY *pkey);
int i2d_PUBKEY_bio(BIO *bp, const EVP_PKEY *pkey);

void X509_PUBKEY_set0_public_key(X509_PUBKEY *pub,
                                 unsigned char *penc, int penclen);
int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj,
                           int ptype, void *pval,
                           unsigned char *penc, int penclen);
int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg,
                           const unsigned char **pk, int *ppklen,
                           X509_ALGOR **pa, const X509_PUBKEY *pub);
int X509_PUBKEY_eq(X509_PUBKEY *a, X509_PUBKEY *b);

πŸ’– DESCRIPTION πŸ’–

the X509_PUBKEY structure is the ASN.1 SubjectPublicKeyInfo structure β€” yes, the one defined in RFC5280, the one that lives inside certificates and certificate requests. it's giving "my public key, but dressed up for the ASN.1 red carpet" πŸ‘‘

X509_PUBKEY_new_ex() allocates and initializes an X509_PUBKEY structure, and it glues that structure to the OSSL_LIB_CTX you hand it in the libctx parameter. any algorithm fetches that happen while using this X509_PUBKEY object will use the property query string propq. want the whole tea on algorithm fetching? go read "ALGORITHM FETCHING" in crypto(7) πŸ«–

X509_PUBKEY_new() is literally the same as X509_PUBKEY_new_ex() except it uses the default (NULL) OSSL_LIB_CTX and a NULL property query string. that's it. that's the whole difference. simple queen behavior ✨

X509_PUBKEY_dup() makes a duplicate copy of the X509_PUBKEY object you point at with a. twin moment πŸͺž

X509_PUBKEY_free() frees up the X509_PUBKEY structure a. and if a is NULL? nothing happens. no drama, nothing is done, we simply move on πŸ’…

X509_PUBKEY_set() sets the public key in *x to the public key contained in the EVP_PKEY structure pkey. and heads up: if *x is not NULL, any existing public key structure gets freed first. out with the old πŸ”₯

X509_PUBKEY_get0() returns the public key contained in key. but bestie listen β€” the returned value is an internal pointer which MUST NOT be freed after use. do not free it. i'm so serious 😭

X509_PUBKEY_get() is similar to X509_PUBKEY_get0() except the reference count on the returned key gets incremented β€” which means this one MUST be freed using EVP_PKEY_free() after use. so this one you do free. know the difference, it's important πŸ™ˆ

d2i_PUBKEY_ex() decodes an EVP_PKEY structure using SubjectPublicKeyInfo format. some public key decoding implementations may use cryptographic algorithms, and in that case the libctx library context and propq property query string you supplied are used. d2i_PUBKEY() does the same as d2i_PUBKEY_ex() except it uses the default library context and property query string.

i2d_PUBKEY() encodes an EVP_PKEY structure using SubjectPublicKeyInfo format. the other direction, slay πŸ’«

d2i_PUBKEY_bio(), d2i_PUBKEY_fp(), i2d_PUBKEY_bio() and i2d_PUBKEY_fp() are similar to d2i_PUBKEY() and i2d_PUBKEY() except they decode or encode using a BIO or FILE pointer. same vibe, different I/O πŸ¦‹

d2i_PUBKEY_ex_bio() and d2i_PUBKEY_ex_fp() are similar to d2i_PUBKEY_ex() except they decode using a BIO or FILE pointer.

X509_PUBKEY_set0_public_key() sets the public-key encoding of pub to the penclen bytes contained in buffer penc. any earlier public-key encoding in pub is freed. penc may be NULL to indicate that there is no actual public key data. ownership of the penc argument is passed to pub β€” it's yours no longer, it belongs to pub now, periodt πŸ‘‘

X509_PUBKEY_set0_param() sets the public-key parameters of pub. the OID associated with the algorithm is set to aobj. the type of the algorithm parameters is set to type using the structure pval. if penc is not NULL, the encoding of the public key itself is set to the penclen bytes contained in buffer penc, and any earlier public-key encoding in pub is freed. on success, ownership of all the supplied arguments is passed to pub, so they must not be freed after the call. don't double-free, i'm begging 🫠

X509_PUBKEY_get0_param() retrieves the public key parameters from pub. *ppkalg gets set to the associated OID, and the encoding consists of *ppklen bytes at *pk, and *pa gets set to the associated AlgorithmIdentifier for the public key. if you don't need any of these parameters, you can set that one to NULL β€” no pressure, optional besties πŸŽ€ all of the retrieved pointers are internal and must not be freed after the call. (again!! don't free them!!)

X509_PUBKEY_eq() compares two X509_PUBKEY values. are they the same? let's find out ⭐


πŸ“ NOTES πŸ“

the X509_PUBKEY functions can be used to encode and decode public keys in a standard format. cute, standardized, iconic.

in many cases applications will not call the X509_PUBKEY functions directly β€” they'll call wrapper functions like X509_get0_pubkey() instead. iykyk πŸ’œ


πŸ”₯ RETURN VALUES πŸ”₯

if the allocation fails, X509_PUBKEY_new() and X509_PUBKEY_dup() return NULL and set an error code you can get with ERR_get_error(3). otherwise? they return a pointer to the brand-new shiny allocated structure ✨

X509_PUBKEY_free() does not return a value. it's a void function, it simply does its thing and leaves πŸ’…

X509_PUBKEY_get0(), X509_PUBKEY_get(), d2i_PUBKEY_ex(), d2i_PUBKEY(), d2i_PUBKEY_ex_bio(), d2i_PUBKEY_bio(), d2i_PUBKEY_ex_fp() and d2i_PUBKEY_fp() return a pointer to an EVP_PKEY structure, or NULL if an error occurs 😭

i2d_PUBKEY() returns the number of bytes successfully encoded, or a negative value if an error occurs.

i2d_PUBKEY_fp() and i2d_PUBKEY_bio() return 1 if successfully encoded, or 0 if an error occurs.

X509_PUBKEY_set0_public_key() does not return a value. nothing to report, loves πŸŽ€

X509_PUBKEY_set(), X509_PUBKEY_set0_param() and X509_PUBKEY_get0_param() return 1 for success and 0 if an error occurred.

X509_PUBKEY_eq() returns 1 for equal, 0 for different, and < 0 on error. three whole outcomes, very versatile 🌈


πŸ‘€ SEE ALSO πŸ‘€

d2i_X509(3), ERR_get_error(3), X509_get_pubkey(3),


⏳ HISTORY ⏳

the X509_PUBKEY_new_ex() and X509_PUBKEY_eq() functions were added in OpenSSL 3.0. glow-up era πŸ’–

the X509_PUBKEY_set0_public_key(), d2i_PUBKEY_ex_bio() and d2i_PUBKEY_ex_fp() functions were added in OpenSSL 3.2. newer, fresher, still iconic πŸ¦‹


Copyright 2016-2022 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>.

no cap: that link is literally in the original, i'm not adding anything, i promise 🫢

and that's the whole page, bestie!! every flag, every pointer, every MUST NOT, every ownership transfer, all accounted for πŸ’―

version 4.0.3 🌸 dated 2026-09-29 🌸 and this was the X509_PUBKEY_NEW(3SSL) manual β€” take care of your internal pointers and they'll take care of you πŸ’…βœ¨πŸ‘‘

πŸ“¦ where this page comes from