Coverage Report

Created: 2024-01-21 07:01

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