Coverage Report

Created: 2025-11-16 07:01

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.6M
{
32
26.6M
    if ((end - *p) < 1) {
33
79
        return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
34
79
    }
35
36
26.6M
    if ((**p & 0x80) == 0) {
37
24.4M
        *len = *(*p)++;
38
24.4M
    } else {
39
2.17M
        int n = (**p) & 0x7F;
40
2.17M
        if (n == 0 || n > 4) {
41
306
            return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
42
306
        }
43
2.17M
        if ((end - *p) <= n) {
44
35
            return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
45
35
        }
46
2.17M
        *len = 0;
47
2.17M
        (*p)++;
48
5.83M
        while (n--) {
49
3.65M
            *len = (*len << 8) | **p;
50
3.65M
            (*p)++;
51
3.65M
        }
52
2.17M
    }
53
54
26.6M
    if (*len > (size_t) (end - *p)) {
55
613
        return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
56
613
    }
57
58
26.6M
    return 0;
59
26.6M
}
60
61
int mbedtls_asn1_get_tag(unsigned char **p,
62
                         const unsigned char *end,
63
                         size_t *len, int tag)
64
25.0M
{
65
25.0M
    if ((end - *p) < 1) {
66
56.5k
        return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
67
56.5k
    }
68
69
24.9M
    if (**p != tag) {
70
2.45M
        return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG;
71
2.45M
    }
72
73
22.5M
    (*p)++;
74
75
22.5M
    return mbedtls_asn1_get_len(p, end, len);
76
24.9M
}
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.41M
{
84
2.41M
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
85
2.41M
    size_t len;
86
87
2.41M
    if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_BOOLEAN)) != 0) {
88
1.54M
        return ret;
89
1.54M
    }
90
91
873k
    if (len != 1) {
92
9
        return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
93
9
    }
94
95
873k
    *val = (**p != 0) ? 1 : 0;
96
873k
    (*p)++;
97
98
873k
    return 0;
99
873k
}
100
101
static int asn1_get_tagged_int(unsigned char **p,
102
                               const unsigned char *end,
103
                               int tag, int *val)
104
439k
{
105
439k
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
106
439k
    size_t len;
107
108
439k
    if ((ret = mbedtls_asn1_get_tag(p, end, &len, tag)) != 0) {
109
81
        return ret;
110
81
    }
111
112
    /*
113
     * len==0 is malformed (0 must be represented as 020100 for INTEGER,
114
     * or 0A0100 for ENUMERATED tags
115
     */
116
439k
    if (len == 0) {
117
15
        return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
118
15
    }
119
    /* This is a cryptography library. Reject negative integers. */
120
439k
    if ((**p & 0x80) != 0) {
121
13
        return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
122
13
    }
123
124
    /* Skip leading zeros. */
125
446k
    while (len > 0 && **p == 0) {
126
7.15k
        ++(*p);
127
7.15k
        --len;
128
7.15k
    }
129
130
    /* Reject integers that don't fit in an int. This code assumes that
131
     * the int type has no padding bit. */
132
439k
    if (len > sizeof(int)) {
133
43
        return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
134
43
    }
135
439k
    if (len == sizeof(int) && (**p & 0x80) != 0) {
136
10
        return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
137
10
    }
138
139
439k
    *val = 0;
140
879k
    while (len-- > 0) {
141
440k
        *val = (*val << 8) | **p;
142
440k
        (*p)++;
143
440k
    }
144
145
439k
    return 0;
146
439k
}
147
148
int mbedtls_asn1_get_int(unsigned char **p,
149
                         const unsigned char *end,
150
                         int *val)
151
439k
{
152
439k
    return asn1_get_tagged_int(p, end, MBEDTLS_ASN1_INTEGER, val);
153
439k
}
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
90.1k
{
167
90.1k
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
168
90.1k
    size_t len;
169
170
90.1k
    if ((ret = mbedtls_asn1_get_tag(p, end, &len, MBEDTLS_ASN1_INTEGER)) != 0) {
171
0
        return ret;
172
0
    }
173
174
90.1k
    ret = mbedtls_mpi_read_binary(X, *p, len);
175
176
90.1k
    *p += len;
177
178
90.1k
    return ret;
179
90.1k
}
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
360k
{
185
360k
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
186
187
    /* Certificate type is a single byte bitstring */
188
360k
    if ((ret = mbedtls_asn1_get_tag(p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING)) != 0) {
189
5
        return ret;
190
5
    }
191
192
    /* Check length, subtract one for actual bit string length */
193
360k
    if (bs->len < 1) {
194
1
        return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
195
1
    }
196
360k
    bs->len -= 1;
197
198
    /* Get number of unused bits, ensure unused bits <= 7 */
199
360k
    bs->unused_bits = **p;
200
360k
    if (bs->unused_bits > 7) {
201
7
        return MBEDTLS_ERR_ASN1_INVALID_LENGTH;
202
7
    }
203
360k
    (*p)++;
204
205
    /* Get actual bitstring */
206
360k
    bs->p = *p;
207
360k
    *p += bs->len;
208
209
360k
    if (*p != end) {
210
1
        return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
211
1
    }
212
213
360k
    return 0;
214
360k
}
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
360k
{
229
360k
    int ret;
230
360k
    size_t len;
231
232
    /* Get main sequence tag */
233
360k
    if ((ret = mbedtls_asn1_get_tag(p, end, &len,
234
360k
                                    MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
235
3
        return ret;
236
3
    }
237
238
360k
    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
10
            return MBEDTLS_ERR_ASN1_UNEXPECTED_TAG;
247
10
        }
248
249
1.03M
        if ((ret = mbedtls_asn1_get_len(p, end, &len)) != 0) {
250
1
            return ret;
251
1
        }
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
360k
    return 0;
266
360k
}
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
876k
{
274
876k
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
275
276
876k
    if ((ret = mbedtls_asn1_get_tag(p, end, len, MBEDTLS_ASN1_BIT_STRING)) != 0) {
277
24
        return ret;
278
24
    }
279
280
876k
    if (*len == 0) {
281
5
        return MBEDTLS_ERR_ASN1_INVALID_DATA;
282
5
    }
283
876k
    --(*len);
284
285
876k
    if (**p != 0) {
286
30
        return MBEDTLS_ERR_ASN1_INVALID_DATA;
287
30
    }
288
876k
    ++(*p);
289
290
876k
    return 0;
291
876k
}
292
293
void mbedtls_asn1_sequence_free(mbedtls_asn1_sequence *seq)
294
1.79M
{
295
2.46M
    while (seq != NULL) {
296
672k
        mbedtls_asn1_sequence *next = seq->next;
297
672k
        mbedtls_free(seq);
298
672k
        seq = next;
299
672k
    }
300
1.79M
}
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
670k
        cur->next =
319
670k
            mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence));
320
321
670k
        if (cur->next == NULL) {
322
0
            return MBEDTLS_ERR_ASN1_ALLOC_FAILED;
323
0
        }
324
325
670k
        cur = cur->next;
326
670k
    }
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
360k
{
344
360k
    asn1_get_sequence_of_cb_ctx_t cb_ctx = { tag, cur };
345
360k
    memset(cur, 0, sizeof(mbedtls_asn1_sequence));
346
360k
    return mbedtls_asn1_traverse_sequence_of(
347
360k
        p, end, 0xFF, tag, 0, 0,
348
360k
        asn1_get_sequence_of_cb, &cb_ctx);
349
360k
}
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.31M
{
355
1.31M
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
356
1.31M
    size_t len;
357
358
1.31M
    if ((ret = mbedtls_asn1_get_tag(p, end, &len,
359
1.31M
                                    MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
360
335
        return ret;
361
335
    }
362
363
1.31M
    if ((end - *p) < 1) {
364
13
        return MBEDTLS_ERR_ASN1_OUT_OF_DATA;
365
13
    }
366
367
1.31M
    alg->tag = **p;
368
1.31M
    end = *p + len;
369
370
1.31M
    if ((ret = mbedtls_asn1_get_tag(p, end, &alg->len, MBEDTLS_ASN1_OID)) != 0) {
371
41
        return ret;
372
41
    }
373
374
1.31M
    alg->p = *p;
375
1.31M
    *p += alg->len;
376
377
1.31M
    if (*p == end) {
378
753k
        mbedtls_platform_zeroize(params, sizeof(mbedtls_asn1_buf));
379
753k
        return 0;
380
753k
    }
381
382
565k
    params->tag = **p;
383
565k
    (*p)++;
384
385
565k
    if ((ret = mbedtls_asn1_get_len(p, end, &params->len)) != 0) {
386
27
        return ret;
387
27
    }
388
389
565k
    params->p = *p;
390
565k
    *p += params->len;
391
392
565k
    if (*p != end) {
393
14
        return MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
394
14
    }
395
396
565k
    return 0;
397
565k
}
398
399
int mbedtls_asn1_get_alg_null(unsigned char **p,
400
                              const unsigned char *end,
401
                              mbedtls_asn1_buf *alg)
402
294
{
403
294
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
404
294
    mbedtls_asn1_buf params;
405
406
294
    memset(&params, 0, sizeof(mbedtls_asn1_buf));
407
408
294
    if ((ret = mbedtls_asn1_get_alg(p, end, alg, &params)) != 0) {
409
19
        return ret;
410
19
    }
411
412
275
    if ((params.tag != MBEDTLS_ASN1_NULL && params.tag != 0) || params.len != 0) {
413
69
        return MBEDTLS_ERR_ASN1_INVALID_DATA;
414
69
    }
415
416
206
    return 0;
417
275
}
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
54
{
435
54
    mbedtls_asn1_named_data *cur;
436
437
120
    while ((cur = *head) != NULL) {
438
66
        *head = cur->next;
439
66
        mbedtls_free(cur->oid.p);
440
66
        mbedtls_free(cur->val.p);
441
66
        mbedtls_free(cur);
442
66
    }
443
54
}
444
445
void mbedtls_asn1_free_named_data_list_shallow(mbedtls_asn1_named_data *name)
446
896k
{
447
904k
    for (mbedtls_asn1_named_data *next; name != NULL; name = next) {
448
7.43k
        next = name->next;
449
7.43k
        mbedtls_free(name);
450
7.43k
    }
451
896k
}
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
66
{
456
150
    while (list != NULL) {
457
84
        if (list->oid.len == len &&
458
74
            memcmp(list->oid.p, oid, len) == 0) {
459
0
            break;
460
0
        }
461
462
84
        list = list->next;
463
84
    }
464
465
66
    return list;
466
66
}
467
468
#endif /* MBEDTLS_ASN1_PARSE_C */