summaryrefslogtreecommitdiff
path: root/lib/libcrypto/man/PEM_read_bio_PrivateKey.3
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libcrypto/man/PEM_read_bio_PrivateKey.3')
-rw-r--r--lib/libcrypto/man/PEM_read_bio_PrivateKey.3997
1 files changed, 997 insertions, 0 deletions
diff --git a/lib/libcrypto/man/PEM_read_bio_PrivateKey.3 b/lib/libcrypto/man/PEM_read_bio_PrivateKey.3
new file mode 100644
index 00000000000..7dcea6dbe12
--- /dev/null
+++ b/lib/libcrypto/man/PEM_read_bio_PrivateKey.3
@@ -0,0 +1,997 @@
+.Dd $Mdocdate: November 3 2016 $
+.Dt PEM_READ_BIO_PRIVATEKEY 3
+.Os
+.Sh NAME
+.Nm PEM ,
+.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_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_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_bio_NETSCAPE_CERT_SEQUENCE ,
+.Nm PEM_read_NETSCAPE_CERT_SEQUENCE ,
+.Nm PEM_write_bio_NETSCAPE_CERT_SEQUENCE ,
+.Nm PEM_write_NETSCAPE_CERT_SEQUENCE
+.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 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 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
+.Ft NETSCAPE_CERT_SEQUENCE *
+.Fo PEM_read_bio_NETSCAPE_CERT_SEQUENCE
+.Fa "BIO *bp"
+.Fa "NETSCAPE_CERT_SEQUENCE **x"
+.Fa "pem_password_cb *cb"
+.Fa "void *u"
+.Fc
+.Ft NETSCAPE_CERT_SEQUENCE *
+.Fo PEM_read_NETSCAPE_CERT_SEQUENCE
+.Fa "FILE *fp"
+.Fa "NETSCAPE_CERT_SEQUENCE **x"
+.Fa "pem_password_cb *cb"
+.Fa "void *u"
+.Fc
+.Ft int
+.Fo PEM_write_bio_NETSCAPE_CERT_SEQUENCE
+.Fa "BIO *bp"
+.Fa "NETSCAPE_CERT_SEQUENCE *x"
+.Fc
+.Ft int
+.Fo PEM_write_NETSCAPE_CERT_SEQUENCE
+.Fa "FILE *fp"
+.Fa "NETSCAPE_CERT_SEQUENCE *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.
+.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 clarity the term
+.Dq Sy foobar No functions
+will be used to collectively refer to the
+.Fn PEM_read_bio_foobar ,
+.Fn PEM_read_foobar ,
+.Fn PEM_write_bio_foobar ,
+and
+.Fn PEM_write_foobar
+functions.
+.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 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 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 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
+(see NOTES section).
+.Pp
+The
+.Sy PUBKEY
+functions process a public key using an
+.Vt EVP_PKEY
+structure.
+The public key is encoded as a 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 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 a 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 a 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 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 ContentInfo using a
+.Vt PKCS7
+structure.
+.Pp
+The
+.Sy NETSCAPE_CERT_SEQUENCE
+functions process a Netscape Certificate Sequence using a
+.Vt NETSCAPE_CERT_SEQUENCE
+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
+.Fa cb
+argument is the callback to use when querying for the passphrase used
+for encrypted PEM structures (normally only private keys).
+.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.
+.Pp
+If the
+.Fa cb
+parameters is set to
+.Dv NULL
+and the
+.Fa u
+parameter is not
+.Dv NULL ,
+then the
+.Fa u
+parameter is interpreted as a null terminated string to use as the
+passphrase.
+If both
+.Fa cb
+and
+.Fa u
+are
+.Dv NULL ,
+then the default callback routine is used which will typically
+prompt for the passphrase on the current terminal with echoing
+turned off.
+.Pp
+The default passphrase callback is sometimes inappropriate (for example
+in a GUI application) so an alternative can be supplied.
+The callback routine has the following form:
+.Bd -filled -offset inset
+.Ft int
+.Fo cb
+.Fa "char *buf"
+.Fa "int size"
+.Fa "int rwflag"
+.Fa "void *u"
+.Fc
+.Ed
+.Pp
+.Fa buf
+is the buffer to write the passphrase to.
+.Fa size
+is the maximum length of the passphrase, i.e. the size of
+.Fa buf .
+.Fa rwflag
+is a flag which is set to 0 when reading and 1 when writing.
+A typical routine will ask the user to verify the passphrase (for
+example by prompting for it twice) if
+.Fa rwflag
+is 1.
+The
+.Fa u
+parameter has the same value as the
+.Fa u
+parameter passed to the PEM routine.
+It allows arbitrary data to be passed to the callback by the application
+(for example a window handle in a GUI application).
+The callback must return the number of characters in the passphrase
+or 0 if an error occurred.
+.Ss PEM encryption format
+This 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
+X509 *x;
+x = PEM_read_bio_X509(bp, NULL, 0, NULL);
+if (x == NULL) {
+ /* Error */
+}
+.Ed
+.Pp
+Alternative method:
+.Bd -literal
+X509 *x = NULL;
+if (!PEM_read_bio_X509(bp, &x, 0, NULL)) {
+ /* Error */
+}
+.Ed
+.Pp
+Write a certificate to a
+.Vt BIO :
+.Bd -literal
+if (!PEM_write_bio_X509(bp, x)) {
+ /* Error */
+}
+.Ed
+.Pp
+Write an unencrypted private key to a
+.Vt FILE :
+.Bd -literal
+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
+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
+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
+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
+key = PEM_read_bio_PrivateKey(bp, NULL, pass_cb, "My Private Key");
+if (key == NULL) {
+ /* Error */
+}
+.Ed
+.Pp
+Skeleton pass phrase callback:
+.Bd -literal
+int
+pass_cb(char *buf, int size, int rwflag, void *u)
+{
+ int len;
+ char *tmp;
+
+ /* We'd probably do something else if 'rwflag' is 1 */
+ printf("Enter pass phrase for \e"%s\e"\en", u);
+
+ /* get pass phrase, length 'len' into 'tmp' */
+ tmp = "hello";
+ len = strlen(tmp);
+
+ if (len == 0)
+ return 0;
+ /* if too long, truncate */
+ if (len > size)
+ len = size;
+ memcpy(buf, tmp, len);
+ return len;
+}
+.Ed
+.Sh CAVEATS
+A frequent cause of problems is attempting to use the PEM routines like
+this:
+.Bd -literal
+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.
+.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.