Skip to content

Commit

Permalink
ASN template documentation: adding basics for decoding
Browse files Browse the repository at this point in the history
First draft of ASN template documentation that helps with writing
parsing code.
  • Loading branch information
SparkiDev committed Oct 29, 2024
1 parent 202822c commit 183cb6f
Showing 1 changed file with 113 additions and 0 deletions.
113 changes: 113 additions & 0 deletions wolfcrypt/src/ASN_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@


# Writing a template

```c
static const ASNItem <template>[] = {
/* <ELEM_0> */ { <depth>, <ASN Type>, <constructed>, <header>, <optional> },
...
};
enum {
<TEMPLATE>_<ELEM_0> = 0,
<TEMPLATE>_<ELEM_1>,
...
};
#define <template>_Length (sizeof(<template>) / sizeof(ASNItem))
```

## Examples of ASN.1 items

### Sequence

When you have a sequence at depth 0 and want to parse the contents:

```c
{ 0, ASN_SEQUENCE, 1, 1, 0 },
```
To skip over the contents of the sequence:
```c
{ 0, ASN_SEQUENCE, 1, 0, 0 },
```

### Simple types

An INTEGER at depth 1:

```c
{ 1, ASN_INTEGER, 0, 0, 1 },
```
An OCTET_STRING at depth 1 but stop after header in order to parse contents:
```c
{ 1, ASN_COTET_STRING, 0, 1, 0 },
```


### Optional items

An optional boolean (like criticality of a certificate extension):

```c
{ 1, ASN_BOOLEAN, 0, 0, 1 },
```
### Choice
Next ASN.1 item, at depth 2, is one of multiple types:
```c
{ 2, ASN_TAG_NULL, 0, 0, 2 },
{ 2, ASN_OBJECT_ID, 0, 0, 2 },
{ 2, ASN_SEQUENCE, 1, 0, 2 },
```

Note, use the optional value to uniquely identify the choices.



# Decoding function outline

An outline of a decoding function:

```c
#include <wolfssl/wolfcrypt/asn.h>

...

static int Decode<Something>(const byte* input, int sz, <Object Type* <obj>)
{
DECL_ASNGETDATA(dataASN, <template>_Length);
int ret = 0;
/* Declare variables to parse data into. For example:
* word32 idx = 0;
* byte isCA = 0;
*/

CALLOC_ASNGETDATA(dataASN, <template>_Length, ret, <obj>->heap);

if (ret == 0) {
/* Set any variables to be filled in by the parser. For example:
* GetASN_Boolean(&dataASN[BASICCONSASN_IDX_CA], &isCA);
* GetASN_Int8Bit(&dataASN[BASICCONSASN_IDX_PLEN], &<obj>->pathLength);
*/

/* Decode the ASN.1 DER. */
ret = GetASN_Items(<template>, dataASN, <template>_Length, 1, input,
&idx, (word32)sz);
}

if (ret == 0) {
/* Check data in variables is valid. */
}
if (ret == 0) {
/* Put data in variables into object. */
}

FREE_ASNGETDATA(dataASN, <obj>->heap);
return ret;
}
```

0 comments on commit 183cb6f

Please sign in to comment.