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 
13 size_t
14 asn1_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 
35 asn1_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* */
63 get_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_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
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
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