Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/mbedtls/library/asn1parse.c
9898 views
1
/*
2
* Generic ASN.1 parsing
3
*
4
* Copyright The Mbed TLS Contributors
5
* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6
*/
7
8
#include "common.h"
9
10
#if defined(MBEDTLS_ASN1_PARSE_C) || defined(MBEDTLS_X509_CREATE_C) || \
11
defined(MBEDTLS_PSA_UTIL_HAVE_ECDSA)
12
13
#include "mbedtls/asn1.h"
14
#include "mbedtls/platform_util.h"
15
#include "mbedtls/error.h"
16
17
#include <string.h>
18
19
#if defined(MBEDTLS_BIGNUM_C)
20
#include "mbedtls/bignum.h"
21
#endif
22
23
#include "mbedtls/platform.h"
24
25
/*
26
* ASN.1 DER decoding routines
27
*/
28
int mbedtls_asn1_get_len(unsigned char **p,
29
const unsigned char *end,
30
size_t *len)
31
{
32
if ((end - *p) < 1) {
33
return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
34
}
35
36
if ((**p & 0x80) == 0) {
37
*len = *(*p)++;
38
} else {
39
int n = (**p) & 0x7F;
40
if (n == 0 || n > 4) {
41
return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
42
}
43
if ((end - *p) <= n) {
44
return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
45
}
46
*len = 0;
47
(*p)++;
48
while (n--) {
49
*len = (*len << 8) | **p;
50
(*p)++;
51
}
52
}
53
54
if (*len > (size_t) (end - *p)) {
55
return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
56
}
57
58
return 0;
59
}
60
61
int mbedtls_asn1_get_tag(unsigned char **p,
62
const unsigned char *end,
63
size_t *len, int tag)
64
{
65
if ((end - *p) < 1) {
66
return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
67
}
68
69
if (**p != tag) {
70
return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG;
71
}
72
73
(*p)++;
74
75
return mbedtls_asn1_get_len(p, end, len);
76
}
77
#endif /* MBEDTLS_ASN1_PARSE_C || MBEDTLS_X509_CREATE_C || MBEDTLS_PSA_UTIL_HAVE_ECDSA */
78
79
#if defined(MBEDTLS_ASN1_PARSE_C)
80
int mbedtls_asn1_get_bool(unsigned char **p,
81
const unsigned char *end,
82
int *val)
83
{
84
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
85
size_t len;
86
87
if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_BOOLEAN)) != 0) {
88
return ret;
89
}
90
91
if (len != 1) {
92
return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
93
}
94
95
*val = (**p != 0) ? 1 : 0;
96
(*p)++;
97
98
return 0;
99
}
100
101
static int asn1_get_tagged_int(unsigned char **p,
102
const unsigned char *end,
103
int tag, int *val)
104
{
105
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
106
size_t len;
107
108
if ((ret = mbedtls_asn1_get_tag(p, end, &len, tag)) != 0) {
109
return ret;
110
}
111
112
/*
113
* len==0 is malformed (0 must be represented as 020100 for INTEGER,
114
* or 0A0100 for ENUMERATED tags
115
*/
116
if (len == 0) {
117
return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
118
}
119
/* This is a cryptography library. Reject negative integers. */
120
if ((**p & 0x80) != 0) {
121
return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
122
}
123
124
/* Skip leading zeros. */
125
while (len > 0 && **p == 0) {
126
++(*p);
127
--len;
128
}
129
130
/* Reject integers that don't fit in an int. This code assumes that
131
* the int type has no padding bit. */
132
if (len > sizeof(int)) {
133
return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
134
}
135
if (len == sizeof(int) && (**p & 0x80) != 0) {
136
return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
137
}
138
139
*val = 0;
140
while (len-- > 0) {
141
*val = (*val << 8) | **p;
142
(*p)++;
143
}
144
145
return 0;
146
}
147
148
int mbedtls_asn1_get_int(unsigned char **p,
149
const unsigned char *end,
150
int *val)
151
{
152
return asn1_get_tagged_int(p, end, MBEDTLS_ASN1_INTEGER, val);
153
}
154
155
int mbedtls_asn1_get_enum(unsigned char **p,
156
const unsigned char *end,
157
int *val)
158
{
159
return asn1_get_tagged_int(p, end, MBEDTLS_ASN1_ENUMERATED, val);
160
}
161
162
#if defined(MBEDTLS_BIGNUM_C)
163
int mbedtls_asn1_get_mpi(unsigned char **p,
164
const unsigned char *end,
165
mbedtls_mpi *X)
166
{
167
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
168
size_t len;
169
170
if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) {
171
return ret;
172
}
173
174
ret = mbedtls_mpi_read_binary(X, *p, len);
175
176
*p += len;
177
178
return ret;
179
}
180
#endif /* MBEDTLS_BIGNUM_C */
181
182
int mbedtls_asn1_get_bitstring(unsigned char **p, const unsigned char *end,
183
mbedtls_asn1_bitstring *bs)
184
{
185
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
186
187
/* Certificate type is a single byte bitstring */
188
if ((ret = mbedtls_asn1_get_tag(p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING)) != 0) {
189
return ret;
190
}
191
192
/* Check length, subtract one for actual bit string length */
193
if (bs->len < 1) {
194
return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
195
}
196
bs->len -= 1;
197
198
/* Get number of unused bits, ensure unused bits <= 7 */
199
bs->unused_bits = **p;
200
if (bs->unused_bits > 7) {
201
return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
202
}
203
(*p)++;
204
205
/* Get actual bitstring */
206
bs->p = *p;
207
*p += bs->len;
208
209
if (*p != end) {
210
return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
211
}
212
213
return 0;
214
}
215
216
/*
217
* Traverse an ASN.1 "SEQUENCE OF <tag>"
218
* and call a callback for each entry found.
219
*/
220
int mbedtls_asn1_traverse_sequence_of(
221
unsigned char **p,
222
const unsigned char *end,
223
unsigned char tag_must_mask, unsigned char tag_must_val,
224
unsigned char tag_may_mask, unsigned char tag_may_val,
225
int (*cb)(void *ctx, int tag,
226
unsigned char *start, size_t len),
227
void *ctx)
228
{
229
int ret;
230
size_t len;
231
232
/* Get main sequence tag */
233
if ((ret = mbedtls_asn1_get_tag(p, end, &len,
234
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
235
return ret;
236
}
237
238
if (*p + len != end) {
239
return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
240
}
241
242
while (*p < end) {
243
unsigned char const tag = *(*p)++;
244
245
if ((tag & tag_must_mask) != tag_must_val) {
246
return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG;
247
}
248
249
if ((ret = mbedtls_asn1_get_len(p, end, &len)) != 0) {
250
return ret;
251
}
252
253
if ((tag & tag_may_mask) == tag_may_val) {
254
if (cb != NULL) {
255
ret = cb(ctx, tag, *p, len);
256
if (ret != 0) {
257
return ret;
258
}
259
}
260
}
261
262
*p += len;
263
}
264
265
return 0;
266
}
267
268
/*
269
* Get a bit string without unused bits
270
*/
271
int mbedtls_asn1_get_bitstring_null(unsigned char **p, const unsigned char *end,
272
size_t *len)
273
{
274
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
275
276
if ((ret = mbedtls_asn1_get_tag(p, end, len, MBEDTLS_ASN1_BIT_STRING)) != 0) {
277
return ret;
278
}
279
280
if (*len == 0) {
281
return MBEDTLS_ERR_ASN1_INVALID_DATA;
282
}
283
--(*len);
284
285
if (**p != 0) {
286
return MBEDTLS_ERR_ASN1_INVALID_DATA;
287
}
288
++(*p);
289
290
return 0;
291
}
292
293
void mbedtls_asn1_sequence_free(mbedtls_asn1_sequence *seq)
294
{
295
while (seq != NULL) {
296
mbedtls_asn1_sequence *next = seq->next;
297
mbedtls_free(seq);
298
seq = next;
299
}
300
}
301
302
typedef struct {
303
int tag;
304
mbedtls_asn1_sequence *cur;
305
} asn1_get_sequence_of_cb_ctx_t;
306
307
static int asn1_get_sequence_of_cb(void *ctx,
308
int tag,
309
unsigned char *start,
310
size_t len)
311
{
312
asn1_get_sequence_of_cb_ctx_t *cb_ctx =
313
(asn1_get_sequence_of_cb_ctx_t *) ctx;
314
mbedtls_asn1_sequence *cur =
315
cb_ctx->cur;
316
317
if (cur->buf.p != NULL) {
318
cur->next =
319
mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence));
320
321
if (cur->next == NULL) {
322
return MBEDTLS_ERR_ASN1_ALLOC_FAILED;
323
}
324
325
cur = cur->next;
326
}
327
328
cur->buf.p = start;
329
cur->buf.len = len;
330
cur->buf.tag = tag;
331
332
cb_ctx->cur = cur;
333
return 0;
334
}
335
336
/*
337
* Parses and splits an ASN.1 "SEQUENCE OF <tag>"
338
*/
339
int mbedtls_asn1_get_sequence_of(unsigned char **p,
340
const unsigned char *end,
341
mbedtls_asn1_sequence *cur,
342
int tag)
343
{
344
asn1_get_sequence_of_cb_ctx_t cb_ctx = { tag, cur };
345
memset(cur, 0, sizeof(mbedtls_asn1_sequence));
346
return mbedtls_asn1_traverse_sequence_of(
347
p, end, 0xFF, tag, 0, 0,
348
asn1_get_sequence_of_cb, &cb_ctx);
349
}
350
351
int mbedtls_asn1_get_alg(unsigned char **p,
352
const unsigned char *end,
353
mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params)
354
{
355
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
356
size_t len;
357
358
if ((ret = mbedtls_asn1_get_tag(p, end, &len,
359
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
360
return ret;
361
}
362
363
if ((end - *p) < 1) {
364
return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
365
}
366
367
alg->tag = **p;
368
end = *p + len;
369
370
if ((ret = mbedtls_asn1_get_tag(p, end, &alg->len, MBEDTLS_ASN1_OID)) != 0) {
371
return ret;
372
}
373
374
alg->p = *p;
375
*p += alg->len;
376
377
if (*p == end) {
378
mbedtls_platform_zeroize(params, sizeof(mbedtls_asn1_buf));
379
return 0;
380
}
381
382
params->tag = **p;
383
(*p)++;
384
385
if ((ret = mbedtls_asn1_get_len(p, end, &params->len)) != 0) {
386
return ret;
387
}
388
389
params->p = *p;
390
*p += params->len;
391
392
if (*p != end) {
393
return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
394
}
395
396
return 0;
397
}
398
399
int mbedtls_asn1_get_alg_null(unsigned char **p,
400
const unsigned char *end,
401
mbedtls_asn1_buf *alg)
402
{
403
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
404
mbedtls_asn1_buf params;
405
406
memset(&params, 0, sizeof(mbedtls_asn1_buf));
407
408
if ((ret = mbedtls_asn1_get_alg(p, end, alg, &params)) != 0) {
409
return ret;
410
}
411
412
if ((params.tag != MBEDTLS_ASN1_NULL && params.tag != 0) || params.len != 0) {
413
return MBEDTLS_ERR_ASN1_INVALID_DATA;
414
}
415
416
return 0;
417
}
418
419
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
420
void mbedtls_asn1_free_named_data(mbedtls_asn1_named_data *cur)
421
{
422
if (cur == NULL) {
423
return;
424
}
425
426
mbedtls_free(cur->oid.p);
427
mbedtls_free(cur->val.p);
428
429
mbedtls_platform_zeroize(cur, sizeof(mbedtls_asn1_named_data));
430
}
431
#endif /* MBEDTLS_DEPRECATED_REMOVED */
432
433
void mbedtls_asn1_free_named_data_list(mbedtls_asn1_named_data **head)
434
{
435
mbedtls_asn1_named_data *cur;
436
437
while ((cur = *head) != NULL) {
438
*head = cur->next;
439
mbedtls_free(cur->oid.p);
440
mbedtls_free(cur->val.p);
441
mbedtls_free(cur);
442
}
443
}
444
445
void mbedtls_asn1_free_named_data_list_shallow(mbedtls_asn1_named_data *name)
446
{
447
for (mbedtls_asn1_named_data *next; name != NULL; name = next) {
448
next = name->next;
449
mbedtls_free(name);
450
}
451
}
452
453
const mbedtls_asn1_named_data *mbedtls_asn1_find_named_data(const mbedtls_asn1_named_data *list,
454
const char *oid, size_t len)
455
{
456
while (list != NULL) {
457
if (list->oid.len == len &&
458
memcmp(list->oid.p, oid, len) == 0) {
459
break;
460
}
461
462
list = list->next;
463
}
464
465
return list;
466
}
467
468
#endif /* MBEDTLS_ASN1_PARSE_C */
469
470