PEM_ASN1_read() -- SSLeay 0.9.0b -- January 1999

NAME

PEM_read, PEM_read_bio, PEM_write, PEM_write_bio,
PEM_ASN1_read, PEM_ASN1_read_bio, PEM_ASN1_write, PEM_ASN1_write_bio,
PEM_X509_INFO_read, PEM_X509_INFO_read_bio,
PEM_X509_INFO_write_bio -- read/write PEM-formatted data

SYNOPSIS

#include "pem.h"

int PEM_read(fp, name, header, data, len)
FILE *fp;
char **name, **header;
unsigned char **data;
long *len;

int PEM_read_bio(bp, name, header, data, len)
BIO *bp;
char **name, **header;
unsigned char **data;
long *len;

int PEM_write(fp, name, header, data, len)
FILE *fp;
char *name, char *header;
unsigned char *data;
long len;

int PEM_write_bio(bp, header, data, len BIO *bp;
char *name, *header;
unsigned char *data;
long len;

char *PEM_ASN1_read(d2i, name, fp, x, cb)
char *(*d2i)(), *name, *fp, **x;
int (*cb)());

char *PEM_ASN1_read_bio(d2i, name, bp, x, cb)
char *(*d2i)(), *name, **x;
BIO *fp,
int (*cb)());

int PEM_ASN1_write(i2d, name, fp, x, enc, kstr, klen, callback)
int (*i2d)(), klen, (*callback)());
char *name, *x;
FILE *fp;
EVP_CIPHER *enc;
unsigned char *kstr;

int PEM_ASN1_write_bio(i2d, name, bp, x, enc, kstr, klen, callback)
) int (*i2d)(), klen, (*callback)());
char *name, *x;
BIO *fp;
EVP_CIPHER *enc;
unsigned char *kstr;

STACK *PEM_X509_INFO_read(fp, sk, cb)
FILE *fp;
STACK *sk;
int (*cb)();

STACK *PEM_X509_INFO_read_bio(bp, sk, cb)
BIO *bp;
STACK *sk;
int (*cb)();

int PEM_X509_INFO_write_bio(bp, xi, enc, kstr, klen, cb)
BIO *bp;
X509_INFO *xi;
EVP_CIPHER *enc;
unsigned char *kstr;
int klen;
int (*cb)();

DESCRIPTION

PEM_read reads a PEM-encoded message from the file <>fp.

It places a pointer to the object name from the BEGIN header into name, collects everything after the BEGIN line and up to the first blank line and places a pointer to it into header (or NULL if there is no header block), and then base64-encodes the message body and places a pointer to it in data with the length in len.

It returns 1 on success, or 0 on error.

PEM_read_bio does the same thing as PEM_read but uses a BIO instead of a file pointer. In fact PEM_read calls this function.

PEM_write puts together a BEGIN header using name, writes it to the file pointer fp, writes the data inheader out to fp followed by a blank line, and then base64encodes len bytes of the data in data and write it out to fp. Finally, it writes out an END header and returns 1 (or 0 on error).

PEM_write_bio does the same thing as PEM_write but uses a BIO instead of a file pointer. In fact PEM_write calls this function.

PEM_ASN1_read reads a PEM-encoded message using PEM_read; calls PEM_get_EVP_CIPHER_INFO to process any DEK-Info header that might be present, in particular determining the cipher that was used to encrypt the message body and retrieving the ivec from the header; calls PEM_do_header to decrypt the message body if it was encrypted (see the description of that function in PEM library routines for details about how a pass phrase (key string) is retrieved from the user or somewhere else); and then converts it to the internal type that x has, using the d2i function specified.

name must be the name that is in the BEGIN header of the PEM data, so somehow you must know this in advance.

x is dealt with as per the standard d2i function interface. See ASN.1 conversion to and from DER-encoded form for more information.

Note that since this function calls PEM_get_EVP_CIPHER_INFO, the appropriate cipher type (according to the name that is present in the PEM header) must be loaded into the static cipher and possibly static alias stack in order for the function to succeed; EVP cipher/digest lookup routines for more on this.

While any data type can be encrypted (see PEM_ASN1_write) usually only RSA private keys are encrypted.

This function can be used to read a series of objects from a file.

PEM_ASN1_read_bio does the same thing as PEM_ASN1_read except that it uses a BIO instead of a FILE. This is called by PEM_ASN1_read.

PEM_ASN1_write converts the object x to DER-encoding using the i2d routine specified. If enc is not NULL, it then uses enc as the cipher function to encrypt the data. kstr is used to generate the key; klen is the length of kstr. If enc is not NULL, but kstr is, the user will be prompted for a password to use in encrypting the data, using either callback or, if that is NULL, a default function. (See the description of PEM_do_header in PEM library routines for details about how a pass phrase (key string) is retrieved from the user or somewhere else.) The data is finally base64-encoded and written out to fp with BEGIN and END headers around it, and with Type-Proc header and DEK-Info header preceding the message body if the message was encrypted.

For those who are interested, the key is immedately zeroed before return. Also, the ivec used is randomly generated separately from the EVP_BytesToKey function.

See EVP handling for symmetric ciphers for a comprehensive list of cipher types available for encrypting the data.

PEM_ASN1_write_bio does the same thing as PEM_ASN1_write except that it uses a BIO instead of a FILE. This is called by PEM_ASN1_write.

STACK *PEM_X509_INFO_read(fp, sk, cb)
does exactly what PEM_ASN1_read does except that it calls the particular function d2i_X509 or PEM_STRING_X509_CRL or d2i_RSAPrivateKey or d2i_DSAPrivateKey depending on what it encounters in the BEGIN header. It will continue processing PEM-encoded objects from the file pointer fp until it encounters an error or there is no BEGIN header left in the file (possibly end of file encountered).

All of the processed objects are put onto a stack, a pointer to which is then returned to the user. The stack sk will be used for this if it is not NULL.

Since data may be encrypted, the user may be prompted for a password using the callback cb, as with PEM_ASN1_read.

STACK *PEM_X509_INFO_read_bio(bp, sk, cb)
does the same thing as PEM_X509_INFO_read except that it uses a BIO instead of a FILE. This is called by PEM_X509_INFO_read.

PEM_X509_INFO_write_bio does exactly the same thing as PEM_ASN1_write_bio except that it takes the X509_INFO xi and processes each part of it that is set, writing out a separate PEM-encoded message with headers for each of xi->x_pkey, and xi->gt;x509 and uses the appropriate i2d functions for these.

As with PEM_ASN1_write_bio, the user may be prompted for a password using the callback cb if the data is to be encrypted (i.e. if enc is not NULL). kstr is the passphrase to use if the user is not to be prompted, andklen is its length in bytes.

The following macros are provided as a convenience to the user:

#define PEM_write_SSL_SESSION(fp,x) 
  PEM_ASN1_write((int (*)())i2d_SSL_SESSION,
    PEM_STRING_SSL_SESSION,fp, (char *)x, NULL,NULL,0,NULL)
#define PEM_write_X509(fp,x) 
  PEM_ASN1_write((int (*)())i2d_X509,PEM_STRING_X509,fp,
    (char *)x, NULL,NULL,0,NULL)
#define PEM_write_X509_REQ(fp,x) 
  PEM_ASN1_write((int (*)())i2d_X509_REQ,PEM_STRING_X509_REQ,
    fp,(char *)x,NULL,NULL,0,NULL)
#define PEM_write_X509_CRL(fp,x)
  PEM_ASN1_write((int (*)())i2d_X509_CRL,PEM_STRING_X509_CRL,
    fp,(char *)x, NULL,NULL,0,NULL)
#define PEM_write_RSAPrivateKey(fp,x,enc,kstr,klen,cb)
  PEM_ASN1_write((int (*)())i2d_RSAPrivateKey,PEM_STRING_RSA,fp,
    (char *)x,enc,kstr,klen,cb)
#define PEM_write_RSAPublicKey(fp,x) 
  PEM_ASN1_write((int (*)())i2d_RSAPublicKey,
    PEM_STRING_RSA_PUBLIC,fp,(char *)x,NULL,NULL,0,NULL)
#define PEM_write_DSAPrivateKey(fp,x,enc,kstr,klen,cb) 
  PEM_ASN1_write((int (*)())i2d_DSAPrivateKey,PEM_STRING_DSA,fp,
    (char *)x,enc,kstr,klen,cb)
#define PEM_write_PrivateKey(bp,x,enc,kstr,klen,cb) 
  PEM_ASN1_write((int (*)())i2d_PrivateKey,
    (((x)->type == EVP_PKEY_DSA)?PEM_STRING_DSA:PEM_STRING_RSA),
    bp,(char *)x,enc,kstr,klen,cb)
#define PEM_write_PKCS7(fp,x) 
  PEM_ASN1_write((int (*)())i2d_PKCS7,PEM_STRING_PKCS7,fp, 
   (char *)x, NULL,NULL,0,NULL)
#define PEM_write_DHparams(fp,x) \
  PEM_ASN1_write((int (*)())i2d_DHparams,PEM_STRING_DHPARAMS,fp,
    (char *)x,NULL,NULL,0,NULL)

#define PEM_read_SSL_SESSION(fp,x,cb) 
  (SSL_SESSION *)PEM_ASN1_read((char *(*)())d2i_SSL_SESSION,
    PEM_STRING_SSL_SESSION,fp,(char **)x,cb)
#define PEM_read_X509(fp,x,cb) 
  (X509 *)PEM_ASN1_read((char *(*)())d2i_X509,PEM_STRING_X509,fp,(char **)x,cb)
#define PEM_read_X509_REQ(fp,x,cb) 
  (X509_REQ *)PEM_ASN1_read((char *(*)())d2i_X509_REQ,PEM_STRING_X509_REQ,
    fp,(char **)x,cb)
#define PEM_read_X509_CRL(fp,x,cb) 
  (X509_CRL *)PEM_ASN1_read((char *(*)())d2i_X509_CRL,PEM_STRING_X509_CRL,
    fp,(char **)x,cb)
#define PEM_read_RSAPrivateKey(fp,x,cb) 
  (RSA *)PEM_ASN1_read((char *(*)())d2i_RSAPrivateKey,PEM_STRING_RSA,
    fp,(char **)x,cb)
#define PEM_read_RSAPublicKey(fp,x,cb) 
  (RSA *)PEM_ASN1_read((char *(*)())d2i_RSAPublicKey,PEM_STRING_RSA_PUBLIC,
    fp,(char **)x,cb)
#define PEM_read_DSAPrivateKey(fp,x,cb) 
  (DSA *)PEM_ASN1_read((char *(*)())d2i_DSAPrivateKey,PEM_STRING_DSA,fp,
    (char **)x,cb)
#define PEM_read_PrivateKey(fp,x,cb) 
  (EVP_PKEY *)PEM_ASN1_read((char *(*)())d2i_PrivateKey,PEM_STRING_EVP_PKEY,
    fp,(char **)x,cb)
#define PEM_read_PKCS7(fp,x,cb) 
  (PKCS7 *)PEM_ASN1_read((char *(*)())d2i_PKCS7,PEM_STRING_PKCS7,fp,    
    (char **)x,cb)
#define PEM_read_DHparams(fp,x,cb) 
  (DH *)PEM_ASN1_read((char *(*)())d2i_DHparams,PEM_STRING_DHPARAMS,fp,
    (char **)x,cb)

#define PEM_write_bio_SSL_SESSION(bp,x)
  PEM_ASN1_write_bio((int (*)())i2d_SSL_SESSION, 
    PEM_STRING_SSL_SESSION,bp, (char *)x, NULL,NULL,0,NULL)
#define PEM_write_bio_X509(bp,x) 
  PEM_ASN1_write_bio((int (*)())i2d_X509,PEM_STRING_X509,bp, 
   (char *)x, NULL,NULL,0,NULL)
#define PEM_write_bio_X509_REQ(bp,x) PEM_ASN1_write_bio( 
  (int (*)())i2d_X509_REQ,PEM_STRING_X509_REQ,bp,(char *)x, 
    NULL,NULL,0,NULL)
#define PEM_write_bio_X509_CRL(bp,x) 
  PEM_ASN1_write_bio((int (*)())i2d_X509_CRL,PEM_STRING_X509_CRL,
    bp,(char *)x, NULL,NULL,0,NULL)
#define PEM_write_bio_RSAPrivateKey(bp,x,enc,kstr,klen,cb) 
  PEM_ASN1_write_bio((int (*)())i2d_RSAPrivateKey,PEM_STRING_RSA,
    bp,(char *)x,enc,kstr,klen,cb)
#define PEM_write_bio_RSAPublicKey(bp,x) 
  PEM_ASN1_write_bio((int (*)())i2d_RSAPublicKey, 
    PEM_STRING_RSA_PUBLIC,bp,(char *)x,NULL,NULL,0,NULL)
#define PEM_write_bio_DSAPrivateKey(bp,x,enc,kstr,klen,cb) 
  PEM_ASN1_write_bio((int (*)())i2d_DSAPrivateKey,PEM_STRING_DSA,
    bp,(char *)x,enc,kstr,klen,cb)
#define PEM_write_bio_PrivateKey(bp,x,enc,kstr,klen,cb) 
  PEM_ASN1_write_bio((int (*)())i2d_PrivateKey,
    (((x)->type == EVP_PKEY_DSA)?PEM_STRING_DSA:PEM_STRING_RSA),
    bp,(char *)x,enc,kstr,klen,cb)
#define PEM_write_bio_PKCS7(bp,x) 
  PEM_ASN1_write_bio((int (*)())i2d_PKCS7,PEM_STRING_PKCS7,bp, 
    (char *)x, NULL,NULL,0,NULL)
#define PEM_write_bio_DHparams(bp,x) 
  PEM_ASN1_write_bio((int (*)())i2d_DHparams,PEM_STRING_DHPARAMS,
    bp,(char *)x,NULL,NULL,0,NULL)
#define PEM_write_bio_DSAparams(bp,x) 
  PEM_ASN1_write_bio((int (*)())i2d_DSAparams, 
    PEM_STRING_DSAPARAMS,bp,(char *)x,NULL,NULL,0,NULL)

#define PEM_read_bio_SSL_SESSION(bp,x,cb) 
  (SSL_SESSION *)PEM_ASN1_read_bio((char *(*)())d2i_SSL_SESSION,
    PEM_STRING_SSL_SESSION,bp,(char **)x,cb)
#define PEM_read_bio_X509(bp,x,cb)
  (X509 *)PEM_ASN1_read_bio((char *(*)())d2i_X509,PEM_STRING_X509,bp,
    (char **)x,cb)
#define PEM_read_bio_X509_REQ(bp,x,cb)
  (X509_REQ *)PEM_ASN1_read_bio((char *(*)())d2i_X509_REQ,
    PEM_STRING_X509_REQ,bp,(char **)x,cb)
#define PEM_read_bio_X509_CRL(bp,x,cb)
  (X509_CRL *)PEM_ASN1_read_bio((char *(*)())d2i_X509_CRL,
    PEM_STRING_X509_CRL,bp,(char **)x,cb)
#define PEM_read_bio_RSAPrivateKey(bp,x,cb)
  (RSA *)PEM_ASN1_read_bio((char *(*)())d2i_RSAPrivateKey,
    PEM_STRING_RSA,bp,(char **)x,cb)
#define PEM_read_bio_RSAPublicKey(bp,x,cb)
  (RSA *)PEM_ASN1_read_bio((char *(*)())d2i_RSAPublicKey,
    PEM_STRING_RSA_PUBLIC,bp,(char **)x,cb)
#define PEM_read_bio_DSAPrivateKey(bp,x,cb)
  (DSA *)PEM_ASN1_read_bio((char *(*)())d2i_DSAPrivateKey,
    PEM_STRING_DSA,bp,(char **)x,cb)
#define PEM_read_bio_PrivateKey(bp,x,cb)
  (EVP_PKEY *)PEM_ASN1_read_bio((char *(*)())d2i_PrivateKey,
    PEM_STRING_EVP_PKEY,bp,(char **)x,cb)

#define PEM_read_bio_PKCS7(bp,x,cb)
  (PKCS7 *)PEM_ASN1_read_bio((char *(*)())d2i_PKCS7,PEM_STRING_PKCS7,
    bp,(char **)x,cb)
#define PEM_read_bio_DHparams(bp,x,cb)
  (DH *)PEM_ASN1_read_bio((char *(*)())d2i_DHparams,PEM_STRING_DHPARAMS,
    bp,(char **)x,cb)
#define PEM_read_bio_DSAparams(bp,x,cb)
  (DSA *)PEM_ASN1_read_bio((char *(*)())d2i_DSAparams,PEM_STRING_DSAPARAMS,
    bp,(char **)x,cb)