From 9946fceb9d9d00b020c44f0bd7d880a6a34d4b96 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Sat, 5 Oct 2002 23:30:10 +0000 Subject: [PATCH] Some docs relating to X509 ASN1 functions. Many other ASN1 functions are identical other than the actual structure being handled. --- doc/crypto/X509_new.pod | 37 +++++++ doc/crypto/d2i_X509.pod | 224 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 261 insertions(+) create mode 100644 doc/crypto/X509_new.pod create mode 100644 doc/crypto/d2i_X509.pod diff --git a/doc/crypto/X509_new.pod b/doc/crypto/X509_new.pod new file mode 100644 index 0000000000..6de81e3d1d --- /dev/null +++ b/doc/crypto/X509_new.pod @@ -0,0 +1,37 @@ +=pod + +=head1 NAME + +X509_new, X509_free, - X509 certificate ASN1 allocation functions + +=head1 SYNOPSIS + + X509 *X509_new(void); + void X509_free(X509 *a); + +=head1 DESCRIPTION + +The X509 ASN1 allocation routines, allocate and free an +X509 structure, which represents an X509 certificate. + +X509_new() allocates and initializes a X509 structure. + +X509_free() frees up the B structure B. + +=head1 RETURN VALUES + +If the allocation fails, X509_new() returns B and sets an error +code that can be obtained by L. +Otherwise it returns a pointer to the newly allocated structure. + +X509_free() returns no value. + +=head1 SEE ALSO + +L, L + +=head1 HISTORY + +X509_new() and X509_free() are available in all versions of SSLeay and OpenSSL. + +=cut diff --git a/doc/crypto/d2i_X509.pod b/doc/crypto/d2i_X509.pod new file mode 100644 index 0000000000..56dfe32864 --- /dev/null +++ b/doc/crypto/d2i_X509.pod @@ -0,0 +1,224 @@ +=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 + + X509 *d2i_X509(X509 **px, 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(X509 *x, BIO *bp); + int i2d_X509_fp(X509 *x, FILE *fp); + +=head1 DESCRIPTION + +The X509 encode and decode routines encode and parse an +B structure, which represents an X509 certificate. + +d2i_X509() attempts to decode B bytes at B<*out>. If +successful a pointer to the B structure is returned. If an error +occurred then B is returned. If B is not B then the +returned structure is written to B<*px>. If B<*px> is not B +then it is assumed that B<*px> contains a valid B +structure and an attempt is made to reuse it. If the call is +successful B<*out> is incremented to the byte following the +parsed data. + +i2d_X509() encodes the structure pointed to by B into DER format. +If B is not B 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. + +For OpenSSL 0.9.7 and later if B<*out> is B 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. + +d2i_X509_fp() is similar to d2i_X509() except it attempts +to parse data from FILE pointer B. + +i2d_X509_bio() is similar to i2d_X509() except it writes +the encoding of the structure B to BIO B. + +i2d_X509_fp() is similar to i2d_X509() except it writes +the encoding of the structure B to BIO B. + +=head1 NOTES + +The letters B and B in for example B stand for +"internal" (that is an internal C structure) and "DER". So that +B converts from internal to DER. + +The functions can also understand B forms. + +The actual X509 structure passed to i2d_X509() must be a valid +populated B structure it can B 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 B will B 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 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, *p; + + len = i2d_X509(x, NULL); + + buf = OPENSSL_malloc(len); + + if (buf == NULL) + /* error */ + + p = buf; + + i2d_X509(x, &p); + +If you are using OpenSSL 0.9.7 or later then this can be +simplified to: + + + 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 apparently containing garbage because +it was incremented after the call to point after the data just written. +Also B will no longer contain the pointer allocated by B +and the subsequent call to B may well crash. + +The auto allocation feature (setting buf to NULL) only works on OpenSSL +0.9.7 and later. Attempts to use it on earlier versions will typically +cause a segmentation violation. + +Another trap to avoid is misuse of the B argument to B: + + X509 *x; + + if (!d2i_X509(&x, &p, len)) + /* Some error */ + +This will probably crash somewhere in B. The reason for this +is that the variable B is uninitialized and an attempt will be made to +interpret its (invalid) value as an B structure, typically causing +a segmentation violation. If B 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. + +=head1 RETURN VALUES + +d2i_X509(), d2i_X509_bio() and d2i_X509_fp() return a valid B structure +or B if an error occurs. The error code that can be obtained by +L. + +i2d_X509(), i2d_X509_bio() and i2d_X509_fp() return a the number of bytes +successfully encoded or a negative value if an error occurs. The error code +can be obtained by L. + +=head1 SEE ALSO + +L + +=head1 HISTORY + +d2i_X509, i2d_X509, d2i_X509_bio, d2i_X509_fp, i2d_X509_bio and i2d_X509_fp +are available in all versions of SSLeay and OpenSSL. + +=cut -- 2.25.1