---
name: "libressl-ASN1_item_d2i"
section: "3"
platform: "linux"
package: "libressl"
version: "4.4.0-1"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/libressl-ASN1_item_d2i"
---

# libressl-ASN1\_item\_d2i(3)

decode and encode ASN.1 objects

## NAME

**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

## SYNOPSIS

Crypto Library (libcrypto, -lcrypto)

**#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*);

*int*\

**ASN1\_item\_i2d**(*ASN1\_VALUE \*val\_in*, *unsigned char \*\*der\_out*, *const ASN1\_ITEM \*it*);

*int*\

**ASN1\_item\_i2d\_bio**(*const ASN1\_ITEM \*it*, *BIO \*out\_bio*, *void \*val\_in*);

*int*\

**ASN1\_item\_i2d\_fp**(*const ASN1\_ITEM \*it*, *FILE \*out\_fp*, *void \*val\_in*);

*int*\

**i2d\_ASN1\_TYPE**(*ASN1\_TYPE \*val\_in*, *unsigned char \*\*der\_out*);

*void* *\**\

**ASN1\_item\_dup**(*const ASN1\_ITEM \*it*, *void \*val\_in*);

*int*\

**ASN1\_item\_print**(*BIO \*out\_bio*, *ASN1\_VALUE \*val\_in*, *int indent*, *const ASN1\_ITEM \*it*, *const ASN1\_PCTX \*pctx*);

## DESCRIPTION

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**() interprets \**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 allocated.

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 discouraged; 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 require 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 overflow can occur.

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 discarded. 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 used.

**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**().

## RETURN VALUES

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 addition, 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 failure.

**ASN1\_item\_dup**() returns the new *ASN1\_VALUE* object or NULL if an error occurs.

## EXAMPLES

Many type-specific wrapper functions exist. Using those wrappers is recommended 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;
const unsigned char	*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;
const unsigned char	*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 */
```

## SEE ALSO

ASN1\_get\_object(3), ASN1\_item\_digest(3), ASN1\_item\_new(3), ASN1\_item\_pack(3), ASN1\_item\_sign(3), ASN1\_item\_verify(3), ASN1\_TYPE\_new(3)

## HISTORY

**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.

## CAVEATS

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)](/strlen/3.md) will not return the correct length of the encoded data.

While the way that \**der\_in* and \**der\_out* are incremented after the operation 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[] */
free(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)](/malloc/3.md) and the subsequent call to [free(3)](/free/3.md) 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 uninitialized 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.

## BUGS

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.
