asn1_module

# Asn1_module

mbedtls_asn1_buf
mbedtls_asn1_bitstring
mbedtls_asn1_sequence
mbedtls_asn1_named_data
Functions to parse ASN.1 data structures
struct mbedtls_asn1_buf typedef struct mbedtls_asn1_buf mbedtls_asn1_buf mbedtls_asn1_buf

Type-length-value structure that allows for ASN1 using DER.

struct mbedtls_asn1_bitstring typedef struct mbedtls_asn1_bitstring mbedtls_asn1_bitstring mbedtls_asn1_bitstring

Container for ASN1 bit strings.

struct mbedtls_asn1_sequence typedef struct mbedtls_asn1_sequence mbedtls_asn1_sequence mbedtls_asn1_sequence

Container for a sequence of ASN.1 items

struct mbedtls_asn1_named_data typedef struct mbedtls_asn1_named_data mbedtls_asn1_named_data mbedtls_asn1_named_data

Container for a sequence or list of 'named' ASN.1 data items

int int mbedtls_asn1_get_len (unsigned char **p, const unsigned char *end, size_t *len) mbedtls_asn1_get_len unsigned char ** p const unsigned char * end size_t * len

Get the length of an ASN.1 element. Updates the pointer to immediately behind the length.

p

On entry, `*p` points to the first byte of the length, i.e. immediately after the tag. On successful completion, `*p` points to the first byte after the length, i.e. the first byte of the content. On error, the value of `*p` is undefined.

end

End of data.

len

On successful completion, `*len` contains the length read from the ASN.1 input.

0 if successful.

MBEDTLS_ERR_ASN1_OUT_OF_DATA if the ASN.1 element would end beyond `end`.

MBEDTLS_ERR_ASN1_INVALID_LENGTH if the length is unparsable.

int int mbedtls_asn1_get_tag (unsigned char **p, const unsigned char *end, size_t *len, int tag) mbedtls_asn1_get_tag unsigned char ** p const unsigned char * end size_t * len int tag

Get the tag and length of the element. Check for the requested tag. Updates the pointer to immediately behind the tag and length.

p

On entry, `*p` points to the start of the ASN.1 element. On successful completion, `*p` points to the first byte after the length, i.e. the first byte of the content. On error, the value of `*p` is undefined.

end

End of data.

len

On successful completion, `*len` contains the length read from the ASN.1 input.

tag

The expected tag.

0 if successful.

MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the data does not start with the requested tag.

MBEDTLS_ERR_ASN1_OUT_OF_DATA if the ASN.1 element would end beyond `end`.

MBEDTLS_ERR_ASN1_INVALID_LENGTH if the length is unparsable.

int int mbedtls_asn1_get_bool (unsigned char **p, const unsigned char *end, int *val) mbedtls_asn1_get_bool unsigned char ** p const unsigned char * end int * val

Retrieve a boolean ASN.1 tag and its value. Updates the pointer to immediately behind the full tag.

p

On entry, `*p` points to the start of the ASN.1 element. On successful completion, `*p` points to the first byte beyond the ASN.1 element. On error, the value of `*p` is undefined.

end

End of data.

val

On success, the parsed value (`0` or `1`).

0 if successful.

An ASN.1 error code if the input does not start with a valid ASN.1 BOOLEAN.

int int mbedtls_asn1_get_int (unsigned char **p, const unsigned char *end, int *val) mbedtls_asn1_get_int unsigned char ** p const unsigned char * end int * val

Retrieve an integer ASN.1 tag and its value. Updates the pointer to immediately behind the full tag.

p

On entry, `*p` points to the start of the ASN.1 element. On successful completion, `*p` points to the first byte beyond the ASN.1 element. On error, the value of `*p` is undefined.

end

End of data.

val

On success, the parsed value.

0 if successful.

An ASN.1 error code if the input does not start with a valid ASN.1 INTEGER.

MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does not fit in an `int`.

int int mbedtls_asn1_get_enum (unsigned char **p, const unsigned char *end, int *val) mbedtls_asn1_get_enum unsigned char ** p const unsigned char * end int * val

Retrieve an enumerated ASN.1 tag and its value. Updates the pointer to immediately behind the full tag.

p

On entry, `*p` points to the start of the ASN.1 element. On successful completion, `*p` points to the first byte beyond the ASN.1 element. On error, the value of `*p` is undefined.

end

End of data.

val

On success, the parsed value.

0 if successful.

An ASN.1 error code if the input does not start with a valid ASN.1 ENUMERATED.

MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does not fit in an `int`.

int int mbedtls_asn1_get_bitstring (unsigned char **p, const unsigned char *end, mbedtls_asn1_bitstring *bs) mbedtls_asn1_get_bitstring unsigned char ** p const unsigned char * end mbedtls_asn1_bitstring * bs

Retrieve a bitstring ASN.1 tag and its value. Updates the pointer to immediately behind the full tag.

p

On entry, `*p` points to the start of the ASN.1 element. On successful completion, `*p` is equal to `end`. On error, the value of `*p` is undefined.

end

End of data.

bs

On success, mbedtls_asn1_bitstring information about the parsed value.

0 if successful.

MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the input contains extra data after a valid BIT STRING.

An ASN.1 error code if the input does not start with a valid ASN.1 BIT STRING.

int int mbedtls_asn1_get_bitstring_null (unsigned char **p, const unsigned char *end, size_t *len) mbedtls_asn1_get_bitstring_null unsigned char ** p const unsigned char * end size_t * len

Retrieve a bitstring ASN.1 tag without unused bits and its value. Updates the pointer to the beginning of the bit/octet string.

p

On entry, `*p` points to the start of the ASN.1 element. On successful completion, `*p` points to the first byte of the content of the BIT STRING. On error, the value of `*p` is undefined.

end

End of data.

len

On success, `*len` is the length of the content in bytes.

0 if successful.

MBEDTLS_ERR_ASN1_INVALID_DATA if the input starts with a valid BIT STRING with a nonzero number of unused bits.

An ASN.1 error code if the input does not start with a valid ASN.1 BIT STRING.

int int mbedtls_asn1_get_sequence_of (unsigned char **p, const unsigned char *end, mbedtls_asn1_sequence *cur, int tag) mbedtls_asn1_get_sequence_of unsigned char ** p const unsigned char * end mbedtls_asn1_sequence * cur int tag

Parses and splits an ASN.1 "SEQUENCE OF <tag>". Updates the pointer to immediately behind the full sequence tag.

This function allocates memory for the sequence elements. You can free the allocated memory with mbedtls_asn1_sequence_free().

On error, this function may return a partial list in `cur`. You must set `cur->next = NULL` before calling this function! Otherwise it is impossible to distinguish a previously non-null pointer from a pointer to an object allocated by this function.

If the sequence is empty, this function does not modify `*cur`. If the sequence is valid and non-empty, this function sets `cur->buf.tag` to `tag`. This allows callers to distinguish between an empty sequence and a one-element sequence.

p

On entry, `*p` points to the start of the ASN.1 element. On successful completion, `*p` is equal to `end`. On error, the value of `*p` is undefined.

end

End of data.

cur

A mbedtls_asn1_sequence which this function fills. When this function returns, `*cur` is the head of a linked list. Each node in this list is allocated with mbedtls_calloc() apart from `cur` itself, and should therefore be freed with mbedtls_free(). The list describes the content of the sequence. The head of the list (i.e. `*cur` itself) describes the first element, `*cur->next` describes the second element, etc. For each element, `buf.tag == tag`, `buf.len` is the length of the content of the content of the element, and `buf.p` points to the first byte of the content (i.e. immediately past the length of the element). Note that list elements may be allocated even on error.

tag

Each element of the sequence must have this tag.

0 if successful.

MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the input contains extra data after a valid SEQUENCE OF `tag`.

MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the input starts with an ASN.1 SEQUENCE in which an element has a tag that is different from `tag`.

MBEDTLS_ERR_ASN1_ALLOC_FAILED if a memory allocation failed.

An ASN.1 error code if the input does not start with a valid ASN.1 SEQUENCE.

void void mbedtls_asn1_sequence_free (mbedtls_asn1_sequence *seq) mbedtls_asn1_sequence_free mbedtls_asn1_sequence * seq

Free a heap-allocated linked list presentation of an ASN.1 sequence, including the first element.

There are two common ways to manage the memory used for the representation of a parsed ASN.1 sequence:

- Allocate a head node `mbedtls_asn1_sequence *head` with mbedtls_calloc(). Pass this node as the `cur` argument to mbedtls_asn1_get_sequence_of(). When you have finished processing the sequence, call mbedtls_asn1_sequence_free() on `head`.

- Allocate a head node `mbedtls_asn1_sequence *head` in any manner, for example on the stack. Make sure that `head->next == NULL`. Pass `head` as the `cur` argument to mbedtls_asn1_get_sequence_of(). When you have finished processing the sequence, call mbedtls_asn1_sequence_free() on `head->cur`, then free `head` itself in the appropriate manner.

seq

The address of the first sequence component. This may be `NULL`, in which case this functions returns immediately.

int int mbedtls_asn1_traverse_sequence_of (unsigned char **p, const unsigned char *end, unsigned char tag_must_mask, unsigned char tag_must_val, unsigned char tag_may_mask, unsigned char tag_may_val, int(*cb)(void *ctx, int tag, unsigned char *start, size_t len), void *ctx) mbedtls_asn1_traverse_sequence_of unsigned char ** p const unsigned char * end unsigned char tag_must_mask unsigned char tag_must_val unsigned char tag_may_mask unsigned char tag_may_val int(*)(void *ctx, int tag, unsigned char *start, size_t len) cb void * ctx

Traverse an ASN.1 SEQUENCE container and call a callback for each entry.

This function checks that the input is a SEQUENCE of elements that each have a "must" tag, and calls a callback function on the elements that have a "may" tag.

For example, to validate that the input is a SEQUENCE of `tag1` and call `cb` on each element, use

    mbedtls_asn1_traverse_sequence_of(&p,end,0xff,tag1,0,0,cb,ctx);

To validate that the input is a SEQUENCE of ANY and call `cb` on each element, use

    mbedtls_asn1_traverse_sequence_of(&p,end,0,0,0,0,cb,ctx);

To validate that the input is a SEQUENCE of CHOICE {NULL, OCTET STRING} and call `cb` on each element that is an OCTET STRING, use

    mbedtls_asn1_traverse_sequence_of(&p,end,0xfe,0x04,0xff,0x04,cb,ctx);

The callback is called on the elements with a "may" tag from left to right. If the input is not a valid SEQUENCE of elements with a "must" tag, the callback is called on the elements up to the leftmost point where the input is invalid.

This function is still experimental and may change at any time.

p

The address of the pointer to the beginning of the ASN.1 SEQUENCE header. This is updated to point to the end of the ASN.1 SEQUENCE container on a successful invocation.

end

The end of the ASN.1 SEQUENCE container.

tag_must_mask

A mask to be applied to the ASN.1 tags found within the SEQUENCE before comparing to `tag_must_val`.

tag_must_val

The required value of each ASN.1 tag found in the SEQUENCE, after masking with `tag_must_mask`. Mismatching tags lead to an error. For example, a value of `0` for both `tag_must_mask` and `tag_must_val` means that every tag is allowed, while a value of `0xFF` for `tag_must_mask` means that `tag_must_val` is the only allowed tag.

tag_may_mask

A mask to be applied to the ASN.1 tags found within the SEQUENCE before comparing to `tag_may_val`.

tag_may_val

The desired value of each ASN.1 tag found in the SEQUENCE, after masking with `tag_may_mask`. Mismatching tags will be silently ignored. For example, a value of `0` for `tag_may_mask` and `tag_may_val` means that any tag will be considered, while a value of `0xFF` for `tag_may_mask` means that all tags with value different from `tag_may_val` will be ignored.

cb

The callback to trigger for each component in the ASN.1 SEQUENCE that matches `tag_may_val`. The callback function is called with the following parameters:

- `ctx`.

- The tag of the current element.

- A pointer to the start of the current element's content inside the input.

- The length of the content of the current element. If the callback returns a non-zero value, the function stops immediately, forwarding the callback's return value.

ctx

The context to be passed to the callback `cb`.

`0` if successful the entire ASN.1 SEQUENCE was traversed without parsing or callback errors.

MBEDTLS_ERR_ASN1_LENGTH_MISMATCH if the input contains extra data after a valid SEQUENCE of elements with an accepted tag.

MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if the input starts with an ASN.1 SEQUENCE in which an element has a tag that is not accepted.

An ASN.1 error code if the input does not start with a valid ASN.1 SEQUENCE.

A non-zero error code forwarded from the callback `cb` in case the latter returns a non-zero value.

int int mbedtls_asn1_get_mpi (unsigned char **p, const unsigned char *end, mbedtls_mpi *X) mbedtls_asn1_get_mpi unsigned char ** p const unsigned char * end mbedtls_mpi * X

Retrieve an integer ASN.1 tag and its value. Updates the pointer to immediately behind the full tag.

p

On entry, `*p` points to the start of the ASN.1 element. On successful completion, `*p` points to the first byte beyond the ASN.1 element. On error, the value of `*p` is undefined.

end

End of data.

X

On success, the parsed value.

0 if successful.

An ASN.1 error code if the input does not start with a valid ASN.1 INTEGER.

MBEDTLS_ERR_ASN1_INVALID_LENGTH if the parsed value does not fit in an `int`.

An MPI error code if the parsed value is too large.

int int mbedtls_asn1_get_alg (unsigned char **p, const unsigned char *end, mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params) mbedtls_asn1_get_alg unsigned char ** p const unsigned char * end mbedtls_asn1_buf * alg mbedtls_asn1_buf * params

Retrieve an AlgorithmIdentifier ASN.1 sequence. Updates the pointer to immediately behind the full AlgorithmIdentifier.

p

On entry, `*p` points to the start of the ASN.1 element. On successful completion, `*p` points to the first byte beyond the AlgorithmIdentifier element. On error, the value of `*p` is undefined.

end

End of data.

alg

The buffer to receive the OID.

params

The buffer to receive the parameters. This is zeroized if there are no parameters.

0 if successful or a specific ASN.1 or MPI error code.

int int mbedtls_asn1_get_alg_null (unsigned char **p, const unsigned char *end, mbedtls_asn1_buf *alg) mbedtls_asn1_get_alg_null unsigned char ** p const unsigned char * end mbedtls_asn1_buf * alg

Retrieve an AlgorithmIdentifier ASN.1 sequence with NULL or no params. Updates the pointer to immediately behind the full AlgorithmIdentifier.

p

On entry, `*p` points to the start of the ASN.1 element. On successful completion, `*p` points to the first byte beyond the AlgorithmIdentifier element. On error, the value of `*p` is undefined.

end

End of data.

alg

The buffer to receive the OID.

0 if successful or a specific ASN.1 or MPI error code.

const mbedtls_asn1_named_data * const mbedtls_asn1_named_data * mbedtls_asn1_find_named_data (const mbedtls_asn1_named_data *list, const char *oid, size_t len) mbedtls_asn1_find_named_data const mbedtls_asn1_named_data * list const char * oid size_t len

Find a specific named_data entry in a sequence or list based on the OID.

list

The list to seek through

oid

The OID to look for

len

Size of the OID

NULL if not found, or a pointer to the existing entry.

void MBEDTLS_DEPRECATED void MBEDTLS_DEPRECATED mbedtls_asn1_free_named_data (mbedtls_asn1_named_data *entry) mbedtls_asn1_free_named_data mbedtls_asn1_named_data * entry

Free a mbedtls_asn1_named_data entry.

Deprecated

This function is deprecated and will be removed in a future version of the library. Please use mbedtls_asn1_free_named_data_list() or mbedtls_asn1_free_named_data_list_shallow().

entry

The named data entry to free. This function calls mbedtls_free() on `entry->oid.p` and `entry->val.p`.

MBEDTLS_DEPRECATED
void void mbedtls_asn1_free_named_data_list (mbedtls_asn1_named_data **head) mbedtls_asn1_free_named_data_list mbedtls_asn1_named_data ** head

Free all entries in a mbedtls_asn1_named_data list.

head

Pointer to the head of the list of named data entries to free. This function calls mbedtls_free() on `entry->oid.p` and `entry->val.p` and then on `entry` for each list entry, and sets `*head` to `NULL`.

void void mbedtls_asn1_free_named_data_list_shallow (mbedtls_asn1_named_data *name) mbedtls_asn1_free_named_data_list_shallow mbedtls_asn1_named_data * name

Free all shallow entries in a mbedtls_asn1_named_data list, but do not free internal pointer targets.

name

Head of the list of named data entries to free. This function calls mbedtls_free() on each list element.

ASN1 Error codes

These error codes are combined with other error codes for higher error granularity. e.g. X.509 and PKCS #7 error codes ASN1 is a standard to specify data structures.

MBEDTLS_ERR_ASN1_OUT_OF_DATA
-0x0060

Out of data when parsing an ASN1 data structure.

MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
-0x0062

ASN1 tag was of an unexpected value.

MBEDTLS_ERR_ASN1_INVALID_LENGTH
-0x0064

Error when trying to determine the length or invalid length.

MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
-0x0066

Actual length differs from expected length.

MBEDTLS_ERR_ASN1_INVALID_DATA
-0x0068

Data is invalid.

MBEDTLS_ERR_ASN1_ALLOC_FAILED
-0x006A

Memory allocation failed

MBEDTLS_ERR_ASN1_BUF_TOO_SMALL
-0x006C

Buffer too small when writing ASN.1 data structure.

DER constants

These constants comply with the DER encoded ASN.1 type tags. DER encoding uses hexadecimal representation. An example DER sequence is:

- 0x02 tag indicating INTEGER

- 0x01 length in octets

- 0x05 value Such sequences are typically read into `mbedtls_x509_buf`.

MBEDTLS_ASN1_BOOLEAN
0x01
MBEDTLS_ASN1_INTEGER
0x02
MBEDTLS_ASN1_BIT_STRING
0x03
MBEDTLS_ASN1_OCTET_STRING
0x04
MBEDTLS_ASN1_NULL
0x05
MBEDTLS_ASN1_OID
0x06
MBEDTLS_ASN1_ENUMERATED
0x0A
MBEDTLS_ASN1_UTF8_STRING
0x0C
MBEDTLS_ASN1_SEQUENCE
0x10
MBEDTLS_ASN1_SET
0x11
MBEDTLS_ASN1_PRINTABLE_STRING
0x13
MBEDTLS_ASN1_T61_STRING
0x14
MBEDTLS_ASN1_IA5_STRING
0x16
MBEDTLS_ASN1_UTC_TIME
0x17
MBEDTLS_ASN1_GENERALIZED_TIME
0x18
MBEDTLS_ASN1_UNIVERSAL_STRING
0x1C
MBEDTLS_ASN1_BMP_STRING
0x1E
MBEDTLS_ASN1_PRIMITIVE
0x00
MBEDTLS_ASN1_CONSTRUCTED
0x20
MBEDTLS_ASN1_CONTEXT_SPECIFIC
0x80
MBEDTLS_ASN1_IS_STRING_TAG
tag
((unsigned int) (tag) < 32u && ( \ ((1u << (tag)) & ((1u << MBEDTLS_ASN1_BMP_STRING) | \ (1u << MBEDTLS_ASN1_UTF8_STRING) | \ (1u << MBEDTLS_ASN1_T61_STRING) | \ (1u << MBEDTLS_ASN1_IA5_STRING) | \ (1u << MBEDTLS_ASN1_UNIVERSAL_STRING) | \ (1u << MBEDTLS_ASN1_PRINTABLE_STRING))) != 0))
MBEDTLS_ASN1_TAG_CLASS_MASK
0xC0
MBEDTLS_ASN1_TAG_PC_MASK
0x20
MBEDTLS_ASN1_TAG_VALUE_MASK
0x1F
MBEDTLS_OID_SIZE
x
(sizeof(x) - 1)

Returns the size of the binary string, without the trailing \0

MBEDTLS_OID_CMP
oid_str
oid_buf
((MBEDTLS_OID_SIZE(oid_str) != (oid_buf)->len) || \ memcmp((oid_str), (oid_buf)->p, (oid_buf)->len) != 0)

Compares an mbedtls_asn1_buf structure to a reference OID.

Only works for 'defined' oid_str values (MBEDTLS_OID_HMAC_SHA1), you cannot use a 'unsigned char *oid' here!

MBEDTLS_OID_CMP_RAW
oid_str
oid_buf
oid_buf_len
((MBEDTLS_OID_SIZE(oid_str) != (oid_buf_len)) || \ memcmp((oid_str), (oid_buf), (oid_buf_len)) != 0)