libcoap 4.3.2rc2

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