ASN1_ITEM_D2I(3)
π
ASN1_item_d2i(3) β decode and encode ASN.1 objects
okay so welcome to the ASN1_ITEM_D2I(3) page, bestie β this is the whole squad that flips ASN.1 values between BER bytes and internal C structures, and honestly itβs giving βglamorous but be careful.β β¨
πΈ NAME πΈ
okay so the cast of this page is: 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, and ASN1_item_print β their whole thing is decode and encode ASN.1 objects. periodt. π
β¨ SYNOPSIS β¨
okay so first things first: the library is libcrypto, and the include is exactly this:
library βlibcryptoβ #include <openssl/asn1.h>
and here are the prototypes, bestie β copy them exactly, Iβm not playing:
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 π¦
okay so the whole vibe: these functions convert ASN.1 values from their BER encoding to internal C structures (thatβs the d2i direction) 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. slay. π
ASN1_item_d2i()β interprets*der_inas a DER- or BER-encoded byte array and decodes one value of typeitrepresented by up tolengthbytes. If successful,*der_inis advanced to the byte following the parsed data.- If decoding succeeds and
val_outor*val_outisNULL, a new object is allocated. - If decoding succeeds and
*val_outis notNULL, 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 byASN1_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.
π¨ bestie, the reuse thing is lowkey a trap. itβs there for backward compatibility, but it is strongly discouraged. do not make it your main character.
ASN1_item_d2i_bio()andASN1_item_d2i_fp()β similar toASN1_item_d2i()except that they read from aBIOorFILE, respectively.d2i_ASN1_TYPE()β similar toASN1_item_d2i()except that it does not require a desired type to be specified by the user, but instead returns anASN1_TYPEwrapper object containing both the type and the value found in the input.ASN1_item_i2d()β encodes the object pointed to byval_ininto DER format.- If
*der_outis notNULL, it writes the DER-encoded data to the buffer at*der_outand 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_outis long enough, such that no buffer overflow can occur. - If
*der_outisNULL, memory is allocated for a buffer, and*der_outis not incremented, but points to the start of the data just written. - If
der_outisNULL, the encoded bytes are not written anywhere but discarded. Forval_inobjects 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 callingASN1_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()andASN1_item_i2d_fp()β similar toASN1_item_i2d()except that they write to aBIOorFILE, respectively.i2d_ASN1_TYPE()β similar toASN1_item_i2d()except that the type and the value are not provided separately, but in the form of a singleASN1_TYPEobject.ASN1_item_dup()β creates a deep copy ofval_inby callingASN1_item_i2d()andASN1_item_d2i().
π RETURN VALUES π
- If successful,
ASN1_item_d2i(),ASN1_item_d2i_bio(),ASN1_item_d2i_fp(), andd2i_ASN1_TYPE()return a pointer to the decoded ASN.1 value. In addition, ifval_outis notNULL, the pointer is also written to*val_out. If an error occurs,NULLis returned. ASN1_item_i2d()andi2d_ASN1_TYPE()return the number of bytes written or a negative value if an error occurs.ASN1_item_i2d_bio()andASN1_item_i2d_fp()return1for success or0for failure.ASN1_item_dup()returns the newASN1_VALUEobject orNULLif 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. iykyk. π«Ά
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()andi2d_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(), andASN1_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
itfails to match the true type ofval_inor*val_out, buffer overflows and segmentation faults are likely to occur. For more details about why the typeASN1_VALUEconstitutes dangerous user interface design, seeASN1_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 encoded data. - While the way that
*der_inand*der_outare 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) 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 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 withASN1_item_d2i()may fail. π
π thatβs the whole page, bestie β source/version: Debian; date: June 8, 2025; manual name: ASN1_ITEM_D2I(3). bye! π
π¦ where this page comes from
- alpine 3.24: libressl-doc 4.3.1-r0 Β· custom
- arch rolling: libressl 4.4.0-1 Β· ISC AND custom:OpenSSL
- Copyright (c) 2016, 2021 Ingo Schwarze <schwarze@openbsd.org>
- Copyright (c) 2002, 2003, 2015 The OpenSSL Project. All rights reserved
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms