Skip to content

Commit 92f7e91

Browse files
authored
Merge pull request wolfSSL#8120 from SparkiDev/asn_templ_doc
ASN template documentation: adding basics for decoding
2 parents 95b4771 + dcd75df commit 92f7e91

2 files changed

Lines changed: 164 additions & 1 deletion

File tree

wolfcrypt/src/ASN_TEMPLATE.md

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
# Writing an ASN Template
2+
3+
## Template
4+
5+
A template that describes the ASN.1 items that are expected is required.
6+
7+
Each ASN.1 item should have a named index to make it easier to choose the item
8+
when assigning variables or getting data.
9+
10+
The number of items in the template is needed too. Use a define using sizeof to
11+
allow for modification.
12+
13+
```c
14+
/* ASN template for <name of ASN.1 definition>.
15+
* <RFC or standard that it comes from>
16+
*/
17+
static const ASNItem <template>[] = {
18+
/* <ITEM_0> */ { <depth>, <ASN Type>, <constructed>, <header>, <optional> },
19+
...
20+
};
21+
/* Named indeces for <template>. */
22+
enum {
23+
<TEMPLATE>_<ITEM_0> = 0,
24+
<TEMPLATE>_<ITEM_1>,
25+
...
26+
};
27+
/* Number of items in <template>. */
28+
#define <template>_Length (sizeof(<template>) / sizeof(ASNItem))
29+
```
30+
31+
## Examples of ASN.1 items
32+
33+
### Sequence
34+
35+
This is a sequence at depth 0 and want to parse the contents.
36+
37+
ASN.1 description would be something like:
38+
```
39+
RSASSA-PSS-params ::= SEQUENCE {
40+
```
41+
42+
```c
43+
{ 0, ASN_SEQUENCE, 1, 1, 0 },
44+
```
45+
46+
To skip over the contents of the sequence, set the header to 0 indicating that
47+
the next item to parse will be this level or higher.
48+
49+
```c
50+
{ 0, ASN_SEQUENCE, 1, 0, 0 },
51+
```
52+
53+
### Simple types
54+
55+
An INTEGER at depth 1.
56+
57+
ASN.1 description would be something like:
58+
```
59+
prime INTEGER,
60+
```
61+
62+
```c
63+
{ 1, ASN_INTEGER, 0, 0, 1 },
64+
```
65+
66+
An OCTET_STRING at depth 1 but stop after header in order to parse contents:
67+
68+
ASN.1 description would be something like:
69+
```
70+
digest OCTET STRING
71+
```
72+
73+
```c
74+
{ 1, ASN_COTET_STRING, 0, 1, 0 },
75+
```
76+
77+
### Context Specific
78+
79+
Content specific ASN.1 items need the value associated with them.
80+
81+
This is a constructed ASN.1 Content Specific item of 1 that is optional.
82+
83+
ASN.1 description would be something like:
84+
```
85+
maskGenAlgorithm [1] MaskGeneration Default mgf1SHA1
86+
```
87+
88+
89+
```c
90+
{ 1, ASN_CONTENT_SPECIFIC | 1, 1, 1, 1 },
91+
```
92+
93+
### Optional items
94+
95+
An optional boolean (like criticality of a certificate extension):
96+
97+
ASN.1 description would be something like:
98+
```
99+
critical BOOLEAN DEFAULT FALSE,
100+
```
101+
102+
```c
103+
{ 1, ASN_BOOLEAN, 0, 0, 1 },
104+
```
105+
106+
### Choice
107+
108+
Next ASN.1 item, at depth 2, is one of multiple types:
109+
110+
```c
111+
{ 2, ASN_TAG_NULL, 0, 0, 2 },
112+
{ 2, ASN_OBJECT_ID, 0, 0, 2 },
113+
{ 2, ASN_SEQUENCE, 1, 0, 2 },
114+
```
115+
116+
Note, use the optional value to uniquely identify the choices.
117+
118+
119+
120+
# Decoding function outline
121+
122+
An outline of a decoding function:
123+
124+
```c
125+
#include <wolfssl/wolfcrypt/asn.h>
126+
127+
...
128+
129+
static int Decode<Something>(const byte* input, int sz, <Object Type* <obj>)
130+
{
131+
DECL_ASNGETDATA(dataASN, <template>_Length);
132+
int ret = 0;
133+
/* Declare variables to parse data into. For example:
134+
* word32 idx = 0;
135+
* byte isCA = 0;
136+
*/
137+
138+
CALLOC_ASNGETDATA(dataASN, <template>_Length, ret, <obj>->heap);
139+
140+
if (ret == 0) {
141+
/* Set any variables to be filled in by the parser. For example:
142+
* GetASN_Boolean(&dataASN[BASICCONSASN_IDX_CA], &isCA);
143+
* GetASN_Int8Bit(&dataASN[BASICCONSASN_IDX_PLEN], &<obj>->pathLength);
144+
*/
145+
146+
/* Decode the ASN.1 DER. */
147+
ret = GetASN_Items(<template>, dataASN, <template>_Length, 1, input,
148+
&idx, (word32)sz);
149+
}
150+
151+
if (ret == 0) {
152+
/* Check data in variables is valid. */
153+
}
154+
if (ret == 0) {
155+
/* Put data in variables into object. */
156+
}
157+
158+
FREE_ASNGETDATA(dataASN, <obj>->heap);
159+
return ret;
160+
}
161+
```
162+

wolfcrypt/src/include.am

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,8 @@ EXTRA_DIST += wolfcrypt/src/port/ti/ti-aes.c \
146146
wolfcrypt/src/port/Renesas/README.md \
147147
wolfcrypt/src/port/cypress/psoc6_crypto.c \
148148
wolfcrypt/src/port/liboqs/liboqs.c \
149-
wolfcrypt/src/port/maxim/max3266x.c
149+
wolfcrypt/src/port/maxim/max3266x.c \
150+
wolfcrypt/src/ASN_TEMPLATE.md
150151

151152
$(ASYNC_FILES):
152153
$(AM_V_at)touch $(srcdir)/$@

0 commit comments

Comments
 (0)