asn1.nx
buildroot/runtime/asn1.nx
about
asn1.nx -- ASN.1 DER TLV (Tag-Length-Value) primitives.
Distinguished Encoding Rules (ITU-T X.690) reader. DER is the
canonical form every X.509 cert uses, every TLS signature, every
PKCS#8 key, every CMS message. We implement a reader-only
subset -- write-side encoders are future work.
DER structure:
TLV byte sequence:
- Tag: 1-N bytes. Low-tag-number form: 1 byte encoding
class (bits 7-6), constructed flag (bit 5), tag (bits 4-0).
High-tag-number form (tag >= 31): bits 4-0 = 0x1F, then
tag in base-128 continuation bytes. X.509 uses low form
exclusively in practice; we support both.
- Length: 1-N bytes. Short form (0-127): single byte.
Long form: byte 0x80+n indicates n bytes of length follow,
big-endian. n <= 126; indefinite-length form (0x80) is
explicitly forbidden in DER.
- Value: length bytes, content depends on tag.
Tags relevant to X.509:
0x02 INTEGER
0x03 BIT STRING
0x04 OCTET STRING
0x05 NULL
0x06 OBJECT IDENTIFIER
0x0C UTF8String
0x13 PrintableString
0x17 UTCTime
0x18 GeneralizedTime
0x30 SEQUENCE (constructed)
0x31 SET (constructed)
0xA0-0xA7 context-specific [0]..[7]
Invariants:
A1 All reads bounds-check against the caller-supplied length.
Negative return signals either "invalid input" (malformed
DER) or "out of bounds" (read would exceed buffer).
A2 Length field rejects indefinite-length form (DER forbids).
A3 No recursion; callers drive descent explicitly.
dependencies 1 imports · 1 importers
imports: syscalls.nx
imported by: x509.nx
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| 68 | struct Asn1Cursor { |
consts
| 47 | const ASN1_INTEGER: i64 = 0x02 |
| 48 | const ASN1_BIT_STRING: i64 = 0x03 |
| 49 | const ASN1_OCTET_STRING: i64 = 0x04 |
| 50 | const ASN1_NULL: i64 = 0x05 |
| 51 | const ASN1_OID: i64 = 0x06 |
| 52 | const ASN1_UTF8: i64 = 0x0C |
| 53 | const ASN1_PRINTABLE: i64 = 0x13 |
| 54 | const ASN1_UTC_TIME: i64 = 0x17 |
| 55 | const ASN1_GENERALIZED: i64 = 0x18 |
| 56 | const ASN1_SEQUENCE: i64 = 0x30 |
| 57 | const ASN1_SET: i64 = 0x31 |
| 60 | const ASN1_ERR_OOB: i64 = -1 |
| 61 | const ASN1_ERR_INDEFINITE: i64 = -2 |
| 62 | const ASN1_ERR_TAG_OVERFLOW:i64 = -3 |
| 63 | const ASN1_ERR_LENGTH_BAD: i64 = -4 |
functions
| 74 | func asn1_cursor_init(c: *Asn1Cursor, len: i64) -> i64 { |
| 83 | func asn1_read_tag(buf: *u8, c: *Asn1Cursor) -> i64 {
called by 1: asn1_read_tlv_header |
| 109 | func asn1_read_length(buf: *u8, c: *Asn1Cursor) -> i64 { |
| 133 | func asn1_read_tlv_header(buf: *u8, c: *Asn1Cursor, |
| 148 | func asn1_skip_value(c: *Asn1Cursor, len: i64) -> i64 { |
| 158 | func asn1_expect_tag(buf: *u8, c: *Asn1Cursor, |
| 175 | func main() -> i64 { |