access_document.c
Overview
@file access_document.c Compact-key CBOR parser for Aliro Access Documents (compact subset of ISO 18013-5 mDoc). Parses strictly with iterative depth traversal (no stack recursion), validates CBOR encoding (no floats, no simple values with payloads, minimal representation), and enforces a 25-level nesting bound. Core: parse_at walks encoded items; root validates full-buffer consumption; child_at / map_find_* retrieve nested elements; integer / timestamp extract scalar fields.
depends on access_document.h
flowchart TD child_at --> head child_at --> parse_at
API
Cstruct item
Parsed CBOR item: major type, argument value, raw encoded bytes (with length), and payload (contents for strings/arrays after the head).
Fstatic int head(const uint8_t *data, size_t length, size_t *offset, uint8_t *major, uint64_t *value)
Parse one CBOR head (major type and argument): consume the initial byte (type in bits 7-5, info in bits 4-0), then additional bytes for arguments 24+ (1/2/4/8 bytes). Return 0 on success, -1 on overflow/underrun/non-canonical encoding. Advances offset.
child_at, map_find_int, map_find_text, parse_at, tagged_embedded, timestampFstatic int child_count(uint8_t major, uint64_t value, uint64_t *count)
Count the number of child elements in a CBOR container by major type: arrays (type 4) → count, maps (type 5) → count*2 (each key-value pair), tags (type 6) → 1 (the tagged value). Returns -1 for invalid major types.
parse_atFstatic int parse_at(const uint8_t *data, size_t length, size_t *offset, struct item *out)
Parse one CBOR-encoded item and all its children iteratively (depth-first traversal), constraining nesting to at most 25 levels to bound the embedded workqueue stack. On success, populate out with the major type, argument value, encoded-byte range, and (for strings) the payload pointer and length. Return 0 on success, -1 on format error, overflow, or underrun.
child_at, map_find_int, map_find_text, root, tagged_embedded, timestamp · calls child_count, headFstatic int root(const uint8_t *data, size_t length, struct item *out)
Parse the root CBOR item and validate that it consumes the entire input. Return 0 on success, -1 if parsing fails or trailing bytes remain.
woz_aliro_parse_access_document · calls parse_atFstatic int child_at(const struct item *container, size_t wanted, struct item *out)
Extract the child at position wanted (0-indexed) from a CBOR array or map, re-reading the container head and walking wanted+1 items to reach it. Return 0 on success, -1 if the container is not an array/map, the index is out of bounds, or parsing fails.
woz_aliro_parse_access_document · calls head, parse_atFstatic int map_find_text(const struct item *map, const char *key, struct item *value)
Search a CBOR map (major type 5) for an entry with text string key (major type 3). Iterate key-value pairs and return 0 when a match is found (value written to result), or -1 if the key is not present or parsing fails.
woz_aliro_parse_access_document · calls head, parse_atFstatic int integer(const struct item *item, int64_t *value)
Extract a signed integer from a parsed CBOR item: major type 0 (uint) → positive value, type 1 (nint) → -(value + 1). Returns 0 on success, -1 if the item is not an integer or overflows int64_t.
map_find_int, woz_aliro_parse_access_documentFstatic int map_find_int(const struct item *map, int64_t key, struct item *value)
Search a CBOR map (major type 5) for an entry with integer key. Iterate key-value pairs and return 0 when a match is found (value written to result), or -1 if the key is not present or parsing fails.
woz_aliro_parse_access_document · calls head, integer, parse_atFstatic int tagged_embedded(const struct item *tag, struct item *embedded)
Extract the byte payload from a CBOR tag with tag number 24 (embedded tag for binary data). Validate that the tag contains exactly one child of type 2 (byte string) and that it fills the entire tag encoding. Return 0 on success, -1 on format error.
woz_aliro_parse_access_document · calls head, parse_atFstatic int timestamp(const struct item *item, uint8_t output[20])
Extract a 20-byte timestamp from a CBOR item: accept a text string (major type 3) directly, or extract and unwrap a tag-0 wrapper around a text string. Validate length and copy the payload. Return 0 on success, -1 if format or length is invalid.
woz_aliro_parse_access_document · calls head, parse_atFint woz_aliro_parse_access_document(const uint8_t *data, size_t length, const uint8_t *requested, size_t requested_length, struct woz_aliro_access_document *r)
Strictly parse the compact-key Aliro Access Document subset used by a reader.
child_at, integer, map_find_int, map_find_text, root, tagged_embedded, timestamp