aliro_stepup_parse.c
DeviceResponse structural decoder for the Aliro step-up phase: a minimal, bounds-checked…
Overview
DeviceResponse structural decoder for the Aliro step-up phase: a minimal, bounds-checked, depth-limited CBOR reader (definite-length core-deterministic only) plus the Table 8-22/7-1/7-2 field walk. No crypto and no allocation; every parsed field is a slice of the caller's buffer. This is the wire-facing attack surface and is fuzzed on its own (tests/host/fuzz/fuzz_stepup.c).
depends on aliro_stepup.h
flowchart TD aliro_stepup_parse_response --> cb_arr aliro_stepup_parse_response --> cb_map aliro_stepup_parse_response --> cb_skip aliro_stepup_parse_response --> cb_tstr aliro_stepup_parse_response --> cb_uint aliro_stepup_parse_response --> key_is aliro_stepup_parse_response --> parse_document
API
Cstruct cbor
CBOR stream parser: p (current position), end (buffer limit).
Fstatic int cb_head(struct cbor *c, uint8_t *mt, uint64_t *arg)
Read one CBOR head: major type + argument. Consumes the argument bytes (and, for major type 7, the simple/float payload). Rejects indefinite lengths and anything truncated. Returns 0 on success.
cb_bool, cb_expect, cb_int_key, cb_skip_dFstatic int cb_skip_d(struct cbor *c, int depth)
Recursively skip one CBOR value: ints/floats/strings/arrays/maps/tags. Depth-checks CB_MAX_DEPTH. Returns 0 on success, -1 on overflow or malformed.
cb_skip · calls cb_headFstatic int cb_skip(struct cbor *c)
Skip one complete CBOR value (int, string, array, map, tag, float, or null). Returns 0 on success, -1 on malformed input or depth overflow.
aliro_stepup_parse_response, parse_document, parse_issuer_auth, parse_issuer_signed, parse_mso, parse_name_spaces, parse_one_item, parse_validity · calls cb_skip_dFstatic int cb_expect(struct cbor *c, uint8_t want_mt, uint64_t *arg)
Parse CBOR major type + argument with type check: consume one head, verify mt matches want_mt, return 0 and set *arg, else -1.
cb_arr, cb_bytes, cb_map, cb_tag, cb_uint · calls cb_headFstatic int cb_map(struct cbor *c, uint64_t *n)
Parse CBOR major type 5 (map) and return the number of key-value pairs.
aliro_stepup_parse_response, parse_document, parse_issuer_auth, parse_issuer_signed, parse_mso, parse_name_spaces, parse_one_item, parse_validity · calls cb_expectFstatic int cb_arr(struct cbor *c, uint64_t *n)
Parse CBOR major type 4 (array) and return the element count.
aliro_stepup_parse_response, parse_issuer_auth, parse_name_spaces · calls cb_expectFstatic int cb_uint(struct cbor *c, uint64_t *v)
Parse CBOR major type 0 (unsigned integer) and return the value.
aliro_stepup_parse_response, parse_one_item, parse_validity, parse_value_digests · calls cb_expectFstatic int cb_bytes(struct cbor *c, uint8_t want_mt, const uint8_t **s, size_t *n)
Parse a CBOR byte string or text string (major type 2 or 3) and return a pointer to its data and length. Returns 0 on success, -1 on type mismatch or overflow.
cb_bstr, cb_tstr · calls cb_expectFstatic int cb_bstr(struct cbor *c, const uint8_t **s, size_t *n)
Parse a CBOR byte string (major type 2) and return a pointer to its data and length.
parse_issuer_auth, parse_one_item, parse_value_digests · calls cb_bytesFstatic int cb_tstr(struct cbor *c, const uint8_t **s, size_t *n)
Parse a CBOR text string (major type 3) and return a pointer to its data and length.
aliro_stepup_parse_response, parse_document, parse_issuer_signed, parse_mso, parse_name_spaces, parse_one_item, parse_validity, parse_value_digests · calls cb_bytesFstatic int cb_int_key(struct cbor *c, int64_t *v)
Read a signed integer map key (uint or nint).
parse_issuer_auth · calls cb_headFstatic int cb_bool(struct cbor *c, int *b)
Parse one CBOR boolean (major type 7, arg 20 or 21). Returns 0 and sets *b to 0 (false) or 1 (true), -1 on mismatch.
parse_mso · calls cb_headFstatic int cb_tag(struct cbor *c, uint64_t *tag)
Parse CBOR major type 6 (semantic tag) and return the tag number.
parse_issuer_auth, parse_one_item, parse_validity · calls cb_expectFstatic void str_copy(char *dst, size_t cap, const uint8_t *s, size_t n)
Copy a text string into a fixed char buffer (NUL-terminated, truncated).
parse_document, parse_mso, parse_name_spaces, parse_one_itemFstatic int key_is(const uint8_t *s, size_t n, char c)
Match a 1-byte text key "1".."9" without allocating.
aliro_stepup_parse_response, parse_document, parse_issuer_signed, parse_mso, parse_one_item, parse_validityFstatic int digit2(const uint8_t *s, int *out)
Parse two decimal digits (s[0], s[1]). Returns 0 and *out = 0-99, else -1.
tdate_epochFstatic int64_t days_from_civil(int64_t y, unsigned m, unsigned d)
days since 1970-01-01 for a proleptic-Gregorian civil date (Hinnant).
tdate_epochFstatic int tdate_epoch(const uint8_t *s, size_t n, int64_t *epoch)
Parse "YYYY-MM-DDTHH:MM:SSZ" (20 chars). Returns 0 and *epoch, else -1.
parse_validity · calls days_from_civil, digit2Fstatic int parse_validity(struct cbor *c, struct aliro_stepup_doc *doc)
Parse the mdoc validity object: extracts validityIteration (key "5") and signed/validFrom/validUntil times (keys "1"/"2"/"3", each tagged with epoch 0). Returns 0 on success, -1 on parse error. Sets have_* flags and epoch values in the output struct for each field found.
parse_mso · calls cb_map, cb_skip, cb_tag, cb_tstr, cb_uint, key_is, tdate_epochFstatic int parse_value_digests(struct cbor *c, struct aliro_stepup_doc *doc)
Parse the mdoc valueDigests map: reads namespace → digest-ID → hash pairs. Collects up to ALIRO_STEPUP_MAX_DIGESTS SHA-256 hashes (32 bytes). Returns 0 on success, -1 on parse error.
parse_mso · calls cb_bstr, cb_map, cb_tstr, cb_uintFstatic int parse_mso(const uint8_t *mso, size_t mso_len, struct aliro_stepup_doc *doc)
Parse the mobile security object (MSO): extracts digest algorithm (key "2"), valueDigests (key "3"), docType (key "5"), validity (key "6"), and timeVerificationRequired (key "7"). Returns 0 on success, -1 on parse error. Calls parse_validity and parse_value_digests.
parse_issuer_auth · calls cb_bool, cb_map, cb_skip, cb_tstr, key_is, parse_validity, parse_value_digests, str_copyFstatic int parse_issuer_auth(struct cbor *c, struct aliro_stepup_doc *doc)
Parse the issuer authentication COSE Sign1 structure: reads protected header, unprotected map (extracts kid at key 4 and x5chain at key 33), payload, and signature (64 bytes). Unwraps the payload from CBOR tag 24 and calls parse_mso. Returns 0 on success, -1 on format error.
parse_issuer_signed · calls cb_arr, cb_bstr, cb_int_key, cb_map, cb_skip, cb_tag, parse_msoFstatic int parse_one_item(struct cbor *c, struct aliro_stepup_item *it)
Parse one mdoc item from an issuer-signed namespace: unwraps CBOR tag 24 and reads elementID (key "3") and digestID (key "1"). Returns 0 on success, -1 on parse error. Stores the full tagged bytes and extracted fields in the output struct.
parse_name_spaces · calls cb_bstr, cb_map, cb_skip, cb_tag, cb_tstr, cb_uint, key_is, str_copyFstatic int parse_name_spaces(struct cbor *c, struct aliro_stepup_doc *doc)
Parse the issuer-signed nameSpaces map: reads namespace → array of items. Stores the first namespace name found, then collects up to ALIRO_STEPUP_MAX_ITEMS from all namespaces. Returns 0 on success, -1 on parse error.
parse_issuer_signed · calls cb_arr, cb_map, cb_skip, cb_tstr, parse_one_item, str_copyFstatic int parse_issuer_signed(struct cbor *c, struct aliro_stepup_doc *doc)
Parse the issuer-signed wrapper: reads nameSpaces (key "1") and issuerAuth (key "2"). Returns 0 on success, -1 on parse error.
parse_document · calls cb_map, cb_skip, cb_tstr, key_is, parse_issuer_auth, parse_name_spacesFstatic int parse_document(struct cbor *c, struct aliro_stepup_doc *doc)
Parse one mdoc document: reads issuerSigned (key "1") and docType (key "5"). Returns 0 on success, -1 on parse error. Calls parse_issuer_signed.
aliro_stepup_parse_response · calls cb_map, cb_skip, cb_tstr, key_is, parse_issuer_signed, str_copyFint aliro_stepup_parse_response(const uint8_t *buf, size_t len, struct aliro_stepup_doc *doc)
Parse a mobile driver license response: top-level CBOR map with status (key "3") and documents array (key "2"). Extracts the first document only and sets have_document flag. Returns 0 on success, -1 on null pointer or parse error. Zeros the output struct on entry.
cb_arr, cb_map, cb_skip, cb_tstr, cb_uint, key_is, parse_document