libcoap
4.3.5
Toggle main menu visibility
Loading...
Searching...
No Matches
coap_asn1.c
Go to the documentation of this file.
1
/* coap_asn1.c -- ASN.1 handling functions
2
*
3
* Copyright (C) 2020-2024 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
15
16
#include "
coap3/coap_libcoap_build.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
}
103
104
/* first part of Raw public key, this is the start of the Subject Public Key */
105
static
const
unsigned
char
cert_asn1_header1
[] = {
106
0x30, 0x59,
/* SEQUENCE, length 89 bytes */
107
0x30, 0x13,
/* SEQUENCE, length 19 bytes */
108
0x06, 0x07,
/* OBJECT IDENTIFIER ecPublicKey (1 2 840 10045 2 1) */
109
0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01,
110
};
111
/* PrimeX will get inserted */
112
#if 0
113
0x06, 0x08,
/* OBJECT IDENTIFIER prime256v1 (1 2 840 10045 3 1 7) */
114
0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07,
115
#endif
116
static
const
unsigned
char
cert_asn1_header2
[] = {
117
0x03, 0x42,
/* BIT STRING, length 66 bytes */
118
/* Note: 0 bits (0x00) and no compression (0x04) are already in the certificate */
119
};
120
121
coap_binary_t
*
122
get_asn1_spki
(
const
uint8_t *data,
size_t
size) {
123
coap_binary_t
*pub_key =
get_asn1_tag
(
COAP_ASN1_BITSTRING
, data, size, NULL);
124
coap_binary_t
*prime =
get_asn1_tag
(
COAP_ASN1_IDENTIFIER
, data, size, NULL);
125
coap_binary_t
*spki = NULL;
126
127
if
(pub_key && prime) {
128
size_t
header_size =
sizeof
(
cert_asn1_header1
) +
129
2 +
130
prime->
length
+
131
sizeof
(
cert_asn1_header2
);
132
spki =
coap_new_binary
(header_size + pub_key->
length
);
133
if
(spki) {
134
memcpy(&spki->
s
[header_size], pub_key->
s
, pub_key->
length
);
135
memcpy(spki->
s
,
cert_asn1_header1
,
sizeof
(
cert_asn1_header1
));
136
spki->
s
[
sizeof
(
cert_asn1_header1
)] =
COAP_ASN1_IDENTIFIER
;
137
spki->
s
[
sizeof
(
cert_asn1_header1
)+1] = (uint8_t)prime->
length
;
138
memcpy(&spki->
s
[
sizeof
(
cert_asn1_header1
)+2],
139
prime->
s
, prime->
length
);
140
memcpy(&spki->
s
[
sizeof
(
cert_asn1_header1
)+2+prime->
length
],
141
cert_asn1_header2
,
sizeof
(
cert_asn1_header2
));
142
spki->
length
= header_size + pub_key->
length
;
143
}
144
}
145
if
(pub_key)
146
coap_delete_binary
(pub_key);
147
if
(prime)
148
coap_delete_binary
(prime);
149
return
spki;
150
}
cert_asn1_header2
static const unsigned char cert_asn1_header2[]
Definition
coap_asn1.c:116
cert_asn1_header1
static const unsigned char cert_asn1_header1[]
Definition
coap_asn1.c:105
coap_libcoap_build.h
Library specific build wrapper for coap_internal.h.
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
get_asn1_spki
coap_binary_t * get_asn1_spki(const uint8_t *data, size_t size)
Abstract SPKI public key from the ASN1.
Definition
coap_asn1.c:122
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_ASN1_BITSTRING
@ COAP_ASN1_BITSTRING
Definition
coap_asn1_internal.h:32
COAP_ASN1_IDENTIFIER
@ COAP_ASN1_IDENTIFIER
Definition
coap_asn1_internal.h:34
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_delete_binary
void coap_delete_binary(coap_binary_t *s)
Deletes the given coap_binary_t object and releases any memory allocated.
Definition
coap_str.c:105
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
src
coap_asn1.c
Generated on
for libcoap by
1.17.0