Coverage Report

Created: 2026-05-24 06:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libspdm/os_stub/mbedtlslib/mbedtls/library/asn1parse.c
Line
Count
Source
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
26.8M
{
32
26.8M
    if ((end - *p) < 1) {
33
63
        return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
34
63
    }
35
36
26.8M
    if ((**p & 0x80) == 0) {
37
24.6M
        *len = *(*p)++;
38
24.6M
    } else {
39
2.21M
        int n = (**p) & 0x7F;
40
2.21M
        if (n == 0 || n > 4) {
41
291
            return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
42
291
        }
43
2.21M
        if ((end - *p) <= n) {
44
30
            return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
45
30
        }
46
2.21M
        *len = 0;
47
2.21M
        (*p)++;
48
5.93M
        while (n--) {
49
3.71M
            *len = (*len << 8) | **p;
50
3.71M
            (*p)++;
51
3.71M
        }
52
2.21M
    }
53
54
26.8M
    if (*len > (size_t) (end - *p)) {
55
637
        return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
56
637
    }
57
58
26.8M
    return 0;
59
26.8M
}
60
61
int mbedtls_asn1_get_tag(unsigned char **p,
62
                         const unsigned char *end,
63
                         size_t *len, int tag)
64
25.2M
{
65
25.2M
    if ((end - *p) < 1) {
66
56.8k
        return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
67
56.8k
    }
68
69
25.1M
    if (**p != tag) {
70
2.46M
        return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG;
71
2.46M
    }
72
73
22.6M
    (*p)++;
74
75
22.6M
    return mbedtls_asn1_get_len(p, end, len);
76
25.1M
}
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
2.43M
{
84
2.43M
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
85
2.43M
    size_t len;
86
87
2.43M
    if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_BOOLEAN)) != 0) {
88
1.55M
        return ret;
89
1.55M
    }
90
91
876k
    if (len != 1) {
92
9
        return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
93
9
    }
94
95
876k
    *val = (**p != 0) ? 1 : 0;
96
876k
    (*p)++;
97
98
876k
    return 0;
99
876k
}
100
101
static int asn1_get_tagged_int(unsigned char **p,
102
                               const unsigned char *end,
103
                               int tag, int *val)
104
442k
{
105
442k
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
106
442k
    size_t len;
107
108
442k
    if ((ret = mbedtls_asn1_get_tag(p, end, &len, tag)) != 0) {
109
72
        return ret;
110
72
    }
111
112
    /*
113
     * len==0 is malformed (0 must be represented as 020100 for INTEGER,
114
     * or 0A0100 for ENUMERATED tags
115
     */
116
442k
    if (len == 0) {
117
14
        return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
118
14
    }
119
    /* This is a cryptography library. Reject negative integers. */
120
442k
    if ((**p & 0x80) != 0) {
121
16
        return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
122
16
    }
123
124
    /* Skip leading zeros. */
125
454k
    while (len > 0 && **p == 0) {
126
12.4k
        ++(*p);
127
12.4k
        --len;
128
12.4k
    }
129
130
    /* Reject integers that don't fit in an int. This code assumes that
131
     * the int type has no padding bit. */
132
442k
    if (len > sizeof(int)) {
133
51
        return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
134
51
    }
135
442k
    if (len == sizeof(int) && (**p & 0x80) != 0) {
136
11
        return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
137
11
    }
138
139
442k
    *val = 0;
140
886k
    while (len-- > 0) {
141
443k
        *val = (*val << 8) | **p;
142
443k
        (*p)++;
143
443k
    }
144
145
442k
    return 0;
146
442k
}
147
148
int mbedtls_asn1_get_int(unsigned char **p,
149
                         const unsigned char *end,
150
                         int *val)
151
442k
{
152
442k
    return asn1_get_tagged_int(p, end, MBEDTLS_ASN1_INTEGER, val);
153
442k
}
154
155
int mbedtls_asn1_get_enum(unsigned char **p,
156
                          const unsigned char *end,
157
                          int *val)
158
0
{
159
0
    return asn1_get_tagged_int(p, end, MBEDTLS_ASN1_ENUMERATED, val);
160
0
}
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
89.3k
{
167
89.3k
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
168
89.3k
    size_t len;
169
170
89.3k
    if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) {
171
0
        return ret;
172
0
    }
173
174
89.3k
    ret = mbedtls_mpi_read_binary(X, *p, len);
175
176
89.3k
    *p += len;
177
178
89.3k
    return ret;
179
89.3k
}
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
362k
{
185
362k
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
186
187
    /* Certificate type is a single byte bitstring */
188
362k
    if ((ret = mbedtls_asn1_get_tag(p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING)) != 0) {
189
3
        return ret;
190
3
    }
191
192
    /* Check length, subtract one for actual bit string length */
193
362k
    if (bs->len < 1) {
194
1
        return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
195
1
    }
196
362k
    bs->len -= 1;
197
198
    /* Get number of unused bits, ensure unused bits <= 7 */
199
362k
    bs->unused_bits = **p;
200
362k
    if (bs->unused_bits > 7) {
201
6
        return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
202
6
    }
203
362k
    (*p)++;
204
205
    /* Get actual bitstring */
206
362k
    bs->p = *p;
207
362k
    *p += bs->len;
208
209
362k
    if (*p != end) {
210
3
        return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
211
3
    }
212
213
362k
    return 0;
214
362k
}
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
361k
{
229
361k
    int ret;
230
361k
    size_t len;
231
232
    /* Get main sequence tag */
233
361k
    if ((ret = mbedtls_asn1_get_tag(p, end, &len,
234
361k
                                    MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
235
3
        return ret;
236
3
    }
237
238
361k
    if (*p + len != end) {
239
1
        return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
240
1
    }
241
242
1.39M
    while (*p < end) {
243
1.03M
        unsigned char const tag = *(*p)++;
244
245
1.03M
        if ((tag & tag_must_mask) != tag_must_val) {
246
12
            return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG;
247
12
        }
248
249
1.03M
        if ((ret = mbedtls_asn1_get_len(p, end, &len)) != 0) {
250
2
            return ret;
251
2
        }
252
253
1.03M
        if ((tag & tag_may_mask) == tag_may_val) {
254
1.03M
            if (cb != NULL) {
255
1.03M
                ret = cb(ctx, tag, *p, len);
256
1.03M
                if (ret != 0) {
257
0
                    return ret;
258
0
                }
259
1.03M
            }
260
1.03M
        }
261
262
1.03M
        *p += len;
263
1.03M
    }
264
265
361k
    return 0;
266
361k
}
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
881k
{
274
881k
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
275
276
881k
    if ((ret = mbedtls_asn1_get_tag(p, end, len, MBEDTLS_ASN1_BIT_STRING)) != 0) {
277
24
        return ret;
278
24
    }
279
280
881k
    if (*len == 0) {
281
7
        return MBEDTLS_ERR_ASN1_INVALID_DATA;
282
7
    }
283
881k
    --(*len);
284
285
881k
    if (**p != 0) {
286
24
        return MBEDTLS_ERR_ASN1_INVALID_DATA;
287
24
    }
288
881k
    ++(*p);
289
290
881k
    return 0;
291
881k
}
292
293
void mbedtls_asn1_sequence_free(mbedtls_asn1_sequence *seq)
294
1.80M
{
295
2.47M
    while (seq != NULL) {
296
674k
        mbedtls_asn1_sequence *next = seq->next;
297
674k
        mbedtls_free(seq);
298
674k
        seq = next;
299
674k
    }
300
1.80M
}
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
1.03M
{
312
1.03M
    asn1_get_sequence_of_cb_ctx_t *cb_ctx =
313
1.03M
        (asn1_get_sequence_of_cb_ctx_t *) ctx;
314
1.03M
    mbedtls_asn1_sequence *cur =
315
1.03M
        cb_ctx->cur;
316
317
1.03M
    if (cur->buf.p != NULL) {
318
672k
        cur->next =
319
672k
            mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence));
320
321
672k
        if (cur->next == NULL) {
322
0
            return MBEDTLS_ERR_ASN1_ALLOC_FAILED;
323
0
        }
324
325
672k
        cur = cur->next;
326
672k
    }
327
328
1.03M
    cur->buf.p = start;
329
1.03M
    cur->buf.len = len;
330
1.03M
    cur->buf.tag = tag;
331
332
1.03M
    cb_ctx->cur = cur;
333
1.03M
    return 0;
334
1.03M
}
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
361k
{
344
361k
    asn1_get_sequence_of_cb_ctx_t cb_ctx = { tag, cur };
345
361k
    memset(cur, 0, sizeof(mbedtls_asn1_sequence));
346
361k
    return mbedtls_asn1_traverse_sequence_of(
347
361k
        p, end, 0xFF, tag, 0, 0,
348
361k
        asn1_get_sequence_of_cb, &cb_ctx);
349
361k
}
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
1.32M
{
355
1.32M
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
356
1.32M
    size_t len;
357
358
1.32M
    if ((ret = mbedtls_asn1_get_tag(p, end, &len,
359
1.32M
                                    MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
360
606
        return ret;
361
606
    }
362
363
1.32M
    if ((end - *p) < 1) {
364
15
        return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
365
15
    }
366
367
1.32M
    alg->tag = **p;
368
1.32M
    end = *p + len;
369
370
1.32M
    if ((ret = mbedtls_asn1_get_tag(p, end, &alg->len, MBEDTLS_ASN1_OID)) != 0) {
371
31
        return ret;
372
31
    }
373
374
1.32M
    alg->p = *p;
375
1.32M
    *p += alg->len;
376
377
1.32M
    if (*p == end) {
378
748k
        mbedtls_platform_zeroize(params, sizeof(mbedtls_asn1_buf));
379
748k
        return 0;
380
748k
    }
381
382
578k
    params->tag = **p;
383
578k
    (*p)++;
384
385
578k
    if ((ret = mbedtls_asn1_get_len(p, end, &params->len)) != 0) {
386
18
        return ret;
387
18
    }
388
389
578k
    params->p = *p;
390
578k
    *p += params->len;
391
392
578k
    if (*p != end) {
393
15
        return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
394
15
    }
395
396
578k
    return 0;
397
578k
}
398
399
int mbedtls_asn1_get_alg_null(unsigned char **p,
400
                              const unsigned char *end,
401
                              mbedtls_asn1_buf *alg)
402
272
{
403
272
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
404
272
    mbedtls_asn1_buf params;
405
406
272
    memset(&params, 0, sizeof(mbedtls_asn1_buf));
407
408
272
    if ((ret = mbedtls_asn1_get_alg(p, end, alg, &params)) != 0) {
409
25
        return ret;
410
25
    }
411
412
247
    if ((params.tag != MBEDTLS_ASN1_NULL && params.tag != 0) || params.len != 0) {
413
70
        return MBEDTLS_ERR_ASN1_INVALID_DATA;
414
70
    }
415
416
177
    return 0;
417
247
}
418
419
#if !defined(MBEDTLS_DEPRECATED_REMOVED)
420
void mbedtls_asn1_free_named_data(mbedtls_asn1_named_data *cur)
421
0
{
422
0
    if (cur == NULL) {
423
0
        return;
424
0
    }
425
426
0
    mbedtls_free(cur->oid.p);
427
0
    mbedtls_free(cur->val.p);
428
429
0
    mbedtls_platform_zeroize(cur, sizeof(mbedtls_asn1_named_data));
430
0
}
431
#endif /* MBEDTLS_DEPRECATED_REMOVED */
432
433
void mbedtls_asn1_free_named_data_list(mbedtls_asn1_named_data **head)
434
60
{
435
60
    mbedtls_asn1_named_data *cur;
436
437
132
    while ((cur = *head) != NULL) {
438
72
        *head = cur->next;
439
72
        mbedtls_free(cur->oid.p);
440
72
        mbedtls_free(cur->val.p);
441
72
        mbedtls_free(cur);
442
72
    }
443
60
}
444
445
void mbedtls_asn1_free_named_data_list_shallow(mbedtls_asn1_named_data *name)
446
903k
{
447
913k
    for (mbedtls_asn1_named_data *next; name != NULL; name = next) {
448
10.5k
        next = name->next;
449
10.5k
        mbedtls_free(name);
450
10.5k
    }
451
903k
}
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
72
{
456
162
    while (list != NULL) {
457
90
        if (list->oid.len == len &&
458
80
            memcmp(list->oid.p, oid, len) == 0) {
459
0
            break;
460
0
        }
461
462
90
        list = list->next;
463
90
    }
464
465
72
    return list;
466
72
}
467
468
#endif /* MBEDTLS_ASN1_PARSE_C */