D2I_PRIVATEKEY(3)

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

okay so this is D2I_PRIVATEKEY(3), a Library Functions Manual page, and it’s literally the algorithm-independent interface to decode and encode private and public keys. Bestie, if you’re here, you’re probably doing EVP_PKEY stuff β€” and yes, this page serves. πŸ’…

πŸ’– NAME πŸ’–

The whole squad: d2i_PrivateKey, d2i_AutoPrivateKey, d2i_PrivateKey_bio, d2i_PrivateKey_fp, i2d_PrivateKey, i2d_PrivateKey_bio, i2d_PrivateKey_fp, i2d_PKCS8PrivateKeyInfo_bio, i2d_PKCS8PrivateKeyInfo_fp, d2i_PublicKey, i2d_PublicKey β€” all here to decode and encode EVP_PKEY objects. Periodt. ✨

✨ SYNOPSIS ✨

Okay, it’s giving libcrypto energy, and you need the header. Copy these signatures exactly, no cap:

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

EVP_PKEY *
d2i_PrivateKey(int type, EVP_PKEY **val_out,
    const unsigned char **der_in, long length);

EVP_PKEY *
d2i_AutoPrivateKey(EVP_PKEY **val_out, const unsigned char **der_in,
    long length);

EVP_PKEY *
d2i_PrivateKey_bio(BIO *in_bio, EVP_PKEY **val_out);

EVP_PKEY *
d2i_PrivateKey_fp(FILE *in_fp, EVP_PKEY **val_out);

int
i2d_PrivateKey(EVP_PKEY *val_in, unsigned char **der_out);

int
i2d_PrivateKey_bio(BIO *out_bio, EVP_PKEY *val_in);

int
i2d_PrivateKey_fp(FILE *out_fp, EVP_PKEY *val_in);

int
i2d_PKCS8PrivateKeyInfo_bio(BIO *out_bio, EVP_PKEY *val_in);

int
i2d_PKCS8PrivateKeyInfo_fp(FILE *out_fp, EVP_PKEY *val_in);

EVP_PKEY *
d2i_PublicKey(int type, EVP_PKEY **val_out,
    const unsigned char **der_in, long length);

int
i2d_PublicKey(EVP_PKEY *val_in, unsigned char **der_out);

🌸 DESCRIPTION 🌸

These are the algorithm-independent interfaces to decode and encode private and public keys. For the full semantics, examples, caveats, and bugs, go read ASN1_item_d2i(3) β€” iykyk.

  • d2i_PrivateKey() β€” decodes a private key using algorithm type. It attempts to use any algorithm specific format or the PKCS#8 unencrypted PrivateKeyInfo format defined in RFC 5208 section 5. The type parameter should be a public key algorithm constant such as EVP_PKEY_RSA. An error occurs if the decoded key does not match type. 🫢
  • d2i_AutoPrivateKey() β€” similar to d2i_PrivateKey() except that it attempts to automatically detect the algorithm. Main character energy, honestly.
  • d2i_PrivateKey_bio() and d2i_PrivateKey_fp() β€” similar to d2i_PrivateKey() except that they read from a BIO or FILE pointer.
  • i2d_PrivateKey() β€” encodes val_in. It uses an algorithm specific format or, if none is defined for that key type, the PKCS#8 unencrypted PrivateKeyInfo format.
  • i2d_PrivateKey_bio() and i2d_PrivateKey_fp() β€” similar to i2d_PrivateKey() except that they write to a BIO or FILE pointer and use a different convention for their return values.
  • i2d_PKCS8PrivateKeyInfo_bio() and i2d_PKCS8PrivateKeyInfo_fp() β€” encode val_in in PKCS#8 unencrypted PrivateKeyInfo format. They are similar to i2d_PrivateKey() except that they don’t use any algorithm-specific formats and that they write to a BIO or FILE pointer rather than to a buffer.
⚠️ bestie, all these functions use DER format and unencrypted keys. Applications wishing to encrypt or decrypt private keys should use other functions such as d2i_PKCS8PrivateKey_bio(3) instead. That’s the move. πŸ”₯

If *val_out is not NULL when calling d2i_PrivateKey() or d2i_AutoPrivateKey() (i.e. an existing structure is being reused) and the key format is PKCS#8, then *val_out will be freed and replaced on a successful call. Not me warning you about pointer reuse β€” but yes, that’s the vibe. πŸŒ€

d2i_PublicKey() calls d2i_DSAPublicKey(3), o2i_ECPublicKey(3), or d2i_RSAPublicKey(3) depending on type and stores the result in the returned EVP_PKEY object.

i2d_PublicKey() calls i2d_DSAPublicKey(3), i2o_ECPublicKey(3), or i2d_RSAPublicKey(3) depending on the algorithm used by val_in. Slay. πŸ’…

πŸ’€ RETURN VALUES πŸ’€

  • d2i_PrivateKey(), d2i_AutoPrivateKey(), d2i_PrivateKey_bio(), d2i_PrivateKey_fp(), and d2i_PublicKey() return a valid EVP_PKEY structure or NULL if an error occurs.
  • i2d_PrivateKey() and i2d_PublicKey() return the number of bytes successfully encoded or a negative value if an error occurs.
  • i2d_PrivateKey_bio(), i2d_PrivateKey_fp(), i2d_PKCS8PrivateKeyInfo_bio(), and i2d_PKCS8PrivateKeyInfo_fp() return 1 for success or 0 if an error occurs.
  • For all functions, the error code can be obtained by calling ERR_get_error(3). Go off. πŸ”₯

πŸ¦‹ SEE ALSO πŸ¦‹

The bestie cross-reference list, no skips:

πŸ‘‘ STANDARDS πŸ‘‘

RFC 5208: Public-Key Cryptography Standards (PKCS) #8: Private-Key Information Syntax Specification β€” iconic, honestly. πŸ’œ

🌈 HISTORY 🌈

  • d2i_PrivateKey(), i2d_PrivateKey(), d2i_PublicKey(), and i2d_PublicKey() first appeared in SSLeay 0.6.0 and have been available since OpenBSD 2.4.
  • d2i_AutoPrivateKey(), d2i_PrivateKey_bio(), d2i_PrivateKey_fp(), i2d_PrivateKey_bio(), i2d_PrivateKey_fp(), i2d_PKCS8PrivateKeyInfo_bio(), and i2d_PKCS8PrivateKeyInfo_fp() first appeared in OpenSSL 0.9.5 and have been available since OpenBSD 2.7.

okay that’s the page, bestie. Source/version vibe: Debian. Date: June 8, 2025. Manual: D2I_PRIVATEKEY(3). Mwah πŸ’‹βœ¨

πŸ“¦ where this page comes from