libcoap
4.3.5b
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-2026 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,
size_t
*plen) {
20
size_t
len = 0;
21
22
if
(*plen == 0)
23
return
0;
24
if
((**ptr) & 0x80) {
25
size_t
octets = (**ptr) & 0x7f;
26
(*plen)--;
27
(*ptr)++;
28
while
(octets) {
29
if
(*plen == 0)
30
return
0;
31
len = (len << 8) + (**ptr);
32
(*plen)--;
33
(*ptr)++;
34
octets--;
35
}
36
}
else
{
37
if
(*plen == 0)
38
return
0;
39
len = (**ptr) & 0x7f;
40
(*plen)--;
41
(*ptr)++;
42
}
43
if
(len > *plen)
44
return
*plen;
45
return
len;
46
}
47
48
coap_asn1_tag_t
49
asn1_tag_c
(
const
uint8_t **ptr,
size_t
*plen,
int
*constructed,
int
*cls) {
50
coap_asn1_tag_t
tag = 0;
51
uint8_t byte;
52
53
if
(*plen == 0) {
54
*constructed = 0;
55
*cls = 0;
56
return
COAP_ASN1_FAIL
;
57
}
58
byte
= (**ptr);
59
*constructed = (
byte
& 0x20) ? 1 : 0;
60
*cls =
byte
>> 6;
61
tag =
byte
& 0x1F;
62
(*plen)--;
63
(*ptr)++;
64
if
(tag < 0x1F)
65
return
tag;
66
67
/* Tag can be one byte or more based on B8 */
68
if
(*plen == 0)
69
return
COAP_ASN1_FAIL
;
70
byte
= (**ptr);
71
while
(
byte
& 0x80) {
72
tag = (tag << 7) + (
byte
& 0x7F);
73
(*plen)--;
74
(*ptr)++;
75
if
(*plen == 0)
76
return
COAP_ASN1_FAIL
;
77
byte
= (**ptr);
78
}
79
/* Do the final one */
80
tag = (tag << 7) + (
byte
& 0x7F);
81
(*plen)--;
82
(*ptr)++;
83
return
tag;
84
}
85
86
/* caller must free off returned coap_binary_t* */
87
coap_binary_t
*
88
get_asn1_tag
(
coap_asn1_tag_t
ltag,
const
uint8_t *ptr,
size_t
tlen,
89
asn1_validate
validate) {
90
int
constructed;
91
int
class
;
92
coap_asn1_tag_t
tag =
asn1_tag_c
(&ptr, &tlen, &constructed, &
class
);
93
size_t
len;
94
coap_binary_t
*tag_data;
95
96
if
(tag ==
COAP_ASN1_FAIL
)
97
return
NULL;
98
len =
asn1_len
(&ptr, &tlen);
99
100
while
(tlen > 0 && len <= tlen) {
101
if
(
class
== 2 && constructed == 1) {
102
/* Skip over element description */
103
tag =
asn1_tag_c
(&ptr, &tlen, &constructed, &
class
);
104
if
(tag ==
COAP_ASN1_FAIL
)
105
return
NULL;
106
len =
asn1_len
(&ptr, &tlen);
107
}
108
if
(tag == ltag) {
109
if
(!validate || validate(ptr, len)) {
110
tag_data =
coap_new_binary
(len);
111
if
(tag_data == NULL)
112
return
NULL;
113
tag_data->
length
= len;
114
memcpy(tag_data->
s
, ptr, len);
115
return
tag_data;
116
}
117
}
118
if
(tag == 0x10 && constructed == 1) {
119
/* SEQUENCE or SEQUENCE OF */
120
tag_data =
get_asn1_tag
(ltag, ptr, len, validate);
121
if
(tag_data)
122
return
tag_data;
123
}
124
/* Skip over non matching tag */
125
ptr += len;
126
tlen -= len;
127
tag =
asn1_tag_c
(&ptr, &tlen, &constructed, &
class
);
128
if
(tag ==
COAP_ASN1_FAIL
)
129
return
NULL;
130
len =
asn1_len
(&ptr, &tlen);
131
}
132
return
NULL;
133
}
134
135
/* first part of Raw public key, this is the start of the Subject Public Key */
136
static
const
unsigned
char
cert_asn1_header1
[] = {
137
0x30, 0x59,
/* SEQUENCE, length 89 bytes */
138
0x30, 0x13,
/* SEQUENCE, length 19 bytes */
139
0x06, 0x07,
/* OBJECT IDENTIFIER ecPublicKey (1 2 840 10045 2 1) */
140
0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x02, 0x01,
141
};
142
/* PrimeX will get inserted */
143
#if 0
144
0x06, 0x08,
/* OBJECT IDENTIFIER prime256v1 (1 2 840 10045 3 1 7) */
145
0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07,
146
#endif
147
static
const
unsigned
char
cert_asn1_header2
[] = {
148
0x03, 0x42,
/* BIT STRING, length 66 bytes */
149
/* Note: 0 bits (0x00) and no compression (0x04) are already in the certificate */
150
};
151
152
coap_binary_t
*
153
get_asn1_spki
(
const
uint8_t *data,
size_t
size) {
154
coap_binary_t
*pub_key =
get_asn1_tag
(
COAP_ASN1_BITSTRING
, data, size, NULL);
155
coap_binary_t
*prime =
get_asn1_tag
(
COAP_ASN1_IDENTIFIER
, data, size, NULL);
156
coap_binary_t
*spki = NULL;
157
158
if
(pub_key && prime) {
159
size_t
header_size =
sizeof
(
cert_asn1_header1
) +
160
2 +
161
prime->
length
+
162
sizeof
(
cert_asn1_header2
);
163
spki =
coap_new_binary
(header_size + pub_key->
length
);
164
if
(spki) {
165
memcpy(&spki->
s
[header_size], pub_key->
s
, pub_key->
length
);
166
memcpy(spki->
s
,
cert_asn1_header1
,
sizeof
(
cert_asn1_header1
));
167
spki->
s
[
sizeof
(
cert_asn1_header1
)] =
COAP_ASN1_IDENTIFIER
;
168
spki->
s
[
sizeof
(
cert_asn1_header1
)+1] = (uint8_t)prime->
length
;
169
memcpy(&spki->
s
[
sizeof
(
cert_asn1_header1
)+2],
170
prime->
s
, prime->
length
);
171
memcpy(&spki->
s
[
sizeof
(
cert_asn1_header1
)+2+prime->
length
],
172
cert_asn1_header2
,
sizeof
(
cert_asn1_header2
));
173
spki->
length
= header_size + pub_key->
length
;
174
}
175
}
176
if
(pub_key)
177
coap_delete_binary
(pub_key);
178
if
(prime)
179
coap_delete_binary
(prime);
180
return
spki;
181
}
cert_asn1_header2
static const unsigned char cert_asn1_header2[]
Definition
coap_asn1.c:147
cert_asn1_header1
static const unsigned char cert_asn1_header1[]
Definition
coap_asn1.c:136
coap_libcoap_build.h
Library specific build wrapper for coap_internal.h.
asn1_len
size_t asn1_len(const uint8_t **ptr, size_t *plen)
Get the asn1 length from the current ptr.
Definition
coap_asn1.c:19
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:88
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:153
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:48
asn1_tag_c
coap_asn1_tag_t asn1_tag_c(const uint8_t **ptr, size_t *plen, int *constructed, int *cls)
Get the asn1 tag from the current ptr.
Definition
coap_asn1.c:49
COAP_ASN1_BITSTRING
@ COAP_ASN1_BITSTRING
Definition
coap_asn1_internal.h:33
COAP_ASN1_FAIL
@ COAP_ASN1_FAIL
Definition
coap_asn1_internal.h:30
COAP_ASN1_IDENTIFIER
@ COAP_ASN1_IDENTIFIER
Definition
coap_asn1_internal.h:35
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