
#use wml::openssl-macros area=docs page=d2i_X509

<title>Documents, d2i_X509(3)</title>

<h1>d2i_X509(3)</h1>

#use wml::imp::generic

{:
## What's this? [[s|(<STRONG>[^<].+?)</A>(</STRONG><DD>)|$1$2|sg]]
[[s|<P>\s+<P>|<P>|sg]]
[[s|<P>\s+</|</|sg]]
[[s|<DD>\s*<DT>|<DD>&nbsp;<DT>|sg]]
[[s|<DD>\s*</DL>|<DD>&nbsp;</DL>|sg]]
[[s|\[|&#91;|sg]]
[[s|\]|&#93;|sg]]

<!-- INDEX BEGIN -->

<UL>

	<LI><A HREF="#NAME">NAME</A>
	<LI><A HREF="#SYNOPSIS">SYNOPSIS</A>
	<LI><A HREF="#DESCRIPTION">DESCRIPTION</A>
	<LI><A HREF="#NOTES">NOTES</A>
	<LI><A HREF="#EXAMPLES">EXAMPLES</A>
	<LI><A HREF="#WARNINGS">WARNINGS</A>
	<LI><A HREF="#BUGS">BUGS</A>
	<LI><A HREF="#RETURN_VALUES">RETURN VALUES</A>
	<LI><A HREF="#SEE_ALSO">SEE ALSO</A>
	<LI><A HREF="#HISTORY">HISTORY</A>
</UL>
<!-- INDEX END -->

<HR>
<P>
<HR>
<H1><A NAME="NAME">NAME</A></H1>
<P>
d2i_X509, i2d_X509, d2i_X509_bio, d2i_X509_fp, i2d_X509_bio, i2d_X509_fp -
X509 encode and decode functions

</P>
<P>
<HR>
<H1><A NAME="SYNOPSIS">SYNOPSIS</A></H1>
<PRE> #include &lt;openssl/x509.h&gt;
</PRE>
<PRE> X509 *d2i_X509(X509 **px, const unsigned char **in, int len);
 int i2d_X509(X509 *x, unsigned char **out);
</PRE>
<PRE> X509 *d2i_X509_bio(BIO *bp, X509 **x);
 X509 *d2i_X509_fp(FILE *fp, X509 **x);
</PRE>
<PRE> int i2d_X509_bio(BIO *bp, X509 *x);
 int i2d_X509_fp(FILE *fp, X509 *x);
</PRE>
<P>
<HR>
<H1><A NAME="DESCRIPTION">DESCRIPTION</A></H1>
<P>
The X509 encode and decode routines encode and parse an
<STRONG>X509</STRONG> structure, which represents an X509 certificate.

</P>
<P>
<CODE>d2i_X509()</CODE> attempts to decode <STRONG>len</STRONG> bytes at <STRONG>*in</STRONG>. If successful a pointer to the <STRONG>X509</STRONG> structure is returned. If an error occurred then <STRONG>NULL</STRONG> is returned. If <STRONG>px</STRONG> is not <STRONG>NULL</STRONG> then the returned structure is written to <STRONG>*px</STRONG>. If <STRONG>*px</STRONG> is not <STRONG>NULL</STRONG>
then it is assumed that <STRONG>*px</STRONG> contains a valid <STRONG>X509</STRONG>
structure and an attempt is made to reuse it. If the call is successful <STRONG>*in</STRONG> is incremented to the byte following the parsed data.

</P>
<P>
<CODE>i2d_X509()</CODE> encodes the structure pointed to by <STRONG>x</STRONG> into DER format. If <STRONG>out</STRONG> is not <STRONG>NULL</STRONG> is writes the DER encoded data to the buffer at <STRONG>*out</STRONG>, 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. 

</P>
<P>
For OpenSSL 0.9.7 and later if <STRONG>*out</STRONG> is <STRONG>NULL</STRONG> memory will be allocated for a buffer and the encoded data written to it.
In this case <STRONG>*out</STRONG> is not incremented and it points to the start of the data just written.

</P>
<P>
<CODE>d2i_X509_bio()</CODE> is similar to <CODE>d2i_X509()</CODE> except it
attempts to parse data from BIO <STRONG>bp</STRONG>.

</P>
<P>
<CODE>d2i_X509_fp()</CODE> is similar to <CODE>d2i_X509()</CODE> except it
attempts to parse data from FILE pointer <STRONG>fp</STRONG>.

</P>
<P>
<CODE>i2d_X509_bio()</CODE> is similar to <CODE>i2d_X509()</CODE> except it
writes the encoding of the structure <STRONG>x</STRONG> to BIO <STRONG>bp</STRONG> and it returns 1 for success and 0 for failure.

</P>
<P>
<CODE>i2d_X509_fp()</CODE> is similar to <CODE>i2d_X509()</CODE> except it
writes the encoding of the structure <STRONG>x</STRONG> to BIO <STRONG>bp</STRONG> and it returns 1 for success and 0 for failure.

</P>
<P>
<HR>
<H1><A NAME="NOTES">NOTES</A></H1>
<P>
The letters <STRONG>i</STRONG> and <STRONG>d</STRONG> in for example <STRONG>i2d_X509</STRONG> stand for ``internal'' (that is an internal C structure) and ``DER''. So
that
<STRONG>i2d_X509</STRONG> converts from internal to DER.

</P>
<P>
The functions can also understand <STRONG>BER</STRONG> forms.

</P>
<P>
The actual X509 structure passed to <CODE>i2d_X509()</CODE> must be a valid
populated <STRONG>X509</STRONG> structure it can <STRONG>not</STRONG> simply be fed with an empty structure such as that returned by
<CODE>X509_new().</CODE>

</P>
<P>
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 <STRONG>strlen()</STRONG> will <STRONG>not</STRONG> return the correct length of the encoded structure.

</P>
<P>
The ways that <STRONG>*in</STRONG> and <STRONG>*out</STRONG> are incremented after the operation can trap the unwary. See the <STRONG>WARNINGS</STRONG> section for some common errors.

</P>
<P>
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.

</P>
<P>
<HR>
<H1><A NAME="EXAMPLES">EXAMPLES</A></H1>
<P>
Allocate and encode the DER encoding of an X509 structure:

</P>
<PRE> int len;
 unsigned char *buf, *p;
</PRE>
<PRE> len = i2d_X509(x, NULL);
</PRE>
<PRE> buf = OPENSSL_malloc(len);
</PRE>
<PRE> if (buf == NULL)
        /* error */
</PRE>
<PRE> p = buf;
</PRE>
<PRE> i2d_X509(x, &amp;p);
</PRE>
<P>
If you are using OpenSSL 0.9.7 or later then this can be simplified to:

</P>
<PRE> int len;
 unsigned char *buf;
</PRE>
<PRE> buf = NULL;
</PRE>
<PRE> len = i2d_X509(x, &amp;buf);
</PRE>
<PRE> if (len &lt; 0)
        /* error */
</PRE>
<P>
Attempt to decode a buffer:

</P>
<PRE> X509 *x;
</PRE>
<PRE> unsigned char *buf, *p;
</PRE>
<PRE> int len;
</PRE>
<PRE> /* Something to setup buf and len */
</PRE>
<PRE> p = buf;
</PRE>
<PRE> x = d2i_X509(NULL, &amp;p, len);
</PRE>
<PRE> if (x == NULL)
    /* Some error */
</PRE>
<P>
Alternative technique:

</P>
<PRE> X509 *x;
</PRE>
<PRE> unsigned char *buf, *p;
</PRE>
<PRE> int len;
</PRE>
<PRE> /* Something to setup buf and len */
</PRE>
<PRE> p = buf;
</PRE>
<PRE> x = NULL;
</PRE>
<PRE> if(!d2i_X509(&amp;x, &amp;p, len))
    /* Some error */
</PRE>
<P>
<HR>
<H1><A NAME="WARNINGS">WARNINGS</A></H1>
<P>
The use of temporary variable is mandatory. A common mistake is to attempt
to use a buffer directly as follows:

</P>
<PRE> int len;
 unsigned char *buf;
</PRE>
<PRE> len = i2d_X509(x, NULL);
</PRE>
<PRE> buf = OPENSSL_malloc(len);
</PRE>
<PRE> if (buf == NULL)
        /* error */
</PRE>
<PRE> i2d_X509(x, &amp;buf);
</PRE>
<PRE> /* Other stuff ... */
</PRE>
<PRE> OPENSSL_free(buf);
</PRE>
<P>
This code will result in <STRONG>buf</STRONG> apparently containing garbage because it was incremented after the call to
point after the data just written. Also <STRONG>buf</STRONG> will no longer contain the pointer allocated by <STRONG>OPENSSL_malloc()</STRONG>
and the subsequent call to <STRONG>OPENSSL_free()</STRONG> may well crash.

</P>
<P>
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.

</P>
<P>
Another trap to avoid is misuse of the <STRONG>xp</STRONG> argument to <STRONG>d2i_X509()</STRONG>:

</P>
<PRE> X509 *x;
</PRE>
<PRE> if (!d2i_X509(&amp;x, &amp;p, len))
        /* Some error */
</PRE>
<P>
This will probably crash somewhere in <STRONG>d2i_X509()</STRONG>. The reason for this is that the variable <STRONG>x</STRONG> is uninitialized and an attempt will be made to interpret its (invalid)
value as an <STRONG>X509</STRONG> structure, typically causing a segmentation violation. If <STRONG>x</STRONG> is set to NULL first then this will not happen.

</P>
<P>
<HR>
<H1><A NAME="BUGS">BUGS</A></H1>
<P>
In some versions of OpenSSL the ``reuse'' behaviour of
<CODE>d2i_X509()</CODE> when 
<STRONG>*px</STRONG> 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.

</P>
<P>
<CODE>i2d_X509()</CODE> 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 <CODE>d2i_X509().</CODE> This may be
fixed in future so code should not assume that <CODE>i2d_X509()</CODE> will
always succeed.

</P>
<P>
<HR>
<H1><A NAME="RETURN_VALUES">RETURN VALUES</A></H1>
<P>
<CODE>d2i_X509(),</CODE> <CODE>d2i_X509_bio()</CODE> and
<CODE>d2i_X509_fp()</CODE> return a valid <STRONG>X509</STRONG> structure or <STRONG>NULL</STRONG> if an error occurs. The error code that can be obtained by
<A HREF="../crypto/ERR_get_error.html#">ERR_get_error(3)</A>. 

</P>
<P>
<CODE>i2d_X509()</CODE> returns the number of bytes successfully encoded or
a negative value if an error occurs. The error code can be obtained by
<A HREF="../crypto/ERR_get_error.html#">ERR_get_error(3)</A>. 

</P>
<P>
<CODE>i2d_X509_bio()</CODE> and <CODE>i2d_X509_fp()</CODE> return 1 for
success and 0 if an error occurs The error code can be obtained by <A HREF="../crypto/ERR_get_error.html#">ERR_get_error(3)</A>. 

</P>
<P>
<HR>
<H1><A NAME="SEE_ALSO">SEE ALSO</A></H1>
<P>
<A HREF="../crypto/ERR_get_error.html#">ERR_get_error(3)</A>



</P>
<P>
<HR>
<H1><A NAME="HISTORY">HISTORY</A></H1>
<P>
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.

</P>
:}


