PEM_READ_CMS(3ossl)

✨ PEM_READ_CMS πŸ’– (that's the 3ossl one, bestie)

okay so. this page lives in the OpenSSL manual, and it's basically the group chat where all the PEM read/write helpers hang out. yes, all of them. buckle up πŸŽ€


🌸 NAME 🌸

DECLARE_PEM_rw, PEM_read_CMS, PEM_read_bio_CMS, PEM_write_CMS, PEM_write_bio_CMS, PEM_write_DHxparams, PEM_write_bio_DHxparams, PEM_read_ECPKParameters, PEM_read_bio_ECPKParameters, PEM_write_ECPKParameters, PEM_write_bio_ECPKParameters, PEM_read_ECPrivateKey, PEM_write_ECPrivateKey, PEM_write_bio_ECPrivateKey, PEM_read_EC_PUBKEY, PEM_read_bio_EC_PUBKEY, PEM_write_EC_PUBKEY, PEM_write_bio_EC_PUBKEY, PEM_read_NETSCAPE_CERT_SEQUENCE, PEM_read_bio_NETSCAPE_CERT_SEQUENCE, PEM_write_NETSCAPE_CERT_SEQUENCE, PEM_write_bio_NETSCAPE_CERT_SEQUENCE, PEM_read_PKCS8, PEM_read_bio_PKCS8, PEM_write_PKCS8, PEM_write_bio_PKCS8, PEM_write_PKCS8_PRIV_KEY_INFO, PEM_read_bio_PKCS8_PRIV_KEY_INFO, PEM_read_PKCS8_PRIV_KEY_INFO, PEM_write_bio_PKCS8_PRIV_KEY_INFO, PEM_read_SSL_SESSION, PEM_read_bio_SSL_SESSION, PEM_write_SSL_SESSION, PEM_write_bio_SSL_SESSION, PEM_read_X509_PUBKEY, PEM_read_bio_X509_PUBKEY, PEM_write_X509_PUBKEY, PEM_write_bio_X509_PUBKEY β€” the PEM object encoding routines. it's giving very much "the whole squad showed up" πŸ’…


✨ SYNOPSIS ✨

the standard ones first, no notes:

#include <openssl/pem.h>

DECLARE_PEM_rw(name, TYPE)

TYPE *PEM_read_TYPE(FILE *fp, TYPE **a, pem_password_cb *cb, void *u);
TYPE *PEM_read_bio_TYPE(BIO *bp, TYPE **a, pem_password_cb *cb, void *u);
int PEM_write_TYPE(FILE *fp, const TYPE *a);
int PEM_write_bio_TYPE(BIO *bp, const TYPE *a);

now the deprecated girlies β€” these have been deprecated since OpenSSL 3.0, and you can hide them entirely by defining OPENSSL_API_COMPAT with a suitable version value, see openssl_user_macros(7). lowkey a glow-down but ok:

#include <openssl/pem.h>

int PEM_write_DHxparams(FILE *out, const DH *dh);
int PEM_write_bio_DHxparams(BIO *out, const DH *dh);
EC_GROUP *PEM_read_ECPKParameters(FILE *fp, EC_GROUP **x, pem_password_cb *cb, void *u);
EC_GROUP *PEM_read_bio_ECPKParameters(BIO *bp, EC_GROUP **x, pem_password_cb *cb, void *u);
int PEM_write_ECPKParameters(FILE *out, const EC_GROUP *x);
int PEM_write_bio_ECPKParameters(BIO *out, const EC_GROUP *x),

EC_KEY *PEM_read_EC_PUBKEY(FILE *fp, EC_KEY **x, pem_password_cb *cb, void *u);
EC_KEY *PEM_read_bio_EC_PUBKEY(BIO *bp, EC_KEY **x, pem_password_cb *cb, void *u);
int PEM_write_EC_PUBKEY(FILE *out, const EC_KEY *x);
int PEM_write_bio_EC_PUBKEY(BIO *out, const EC_KEY *x);

EC_KEY *PEM_read_ECPrivateKey(FILE *out, EC_KEY **x, pem_password_cb *cb, void *u);
EC_KEY *PEM_read_bio_ECPrivateKey(FILE *out, EC_KEY **x, pem_password_cb *cb, void *u);
int PEM_write_ECPrivateKey(FILE *out, const EC_KEY *x, const EVP_CIPHER *enc,
                           const unsigned char *kstr, int klen,
                           pem_password_cb *cb, void *u);
int PEM_write_bio_ECPrivateKey(BIO *out, const EC_KEY *x, const EVP_CIPHER *enc,
                               const unsigned char *kstr, int klen,
                               pem_password_cb *cb, void *u);

πŸ¦‹ DESCRIPTION πŸ¦‹

so, first things first, the important bit: to replace all those deprecated functions listed up there, applications should use the EVP_PKEY type plus OSSL_DECODER_from_bio() and OSSL_ENCODER_to_bio() to read and write PEM data containing key parameters, or private and public keys. that's the move. periodt. πŸ‘‘

now, throughout this whole description, TYPE is just a placeholder for any of the OpenSSL datatypes β€” like X509, for example. and the macro DECLARE_PEM_rw? it expands to the set of declarations shown in the next four lines of the synopsis. iykyk ✨

these routines convert between local instances of ASN1 datatypes and the PEM encoding. for more on the templates, go look at ASN1_ITEM(3). for more on the lower-level routines these functions use, go look at PEM_read(3). 🫢

  • PEM_read_TYPE() β€” reads a PEM-encoded object of TYPE from the file fp and returns it. the cb and u parameters are exactly as described in pem_password_cb(3).
  • PEM_read_bio_TYPE() β€” same vibe as PEM_read_TYPE(), but it reads from the BIO bp.
  • PEM_write_TYPE() β€” writes the PEM encoding of the object a to the file fp.
  • PEM_write_bio_TYPE() β€” same energy, writes to the BIO bp.

πŸ’œ NOTES πŸ’œ

these functions make no assumption regarding the pass phrase they receive from the password callback. it will simply be treated as a byte sequence. that's it, that's the whole note, no cap πŸ’€


🌈 RETURN VALUES 🌈

  • PEM_read_TYPE() and PEM_read_bio_TYPE() return a pointer to an allocated object β€” which you should release by calling TYPE_free() β€” or NULL on error. so like, free it bestie, don't ghost your memory πŸŽ€
  • PEM_write_TYPE() and PEM_write_bio_TYPE() return 1 for success or 0 for failure.

πŸ“ SEE ALSO πŸ“

PEM_read(3), passphrase-encoding(7) β€” go read those too, they're iconic ✨


πŸ‘‘ HISTORY πŸ‘‘

these functions were deprecated in OpenSSL 3.0:

PEM_write_DHxparams(), PEM_write_bio_DHxparams(), PEM_read_ECPKParameters(), PEM_read_bio_ECPKParameters(), PEM_write_ECPKParameters(), PEM_write_bio_ECPKParameters(), PEM_read_EC_PUBKEY(), PEM_read_bio_EC_PUBKEY(), PEM_write_EC_PUBKEY(), PEM_write_bio_EC_PUBKEY(), PEM_read_ECPrivateKey(), PEM_read_bio_ECPrivateKey(), PEM_write_ECPrivateKey() and PEM_write_bio_ECPrivateKey().


Copyright 1998-2025 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>.


and that's the page, bestie 🫢 written for OpenSSL 3.5.9, dated 2026-09-29, filed under PEM_READ_CMS(3ossl). slay, go forth and encode responsibly πŸ’…βœ¨
πŸ“¦ where this page comes from