ASN1_PARSE_DUMP(3)

๐Ÿ“ฆ version 4.1.0, in opensuse-leap 16.0

โœจ ASN1_PARSE_DUMP(3) โœจ

okay so bestie, this is a Library Functions Manual page, and we're about to dive into the absolute iconic world of ASN.1 parsing. like, this is the glamorous stuff โ€” BER encoding, hex dumps, recursive structures... it's giving "I'm a protocol analyzer and I know it" ๐Ÿ’…


๐ŸŒธ NAME ๐ŸŒธ

ASN1_parse_dump, ASN1_parse โ€” parse BER and print information about it

like literally, it looks at your BER-encoded data and tells you everything about what's going on in there. no cap, it's so useful. ๐ŸŽ€


๐Ÿฆ‹ SYNOPSIS ๐Ÿฆ‹

#include <openssl/asn1.h>

int
ASN1_parse_dump(BIO *bio, const unsigned char *ber_in, long length,
    int indent, int dump);

int
ASN1_parse(BIO *bio, const unsigned char *ber_in, long length,
    int indent);

๐Ÿ’– DESCRIPTION ๐Ÿ’–

okay so ASN1_parse_dump() is the main character here โ€” it parses BER-encoded values and prints all the tea about them to bio. โ˜•โœจ

when you call it, *ber_in should point to the first identifier octet of an encoded value (like, the very beginning of the vibe). and it only inspects at most length bytes. don't come for me if you pass a bad length, okay? ๐Ÿ™ˆ

for each value it successfully parses, it prints these iconic details โ€” and I'm gonna walk you through each one like we're doing a group project:

  1. the index of its first identifier octet relative to ber_in, as a decimal number followed by a colon. for the first value parsed and printed, this is literally "0:". like, the origin story. ๐ŸŒŸ
  2. the nesting depth as a decimal integer. for the first value, this is "d=0". that's baby's first depth, bestie. ๐Ÿผ
  3. the header length in bytes โ€” including the identifier octets and the length octets โ€” as a decimal integer. for example, for a boolean value this is "hl=2" because the encoding contains one identifier octet (0x01) and one length octet (also 0x01 because one content octet follows after the header). math is mathing! ๐Ÿ”ข
  4. if the value uses the definite form for the length octets, it prints the number encoded in those length octets as a decimal integer โ€” this is the number of content octets that follow. for a boolean value, this is "l=1". but if it's the indefinite form, it prints "l=inf" instead. dramatic much? ๐Ÿ’…
  5. if the value is primitive, it prints "prim:"; if it's constructed, "cons:". slay for categorization! ๐Ÿท๏ธ
  6. the next field depends on the class of the tag, and this is where it gets spicy:
    • V_ASN1_PRIVATE โ€” prints "priv" followed by the decimal tag number in square brackets. private vibes only. ๐Ÿ”’
    • V_ASN1_CONTEXT_SPECIFIC โ€” prints "cont" followed by the decimal tag number in square brackets. context is everything, bestie. ๐Ÿ“
    • V_ASN1_APPLICATION โ€” prints "appl" followed by the decimal tag number in square brackets. application era! ๐Ÿ“ฑ
    • V_ASN1_UNIVERSAL โ€” if the tag number is 30 or less, it prints the return value from ASN1_tag2str(3). otherwise, it prints "<ASN1" followed by the decimal tag number and a closing angle bracket. universal icon behavior. ๐ŸŒ

for constructed values, the contained values are recursively printed. it's like nested drama โ€” yes, we're going there. ๐ŸŽญ


๐ŸŒˆ Primitive values processing ๐ŸŒˆ

okay so primitive values get special treatment, and here's the breakdown:

  • V_ASN1_BOOLEAN โ€” its integer value is printed as a decimal number. simple, clean, iconic. โœ…
  • V_ASN1_INTEGER โ€” decoded with d2i_ASN1_INTEGER(3) and printed as a hexadecimal number with an even number of digits. hex girl summer! ๐Ÿ”ฎ
  • V_ASN1_ENUMERATED โ€” decoded with d2i_ASN1_ENUMERATED(3) and printed as a hexadecimal number with an even number of digits. same energy. ๐Ÿ“Š
  • V_ASN1_OBJECT โ€” decoded with d2i_ASN1_OBJECT(3) and printed with i2a_ASN1_OBJECT(3). object permanence! ๐ŸŽฏ
  • V_ASN1_OCTET_STRING โ€” decoded with d2i_ASN1_OCTET_STRING(3). if the data is only printable ASCII characters, line feeds, carriage returns, and horizontal tabs, it's printed as an ASCII string. otherwise, the dump argument decides the format. if dump is zero, a raw hex dump is emitted โ€” two hexadecimal digits for every data byte. if dump is non-zero, BIO_dump_indent(3) is used. and unless dump is -1, the data is truncated after dump bytes. so many options, so little time! ๐Ÿ’€
  • V_ASN1_PRINTABLESTRING โ€” printed as an ASCII string. the same applies to V_ASN1_IA5STRING, V_ASN1_T61STRING, V_ASN1_NUMERICSTRING, V_ASN1_VISIBLESTRING, V_ASN1_UTF8STRING, V_ASN1_UTCTIME, and V_ASN1_GENERALIZEDTIME. string theory but make it fashion. ๐Ÿงต
  • Other tags โ€” if dump is 0, their data is silently ignored (ghosted! ๐Ÿ‘ป). if dump is non-zero, BIO_dump_indent(3) is used. and unless dump is -1, the data is truncated after dump bytes. same rules, different tag. ๐Ÿ”„

and bestie, ASN1_parse() is literally identical to ASN1_parse_dump() except it passes 0 as the dump argument. it's the low-key version. ๐Ÿ˜Œ


๐Ÿ”ฅ RETURN VALUES ๐Ÿ”ฅ

these functions return 1 for success or 0 for failure. that's it. binary. no in-between. ๐Ÿ’ฏ

but like, here's when they're gonna fail on you (and they will let you know by printing an error message to bio):

  • when parsing or decoding fails
  • when a recursive call fails
  • when encountering a value extending beyond length
  • when encountering a nesting level in excess of 128
  • when any printing operation fails

in all these cases, they abort parsing and printing and return 0. so like, don't say I didn't warn you. ๐Ÿ˜ญ


๐Ÿ‘‘ SEE ALSO ๐Ÿ‘‘

ASN1_get_object(3), ASN1_item_d2i(3), ASN1_item_new(3), ASN1_STRING_print(3), ASN1_TYPE_new(3)

go read these if you wanna be as smart as me. iykyk. ๐Ÿ“šโœจ


โญ STANDARDS โญ

ITU-T Recommendation X.690, also known as ISO/IEC 8825-1: Information technology - ASN.1 encoding rules: Specification of Basic Encoding Rules (BER), Canonical Encoding Rules (CER) and Distinguished Encoding Rules (DER), section 8.1: General rules for encoding

like, the whole alphabet soup of encoding rules. we love a standardized queen. ๐Ÿ‘ธ


๐Ÿฆ‹ HISTORY ๐Ÿฆ‹

  • ASN1_parse() first appeared in SSLeay 0.5.1 and has been available since OpenBSD 2.4. she's been around. vintage. ๐Ÿ•ฐ๏ธ
  • ASN1_parse_dump() first appeared in OpenSSL 0.9.6 and has been available since OpenBSD 2.9. the newer sister. ๐Ÿ’ซ

๐Ÿ’€ BUGS ๐Ÿ’€

okay so this is the messy part: the content of values tagged as V_ASN1_BMPSTRING is silently ignored and none of it is printed. like, it's just not there. gone. ghosted. don't ask questions you don't want answers to. ๐Ÿ™ˆ


so like, that's the whole manual page bestie! ๐Ÿ’– this was Debian, version from December 9, 2021, and the page is ASN1_PARSE_DUMP(3). now go parse some BER and slay! ๐ŸŽ€โœจ๐Ÿฆ‹
๐Ÿ“ฆ where this page comes from