I2A_ASN1_STRING(3)
π I2A_ASN1_STRING(3) π
okay bestie, so this is a page from the Library Functions Manual, and it's all about dumping ASN.1 strings as hexadecimal and then reading them back in. it's giving "hex girl summer" and honestly? iconic. let's get into it π
β¨ NAME β¨
i2a_ASN1_STRING, i2a_ASN1_INTEGER, i2a_ASN1_ENUMERATED, a2i_ASN1_STRING, a2i_ASN1_INTEGER, a2i_ASN1_ENUMERATED β literally just a hexadecimal dump of an ASN.1 string π¦
πΈ SYNOPSIS πΈ
#include <openssl/asn1.h>
int
i2a_ASN1_STRING(BIO *out_bio, const ASN1_STRING *a, int type);
int
i2a_ASN1_INTEGER(BIO *out_bio, const ASN1_INTEGER *a);
int
i2a_ASN1_ENUMERATED(BIO *out_bio, const i2a_ASN1_ENUMERATED *a);
int
a2i_ASN1_STRING(BIO *in_bio, ASN1_STRING *out_string, char *buffer,
int size);
int
a2i_ASN1_INTEGER(BIO *in_bio, ASN1_INTEGER *out_string, char *buffer,
int size);
int
a2i_ASN1_ENUMERATED(BIO *in_bio, ASN1_ENUMERATED *out_string,
char *buffer, int size);
π«Ά and yes, const i2a_ASN1_ENUMERATED *a in the third one is exactly what the page says. not a typo i made, bestie β i'm just the messenger. copy it character for character. π
π¦ DESCRIPTION π¦
so the i2a_ girlies β i2a_ASN1_STRING(), i2a_ASN1_INTEGER(), and i2a_ASN1_ENUMERATED() β write a hexadecimal representation of a to out_bio. and the type argument? totally ignored. not even a vibe check. π
each byte of ASN1_STRING_get0_data(3) gets written as a number made of two upper-case hexadecimal digits. and after every group of 70 digits, a backslash + a linefeed get inserted before the next digit. like a little line break moment β¨
if the ASN1_STRING_length(3) of a is 0, then instead you get a pair of zero digits ("00") from i2a_ASN1_INTEGER() and i2a_ASN1_ENUMERATED(), and a single zero digit ("0") from i2a_ASN1_STRING(). and if a is a NULL pointer? nothing gets written. silence. ghosted. π
if a represents a negative integer, i2a_ASN1_INTEGER() prepends a minus sign to the output. tiny little -, big main character energy. π
now the a2i_ squad β a2i_ASN1_STRING(), a2i_ASN1_INTEGER(), and a2i_ASN1_ENUMERATED() β parse a hexadecimal representation of an ASN.1 string into out_string. both lower-case AND upper-case hexadecimal digits are accepted, we're not gatekeeping case here π every pair of input digits becomes one output byte.
on every input line, the trailing newline character gets ignored, and so does an optional carriage return character right before it. the trailing newline doesn't even need to be there on the last line β lowkey chill of it. and if there's a backslash character before the newline character, parsing just keeps going on the next input line. continuity slay. π
a2i_ASN1_INTEGER() and a2i_ASN1_ENUMERATED() need at least one pair of input digits, whereas a2i_ASN1_STRING() converts empty input to an empty string. different standards, same friend group. π«Ά
these functions can parse the output of i2a_ASN1_ENUMERATED(). they can parse the output of i2a_ASN1_INTEGER() unless a was negative. and they can parse the output of i2a_ASN1_STRING() unless the ASN1_STRING_length(3) of a was 0. so likeβ¦ mostly round-trippable, with a couple of noted exceptions. no cap. π
parsing fails if an input line contains an odd number of input digits, or if memory allocation fails. odd digits are NOT the vibe.
these functions use the buffer provided by the caller and assume it's at least size bytes long. it is unspecified what the buffer contains after the functions return β so don't come asking, because nobody knows. π
π RETURN VALUES π
the i2a_ASN1_STRING(), i2a_ASN1_INTEGER(), and i2a_ASN1_ENUMERATED() girlies return the number of bytes written, or -1 if BIO_write(3) fails. and specifically: they all return 0 when a is a NULL pointer.
i2a_ASN1_STRING()returns1for an empty string, or an even number greater than1for a string that is not empty.i2a_ASN1_INTEGER()returns an even number greater than1for positive input, or an odd number greater than2for negative input.i2a_ASN1_ENUMERATED()always returns a non-negative even number when successful. consistency queen. π
and the a2i_ASN1_STRING(), a2i_ASN1_INTEGER(), and a2i_ASN1_ENUMERATED() functions are intended to return 1 for success or 0 for failure β but bestie, see the βBUGSβ section below for a number of traps. it's giving "we tried". π
π₯ SEE ALSO π₯
a2i_ipadd(3), ASN1_STRING_length(3), ASN1_STRING_new(3), ASN1_STRING_print_ex(3), i2a_ASN1_OBJECT(3), i2s_ASN1_INTEGER(3)
go read those too, iykyk π
π HISTORY π
i2a_ASN1_INTEGER() and a2i_ASN1_INTEGER() first appeared in SSLeay 0.6.0. i2a_ASN1_STRING() and a2i_ASN1_STRING() first appeared in SSLeay 0.6.5. a2i_ASN1_STRING() has been part of the public API since SSLeay 0.6.5, and i2a_ASN1_STRING() since SSLeay 0.8.0. these functions have been available since OpenBSD 2.4. old money, fr fr. π
i2a_ASN1_ENUMERATED() and a2i_ASN1_ENUMERATED() first appeared in OpenSSL 0.9.2 and have been available since OpenBSD 2.6. late arrivals but they ate. β¨
π BUGS π
okay this is the part where we get real. π«Ά
if the first call to BIO_gets(3) doesn't return any data β even if that's caused by a fatal I/O error, or if the BIO type doesn't support the βgetsβ operation, or if it's caused by the BIO being non-blocking β then a2i_ASN1_STRING() immediately succeeds and returns an empty out_string. yes. it justβ¦ succeeds. at nothing. π this is a trap.
if BIO_gets(3) returns a partial line β for example because the given size is insufficient to contain one of the input lines, or for reasons specific to the BIO type β then a2i_ASN1_STRING(), a2i_ASN1_INTEGER(), and a2i_ASN1_ENUMERATED() may fail, or silently return a truncated result. silently!! truncated!! π¨ the caller is responsible for providing a buffer of sufficient size to contain the longest possible input line, and for choosing a BIO of a type that only returns complete input lines and does not perform partial reads. that's on you, bestie. π
and lastly: a2i_ASN1_STRING(), a2i_ASN1_INTEGER(), and a2i_ASN1_ENUMERATED() do not support non-blocking BIOs. reading is terminated as soon as BIO_gets(3) returns a value less than 1. that's the rule. periodt. π
β tl;dr: give it a big enough buffer, use a BIO that returns whole lines, and don't try to be non-blocking with these. you're welcome. π
and that's the whole page, bestie!! this one came from the Debian edition, dated December 27, 2024, and it's filed under I2A_ASN1_STRING(3). go forth and hex-dump responsibly. mwah πβ¨π
π¦ where this page comes from
- opensuse-leap 16.0: libressl-devel-doc 4.1.0-bp160.1.1 Β· OpenSSL
- Copyright (c) 2019, 2021 Ingo Schwarze <schwarze@openbsd.org>
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms