ASN1_ITEM_D2I_BIO(3ossl)
β¨ ASN1_ITEM_D2I_BIO π
β the OpenSSL 3ossl glow-up β¨
okay bestie, sit down, hydrate, and let me tell you about decoding and encoding DER-encoded ASN.1 structures π¦ this page covers a whole little friend group of functions β ASN1_item_d2i_ex, ASN1_item_d2i, ASN1_item_d2i_bio_ex, ASN1_item_d2i_bio, ASN1_item_d2i_fp_ex, ASN1_item_d2i_fp, ASN1_item_i2d_mem_bio, ASN1_item_pack, ASN1_item_unpack_ex and ASN1_item_unpack β and yes, they're all iconic, no skips π
πΈ NAME πΈ
ASN1_item_d2i_ex, ASN1_item_d2i, ASN1_item_d2i_bio_ex, ASN1_item_d2i_bio, ASN1_item_d2i_fp_ex, ASN1_item_d2i_fp, ASN1_item_i2d_mem_bio, ASN1_item_pack, ASN1_item_unpack_ex, ASN1_item_unpack β decode and encode DER-encoded ASN.1 structures π
π§ SYNOPSIS π§
#include <openssl/asn1.h>
ASN1_VALUE *ASN1_item_d2i_ex(ASN1_VALUE **pval, const unsigned char **in,
long len, const ASN1_ITEM *it,
OSSL_LIB_CTX *libctx, const char *propq);
ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, const unsigned char **in,
long len, const ASN1_ITEM *it);
void *ASN1_item_d2i_bio_ex(const ASN1_ITEM *it, BIO *in, void *x,
OSSL_LIB_CTX *libctx, const char *propq);
void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x);
void *ASN1_item_d2i_fp_ex(const ASN1_ITEM *it, FILE *in, void *x,
OSSL_LIB_CTX *libctx, const char *propq);
void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x);
BIO *ASN1_item_i2d_mem_bio(const ASN1_ITEM *it, const ASN1_VALUE *val);
ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct);
void *ASN1_item_unpack(const ASN1_STRING *oct, const ASN1_ITEM *it);
void *ASN1_item_unpack_ex(const ASN1_STRING *oct, const ASN1_ITEM *it,
OSSL_LIB_CTX *libctx, const char *propq);
π DESCRIPTION π
π«Ά the d2i girls (decoding, going byte-by-byte)
ASN1_item_d2i_ex() decodes the contents of the data stored in *in, which has length len and must be a DER-encoded ASN.1 structure, using the ASN.1 template it. It places the result in *pval unless pval is NULL. And listen β if *pval is non-NULL on entry, the ASN1_VALUE already sitting there gets reused. Otherwise a brand new ASN1_VALUE gets allocated. Slay, no waste π
If any algorithm fetches are required during the process, they'll use the OSSL_LIB_CTX provided in the libctx parameter and the property query string in propq. Want the whole lore on algorithm fetching? Go read "ALGORITHM FETCHING" in crypto(7) β¨
On exit, *in gets updated to point to the next byte in the buffer after the decoded structure. Moving on up, literally π¦
ASN1_item_d2i() is the same as ASN1_item_d2i_ex() except the default OSSL_LIB_CTX is used (i.e. NULL) and it uses a NULL property query string. Same girl, simpler fit π
ASN1_item_d2i_bio_ex() decodes the contents of its input BIO in, which must be a DER-encoded ASN.1 structure, using the ASN.1 template it, and places the result in *pval unless pval is NULL. If in is NULL it returns NULL, else a pointer to the parsed structure. If any algorithm fetches are required during the process, they'll use the OSSL_LIB_CTX provided in the libctx parameter and the property query string in propq. Again: "ALGORITHM FETCHING" in crypto(7), go read it π
When reading from in, decoding consumes one complete DER-encoded structure and leaves any following bytes in the BIO, so concatenated structures can be read with successive calls. Very "one at a time, bestie" of it πΈ
Reaching the end of the input cleanly, at a structure boundary, is not treated as an error: the function returns NULL without adding to the error queue. But if the end of the input is reached in the middle of a structure, or an indefinite-length value is missing its end-of-contents octets (that is, the input is truncated π), an error is queued with reason codeASN1_R_NOT_ENOUGH_DATA. The same applies toASN1_item_d2i_fp_ex().
ASN1_item_d2i_bio() is the same as ASN1_item_d2i_bio_ex() except the default OSSL_LIB_CTX is used (i.e. NULL) and with a NULL property query string β¨
ASN1_item_d2i_fp_ex() is the same as ASN1_item_d2i_bio_ex() except a FILE pointer is provided instead of a BIO π
ASN1_item_d2i_fp() is the same as ASN1_item_d2i_fp_ex() except the default OSSL_LIB_CTX is used (i.e. NULL) and with a NULL property query string π
π the i2d/pack/unpack girls (encoding & the reverse)
ASN1_item_i2d_mem_bio() encodes the given ASN.1 value val using the ASN.1 template it and returns the result in a memory BIO. Cute, contained, memory-based. Main character energy π
ASN1_item_pack() encodes the given ASN.1 value in obj using the ASN.1 template it and returns an ASN1_STRING object. Now pay attention bestie, the pointer rules here are giving very specific:
- If the passed in
*octis not NULL, then it's used to store the returned result. - Otherwise a new
ASN1_STRINGobject is created. - If
octis not NULL and*octis NULL, then the returned return is also set into*oct.
And if there's an error, the optional passed-inASN1_STRINGwill not be freed β but the previous value may be cleared whenASN1_STRING_set0(*oct, NULL, 0)is called internally. Not me warning you about the sneaky internal clear π
ASN1_item_unpack() uses ASN1_item_d2i() to decode the DER-encoded ASN1_STRING oct using the ASN.1 template it π«
ASN1_item_unpack_ex() is similar to ASN1_item_unpack(), but uses ASN1_item_d2i_ex() so that the libctx and propq can be used when doing algorithm fetching. Fancy upgrade, same vibe π
π RETURN VALUES π
ASN1_item_d2i_bio(), ASN1_item_unpack_ex() and ASN1_item_unpack() return a pointer to an ASN1_VALUE or NULL on error π
The ASN1_item_d2i_bio() and ASN1_item_d2i_fp() functions, including their _ex variants, also return NULL at a clean end of input. In that case the error queue is left unchanged, so a caller reading concatenated structures in a loop can distinguish a clean end of input from a decoding error by inspecting the error queue, for example with ERR_peek_error(3). iykyk π
ASN1_item_i2d_mem_bio() returns a pointer to a memory BIO or NULL on error πΈ
ASN1_item_pack() returns a pointer to an ASN1_STRING or NULL on error π¦
β HISTORY β
The functions ASN1_item_d2i_ex(), ASN1_item_d2i_bio_ex(), ASN1_item_d2i_fp_ex() and ASN1_item_i2d_mem_bio() were added in OpenSSL 3.0 β¨
The function ASN1_item_unpack_ex() was added in OpenSSL 3.2 π
π COPYRIGHT π
Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy in the file LICENSE in the source distribution or at <https://www.openssl.org/source/license.html>.
and that's the whole page bestie, no cap π
this was the ASN1_ITEM_D2I_BIO(3ossl) manual from OpenSSL 3.5.9, dated 2026-09-29 β periodt, go decode something responsibly π«Άπ
π¦ where this page comes from
- fedora 43: openssl-devel 1:3.5.9-1.fc43 Β· Apache-2.0
- fedora 43: openssl-devel 1:3.5.9-1.fc43 Β· Apache-2.0
- fedora 44: openssl-devel 1:3.5.9-1.fc44 Β· Apache-2.0
- fedora 44: openssl-devel 1:3.5.9-1.fc44 Β· Apache-2.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms