.\" $OpenBSD: PEM_read_bio_PrivateKey.3,v 1.23 2024/09/02 08:04:32 tb Exp $ .\" full merge up to: .\" OpenSSL man3/PEM_read_bio_PrivateKey.pod 18bad535 Apr 9 15:13:55 2019 +0100 .\" OpenSSL man3/PEM_read_CMS.pod 83cf7abf May 29 13:07:08 2018 +0100 .\" .\" This file was written by Dr. Stephen Henson . .\" Copyright (c) 2001-2004, 2009, 2013-2016 The OpenSSL Project. .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in .\" the documentation and/or other materials provided with the .\" distribution. .\" .\" 3. All advertising materials mentioning features or use of this .\" software must display the following acknowledgment: .\" "This product includes software developed by the OpenSSL Project .\" for use in the OpenSSL Toolkit. (http://www.openssl.org/)" .\" .\" 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to .\" endorse or promote products derived from this software without .\" prior written permission. For written permission, please contact .\" openssl-core@openssl.org. .\" .\" 5. Products derived from this software may not be called "OpenSSL" .\" nor may "OpenSSL" appear in their names without prior written .\" permission of the OpenSSL Project. .\" .\" 6. Redistributions of any form whatsoever must retain the following .\" acknowledgment: .\" "This product includes software developed by the OpenSSL Project .\" for use in the OpenSSL Toolkit (http://www.openssl.org/)" .\" .\" THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY .\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR .\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR .\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, .\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT .\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; .\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, .\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED .\" OF THE POSSIBILITY OF SUCH DAMAGE. .\" .Dd $Mdocdate: September 2 2024 $ .Dt PEM_READ_BIO_PRIVATEKEY 3 .Os .Sh NAME .Nm PEM_read_bio_PrivateKey , .Nm PEM_read_PrivateKey , .Nm PEM_write_bio_PrivateKey , .Nm PEM_write_PrivateKey , .Nm PEM_write_bio_PKCS8PrivateKey , .Nm PEM_write_PKCS8PrivateKey , .Nm PEM_write_bio_PKCS8PrivateKey_nid , .Nm PEM_write_PKCS8PrivateKey_nid , .Nm PEM_read_bio_PKCS8 , .Nm PEM_read_PKCS8 , .Nm PEM_write_bio_PKCS8 , .Nm PEM_write_PKCS8 , .Nm PEM_read_bio_PKCS8_PRIV_KEY_INFO , .Nm PEM_read_PKCS8_PRIV_KEY_INFO , .Nm PEM_write_bio_PKCS8_PRIV_KEY_INFO , .Nm PEM_write_PKCS8_PRIV_KEY_INFO , .Nm PEM_read_bio_PUBKEY , .Nm PEM_read_PUBKEY , .Nm PEM_write_bio_PUBKEY , .Nm PEM_write_PUBKEY , .Nm PEM_read_bio_RSAPrivateKey , .Nm PEM_read_RSAPrivateKey , .Nm PEM_write_bio_RSAPrivateKey , .Nm PEM_write_RSAPrivateKey , .Nm PEM_read_bio_RSAPublicKey , .Nm PEM_read_RSAPublicKey , .Nm PEM_write_bio_RSAPublicKey , .Nm PEM_write_RSAPublicKey , .Nm PEM_read_bio_RSA_PUBKEY , .Nm PEM_read_RSA_PUBKEY , .Nm PEM_write_bio_RSA_PUBKEY , .Nm PEM_write_RSA_PUBKEY , .Nm PEM_read_bio_DSAPrivateKey , .Nm PEM_read_DSAPrivateKey , .Nm PEM_write_bio_DSAPrivateKey , .Nm PEM_write_DSAPrivateKey , .Nm PEM_read_bio_DSA_PUBKEY , .Nm PEM_read_DSA_PUBKEY , .Nm PEM_write_bio_DSA_PUBKEY , .Nm PEM_write_DSA_PUBKEY , .Nm PEM_read_bio_DSAparams , .Nm PEM_read_DSAparams , .Nm PEM_write_bio_DSAparams , .Nm PEM_write_DSAparams , .Nm PEM_read_bio_DHparams , .Nm PEM_read_DHparams , .Nm PEM_write_bio_DHparams , .Nm PEM_write_DHparams , .Nm PEM_read_bio_ECPKParameters , .Nm PEM_read_ECPKParameters , .Nm PEM_write_bio_ECPKParameters , .Nm PEM_write_ECPKParameters , .Nm PEM_read_bio_ECPrivateKey , .Nm PEM_read_ECPrivateKey , .Nm PEM_write_bio_ECPrivateKey , .Nm PEM_write_ECPrivateKey , .Nm PEM_read_bio_EC_PUBKEY , .Nm PEM_read_EC_PUBKEY , .Nm PEM_write_bio_EC_PUBKEY , .Nm PEM_write_EC_PUBKEY , .Nm PEM_read_bio_X509 , .Nm PEM_read_X509 , .Nm PEM_write_bio_X509 , .Nm PEM_write_X509 , .Nm PEM_read_bio_X509_AUX , .Nm PEM_read_X509_AUX , .Nm PEM_write_bio_X509_AUX , .Nm PEM_write_X509_AUX , .Nm PEM_read_bio_X509_REQ , .Nm PEM_read_X509_REQ , .Nm PEM_write_bio_X509_REQ , .Nm PEM_write_X509_REQ , .Nm PEM_write_bio_X509_REQ_NEW , .Nm PEM_write_X509_REQ_NEW , .Nm PEM_read_bio_X509_CRL , .Nm PEM_read_X509_CRL , .Nm PEM_write_bio_X509_CRL , .Nm PEM_write_X509_CRL , .Nm PEM_read_bio_PKCS7 , .Nm PEM_read_PKCS7 , .Nm PEM_write_bio_PKCS7 , .Nm PEM_write_PKCS7 , .Nm PEM_read_CMS , .Nm PEM_read_bio_CMS , .Nm PEM_write_CMS , .Nm PEM_write_bio_CMS .Nd PEM routines .Sh SYNOPSIS .In openssl/pem.h .Ft EVP_PKEY * .Fo PEM_read_bio_PrivateKey .Fa "BIO *bp" .Fa "EVP_PKEY **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft EVP_PKEY * .Fo PEM_read_PrivateKey .Fa "FILE *fp" .Fa "EVP_PKEY **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft int .Fo PEM_write_bio_PrivateKey .Fa "BIO *bp" .Fa "EVP_PKEY *x" .Fa "const EVP_CIPHER *enc" .Fa "unsigned char *kstr" .Fa "int klen" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft int .Fo PEM_write_PrivateKey .Fa "FILE *fp" .Fa "EVP_PKEY *x" .Fa "const EVP_CIPHER *enc" .Fa "unsigned char *kstr" .Fa "int klen" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft int .Fo PEM_write_bio_PKCS8PrivateKey .Fa "BIO *bp" .Fa "EVP_PKEY *x" .Fa "const EVP_CIPHER *enc" .Fa "char *kstr" .Fa "int klen" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft int .Fo PEM_write_PKCS8PrivateKey .Fa "FILE *fp" .Fa "EVP_PKEY *x" .Fa "const EVP_CIPHER *enc" .Fa "char *kstr" .Fa "int klen" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft int .Fo PEM_write_bio_PKCS8PrivateKey_nid .Fa "BIO *bp" .Fa "EVP_PKEY *x" .Fa "int nid" .Fa "char *kstr" .Fa "int klen" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft int .Fo PEM_write_PKCS8PrivateKey_nid .Fa "FILE *fp" .Fa "EVP_PKEY *x" .Fa "int nid" .Fa "char *kstr" .Fa "int klen" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft X509_SIG * .Fo PEM_read_bio_PKCS8 .Fa "BIO *bp" .Fa "X509_SIG **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft X509_SIG * .Fo PEM_read_PKCS8 .Fa "FILE *fp" .Fa "X509_SIG **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft int .Fo PEM_write_bio_PKCS8 .Fa "BIO *bp" .Fa "X509_SIG *x" .Fc .Ft int .Fo PEM_write_PKCS8 .Fa "FILE *fp" .Fa "X509_SIG *x" .Fc .Ft PKCS8_PRIV_KEY_INFO * .Fo PEM_read_bio_PKCS8_PRIV_KEY_INFO .Fa "BIO *bp" .Fa "PKCS8_PRIV_KEY_INFO **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft PKCS8_PRIV_KEY_INFO * .Fo PEM_read_PKCS8_PRIV_KEY_INFO .Fa "FILE *fp" .Fa "PKCS8_PRIV_KEY_INFO **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft int .Fo PEM_write_bio_PKCS8_PRIV_KEY_INFO .Fa "BIO *bp" .Fa "PKCS8_PRIV_KEY_INFO *x" .Fc .Ft int .Fo PEM_write_PKCS8_PRIV_KEY_INFO .Fa "FILE *fp" .Fa "PKCS8_PRIV_KEY_INFO *x" .Fc .Ft EVP_PKEY * .Fo PEM_read_bio_PUBKEY .Fa "BIO *bp" .Fa "EVP_PKEY **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft EVP_PKEY * .Fo PEM_read_PUBKEY .Fa "FILE *fp" .Fa "EVP_PKEY **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft int .Fo PEM_write_bio_PUBKEY .Fa "BIO *bp" .Fa "EVP_PKEY *x" .Fc .Ft int .Fo PEM_write_PUBKEY .Fa "FILE *fp" .Fa "EVP_PKEY *x" .Fc .Ft RSA * .Fo PEM_read_bio_RSAPrivateKey .Fa "BIO *bp" .Fa "RSA **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft RSA * .Fo PEM_read_RSAPrivateKey .Fa "FILE *fp" .Fa "RSA **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft int .Fo PEM_write_bio_RSAPrivateKey .Fa "BIO *bp" .Fa "RSA *x" .Fa "const EVP_CIPHER *enc" .Fa "unsigned char *kstr" .Fa "int klen" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft int .Fo PEM_write_RSAPrivateKey .Fa "FILE *fp" .Fa "RSA *x" .Fa "const EVP_CIPHER *enc" .Fa "unsigned char *kstr" .Fa "int klen" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft RSA * .Fo PEM_read_bio_RSAPublicKey .Fa "BIO *bp" .Fa "RSA **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft RSA * .Fo PEM_read_RSAPublicKey .Fa "FILE *fp" .Fa "RSA **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft int .Fo PEM_write_bio_RSAPublicKey .Fa "BIO *bp" .Fa "RSA *x" .Fc .Ft int .Fo PEM_write_RSAPublicKey .Fa "FILE *fp" .Fa "RSA *x" .Fc .Ft RSA * .Fo PEM_read_bio_RSA_PUBKEY .Fa "BIO *bp" .Fa "RSA **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft RSA * .Fo PEM_read_RSA_PUBKEY .Fa "FILE *fp" .Fa "RSA **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft int .Fo PEM_write_bio_RSA_PUBKEY .Fa "BIO *bp" .Fa "RSA *x" .Fc .Ft int .Fo PEM_write_RSA_PUBKEY .Fa "FILE *fp" .Fa "RSA *x" .Fc .Ft DSA * .Fo PEM_read_bio_DSAPrivateKey .Fa "BIO *bp" .Fa "DSA **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft DSA * .Fo PEM_read_DSAPrivateKey .Fa "FILE *fp" .Fa "DSA **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft int .Fo PEM_write_bio_DSAPrivateKey .Fa "BIO *bp" .Fa "DSA *x" .Fa "const EVP_CIPHER *enc" .Fa "unsigned char *kstr" .Fa "int klen" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft int .Fo PEM_write_DSAPrivateKey .Fa "FILE *fp" .Fa "DSA *x" .Fa "const EVP_CIPHER *enc" .Fa "unsigned char *kstr" .Fa "int klen" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft DSA * .Fo PEM_read_bio_DSA_PUBKEY .Fa "BIO *bp" .Fa "DSA **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft DSA * .Fo PEM_read_DSA_PUBKEY .Fa "FILE *fp" .Fa "DSA **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft int .Fo PEM_write_bio_DSA_PUBKEY .Fa "BIO *bp" .Fa "DSA *x" .Fc .Ft int .Fo PEM_write_DSA_PUBKEY .Fa "FILE *fp" .Fa "DSA *x" .Fc .Ft DSA * .Fo PEM_read_bio_DSAparams .Fa "BIO *bp" .Fa "DSA **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft DSA * .Fo PEM_read_DSAparams .Fa "FILE *fp" .Fa "DSA **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft int .Fo PEM_write_bio_DSAparams .Fa "BIO *bp" .Fa "DSA *x" .Fc .Ft int .Fo PEM_write_DSAparams .Fa "FILE *fp" .Fa "DSA *x" .Fc .Ft DH * .Fo PEM_read_bio_DHparams .Fa "BIO *bp" .Fa "DH **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft DH * .Fo PEM_read_DHparams .Fa "FILE *fp" .Fa "DH **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft int .Fo PEM_write_bio_DHparams .Fa "BIO *bp" .Fa "DH *x" .Fc .Ft int .Fo PEM_write_DHparams .Fa "FILE *fp" .Fa "DH *x" .Fc .Ft EC_GROUP * .Fo PEM_read_bio_ECPKParameters .Fa "BIO *bp" .Fa "EC_GROUP **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft EC_GROUP * .Fo PEM_read_ECPKParameters .Fa "FILE *fp" .Fa "EC_GROUP **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft int .Fo PEM_write_bio_ECPKParameters .Fa "BIO *bp" .Fa "const EC_GROUP *x" .Fc .Ft int .Fo PEM_write_ECPKParameters .Fa "FILE *fp" .Fa "const EC_GROUP *x" .Fc .Ft EC_KEY * .Fo PEM_read_bio_ECPrivateKey .Fa "BIO *bp" .Fa "EC_KEY **key" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft EC_KEY * .Fo PEM_read_ECPrivateKey .Fa "FILE *fp" .Fa "EC_KEY **eckey" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft int .Fo PEM_write_bio_ECPrivateKey .Fa "BIO *bp" .Fa "EC_KEY *x" .Fa "const EVP_CIPHER *enc" .Fa "unsigned char *kstr" .Fa "int klen" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft int .Fo PEM_write_ECPrivateKey .Fa "FILE *fp" .Fa "EC_KEY *x" .Fa "const EVP_CIPHER *enc" .Fa "unsigned char *kstr" .Fa "int klen" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft EC_KEY * .Fo PEM_read_bio_EC_PUBKEY .Fa "BIO *bp" .Fa "EC_KEY **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft EC_KEY * .Fo PEM_read_EC_PUBKEY .Fa "FILE *fp" .Fa "EC_KEY **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft int .Fo PEM_write_bio_EC_PUBKEY .Fa "BIO *bp" .Fa "EC_KEY *x" .Fc .Ft int .Fo PEM_write_EC_PUBKEY .Fa "FILE *fp" .Fa "EC_KEY *x" .Fc .Ft X509 * .Fo PEM_read_bio_X509 .Fa "BIO *bp" .Fa "X509 **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft X509 * .Fo PEM_read_X509 .Fa "FILE *fp" .Fa "X509 **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft int .Fo PEM_write_bio_X509 .Fa "BIO *bp" .Fa "X509 *x" .Fc .Ft int .Fo PEM_write_X509 .Fa "FILE *fp" .Fa "X509 *x" .Fc .Ft X509 * .Fo PEM_read_bio_X509_AUX .Fa "BIO *bp" .Fa "X509 **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft X509 * .Fo PEM_read_X509_AUX .Fa "FILE *fp" .Fa "X509 **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft int .Fo PEM_write_bio_X509_AUX .Fa "BIO *bp" .Fa "X509 *x" .Fc .Ft int .Fo PEM_write_X509_AUX .Fa "FILE *fp" .Fa "X509 *x" .Fc .Ft X509_REQ * .Fo PEM_read_bio_X509_REQ .Fa "BIO *bp" .Fa "X509_REQ **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft X509_REQ * .Fo PEM_read_X509_REQ .Fa "FILE *fp" .Fa "X509_REQ **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft int .Fo PEM_write_bio_X509_REQ .Fa "BIO *bp" .Fa "X509_REQ *x" .Fc .Ft int .Fo PEM_write_X509_REQ .Fa "FILE *fp" .Fa "X509_REQ *x" .Fc .Ft int .Fo PEM_write_bio_X509_REQ_NEW .Fa "BIO *bp" .Fa "X509_REQ *x" .Fc .Ft int .Fo PEM_write_X509_REQ_NEW .Fa "FILE *fp" .Fa "X509_REQ *x" .Fc .Ft X509_CRL * .Fo PEM_read_bio_X509_CRL .Fa "BIO *bp" .Fa "X509_CRL **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft X509_CRL * .Fo PEM_read_X509_CRL .Fa "FILE *fp" .Fa "X509_CRL **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft int .Fo PEM_write_bio_X509_CRL .Fa "BIO *bp" .Fa "X509_CRL *x" .Fc .Ft int .Fo PEM_write_X509_CRL .Fa "FILE *fp" .Fa "X509_CRL *x" .Fc .Ft PKCS7 * .Fo PEM_read_bio_PKCS7 .Fa "BIO *bp" .Fa "PKCS7 **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft PKCS7 * .Fo PEM_read_PKCS7 .Fa "FILE *fp" .Fa "PKCS7 **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft int .Fo PEM_write_bio_PKCS7 .Fa "BIO *bp" .Fa "PKCS7 *x" .Fc .Ft int .Fo PEM_write_PKCS7 .Fa "FILE *fp" .Fa "PKCS7 *x" .Fc .In openssl/cms.h .Ft CMS_ContentInfo * .Fo PEM_read_CMS .Fa "FILE *fp" .Fa "CMS_ContentInfo **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft CMS_ContentInfo * .Fo PEM_read_bio_CMS .Fa "BIO *bp" .Fa "CMS_ContentInfo **x" .Fa "pem_password_cb *cb" .Fa "void *u" .Fc .Ft int .Fo PEM_write_CMS .Fa "FILE *fp" .Fa "const CMS_ContentInfo *x" .Fc .Ft int .Fo PEM_write_bio_CMS .Fa "BIO *bp" .Fa "const CMS_ContentInfo *x" .Fc .Sh DESCRIPTION The PEM functions read or write structures in PEM format. In this sense PEM format is simply base64-encoded data surrounded by header lines; see .Xr PEM_read 3 for more details. .Pp For more details about the meaning of arguments see the .Sx PEM function arguments section. .Pp Each operation has four functions associated with it. For brevity the term .Dq Ar TYPE No functions will be used to collectively refer to the .Fn PEM_read_bio_TYPE , .Fn PEM_read_TYPE , .Fn PEM_write_bio_TYPE , and .Fn PEM_write_TYPE functions. If no set of specific functions exists for a given type, .Xr PEM_ASN1_read 3 can be used instead. .Pp The .Sy PrivateKey functions read or write a private key in PEM format using an .Vt EVP_PKEY structure. The write routines use "traditional" private key format and can handle both RSA and DSA private keys. The read functions can additionally transparently handle PKCS#8 format encrypted and unencrypted keys too. .Pp .Fn PEM_write_bio_PKCS8PrivateKey and .Fn PEM_write_PKCS8PrivateKey write a private key in an .Vt EVP_PKEY structure in PKCS#8 .Vt EncryptedPrivateKeyInfo format using PKCS#5 v2.0 password based encryption algorithms. The .Fa enc argument specifies the encryption algorithm to use: unlike all other PEM routines, the encryption is applied at the PKCS#8 level and not in the PEM headers. If .Fa enc is .Dv NULL , then no encryption is used and a PKCS#8 .Vt PrivateKeyInfo structure is used instead. .Pp .Fn PEM_write_bio_PKCS8PrivateKey_nid and .Fn PEM_write_PKCS8PrivateKey_nid also write out a private key as a PKCS#8 .Vt EncryptedPrivateKeyInfo . However they use PKCS#5 v1.5 or PKCS#12 encryption algorithms instead. The algorithm to use is specified in the .Fa nid parameter and should be the NID of the corresponding OBJECT IDENTIFIER. .Pp The .Sy PKCS8 functions process an encrypted private key using an .Vt X509_SIG structure and the .Xr d2i_X509_SIG 3 function. .Pp The .Sy PKCS8_PRIV_KEY_INFO functions process a private key using a .Vt PKCS8_PRIV_KEY_INFO structure. .Pp The .Sy PUBKEY functions process a public key using an .Vt EVP_PKEY structure. The public key is encoded as an ASN.1 .Vt SubjectPublicKeyInfo structure. .Pp The .Sy RSAPrivateKey functions process an RSA private key using an .Vt RSA structure. They handle the same formats as the .Sy PrivateKey functions, but an error occurs if the private key is not RSA. .Pp The .Sy RSAPublicKey functions process an RSA public key using an .Vt RSA structure. The public key is encoded using a PKCS#1 .Vt RSAPublicKey structure. .Pp The .Sy RSA_PUBKEY functions also process an RSA public key using an .Vt RSA structure. However the public key is encoded using an ASN.1 .Vt SubjectPublicKeyInfo structure and an error occurs if the public key is not RSA. .Pp The .Sy DSAPrivateKey functions process a DSA private key using a .Vt DSA structure. They handle the same formats as the .Sy PrivateKey functions but an error occurs if the private key is not DSA. .Pp The .Sy DSA_PUBKEY functions process a DSA public key using a .Vt DSA structure. The public key is encoded using an ASN.1 .Vt SubjectPublicKeyInfo structure and an error occurs if the public key is not DSA. .Pp The .Sy DSAparams functions process DSA parameters using a .Vt DSA structure. The parameters are encoded using a Dss-Parms structure as defined in RFC 2459. .Pp The .Sy DHparams functions process DH parameters using a .Vt DH structure. The parameters are encoded using a PKCS#3 DHparameter structure. .Pp The .Sy ECPKParameters functions process EC parameters using an .Vt EC_GROUP structure and the .Xr d2i_ECPKParameters 3 function. .Pp The .Sy ECPrivateKey functions process an EC private key using an .Vt EC_KEY structure. .Pp The .Sy EC_PUBKEY functions process an EC public key using an .Vt EC_KEY structure. .Pp The .Sy X509 functions process an X509 certificate using an .Vt X509 structure. They will also process a trusted X509 certificate but any trust settings are discarded. .Pp The .Sy X509_AUX functions process a trusted X509 certificate using an .Vt X509 structure. .Pp The .Sy X509_REQ and .Sy X509_REQ_NEW functions process a PKCS#10 certificate request using an .Vt X509_REQ structure. The .Sy X509_REQ write functions use CERTIFICATE REQUEST in the header whereas the .Sy X509_REQ_NEW functions use NEW CERTIFICATE REQUEST (as required by some CAs). The .Sy X509_REQ read functions will handle either form so there are no .Sy X509_REQ_NEW read functions. .Pp The .Sy X509_CRL functions process an X509 CRL using an .Vt X509_CRL structure. .Pp The .Sy PKCS7 functions process a PKCS#7 .Vt ContentInfo using a .Vt PKCS7 structure. .Pp The .Sy CMS functions process a .Vt CMS_ContentInfo structure. .Pp The old .Sy PrivateKey write routines are retained for compatibility. New applications should write private keys using the .Fn PEM_write_bio_PKCS8PrivateKey or .Fn PEM_write_PKCS8PrivateKey routines because they are more secure (they use an iteration count of 2048 whereas the traditional routines use a count of 1) unless compatibility with older versions of OpenSSL is important. .Pp The .Sy PrivateKey read routines can be used in all applications because they handle all formats transparently. .Ss PEM function arguments The PEM functions have many common arguments. .Pp The .Fa bp parameter specifies the .Vt BIO to read from or write to. .Pp The .Fa fp parameter specifies the .Vt FILE pointer to read from or write to. .Pp The PEM read functions all take a pointer to pointer argument .Fa x and return a pointer of the same type. If .Fa x is .Dv NULL , then the parameter is ignored. If .Fa x is not .Dv NULL but .Pf * Fa x is .Dv NULL , then the structure returned will be written to .Pf * Fa x . If neither .Fa x nor .Pf * Fa x are .Dv NULL , then an attempt is made to reuse the structure at .Pf * Fa x , but see the .Sx BUGS and .Sx EXAMPLES sections. Irrespective of the value of .Fa x , a pointer to the structure is always returned, or .Dv NULL if an error occurred. .Pp The PEM functions which write private keys take an .Fa enc parameter, which specifies the encryption algorithm to use. Encryption is done at the PEM level. If this parameter is set to .Dv NULL , then the private key is written in unencrypted form. .Pp The optional arguments .Fa u and .Fa cb are a passphrase used for encrypting a PEM structure or a callback to obtain the passphrase; see .Xr pem_password_cb 3 for details. .Pp For the PEM write routines, if the .Fa kstr parameter is not .Dv NULL , then .Fa klen bytes at .Fa kstr are used as the passphrase and .Fa cb is ignored. .Ss PEM encryption format These old .Sy PrivateKey routines use a non-standard technique for encryption. .Pp The private key (or other data) takes the following form: .Bd -literal -offset indent -----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-CBC,3F17F5316E2BAC89 \&...base64 encoded data... -----END RSA PRIVATE KEY----- .Ed .Pp The line beginning with .Dq DEK-Info contains two comma separated pieces of information: the encryption algorithm name as used by .Xr EVP_get_cipherbyname 3 and an 8-byte salt encoded as a set of hexadecimal digits. .Pp After this is the base64-encoded encrypted data. .Pp The encryption key is determined using .Xr EVP_BytesToKey 3 , using the salt and an iteration count of 1. The IV used is the value of the salt and *not* the IV returned by .Xr EVP_BytesToKey 3 . .Sh RETURN VALUES The read routines return either a pointer to the structure read or .Dv NULL if an error occurred. .Pp The write routines return 1 for success or 0 for failure. .Sh EXAMPLES Although the PEM routines take several arguments, in almost all applications most of them are set to 0 or .Dv NULL . .Pp Read a certificate in PEM format from a .Vt BIO : .Bd -literal -offset indent X509 *x; x = PEM_read_bio_X509(bp, NULL, 0, NULL); if (x == NULL) { /* Error */ } .Ed .Pp Alternative method: .Bd -literal -offset indent X509 *x = NULL; if (!PEM_read_bio_X509(bp, &x, 0, NULL)) { /* Error */ } .Ed .Pp Write a certificate to a .Vt BIO : .Bd -literal -offset indent if (!PEM_write_bio_X509(bp, x)) { /* Error */ } .Ed .Pp Write an unencrypted private key to a .Vt FILE : .Bd -literal -offset indent if (!PEM_write_PrivateKey(fp, key, NULL, NULL, 0, 0, NULL)) { /* Error */ } .Ed .Pp Write a private key (using traditional format) to a .Vt BIO using triple DES encryption; the pass phrase is prompted for: .Bd -literal -offset indent if (!PEM_write_bio_PrivateKey(bp, key, EVP_des_ede3_cbc(), NULL, 0, 0, NULL)) { /* Error */ } .Ed .Pp Write a private key (using PKCS#8 format) to a .Vt BIO using triple DES encryption, using the pass phrase "hello": .Bd -literal -offset indent if (!PEM_write_bio_PKCS8PrivateKey(bp, key, EVP_des_ede3_cbc(), NULL, 0, 0, "hello")) { /* Error */ } .Ed .Pp Read a private key from a .Vt BIO using the pass phrase "hello": .Bd -literal -offset indent key = PEM_read_bio_PrivateKey(bp, NULL, 0, "hello"); if (key == NULL) { /* Error */ } .Ed .Pp Read a private key from a .Vt BIO using a pass phrase callback: .Bd -literal -offset indent key = PEM_read_bio_PrivateKey(bp, NULL, pass_cb, "My Private Key"); if (key == NULL) { /* Error */ } .Ed .Pp Skeleton pass phrase callback: .Bd -literal -offset indent int pass_cb(char *buf, int size, int rwflag, void *u) { char *tmp; size_t len; /* We'd probably do something else if 'rwflag' is 1 */ printf("Enter pass phrase for \e"%s\e"\en", u); /* * Instead of the following line, get the passphrase * from the user in some way. */ tmp = "hello"; if (tmp == NULL) /* An error occurred. */ return -1; len = strlen(tmp); if (len == 0) /* Treat an empty passphrase as an error, too. */ return -1; /* if too long, truncate */ if (len > size) len = size; memcpy(buf, tmp, len); return len; } .Ed .Sh SEE ALSO .Xr BIO_new 3 , .Xr DSA_new 3 , .Xr PEM_ASN1_read 3 , .Xr PEM_bytes_read_bio 3 , .Xr PEM_read 3 , .Xr PEM_read_SSL_SESSION 3 , .Xr PEM_write_bio_CMS_stream 3 , .Xr PEM_write_bio_PKCS7_stream 3 , .Xr PEM_X509_INFO_read 3 , .Xr RSA_new 3 , .Xr X509_CRL_new 3 , .Xr X509_REQ_new 3 , .Xr X509_SIG_new 3 .Sh HISTORY .Fn PEM_read_X509 and .Fn PEM_write_X509 appeared in SSLeay 0.4 or earlier. .Fn PEM_read_X509_REQ , .Fn PEM_write_X509_REQ , .Fn PEM_read_X509_CRL , and .Fn PEM_write_X509_CRL first appeared in SSLeay 0.4.4. .Fn PEM_read_RSAPrivateKey , .Fn PEM_write_RSAPrivateKey , .Fn PEM_read_DHparams , .Fn PEM_write_DHparams , .Fn PEM_read_PKCS7 , and .Fn PEM_write_PKCS7 first appeared in SSLeay 0.5.1. .Fn PEM_read_bio_PrivateKey , .Fn PEM_read_PrivateKey , .Fn PEM_read_bio_RSAPrivateKey , .Fn PEM_write_bio_RSAPrivateKey , .Fn PEM_read_bio_DSAPrivateKey , .Fn PEM_read_DSAPrivateKey , .Fn PEM_write_bio_DSAPrivateKey , .Fn PEM_write_DSAPrivateKey , .Fn PEM_read_bio_DHparams , .Fn PEM_write_bio_DHparams , .Fn PEM_read_bio_X509 , .Fn PEM_write_bio_X509 , .Fn PEM_read_bio_X509_REQ , .Fn PEM_write_bio_X509_REQ , .Fn PEM_read_bio_X509_CRL , .Fn PEM_write_bio_X509_CRL , .Fn PEM_read_bio_PKCS7 , and .Fn PEM_write_bio_PKCS7 first appeared in SSLeay 0.6.0. .Fn PEM_write_bio_PrivateKey , .Fn PEM_write_PrivateKey , .Fn PEM_read_bio_DSAparams , .Fn PEM_read_DSAparams , .Fn PEM_write_bio_DSAparams , and .Fn PEM_write_DSAparams first appeared in SSLeay 0.8.0. .Fn PEM_read_bio_RSAPublicKey , .Fn PEM_read_RSAPublicKey , .Fn PEM_write_bio_RSAPublicKey , and .Fn PEM_write_RSAPublicKey first appeared in SSLeay 0.8.1. All these functions have been available since .Ox 2.4 . .Pp .Fn PEM_write_bio_PKCS8PrivateKey , .Fn PEM_write_PKCS8PrivateKey , .Fn PEM_read_bio_PKCS8 , .Fn PEM_read_PKCS8 , .Fn PEM_write_bio_PKCS8 , .Fn PEM_write_PKCS8 , .Fn PEM_read_bio_PKCS8_PRIV_KEY_INFO , .Fn PEM_read_PKCS8_PRIV_KEY_INFO , .Fn PEM_write_bio_PKCS8_PRIV_KEY_INFO , .Fn PEM_write_PKCS8_PRIV_KEY_INFO , .Pp .Fn PEM_write_bio_PKCS8PrivateKey_nid , .Fn PEM_write_PKCS8PrivateKey_nid , .Fn PEM_read_bio_PUBKEY , .Fn PEM_read_PUBKEY , .Fn PEM_write_bio_PUBKEY , .Fn PEM_write_PUBKEY , .Fn PEM_read_bio_RSA_PUBKEY , .Fn PEM_read_RSA_PUBKEY , .Fn PEM_write_bio_RSA_PUBKEY , .Fn PEM_write_RSA_PUBKEY , .Fn PEM_read_bio_DSA_PUBKEY , .Fn PEM_read_DSA_PUBKEY , .Fn PEM_write_bio_DSA_PUBKEY , .Fn PEM_write_DSA_PUBKEY , .Fn PEM_write_bio_X509_REQ_NEW , .Fn PEM_write_X509_REQ_NEW , .Fn PEM_read_bio_X509_AUX , .Fn PEM_read_X509_AUX , .Fn PEM_write_bio_X509_AUX , and .Fn PEM_write_X509_AUX first appeared in OpenSSL 0.9.5 and have been available since .Ox 2.7 . .Pp .Fn PEM_read_bio_ECPKParameters , .Fn PEM_read_ECPKParameters , .Fn PEM_write_bio_ECPKParameters , .Fn PEM_write_ECPKParameters , .Fn PEM_read_bio_ECPrivateKey , .Fn PEM_read_ECPrivateKey , .Fn PEM_write_bio_ECPrivateKey , .Fn PEM_write_ECPrivateKey , .Fn PEM_read_bio_EC_PUBKEY , .Fn PEM_read_EC_PUBKEY , .Fn PEM_write_bio_EC_PUBKEY , and .Fn PEM_write_EC_PUBKEY first appeared in OpenSSL 0.9.8 and have been available since .Ox 4.5 . .Pp .Fn PEM_read_CMS , .Fn PEM_read_bio_CMS , .Fn PEM_write_CMS , and .Fn PEM_write_bio_CMS first appeared in OpenSSL 0.9.8h and have been available since .Ox 6.7 . .Sh CAVEATS A frequent cause of problems is attempting to use the PEM routines like this: .Bd -literal -offset indent X509 *x; PEM_read_bio_X509(bp, &x, 0, NULL); .Ed .Pp This is a bug because an attempt will be made to reuse the data at .Fa x , which is an uninitialised pointer. .Pp These functions make no assumption regarding the pass phrase received from the password callback. It will simply be treated as a byte sequence. .Sh BUGS The PEM read routines in some versions of OpenSSL will not correctly reuse an existing structure. Therefore .Pp .Dl PEM_read_bio_X509(bp, &x, 0, NULL); .Pp where .Fa x already contains a valid certificate may not work, whereas .Bd -literal -offset indent X509_free(x); x = PEM_read_bio_X509(bp, NULL, 0, NULL); .Ed .Pp is guaranteed to work.