ASN1_EXTERN_FUNCS(3ossl)
β¨ NAME β¨
ASN1_EXTERN_FUNCS, ASN1_ex_d2i, ASN1_ex_d2i_ex, ASN1_ex_i2d, ASN1_ex_new_func, ASN1_ex_new_ex_func, ASN1_ex_free_func, ASN1_ex_print_func, IMPLEMENT_EXTERN_ASN1 β it's giving ASN.1 external function support π¦
okay bestie, this is the ASN1_EXTERN_FUNCS page from the OpenSSL manual, and yes we're doing it in group-chat voice, no cap π
πΈ SYNOPSIS πΈ
#include <openssl/asn1t.h>
typedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
const ASN1_ITEM *it, int tag, int aclass, char opt,
ASN1_TLC *ctx);
typedef int ASN1_ex_d2i_ex(ASN1_VALUE **pval, const unsigned char **in, long len,
const ASN1_ITEM *it, int tag, int aclass, char opt,
ASN1_TLC *ctx, OSSL_LIB_CTX *libctx,
const char *propq);
typedef int ASN1_ex_i2d(const ASN1_VALUE **pval, unsigned char **out,
const ASN1_ITEM *it, int tag, int aclass);
typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
typedef int ASN1_ex_new_ex_func(ASN1_VALUE **pval, const ASN1_ITEM *it,
OSSL_LIB_CTX *libctx, const char *propq);
typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
typedef int ASN1_ex_print_func(BIO *out, const ASN1_VALUE **pval,
int indent, const char *fname,
const ASN1_PCTX *pctx);
struct ASN1_EXTERN_FUNCS_st {
void *app_data;
ASN1_ex_new_func *asn1_ex_new;
ASN1_ex_free_func *asn1_ex_free;
ASN1_ex_free_func *asn1_ex_clear;
ASN1_ex_d2i *asn1_ex_d2i;
ASN1_ex_i2d *asn1_ex_i2d;
ASN1_ex_print_func *asn1_ex_print;
ASN1_ex_new_ex_func *asn1_ex_new_ex;
ASN1_ex_d2i_ex *asn1_ex_d2i_ex;
};
typedef struct ASN1_EXTERN_FUNCS_st ASN1_EXTERN_FUNCS;
#define IMPLEMENT_EXTERN_ASN1(sname, tag, fptrs)
like. look at that struct. it's a whole vibe. π
π DESCRIPTION π
so normally, when OpenSSL defines ASN.1 data structure templates, it uses a lil series of macros β think ASN1_SEQUENCE(), ASN1_SEQUENCE_END() and friends, the usual suspects β¨. But β plot twist β templates can also be defined entirely on external functions instead. these external functions get called to do the stuff like creating a new ASN1_VALUE, or converting an ASN1_VALUE to or from DER encoding. main character energy, honestly. π
the macro IMPLEMENT_EXTERN_ASN1() is what you use to create one of these externally defined structures. here's the rundown:
- the name of the structure goes in the
snameparameter - the tag for the structure (e.g. typically
V_ASN1_SEQUENCE) goes in thetagparameter - and finally, a pointer to an
ASN1_EXTERN_FUNCSstructure goes in thefptrsparameter
π the ASN1_EXTERN_FUNCS structure, entry by entry
it has the following entries. buckle up, bestie, there's nine of them and we're doing ALL of them π«Ά
app_data
a pointer to arbitrary application specific data. that's it. that's the entry. it's the little pocket where you keep your stuff. π
asn1_ex_new
a "new" function, responsible for constructing a new ASN1_VALUE object. the newly constructed value should be stored in *pval. the it parameter is a pointer to the ASN1_ITEM template object created via the IMPLEMENT_EXTERN_ASN1() macro.
returns a positive value on success, or 0 on error. π
asn1_ex_free
a "free" function, responsible for freeing the ASN1_VALUE passed in *pval that was previously allocated via a "new" function. the it parameter is a pointer to the ASN1_ITEM template object created via the IMPLEMENT_EXTERN_ASN1() macro.
asn1_ex_clear
a "clear" function, responsible for clearing any data in the ASN1_VALUE passed in *pval and making it suitable for reuse. the it parameter is a pointer to the ASN1_ITEM template object created via the IMPLEMENT_EXTERN_ASN1() macro.
asn1_ex_d2i
a "d2i" function, responsible for converting DER data with the tag tag and class class into an ASN1_VALUE. the deets:
- if
*pvalis non-NULL, then theASN_VALUEit points to should be reused. otherwise a newASN1_VALUEshould be allocated and stored in*pval. *inpoints to the DER data to be decoded, andlenis the length of that data.- after decoding,
*inshould be updated to point at the next byte after the decoded data. - if the
ASN1_VALUEis considered optional in this context, thenoptwill be nonzero. otherwise it will be zero. - the
itparameter is a pointer to theASN1_ITEMtemplate object created via theIMPLEMENT_EXTERN_ASN1()macro. - a pointer to the current
ASN1_TLCcontext (which may be required for other ASN1 function calls) is passed in thectxparameter.
the asn1_ex_d2i entry may be NULL if asn1_ex_d2i_ex has been specified instead.
returns <= 0 on error, or a positive value on success. π«‘
asn1_ex_i2d
an "i2d" function, responsible for converting an ASN1_VALUE into DER encoding. on entry *pval will contain the ASN1_VALUE to be encoded.
- if default tagging is to be used, then
tagwill be-1on entry. otherwise, if implicit tagging should be used, thentagandaclasswill be the tag and associated class. - if
outis notNULL, then this function should write the DER encoded data to the buffer in*out, and then increment*outto point to immediately after the data just written. βοΈ - if
outisNULL, then no data should be written β but the length should be calculated and returned as if it were.
the asn1_ex_i2d entry may be NULL if asn1_ex_i2d_ex has been specified instead.
the return value should be negative if a fatal error occurred, or 0 if a non-fatal error occurred. otherwise it should return the length of the encoded data. π (dramatic but accurate)
asn1_ex_print
a "print" function. here's the map:
outis theBIOto print the output to.*pvalis theASN1_VALUEto be printed.indentis the number of spaces of indenting to be printed before any data is printed.fnameis currently unused and is always"".pctxis a pointer to theASN1_PCTXfor the print operation.
returns 0 on error, or a positive value on success. and ooh, here's a cute one: if the return value is 2, then an additional newline will be printed after the data printed by this function. β¨
asn1_ex_new_ex
this is the same as asn1_ex_new, except that it is additionally passed the OSSL_LIB_CTX to be used in libctx, and any property query string to be used for algorithm fetching in the propq parameter. see "ALGORITHM FETCHING" in crypto(7) for further details.
if asn1_ex_new_ex is non NULL, then it will always be called in preference to asn1_ex_new. no debate, it wins, periodt. π
asn1_ex_d2i_ex
this is the same as asn1_ex_d2i, except that it is additionally passed the OSSL_LIB_CTX to be used in libctx, and any property query string to be used for algorithm fetching in the propq parameter. see "ALGORITHM FETCHING" in crypto(7) for further details.
if asn1_ex_d2i_ex is non NULL, then it will always be called in preference to asn1_ex_d2i. same energy, different function. π¦
π RETURN VALUES π
return values for the various callbacks are as described above. yes bestie, you have to scroll back up, they're all up there in the descriptions π
π SEE ALSO π
π HISTORY π
the asn1_ex_new_ex and asn1_ex_d2i_ex callbacks were added in OpenSSL 3.0. so they're the newer girlies of the group chat. π
π COPYRIGHT π
copyright 2021 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!! π written by the OpenSSL girlies, version 3.5.9, dated 2026-09-29 β mwah, slay, go read ASN1_item_new_ex(3) next, ily π«Άβ¨
π¦ 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