Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
ASN1_ITEM_D2I(3)       FreeBSD Library Functions Manual	      ASN1_ITEM_D2I(3)

     ASN1_item_d2i, ASN1_item_d2i_bio, ASN1_item_d2i_fp, d2i_ASN1_TYPE,
     ASN1_item_i2d, ASN1_item_i2d_bio, ASN1_item_i2d_fp, i2d_ASN1_TYPE,
     ASN1_item_dup, ASN1_item_print -- decode and encode ASN.1 objects

     #include <openssl/asn1.h>

     ASN1_VALUE	*
     ASN1_item_d2i(ASN1_VALUE **val_out, const unsigned	char **der_in,
	 long length, const ASN1_ITEM *it);

     void *
     ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO	*in_bio, void *val_out);

     void *
     ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE	*in_fp,	void *val_out);

     ASN1_TYPE *
     d2i_ASN1_TYPE(ASN1_TYPE **val_out,	const unsigned char **der_in,
	 long length);

     ASN1_item_i2d(ASN1_VALUE *val_in, unsigned	char **der_out,
	 const ASN1_ITEM *it);

     ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO	*out_bio, void *val_in);

     ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE	*out_fp, void *val_in);

     i2d_ASN1_TYPE(ASN1_TYPE *val_in, unsigned char **der_out);

     void *
     ASN1_item_dup(const ASN1_ITEM *it,	void *val_in);

     ASN1_item_print(BIO *out_bio, ASN1_VALUE *val_in, int indent,
	 const ASN1_ITEM *it, const ASN1_PCTX *pctx);

     These functions convert ASN.1 values from their BER encoding to internal
     C structures ("d2i") and vice versa ("i2d").  Unlike the C	structures
     which contain pointers to sub-objects, BER	is a serialized	encoding,
     suitable for transfer over	the network and	for storage in a file.

     ASN1_item_d2i() interpretes *der_in as a DER- or BER-encoded byte array
     and decodes one value of type it represented by up	to length bytes.  If
     successful, *der_in is advanced to	the byte following the parsed data.

     If	decoding succeeds and val_out or *val_out is NULL, a new object	is al-

     If	decoding succeeds and *val_out is not NULL, it is assumed to point to
     a valid populated object and an attempt is	made to	reuse it.  It must not
     be	an empty structure such	as one returned	by ASN1_item_new(3) or by one
     of	the various type-specific *_new() functions.  This "reuse" capability
     is	present	for backward compatibility, but	its use	is strongly discour-
     aged; see the BUGS	section	below.

     ASN1_item_d2i_bio() and ASN1_item_d2i_fp()	are similar to ASN1_item_d2i()
     except that they read from	a BIO or FILE, respectively.

     d2i_ASN1_TYPE() is	similar	to ASN1_item_d2i() except that it does not re-
     quire a desired type to be	specified by the user, but instead returns an
     ASN1_TYPE wrapper object containing both the type and the value found in
     the input.

     ASN1_item_i2d() encodes the object	pointed	to by val_in into DER format.

     If	*der_out is not	NULL, it writes	the DER-encoded	data to	the buffer at
     *der_out and increments it	to point after the data	just written.  In this
     case, it is the responsibility of the user	to make	sure that the buffer
     pointed to	by *der_out is long enough, such that no buffer	owerflow can

     If	*der_out is NULL, memory is allocated for a buffer, and	*der_out is
     not incremented, but points to the	start of the data just written.

     If	der_out	is NULL, the encoded bytes are not written anywhere but	dis-
     carded.  For val_in objects of variable encoding size, this is sometimes
     used to first find	the number of bytes that will be written.  Then, a
     sufficient	amount of memory is allocated before calling ASN1_item_i2d()
     again.  This explicit double-call technique is often not needed because
     the auto-allocation technique described in	the previous paragraph can be

     ASN1_item_i2d_bio() and ASN1_item_i2d_fp()	are similar to ASN1_item_i2d()
     except that they write to a BIO or	FILE, respectively.

     i2d_ASN1_TYPE() is	similar	to ASN1_item_i2d() except that the type	and
     the value are not provided	separately, but	in the form of a single
     ASN1_TYPE object.

     ASN1_item_dup() creates a deep copy of val_in by calling ASN1_item_i2d()
     and ASN1_item_d2i().

     If	successful, ASN1_item_d2i(), ASN1_item_d2i_bio(), ASN1_item_d2i_fp(),
     and d2i_ASN1_TYPE() return	a pointer to the decoded ASN.1 value.  In ad-
     dition, if	val_out	is not NULL, the pointer is also written to *val_out.
     If	an error occurs, NULL is returned.

     ASN1_item_i2d() and i2d_ASN1_TYPE() return	the number of bytes written or
     a negative	value if an error occurs.

     ASN1_item_i2d_bio() and ASN1_item_i2d_fp()	return 1 for success or	0 for

     ASN1_item_dup() returns the new ASN1_VALUE	object or NULL if an error oc-

     Many type-specific	wrapper	functions exist.  Using	those wrappers is rec-
     ommended in application code because it restores part of the type safety
     that the low-level	interfaces using ASN1_VALUE lack.

     For example, to allocate a	buffer and write the DER encoding of an	X509
     object into it:

	   X509		   *x;
	   unsigned char   *buf;
	   int		    len;

	   buf = NULL;
	   len = i2d_X509(x, &buf);
	   if (len < 0)
		   /* error */

     Attempt to	decode a buffer:

	   X509		   *x;
	   unsigned char   *buf, *p;
	   int		    len;

	   /* Set up buf and len to point to the input buffer. */
	   p = buf;
	   x = d2i_X509(NULL, &p, len);
	   if (x == NULL)
		   /* error */

     Equivalent	technique:

	   X509		   *x;
	   unsigned char   *buf, *p;
	   int		    len;

	   /* Set up buf and len to point to the input buffer. */
	   p = buf;
	   x = NULL;

	   if (d2i_X509(&x, &p,	len) ==	NULL)
		   /* error */

     ASN1_item_new(3), ASN1_TYPE_new(3)

     d2i_ASN1_TYPE() and i2d_ASN1_TYPE() first appeared	in SSLeay 0.5.1	and
     have been available since OpenBSD 2.4.

     ASN1_item_d2i(), ASN1_item_d2i_bio(), ASN1_item_d2i_fp(),
     ASN1_item_i2d(), ASN1_item_i2d_bio(), ASN1_item_i2d_fp(), and
     ASN1_item_dup() first appeared in OpenSSL 0.9.7 and have been available
     since OpenBSD 3.2.

     ASN1_item_print() first appeared in OpenSSL 1.0.0 and has been available
     since OpenBSD 4.9.

     If	the type described by it fails to match	the true type of val_in	or
     *val_out, buffer overflows	and segmentation faults	are likely to occur.
     For more details about why	the type ASN1_VALUE constitutes	dangerous user
     interface design, see ASN1_item_new(3).

     The encoded data is in binary form	and may	contain	embedded NUL bytes.
     Functions such as strlen(3) will not return the correct length of the en-
     coded data.

     While the way that	*der_in	and *der_out are incremented after the opera-
     tion supports the typical usage patterns of reading or writing one	object
     after another, this behaviour can trap the	unwary.

     Using a temporary pointer into the	buffer is mandatory.  A	common mistake
     is	to attempt to use a buffer directly as follows:

	   X509		   *x;
	   unsigned char   *buf;
	   int		    len;

	   len = i2d_X509(x, NULL);
	   buf = malloc(len);
	   i2d_X509(x, &buf);
	   /* do something with	buf[] */

     This code will result in buf apparently containing	garbage	because	it was
     incremented during	i2d_X509() to point after the data just	written.  Also
     buf will no longer	contain	the pointer allocated by malloc(3) and the
     subsequent	call to	free(3)	is likely to crash.

     Another trap to avoid is misuse of	the val_out argument:

	   X509		   *x;

	   if (d2i_X509(&x, &p,	len) ==	NULL)
		   /* error */

     This will probably	crash somewhere	in d2i_X509() because x	is uninitial-
     ized and an attempt will be made to interpret its invalid content as an
     X509 object, typically causing a segmentation violation.  If x is set to
     NULL first, then this will	not happen.

     If	the "reuse" capability is used,	a valid	object is passed in via
     *val_out, and an error occurs, then the object is not freed and may be
     left in an	invalid	or inconsistent	state.

     In	some versions of OpenSSL, the "reuse" behaviour	is broken such that
     some parts	of the reused object may persist if they are not present in
     the new one.

     In	many versions of OpenSSL, ASN1_item_i2d() will not return an error if
     mandatory fields are not initialized due to a programming error.  In that
     case, the encoded structure may contain invalid data and some fields may
     be	missing	entirely, such that trying to parse it with ASN1_item_d2i()
     may fail.

     Any function which	encodes	an object may return a stale encoding if the
     object has	been modified after deserialization or previous	serialization.
     This is because some objects cache	the encoding for efficiency reasons.

FreeBSD	13.0			March 27, 2018			  FreeBSD 13.0


Want to link to this manual page? Use this URL:

home | help