# Syntax for Walking Paths Quick DER logo This specification describes how to make `der_walk()` traverse the path in DER binaries that you intend it to take. ## Declaring and Using a Walking Path The walk path is described as a sequence of values that ends in `DER_WALK_END`: #include derwalk path_demo [] = { ..., DER_WALK_END } which is then used to move a `dercursor crs` with int prsok; prsok = der_walk (&crs, path_demo); The output is -1 for hard errors or 0 for success. If it fails to parse the path at some point, the return value is a positive integer, indicating how much of `path_demo` was left unprocessed before `DER_WALK_END`. The `crs` value is updated by this call to point to the end of the `path_demo` walk. ## Entering and Skipping There are two basic actions that `der_walk()` takes at each position along the path; it may either enter or skip a DER element. This is defined in the path with `DER_WALK_ENTER` and `DER_WALK_SKIP`, respectively, as in derwalk path_demo [] = { DER_WALK_ENTER | ..., DER_WALK_SKIP | ..., ..., DER_WALK_END } ## Matching tags The tag found in the DER code must be matched, or otherwise a validation error is raised (and a positive integer returned from `der_walk()` to indicate where the problem was encountered). Tags are quite simply matched by mentioning them after the enter-or-skip choice, as in derwalk path_demo [] = { DER_WALK_ENTER | DER_TAG_SEQUENCE, DER_WALK_SKIP | DER_TAG_CONTEXT (0), DER_WALK_ENTER | DER_TAG_OCTETSTRING, DER_WALK_END } The two statements shown could be used to get to the `OCTET STRING` in demoStruct ::= SEQUENCE { demoCounter [0] INTEGER, demoName OCTET STRING } This relates to the DER sequence for this structure; let's say the `INTEGER` value is `7` and the `OCTET STRING` is `Quick DER`, then the encoding would be 30 16 -- tag SEQUENCE, length 16 a0 03 -- tag a0 for [0], length 3 02 01 07 -- tag INTEGER, length 1, value 7 04 09 51 75 69 63 6b 20 44 45 52 -- tag 4, length 9, "Quick DER" From the start of this structure, we need to: * Enter the `SEQUENCE` * Skip the `[0]` rather then entering it * Enter the `OCTET STRING` * Stop processing This is precisely what the path walk describes. Although *some* understanding of the mapping to DER is helpful, you can generally derive the path to walk directly from the ASN.1 structure. When done, `der_walk()` returns the pointer to the string "Quick DER" with a length of 9, and you can continue to process it: printf ("Found \"%.*s\"\n", crs.derlen, crs.derptr); ## Optionals, Choices and the ANYs There is a possibility in ASN.1 to specify an element as `OPTIONAL`, perhaps even having a `DEFAULT` value (which is ignored by Quick DER). To mark an entry as optional, precede it with `DER_WALK_OPTIONAL`. Choices are barely interesting during a walk; in fact, the only purpose they serve is as something to skip over (since we obviously have no idea how to get into a structure if we don't know yet what that structure is like). So, specify `DER_WALK_SKIP | DER_WALK_CHOICE` to skip an arbitrary element; there will be no validation of that particular tag. The forms `ANY` and `ANY DEFINED BY` receive the same treatment as `CHOICE`, but can be declare with a separate symbol `DER_WALK_ANY`. ## There is more Also have a look at the individual steps that can be taken with `der_enter()` and `der_skip()`. And take a look at `der_iterate_first()` and `der_iterate_next()` if you need iterators. Where `der_walk()` is ideally suited to retrieve a single bit of information from the repository, the `der_unpack()` routine can unpack a complete DER structure (only deferring dynamically-sized parts to later calls). The latter also has a reverse routine `der_pack()`. You will want to read the [PACK SYNTAX](PACK-SYNTAX.MD) for the walking paths used with those routines.