X.509 public and private key handling -- SSLeay 0.9.0b -- January 1999

NAME

RSAPublicKey_dup, d2i_RSAPublicKey_fp, i2d_RSAPublicKey_fp, d2i_RSAPublicKey_bio,
i2d_RSAPublicKey_bio, RSAPrivateKey_dup, d2i_RSAPrivateKey_fp, i2d_RSAPrivateKey_fp,
d2i_RSAPrivateKey_bio, i2d_RSAPrivateKey_bio, d2i_DSAPrivateKey_fp, i2d_DSAPrivateKey_fp,
d2i_DSAPrivateKey_bio, i2d_DSAPrivateKey_bio, X509_PKEY_new, X509_PKEY_free,
i2d_X509_PKEY, d2i_X509_PKEY, X509_PUBKEY_set, X509_PUBKEY_get,
X509_get_pubkey_parameters -- X.509 public and private key handling

SYNOPSIS

#include "x509.h"

X509_PKEY *X509_PKEY_new();

void X509_PKEY_free(a)
X509_PKEY *a;

int i2d_X509_PKEY(a, pp)
X509_PKEY *a;
unsigned char **pp;

X509_PKEY *d2i_X509_PKEY(a, pp, length)
X509_PKEY **a;
unsigned char **pp;
long length;

int X509_PUBKEY_set(x, pkey)
X509_PUBKEY **x;
EVP_PKEY *pkey;

EVP_PKEY *X509_PUBKEY_get(key)
X509_PUBKEY *key;

int X509_get_pubkey_parameters(pkey, chain)
EVP_PKEY *pkey;
STACK *chain;

DESCRIPTION

The functions that deal with RSAPublicKey and RSAPrivateKey all operate on an RSA structure. That structure, and other functions that use RSAPrivateKey and RSAPublicKey are defined in RSA encryption.

These functions are all macros:

#define RSAPublicKey_dup(rsa) 
  (RSA *)ASN1_dup((int (*)())i2d_RSAPublicKey,(char *(*)())d2i_RSAPublicKey,(char *)rsa)
#define d2i_RSAPublicKey_fp(fp,rsa) 
  (RSA *)ASN1_d2i_fp((char *(*)())RSA_new,(char *(*)())d2i_RSAPublicKey, 
  (fp),(unsigned char **)(rsa))
#define i2d_RSAPublicKey_fp(fp,rsa) 
  ASN1_i2d_fp(i2d_RSAPublicKey,fp,(unsigned char *)rsa)
#define d2i_RSAPublicKey_bio(bp,rsa) 
  (RSA *)ASN1_d2i_bio((char *(*)())RSA_new,(char *(*)())d2i_RSAPublicKey, 
  (bp),(unsigned char **)(rsa))
#define i2d_RSAPublicKey_bio(bp,rsa) 
  ASN1_i2d_bio(i2d_RSAPublicKey,bp,(unsigned char *)rsa)

#define RSAPrivateKey_dup(rsa) 
  (RSA *)ASN1_dup((int (*)())i2d_RSAPrivateKey,(char *(*)())d2i_RSAPrivateKey,(char *)rsa)
#define d2i_RSAPrivateKey_fp(fp,rsa) 
  (RSA *)ASN1_d2i_fp((char *(*)())RSA_new,(char *(*)())d2i_RSAPrivateKey, 
  (fp), (unsigned char **)(rsa))
#define i2d_RSAPrivateKey_fp(fp,rsa) 
  ASN1_i2d_fp(i2d_RSAPrivateKey,fp,(unsigned char *)rsa)
#define d2i_RSAPrivateKey_bio(bp,rsa) 
  (RSA *)ASN1_d2i_bio((char *(*)())RSA_new,(char *(*)())d2i_RSAPrivateKey,
  (bp),(unsigned char **)(rsa))
#define i2d_RSAPrivateKey_bio(bp,rsa) 
  ASN1_i2d_bio(i2d_RSAPrivateKey,bp,(unsigned char *)rsa)

#define d2i_DSAPrivateKey_fp(fp,dsa) 
  (DSA *)ASN1_d2i_fp((char *(*)())DSA_new,(char *(*)())d2i_DSAPrivateKey,
  (fp),(unsigned char **)(dsa))
#define i2d_DSAPrivateKey_fp(fp,dsa) 
  ASN1_i2d_fp(i2d_DSAPrivateKey,fp,(unsigned char *)dsa)
#define d2i_DSAPrivateKey_bio(bp,dsa) 
  (DSA *)ASN1_d2i_bio((char *(*)())DSA_new,(char *(*)())d2i_DSAPrivateKey, 
  (bp),(unsigned char **)(dsa))
#define i2d_DSAPrivateKey_bio(bp,dsa) 
  ASN1_i2d_bio(i2d_DSAPrivateKey,bp,(unsigned char *)dsa)

The dup functions make a copy of the structure that the argument points to and return it, or NULL on error.

The d2i_fp functions read from fp as much data as they can, in DER-encoded form, and then use the appropriate d2i conversion function to translate that into a structure of the proper sort, which is placed in the second argument to the function, if that argument is not NULL, or into a newly malloced structure otherwise. A pointer to the populated structure is returned, or NULL on error.

The i2d_fp functions convert the structure pointed to by the second argument to the function to DER-encoded form and write it out to the file pointer fp.

They return 1 on success and 0 on error.

The d2i_bio functions do exactly what the d2i_fp functions do, except that they read from a BIO instead of a file pointer.

The i2d_bio functions do exactly what the i2d_fp functions do, except that they write to a BIO instead of a file pointer.

The following functions deal with an X509_PKEY structure. Here's the definition:

typedef struct private_key_st
{
        int version;
        /* The PKCS#8 data types */
        X509_ALGOR *enc_algor;
        ASN1_OCTET_STRING *enc_pkey;    /* encrypted pub key */

        /* When decrypted, the following will not be NULL */
        EVP_PKEY *dec_pkey;

        /* used to encrypt and decrypt */
        int key_length;
        char *key_data;
        int key_free;   /* true if we should auto free key_data */

        /* expanded version of 'enc_algor' */
        EVP_CIPHER_INFO cipher;

        int references;
} X509_PKEY;

This structure is a subfield in the X509_INFO structure; see X.509 miscellaneous functions for more on the X509_INFO structure and functions that use it.

X509_PKEY_new creates a new X509_PKEY structure and returns a pointer to it, or NULL on error.

X509_PKEY_free frees a.

i2d_X509_PKEY converts an X509_PKEY structure pointed to by a to DER-encoded form; it places the results in *pp and then increments *pp to point to the end of the byte string it has just written, so you can call several i2d functions in a row. It returns the number of bytes written to the string or 0 on error.

See ASN.1 conversion to and from DER-encoded form for more on i2d functions.

d2i_X509_PKEY converts length bytes of the DER-encoded string in *pp to an X509_PKEY structure, updates *pp to point to the next byte to be processed, places the new X509 structure in *a, and returns it, or NULL on error.

See ASN.1 conversion to and from DER-encoded form for more on d2i functions.

The following functions deal with an X509_PUBKEY. Here's its definition:

typedef struct X509_pubkey_st
{
   X509_ALGOR *algor;
   ASN1_BIT_STRING *public_key;  /* DER-encoded form of pkey->pkey 
                                    is the data in this string */
   struct evp_pkey_st *pkey;     /* EVP_PKEY*/
} X509_PUBKEY;

The generic routines for new, free, and i2d/d2i conversion for X509_PUBKEY are discussed in X.509 Certificate Substructures; the functions specific to X509_PUBKEY only are described here.

X509_PUBKEY_set creates a new X509_PUBKEY structures, fills the public_key subfield with the DER-encoded form of pkey->pkey (the public key part only), fills the algor subfield from pkey->type, and if needed copies the parameters (only for a DSA key). A pointer to the new structure is placed into *x. The function returns 1 on success or 0 on error. If the key is neither a DSA key nor an RSA key an error will be flagged and 0 will be returned.

I should discuss the CRYPTO_add call that it does. But I won't.

X509_PUBKEY_get either immediately returns a pointer to the pkey subfield of key, or, if that subfield has not been filled in yet, fills it in by converting key->public_key to an EVP_PKEY and using it to fill in the appropriate parts, and then returns the pointer.

It returns NULL on error.

This function is used in the verify routines.

X509_get_pubkey_parameters wades through the whole stack of certificates chain looking for the first one where we have DSA parameters. It then copies these same parameters into the public keys of the certificates earlier in the stack (if any). It copies them into pkey too if pkey is not NULL. It returns 1 on success and 0 on error. In fact, the one place it is invoked, in X509_verify_cert, the return value is never checked. Oh well.