libcoap 4.3.1
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
16#include "coap3/coap_internal.h"
17
18size_t
19asn1_len(const uint8_t **ptr)
20{
21 size_t len = 0;
22
23 if ((**ptr) & 0x80) {
24 size_t octets = (**ptr) & 0x7f;
25 (*ptr)++;
26 while (octets) {
27 len = (len << 8) + (**ptr);
28 (*ptr)++;
29 octets--;
30 }
31 }
32 else {
33 len = (**ptr) & 0x7f;
34 (*ptr)++;
35 }
36 return len;
37}
38
40asn1_tag_c(const uint8_t **ptr, int *constructed, int *class)
41{
42 coap_asn1_tag_t tag = 0;
43 uint8_t byte;
44
45 byte = (**ptr);
46 *constructed = (byte & 0x20) ? 1 : 0;
47 *class = byte >> 6;
48 tag = byte & 0x1F;
49 (*ptr)++;
50 if (tag < 0x1F)
51 return tag;
52
53 /* Tag can be one byte or more based on B8 */
54 byte = (**ptr);
55 while (byte & 0x80) {
56 tag = (tag << 7) + (byte & 0x7F);
57 (*ptr)++;
58 byte = (**ptr);
59 }
60 /* Do the final one */
61 tag = (tag << 7) + (byte & 0x7F);
62 (*ptr)++;
63 return tag;
64}
65
66/* caller must free off returned coap_binary_t* */
68get_asn1_tag(coap_asn1_tag_t ltag, const uint8_t *ptr, size_t tlen,
69 asn1_validate validate)
70{
71 int constructed;
72 int class;
73 const uint8_t *acp = ptr;
74 uint8_t tag = asn1_tag_c(&acp, &constructed, &class);
75 size_t len = asn1_len(&acp);
76 coap_binary_t *tag_data;
77
78 while (tlen > 0 && len <= tlen) {
79 if (class == 2 && constructed == 1) {
80 /* Skip over element description */
81 tag = asn1_tag_c(&acp, &constructed, &class);
82 len = asn1_len(&acp);
83 }
84 if (tag == ltag) {
85 if (!validate || validate(acp, len)) {
86 tag_data = coap_new_binary(len);
87 if (tag_data == NULL)
88 return NULL;
89 tag_data->length = len;
90 memcpy(tag_data->s, acp, len);
91 return tag_data;
92 }
93 }
94 if (tag == 0x10 && constructed == 1) {
95 /* SEQUENCE or SEQUENCE OF */
96 tag_data = get_asn1_tag(ltag, acp, len, validate);
97 if (tag_data)
98 return tag_data;
99 }
100 acp += len;
101 tlen -= len;
102 tag = asn1_tag_c(&acp, &constructed, &class);
103 len = asn1_len(&acp);
104 }
105 return NULL;
106}
107
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:68
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:40
size_t asn1_len(const uint8_t **ptr)
Get the asn1 length from the current ptr.
Definition: coap_asn1.c:19
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:72
CoAP binary data definition.
Definition: str.h:56
size_t length
length of binary data
Definition: str.h:57
uint8_t * s
binary data
Definition: str.h:58