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