From 78c2528c567b9a9c6790d3047db8640a67b389c8 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Mon, 24 Aug 2026 10:52:23 +1000 Subject: [PATCH] ASN Template documentation: add more content Added a bunch of content about how to use ASN templates. Added a section with a list of things to do when adding a new template. Added mappiong of ASN.1 notation to template lines. Added ASN.1 type specific information. Added a checklist at the end to head off the common issues. Added references to ASN_TEMPLATE.md. Added other informatrion. --- AGENTS.md | 1 + wolfcrypt/src/ASN_TEMPLATE.md | 1301 ++++++++++++++++++++++++++++++++- wolfcrypt/src/asn.c | 5 + wolfssl/wolfcrypt/asn.h | 7 +- 4 files changed, 1302 insertions(+), 12 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index dbe93e6e1c2..b4181e54a39 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -150,6 +150,7 @@ set the macros in `user_settings.h` or your build flags. | `wolfssl/internal.h` | Internal -- do not use from applications | | `src/` | TLS implementation (ssl.c, tls13.c, dtls13.c, internal.c) | | `wolfcrypt/src/` | Crypto implementations | +| `wolfcrypt/src/ASN_TEMPLATE.md` | How ASN.1 structures are described and parsed/encoded -- read before touching `asn.c` | | `wolfcrypt/src/port/` | ~30 hardware/OS crypto ports: arm, intel, Espressif, Renesas, st, nxp, atmel, silabs, psa, kcapi, caam, liboqs, ... | | `examples/client/`, `examples/server/` | Full-featured reference apps; run with `-h` for all flags | | `examples/tls13/` | Minimal TLS 1.3 samples, incl. in-memory I/O (no sockets) | diff --git a/wolfcrypt/src/ASN_TEMPLATE.md b/wolfcrypt/src/ASN_TEMPLATE.md index 5fa3fce320f..a56ddf514a2 100644 --- a/wolfcrypt/src/ASN_TEMPLATE.md +++ b/wolfcrypt/src/ASN_TEMPLATE.md @@ -1,5 +1,65 @@ # Writing an ASN Template +wolfSSL describes each ASN.1 structure once, as a static table of `ASNItem`, +and uses that one table for both directions: + +| Direction | Entry points | +|---|---| +| Decode | `GetASN_Items()` | +| Encode | `SizeASN_Items()` then `SetASN_Items()` | + +The types and helpers are declared in `wolfssl/wolfcrypt/asn.h` and implemented +in `wolfcrypt/src/asn.c`. All of it is compiled only when +`WOLFSSL_ASN_TEMPLATE` is defined, which is the default (see +`wolfssl/wolfcrypt/settings.h`); the alternative implementation lives in +`wolfcrypt/src/asn_orig.c` and is selected with `WOLFSSL_ASN_ORIGINAL` +(`./configure --enable-asn=original`). A change to a template usually needs a +matching change to the original implementation, and both need building. + +Only definite-length encodings are supported. A template describes DER, and +the BER it will read is BER with definite lengths - an indefinite length +(a length byte of 0x80, terminated by an end-of-contents pair) cannot be +described with a template and is not handled by the parser. Convert such an +encoding with `wc_BerToDer()` first and parse the result, as `pkcs7.c` and +`pkcs12.c` do. + +Describing a structure once has a few consequences worth knowing before +writing one. The encoder and the decoder read the same table, so they cannot +drift apart the way two hand-written functions can - which is what the +original implementation has for each structure. A template is `static const`, +so it holds no state, lives in read-only memory rather than RAM, and can be +used from any number of threads at once. All the per-call state is in the +separate `ASNGetData` or `ASNSetData` array, which is why that array is +declared through macros that can put it on the stack or the heap depending on +the build. + +## Adding a template + +The rest of this file is reference material; this is the order to do things in. + +1. Write the table - one `ASNItem` per ASN.1 item, in encoding order, with + `depth` following the nesting. See "Template" and "Examples of ASN.1 items". +2. Write the index enum beside it, ending with + `WOLF_ENUM_DUMMY_LAST_ELEMENT`. Repeat every `#if` from the table around the + matching enumerator. +3. Add the `