ASN1_ITEM_D2I_BIO(3SSL)
π ASN1_ITEM_D2I_BIO(3SSL) π
okay bestie, sit down, hydrate, and let me tell you about the OpenSSL crew of functions that decode and encode DER-encoded ASN.1 structures. They live in the 3SSL manual section (iykyk) and honestly? they're a whole vibe. π¦
β¨ 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. that's the whole job. glamorous? no. essential? absolutely. π
πΈ 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 π
ASN1_item_d2i_ex() decodes the contents of the data stored in *in, of length len, which must be a DER-encoded ASN.1 structure, using the ASN.1 template it. it drops the result into *pval unless pval is NULL (rude of you, but okay). if *pval is non-NULL on entry then the ASN1_VALUE already sitting there gets reused β no new allocation, we're being economical. otherwise a brand new ASN1_VALUE gets allocated. 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. for more tea on algorithm fetching, see "ALGORITHM FETCHING" in crypto(7). on exit, *in will be updated to point to the next byte in the buffer after the decoded structure. she moves forward. π
ASN1_item_d2i() is exactly the same as ASN1_item_d2i_ex() except the default OSSL_LIB_CTX is used (i.e. NULL) and with a NULL property query string. lowkey the chill version.
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. (yes, the doc says *pval even though there's no pval parameter here β iconic of the docs, but that's what it says, bestie, so I'm telling you exactly that. π«Ά) 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. more on algorithm fetching: "ALGORITHM FETCHING" in crypto(7).
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. 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 code ASN1_R_NOT_ENOUGH_DATA. same deal for ASN1_item_d2i_fp_ex().
ASN1_item_d2i_bio() is the same as ASN1_item_d2i_bio_ex() except that 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 that a FILE pointer is provided instead of a BIO.
ASN1_item_d2i_fp() is the same as ASN1_item_d2i_fp_ex() except that the default OSSL_LIB_CTX is used (i.e. NULL) and with a NULL property query string.
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. π«Ά
ASN1_item_pack() encodes the given ASN.1 value in obj using the ASN.1 template it and returns an ASN1_STRING object. if the passed-in *oct is not NULL then that's where the returned result gets stored, otherwise a new ASN1_STRING object is created. if oct is not NULL and *oct is NULL then the returned return is also set into *oct. if there's an error, the optional passed-in ASN1_STRING will not be freed, but the previous value may be cleared when ASN1_STRING_set0(*oct, NULL, 0) is called internally. so heads up on that, bestie. β οΈ
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. glow up. β¨
π₯ 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 if you're a caller reading concatenated structures in a loop, you can tell a clean end of input apart from a decoding error by inspecting the error queue, for example with ERR_peek_error(3). this is the key distinction, do not sleep on it. π
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. she's the baby of the group. π
π 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 β slay. π¦ this was OpenSSL, version 4.0.3, dated 2026-09-29, and yes, it's giving main character energy from the OpenSSL source distribution. go forth and decode responsibly πβ¨πΈ
π¦ where this page comes from
- ubuntu stonking: libssl-doc 4.0.3-1ubuntu1 Β· Apache-2.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms