libcoap 4.3.0
coap_asn1.c
Go to the documentation of this file.
1/* coap_asn1.c -- ASN.1 handling functions
2*
3* Copyright (C) 2020 Jon Shallow <supjps-libcoap@jpshallow.com>
4*
5 * SPDX-License-Identifier: BSD-2-Clause
6 *
7* This file is part of the CoAP library libcoap. Please see
8* README for terms of use.
9*/
10
11#include "coap3/coap_internal.h"
12
13size_t
14asn1_len(const uint8_t **ptr)
15{
16 size_t len = 0;
17
18 if ((**ptr) & 0x80) {
19 size_t octets = (**ptr) & 0x7f;
20 (*ptr)++;
21 while (octets) {
22 len = (len << 8) + (**ptr);
23 (*ptr)++;
24 octets--;
25 }
26 }
27 else {
28 len = (**ptr) & 0x7f;
29 (*ptr)++;
30 }
31 return len;
32}
33
35asn1_tag_c(const uint8_t **ptr, int *constructed, int *class)
36{
37 coap_asn1_tag_t tag = 0;
38 uint8_t byte;
39
40 byte = (**ptr);
41 *constructed = (byte & 0x20) ? 1 : 0;
42 *class = byte >> 6;
43 tag = byte & 0x1F;
44 (*ptr)++;
45 if (tag < 0x1F)
46 return tag;
47
48 /* Tag can be one byte or more based on B8 */
49 byte = (**ptr);
50 while (byte & 0x80) {
51 tag = (tag << 7) + (byte & 0x7F);
52 (*ptr)++;
53 byte = (**ptr);
54 }
55 /* Do the final one */
56 tag = (tag << 7) + (byte & 0x7F);
57 (*ptr)++;
58 return tag;
59}
60
61/* caller must free off returned coap_binary_t* */
63get_asn1_tag(coap_asn1_tag_t ltag, const uint8_t *ptr, size_t tlen,
64 asn1_validate validate)
65{
66 int constructed;
67 int class;
68 const uint8_t *acp = ptr;
69 uint8_t tag = asn1_tag_c(&acp, &constructed, &class);
70 size_t len = asn1_len(&acp);
71 coap_binary_t *tag_data;
72
73 while (tlen > 0 && len <= tlen) {
74 if (class == 2 && constructed == 1) {
75 /* Skip over element description */
76 tag = asn1_tag_c(&acp, &constructed, &class);
77 len = asn1_len(&acp);
78 }
79 if (tag == ltag) {
80 if (!validate || validate(acp, len)) {
81 tag_data = coap_new_binary(len);
82 if (tag_data == NULL)
83 return NULL;
84 tag_data->length = len;
85 memcpy(tag_data->s, acp, len);
86 return tag_data;
87 }
88 }
89 if (tag == 0x10 && constructed == 1) {
90 /* SEQUENCE or SEQUENCE OF */
91 tag_data = get_asn1_tag(ltag, acp, len, validate);
92 if (tag_data)
93 return tag_data;
94 }
95 acp += len;
96 tlen -= len;
97 tag = asn1_tag_c(&acp, &constructed, &class);
98 len = asn1_len(&acp);
99 }
100 return NULL;
101}
102
Pulls together all the internal only header files.
coap_binary_t * get_asn1_tag(coap_asn1_tag_t ltag, const uint8_t *ptr, size_t tlen, asn1_validate validate)
Get the asn1 tag and data from the current ptr.
Definition: coap_asn1.c:63
coap_asn1_tag_t asn1_tag_c(const uint8_t **ptr, int *constructed, int *class)
Get the asn1 tag from the current ptr.
Definition: coap_asn1.c:35
size_t asn1_len(const uint8_t **ptr)
Get the asn1 length from the current ptr.
Definition: coap_asn1.c:14
coap_asn1_tag_t
int(* asn1_validate)(const uint8_t *data, size_t size)
Callback to validate the asn1 tag and data.
coap_binary_t * coap_new_binary(size_t size)
Returns a new binary object with at least size bytes storage allocated.
Definition: str.c:67
CoAP binary data definition.
Definition: str.h:50
size_t length
length of binary data
Definition: str.h:51
uint8_t * s
binary data
Definition: str.h:52