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