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 
18 size_t
19 asn1_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 
40 asn1_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* */
68 get_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_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
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
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