|  | =pod | 
|  |  | 
|  | =head1 NAME | 
|  |  | 
|  | d2i_X509, i2d_X509, d2i_X509_bio, d2i_X509_fp, i2d_X509_bio, | 
|  | i2d_X509_fp - X509 encode and decode functions | 
|  |  | 
|  | =head1 SYNOPSIS | 
|  |  | 
|  | #include <openssl/x509.h> | 
|  |  | 
|  | X509 *d2i_X509(X509 **px, const unsigned char **in, int len); | 
|  | int i2d_X509(X509 *x, unsigned char **out); | 
|  |  | 
|  | X509 *d2i_X509_bio(BIO *bp, X509 **x); | 
|  | X509 *d2i_X509_fp(FILE *fp, X509 **x); | 
|  |  | 
|  | int i2d_X509_bio(BIO *bp, X509 *x); | 
|  | int i2d_X509_fp(FILE *fp, X509 *x); | 
|  |  | 
|  | int i2d_re_X509_tbs(X509 *x, unsigned char **out); | 
|  |  | 
|  | =head1 DESCRIPTION | 
|  |  | 
|  | The X509 encode and decode routines encode and parse an | 
|  | B<X509> structure, which represents an X509 certificate. | 
|  |  | 
|  | d2i_X509() attempts to decode B<len> bytes at B<*in>. If | 
|  | successful a pointer to the B<X509> structure is returned. If an error | 
|  | occurred then B<NULL> is returned. If B<px> is not B<NULL> then the | 
|  | returned structure is written to B<*px>. If B<*px> is not B<NULL> | 
|  | then it is assumed that B<*px> contains a valid B<X509> | 
|  | structure and an attempt is made to reuse it. This "reuse" capability is present | 
|  | for historical compatibility but its use is B<strongly discouraged> (see BUGS | 
|  | below, and the discussion in the RETURN VALUES section). | 
|  |  | 
|  | If the call is successful B<*in> is incremented to the byte following the | 
|  | parsed data. | 
|  |  | 
|  | i2d_X509() encodes the structure pointed to by B<x> into DER format. | 
|  | If B<out> is not B<NULL> is writes the DER encoded data to the buffer | 
|  | at B<*out>, and increments it to point after the data just written. | 
|  | If the return value is negative an error occurred, otherwise it | 
|  | returns the length of the encoded data. | 
|  |  | 
|  | If B<*out> is B<NULL> memory will be | 
|  | allocated for a buffer and the encoded data written to it. In this | 
|  | case B<*out> is not incremented and it points to the start of the | 
|  | data just written. | 
|  |  | 
|  | d2i_X509_bio() is similar to d2i_X509() except it attempts | 
|  | to parse data from BIO B<bp>. | 
|  |  | 
|  | d2i_X509_fp() is similar to d2i_X509() except it attempts | 
|  | to parse data from FILE pointer B<fp>. | 
|  |  | 
|  | i2d_X509_bio() is similar to i2d_X509() except it writes | 
|  | the encoding of the structure B<x> to BIO B<bp> and it | 
|  | returns 1 for success and 0 for failure. | 
|  |  | 
|  | i2d_X509_fp() is similar to i2d_X509() except it writes | 
|  | the encoding of the structure B<x> to BIO B<bp> and it | 
|  | returns 1 for success and 0 for failure. | 
|  |  | 
|  | i2d_re_X509_tbs() is similar to i2d_X509() except it encodes | 
|  | only the TBSCertificate portion of the certificate. | 
|  |  | 
|  | =head1 NOTES | 
|  |  | 
|  | The letters B<i> and B<d> in for example B<i2d_X509> stand for | 
|  | "internal" (that is an internal C structure) and "DER". So | 
|  | B<i2d_X509> converts from internal to DER. The "re" in | 
|  | B<i2d_re_X509_tbs> stands for "re-encode", and ensures that a fresh | 
|  | encoding is generated in case the object has been modified after | 
|  | creation (see the BUGS section). | 
|  |  | 
|  | The functions can also understand B<BER> forms. | 
|  |  | 
|  | The actual X509 structure passed to i2d_X509() must be a valid | 
|  | populated B<X509> structure it can B<not> simply be fed with an | 
|  | empty structure such as that returned by X509_new(). | 
|  |  | 
|  | The encoded data is in binary form and may contain embedded zeroes. | 
|  | Therefore any FILE pointers or BIOs should be opened in binary mode. | 
|  | Functions such as strlen() will B<not> return the correct length | 
|  | of the encoded structure. | 
|  |  | 
|  | The ways that B<*in> and B<*out> are incremented after the operation | 
|  | can trap the unwary. See the B<WARNINGS> section for some common | 
|  | errors. | 
|  |  | 
|  | The reason for the auto increment behaviour is to reflect a typical | 
|  | usage of ASN1 functions: after one structure is encoded or decoded | 
|  | another will processed after it. | 
|  |  | 
|  | =head1 EXAMPLES | 
|  |  | 
|  | Allocate and encode the DER encoding of an X509 structure: | 
|  |  | 
|  | int len; | 
|  | unsigned char *buf; | 
|  |  | 
|  | buf = NULL; | 
|  | len = i2d_X509(x, &buf); | 
|  | if (len < 0) | 
|  | /* error */ | 
|  |  | 
|  | Attempt to decode a buffer: | 
|  |  | 
|  | X509 *x; | 
|  | unsigned char *buf, *p; | 
|  | int len; | 
|  |  | 
|  | /* Something to setup buf and len */ | 
|  | p = buf; | 
|  | x = d2i_X509(NULL, &p, len); | 
|  |  | 
|  | if (x == NULL) | 
|  | /* Some error */ | 
|  |  | 
|  | Alternative technique: | 
|  |  | 
|  | X509 *x; | 
|  | unsigned char *buf, *p; | 
|  | int len; | 
|  |  | 
|  | /* Something to setup buf and len */ | 
|  | p = buf; | 
|  | x = NULL; | 
|  |  | 
|  | if (!d2i_X509(&x, &p, len)) | 
|  | /* Some error */ | 
|  |  | 
|  |  | 
|  | =head1 WARNINGS | 
|  |  | 
|  | The use of temporary variable is mandatory. A common | 
|  | mistake is to attempt to use a buffer directly as follows: | 
|  |  | 
|  | int len; | 
|  | unsigned char *buf; | 
|  |  | 
|  | len = i2d_X509(x, NULL); | 
|  | buf = OPENSSL_malloc(len); | 
|  | if (buf == NULL) | 
|  | /* error */ | 
|  |  | 
|  | i2d_X509(x, &buf); | 
|  | /* Other stuff ... */ | 
|  | OPENSSL_free(buf); | 
|  |  | 
|  | This code will result in B<buf> apparently containing garbage because | 
|  | it was incremented after the call to point after the data just written. | 
|  | Also B<buf> will no longer contain the pointer allocated by OPENSSL_malloc() | 
|  | and the subsequent call to OPENSSL_free() may well crash. | 
|  |  | 
|  | Another trap to avoid is misuse of the B<xp> argument to d2i_X509(): | 
|  |  | 
|  | X509 *x; | 
|  |  | 
|  | if (!d2i_X509(&x, &p, len)) | 
|  | /* Some error */ | 
|  |  | 
|  | This will probably crash somewhere in d2i_X509(). The reason for this | 
|  | is that the variable B<x> is uninitialized and an attempt will be made to | 
|  | interpret its (invalid) value as an B<X509> structure, typically causing | 
|  | a segmentation violation. If B<x> is set to NULL first then this will not | 
|  | happen. | 
|  |  | 
|  | =head1 BUGS | 
|  |  | 
|  | In some versions of OpenSSL the "reuse" behaviour of d2i_X509() when | 
|  | B<*px> is valid is broken and some parts of the reused structure may | 
|  | persist if they are not present in the new one. As a result the use | 
|  | of this "reuse" behaviour is strongly discouraged. | 
|  |  | 
|  | i2d_X509() will not return an error in many versions of OpenSSL, | 
|  | if mandatory fields are not initialized due to a programming error | 
|  | then the encoded structure may contain invalid data or omit the | 
|  | fields entirely and will not be parsed by d2i_X509(). This may be | 
|  | fixed in future so code should not assume that i2d_X509() will | 
|  | always succeed. | 
|  |  | 
|  | The encoding of the TBSCertificate portion of a certificate is cached | 
|  | in the B<X509> structure internally to improve encoding performance | 
|  | and to ensure certificate signatures are verified correctly in some | 
|  | certificates with broken (non-DER) encodings. | 
|  |  | 
|  | Any function which encodes an X509 structure such as i2d_X509(), | 
|  | i2d_X509_fp() or i2d_X509_bio() may return a stale encoding if the | 
|  | B<X509> structure has been modified after deserialization or previous | 
|  | serialization. | 
|  |  | 
|  | If, after modification, the B<X509> object is re-signed with X509_sign(), | 
|  | the encoding is automatically renewed. Otherwise, the encoding of the | 
|  | TBSCertificate portion of the B<X509> can be manually renewed by calling | 
|  | i2d_re_X509_tbs(). | 
|  |  | 
|  | =head1 RETURN VALUES | 
|  |  | 
|  | d2i_X509(), d2i_X509_bio() and d2i_X509_fp() return a valid B<X509> structure | 
|  | or B<NULL> if an error occurs. The error code that can be obtained by | 
|  | L<ERR_get_error(3)>. If the "reuse" capability has been used | 
|  | with a valid X509 structure being passed in via B<px> then the object is not | 
|  | freed in the event of error but may be in a potentially invalid or inconsistent | 
|  | state. | 
|  |  | 
|  | i2d_X509() returns the number of bytes successfully encoded or a negative | 
|  | value if an error occurs. The error code can be obtained by | 
|  | L<ERR_get_error(3)>. | 
|  |  | 
|  | i2d_X509_bio() and i2d_X509_fp() return 1 for success and 0 if an error | 
|  | occurs The error code can be obtained by L<ERR_get_error(3)>. | 
|  |  | 
|  | =head1 SEE ALSO | 
|  |  | 
|  | L<ERR_get_error(3)> | 
|  | L<X509_CRL_get0_by_serial(3)>, | 
|  | L<X509_get0_signature(3)>, | 
|  | L<X509_get_ext_d2i(3)>, | 
|  | L<X509_get_extension_flags(3)>, | 
|  | L<X509_get_pubkey(3)>, | 
|  | L<X509_get_subject_name(3)>, | 
|  | L<X509_get_version(3)>, | 
|  | L<X509_NAME_add_entry_by_txt(3)>, | 
|  | L<X509_NAME_ENTRY_get_object(3)>, | 
|  | L<X509_NAME_get_index_by_NID(3)>, | 
|  | L<X509_NAME_print_ex(3)>, | 
|  | L<X509_new(3)>, | 
|  | L<X509_sign(3)>, | 
|  | L<X509V3_get_d2i(3)>, | 
|  | L<X509_verify_cert(3)> | 
|  |  | 
|  | =cut |