X509_type_new
X509_type_free
i2d_X509_type
d2i_X509_type
where type is one of:
ALGOR VAL PUBKEY SIG REQ_INFO ATTRIBUTE EXTENSION NAME NAME_ENTRY
This does not go into depth into X509_NAME, X509_NAME_ENTRY, X509_PUBKEY, or the X.509v3 extensions, which are covered in other documents; see X509_NAME Handling, X509_NAME_ENTRY Handling, X509_PUBKEY Handling, and X.509 Extension Handling for more details.
Here's the ASN.1 for the certificate's subfields:
Version ::= INTEGER { v1(0), v2(1), v3(2) } CertificateSerialNumber ::= INTEGER AlgorithmIdentifier ::= SEQUENCE { algorithm OBJECT IDENTIFIER, parameters ANY DEFINED BY algorithm OPTIONAL } -- contains a value of the type -- registered for use with the -- algorithm object identifier value Name ::= CHOICE { -- only one possibility for now -- rdnSequence RDNSequence } RDNSequence ::= SEQUENCE OF RelativeDistinguishedName DistinguishedName ::= RDNSequence RelativeDistinguishedName ::= SET SIZE (1 .. MAX) OF AttributeTypeAndValue AttributeTypeAndValue ::= SEQUENCE { type AttributeType, value AttributeValue } AttributeType ::= OBJECT IDENTIFIER AttributeValue ::= ANY Validity ::= SEQUENCE { notBefore Time, notAfter Time } Time ::= CHOICE { utcTime UTCTime, generalTime GeneralizedTime } UniqueIdentifier ::= BIT STRING SubjectPublicKeyInfo ::= SEQUENCE { algorithm AlgorithmIdentifier, subjectPublicKey BIT STRING } Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension Extension ::= SEQUENCE { extnID OBJECT IDENTIFIER, critical BOOLEAN DEFAULT FALSE, extnValue OCTET STRING }
Now let's look at X509 subfields as the library defines them:
typedef struct X509_algor_st { ASN1_OBJECT *algorithm; ASN1_TYPE *parameter; } X509_ALGOR; typedef struct X509_val_st { ASN1_UTCTIME *notBefore; ASN1_UTCTIME *notAfter; } X509_VAL; typedef struct X509_pubkey_st { X509_ALGOR *algor; ASN1_BIT_STRING *public_key; struct evp_pkey_st /* EVP_PKEY*/ *pkey; } X509_PUBKEY; typedef struct X509_sig_st { X509_ALGOR *algor; ASN1_OCTET_STRING *digest; } X509_SIG; typedef struct X509_name_entry_st { ASN1_OBJECT *object; ASN1_STRING *value; int set; int size; /* temp variable */ } X509_NAME_ENTRY; typedef struct X509_name_st { STACK *entries; /* of X509_NAME_ENTRY */ int modified; /* true if 'bytes' needs to be built */ #ifdef HEADER_BUFFER_H BUF_MEM *bytes; #else char *bytes; #endif unsigned long hash; /* Keep the hash around for lookups */ } X509_NAME; typedef struct X509_extension_st { ASN1_OBJECT *object; short critical; short netscape_hack; ASN1_OCTET_STRING *value; long argl; /* used when decoding */ char *argp; /* used when decoding */ void (*ex_free)(); /* clear argp stuff */ } X509_EXTENSION;
The new functions all create a new structure of the type specified by the function and return a pointer to it; if memory cannot be allocated they return NULL.
The free functions all free the memory of the object pointed to by the argument, unless the argument is NULL, in which case they do nothing.
The i2d functions all convert a structure of the appropriate type pointed to by a to DER-encoded form; they place the results in *pp and then increment *pp to point to the end of the byte string it has just written, so you can call several i2d functions in a row. They return 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.
The d2i functions all convert length bytes of the DER-encoded string in *pp to a structure of the appropriate type, update *pp to point to the next byte to be processed, place a pointer to the new structure in a, and return it, or NULL on error.
See ASN.1 conversion to and from DER-encoded form for more on d2i functions.