Coverage Report

Created: 2025-07-01 06:54

/work/mbedtls-2.28.8/library/x509.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 *  X.509 common functions for parsing and verification
3
 *
4
 *  Copyright The Mbed TLS Contributors
5
 *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6
 */
7
/*
8
 *  The ITU-T X.509 standard defines a certificate format for PKI.
9
 *
10
 *  http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
11
 *  http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
12
 *  http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
13
 *
14
 *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
15
 *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
16
 */
17
18
#include "common.h"
19
20
#if defined(MBEDTLS_X509_USE_C)
21
22
#include "mbedtls/x509.h"
23
#include "mbedtls/asn1.h"
24
#include "mbedtls/error.h"
25
#include "mbedtls/oid.h"
26
27
#include <stdio.h>
28
#include <string.h>
29
30
#if defined(MBEDTLS_PEM_PARSE_C)
31
#include "mbedtls/pem.h"
32
#endif
33
34
#include "mbedtls/platform.h"
35
36
#if defined(MBEDTLS_HAVE_TIME)
37
#include "mbedtls/platform_time.h"
38
#endif
39
#if defined(MBEDTLS_HAVE_TIME_DATE)
40
#include "mbedtls/platform_util.h"
41
#include <time.h>
42
#endif
43
44
#define CHECK(code)                                     \
45
0
    do {                                                \
46
0
        if ((ret = (code)) != 0) {                      \
47
0
            return ret;                                 \
48
0
        }                                               \
49
0
    } while (0)
50
51
#define CHECK_RANGE(min, max, val)                      \
52
0
    do {                                                \
53
0
        if ((val) < (min) || (val) > (max)) {           \
54
0
            return ret;                                 \
55
0
        }                                               \
56
0
    } while (0)
57
58
/*
59
 *  CertificateSerialNumber  ::=  INTEGER
60
 */
61
int mbedtls_x509_get_serial(unsigned char **p, const unsigned char *end,
62
                            mbedtls_x509_buf *serial)
63
0
{
64
0
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
65
66
0
    if ((end - *p) < 1) {
67
0
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_SERIAL,
68
0
                                 MBEDTLS_ERR_ASN1_OUT_OF_DATA);
69
0
    }
70
71
0
    if (**p != (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_PRIMITIVE | 2) &&
72
0
        **p !=   MBEDTLS_ASN1_INTEGER) {
73
0
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_SERIAL,
74
0
                                 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
75
0
    }
76
77
0
    serial->tag = *(*p)++;
78
79
0
    if ((ret = mbedtls_asn1_get_len(p, end, &serial->len)) != 0) {
80
0
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_SERIAL, ret);
81
0
    }
82
83
0
    serial->p = *p;
84
0
    *p += serial->len;
85
86
0
    return 0;
87
0
}
88
89
/* Get an algorithm identifier without parameters (eg for signatures)
90
 *
91
 *  AlgorithmIdentifier  ::=  SEQUENCE  {
92
 *       algorithm               OBJECT IDENTIFIER,
93
 *       parameters              ANY DEFINED BY algorithm OPTIONAL  }
94
 */
95
int mbedtls_x509_get_alg_null(unsigned char **p, const unsigned char *end,
96
                              mbedtls_x509_buf *alg)
97
0
{
98
0
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
99
100
0
    if ((ret = mbedtls_asn1_get_alg_null(p, end, alg)) != 0) {
101
0
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
102
0
    }
103
104
0
    return 0;
105
0
}
106
107
/*
108
 * Parse an algorithm identifier with (optional) parameters
109
 */
110
int mbedtls_x509_get_alg(unsigned char **p, const unsigned char *end,
111
                         mbedtls_x509_buf *alg, mbedtls_x509_buf *params)
112
0
{
113
0
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
114
115
0
    if ((ret = mbedtls_asn1_get_alg(p, end, alg, params)) != 0) {
116
0
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
117
0
    }
118
119
0
    return 0;
120
0
}
121
122
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
123
/*
124
 * HashAlgorithm ::= AlgorithmIdentifier
125
 *
126
 * AlgorithmIdentifier  ::=  SEQUENCE  {
127
 *      algorithm               OBJECT IDENTIFIER,
128
 *      parameters              ANY DEFINED BY algorithm OPTIONAL  }
129
 *
130
 * For HashAlgorithm, parameters MUST be NULL or absent.
131
 */
132
static int x509_get_hash_alg(const mbedtls_x509_buf *alg, mbedtls_md_type_t *md_alg)
133
0
{
134
0
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
135
0
    unsigned char *p;
136
0
    const unsigned char *end;
137
0
    mbedtls_x509_buf md_oid;
138
0
    size_t len;
139
140
    /* Make sure we got a SEQUENCE and setup bounds */
141
0
    if (alg->tag != (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) {
142
0
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
143
0
                                 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
144
0
    }
145
146
0
    p = alg->p;
147
0
    end = p + alg->len;
148
149
0
    if (p >= end) {
150
0
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
151
0
                                 MBEDTLS_ERR_ASN1_OUT_OF_DATA);
152
0
    }
153
154
    /* Parse md_oid */
155
0
    md_oid.tag = *p;
156
157
0
    if ((ret = mbedtls_asn1_get_tag(&p, end, &md_oid.len, MBEDTLS_ASN1_OID)) != 0) {
158
0
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
159
0
    }
160
161
0
    md_oid.p = p;
162
0
    p += md_oid.len;
163
164
    /* Get md_alg from md_oid */
165
0
    if ((ret = mbedtls_oid_get_md_alg(&md_oid, md_alg)) != 0) {
166
0
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
167
0
    }
168
169
    /* Make sure params is absent of NULL */
170
0
    if (p == end) {
171
0
        return 0;
172
0
    }
173
174
0
    if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_NULL)) != 0 || len != 0) {
175
0
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
176
0
    }
177
178
0
    if (p != end) {
179
0
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
180
0
                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
181
0
    }
182
183
0
    return 0;
184
0
}
185
186
/*
187
 *    RSASSA-PSS-params  ::=  SEQUENCE  {
188
 *       hashAlgorithm     [0] HashAlgorithm DEFAULT sha1Identifier,
189
 *       maskGenAlgorithm  [1] MaskGenAlgorithm DEFAULT mgf1SHA1Identifier,
190
 *       saltLength        [2] INTEGER DEFAULT 20,
191
 *       trailerField      [3] INTEGER DEFAULT 1  }
192
 *    -- Note that the tags in this Sequence are explicit.
193
 *
194
 * RFC 4055 (which defines use of RSASSA-PSS in PKIX) states that the value
195
 * of trailerField MUST be 1, and PKCS#1 v2.2 doesn't even define any other
196
 * option. Enforce this at parsing time.
197
 */
198
int mbedtls_x509_get_rsassa_pss_params(const mbedtls_x509_buf *params,
199
                                       mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md,
200
                                       int *salt_len)
201
0
{
202
0
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
203
0
    unsigned char *p;
204
0
    const unsigned char *end, *end2;
205
0
    size_t len;
206
0
    mbedtls_x509_buf alg_id, alg_params;
207
208
    /* First set everything to defaults */
209
0
    *md_alg = MBEDTLS_MD_SHA1;
210
0
    *mgf_md = MBEDTLS_MD_SHA1;
211
0
    *salt_len = 20;
212
213
    /* Make sure params is a SEQUENCE and setup bounds */
214
0
    if (params->tag != (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) {
215
0
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
216
0
                                 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
217
0
    }
218
219
0
    p = (unsigned char *) params->p;
220
0
    end = p + params->len;
221
222
0
    if (p == end) {
223
0
        return 0;
224
0
    }
225
226
    /*
227
     * HashAlgorithm
228
     */
229
0
    if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
230
0
                                    MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED |
231
0
                                    0)) == 0) {
232
0
        end2 = p + len;
233
234
        /* HashAlgorithm ::= AlgorithmIdentifier (without parameters) */
235
0
        if ((ret = mbedtls_x509_get_alg_null(&p, end2, &alg_id)) != 0) {
236
0
            return ret;
237
0
        }
238
239
0
        if ((ret = mbedtls_oid_get_md_alg(&alg_id, md_alg)) != 0) {
240
0
            return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
241
0
        }
242
243
0
        if (p != end2) {
244
0
            return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
245
0
                                     MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
246
0
        }
247
0
    } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
248
0
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
249
0
    }
250
251
0
    if (p == end) {
252
0
        return 0;
253
0
    }
254
255
    /*
256
     * MaskGenAlgorithm
257
     */
258
0
    if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
259
0
                                    MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED |
260
0
                                    1)) == 0) {
261
0
        end2 = p + len;
262
263
        /* MaskGenAlgorithm ::= AlgorithmIdentifier (params = HashAlgorithm) */
264
0
        if ((ret = mbedtls_x509_get_alg(&p, end2, &alg_id, &alg_params)) != 0) {
265
0
            return ret;
266
0
        }
267
268
        /* Only MFG1 is recognised for now */
269
0
        if (MBEDTLS_OID_CMP(MBEDTLS_OID_MGF1, &alg_id) != 0) {
270
0
            return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE,
271
0
                                     MBEDTLS_ERR_OID_NOT_FOUND);
272
0
        }
273
274
        /* Parse HashAlgorithm */
275
0
        if ((ret = x509_get_hash_alg(&alg_params, mgf_md)) != 0) {
276
0
            return ret;
277
0
        }
278
279
0
        if (p != end2) {
280
0
            return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
281
0
                                     MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
282
0
        }
283
0
    } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
284
0
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
285
0
    }
286
287
0
    if (p == end) {
288
0
        return 0;
289
0
    }
290
291
    /*
292
     * salt_len
293
     */
294
0
    if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
295
0
                                    MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED |
296
0
                                    2)) == 0) {
297
0
        end2 = p + len;
298
299
0
        if ((ret = mbedtls_asn1_get_int(&p, end2, salt_len)) != 0) {
300
0
            return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
301
0
        }
302
303
0
        if (p != end2) {
304
0
            return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
305
0
                                     MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
306
0
        }
307
0
    } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
308
0
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
309
0
    }
310
311
0
    if (p == end) {
312
0
        return 0;
313
0
    }
314
315
    /*
316
     * trailer_field (if present, must be 1)
317
     */
318
0
    if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
319
0
                                    MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED |
320
0
                                    3)) == 0) {
321
0
        int trailer_field;
322
323
0
        end2 = p + len;
324
325
0
        if ((ret = mbedtls_asn1_get_int(&p, end2, &trailer_field)) != 0) {
326
0
            return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
327
0
        }
328
329
0
        if (p != end2) {
330
0
            return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
331
0
                                     MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
332
0
        }
333
334
0
        if (trailer_field != 1) {
335
0
            return MBEDTLS_ERR_X509_INVALID_ALG;
336
0
        }
337
0
    } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
338
0
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
339
0
    }
340
341
0
    if (p != end) {
342
0
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
343
0
                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
344
0
    }
345
346
0
    return 0;
347
0
}
348
#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
349
350
/*
351
 *  AttributeTypeAndValue ::= SEQUENCE {
352
 *    type     AttributeType,
353
 *    value    AttributeValue }
354
 *
355
 *  AttributeType ::= OBJECT IDENTIFIER
356
 *
357
 *  AttributeValue ::= ANY DEFINED BY AttributeType
358
 */
359
static int x509_get_attr_type_value(unsigned char **p,
360
                                    const unsigned char *end,
361
                                    mbedtls_x509_name *cur)
362
0
{
363
0
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
364
0
    size_t len;
365
0
    mbedtls_x509_buf *oid;
366
0
    mbedtls_x509_buf *val;
367
368
0
    if ((ret = mbedtls_asn1_get_tag(p, end, &len,
369
0
                                    MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
370
0
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME, ret);
371
0
    }
372
373
0
    end = *p + len;
374
375
0
    if ((end - *p) < 1) {
376
0
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME,
377
0
                                 MBEDTLS_ERR_ASN1_OUT_OF_DATA);
378
0
    }
379
380
0
    oid = &cur->oid;
381
0
    oid->tag = **p;
382
383
0
    if ((ret = mbedtls_asn1_get_tag(p, end, &oid->len, MBEDTLS_ASN1_OID)) != 0) {
384
0
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME, ret);
385
0
    }
386
387
0
    oid->p = *p;
388
0
    *p += oid->len;
389
390
0
    if ((end - *p) < 1) {
391
0
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME,
392
0
                                 MBEDTLS_ERR_ASN1_OUT_OF_DATA);
393
0
    }
394
395
0
    if (**p != MBEDTLS_ASN1_BMP_STRING && **p != MBEDTLS_ASN1_UTF8_STRING      &&
396
0
        **p != MBEDTLS_ASN1_T61_STRING && **p != MBEDTLS_ASN1_PRINTABLE_STRING &&
397
0
        **p != MBEDTLS_ASN1_IA5_STRING && **p != MBEDTLS_ASN1_UNIVERSAL_STRING &&
398
0
        **p != MBEDTLS_ASN1_BIT_STRING) {
399
0
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME,
400
0
                                 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
401
0
    }
402
403
0
    val = &cur->val;
404
0
    val->tag = *(*p)++;
405
406
0
    if ((ret = mbedtls_asn1_get_len(p, end, &val->len)) != 0) {
407
0
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME, ret);
408
0
    }
409
410
0
    val->p = *p;
411
0
    *p += val->len;
412
413
0
    if (*p != end) {
414
0
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME,
415
0
                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
416
0
    }
417
418
0
    cur->next = NULL;
419
420
0
    return 0;
421
0
}
422
423
/*
424
 *  Name ::= CHOICE { -- only one possibility for now --
425
 *       rdnSequence  RDNSequence }
426
 *
427
 *  RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
428
 *
429
 *  RelativeDistinguishedName ::=
430
 *    SET OF AttributeTypeAndValue
431
 *
432
 *  AttributeTypeAndValue ::= SEQUENCE {
433
 *    type     AttributeType,
434
 *    value    AttributeValue }
435
 *
436
 *  AttributeType ::= OBJECT IDENTIFIER
437
 *
438
 *  AttributeValue ::= ANY DEFINED BY AttributeType
439
 *
440
 * The data structure is optimized for the common case where each RDN has only
441
 * one element, which is represented as a list of AttributeTypeAndValue.
442
 * For the general case we still use a flat list, but we mark elements of the
443
 * same set so that they are "merged" together in the functions that consume
444
 * this list, eg mbedtls_x509_dn_gets().
445
 *
446
 * On success, this function may allocate a linked list starting at cur->next
447
 * that must later be free'd by the caller using mbedtls_free(). In error
448
 * cases, this function frees all allocated memory internally and the caller
449
 * has no freeing responsibilities.
450
 */
451
int mbedtls_x509_get_name(unsigned char **p, const unsigned char *end,
452
                          mbedtls_x509_name *cur)
453
0
{
454
0
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
455
0
    size_t set_len;
456
0
    const unsigned char *end_set;
457
0
    mbedtls_x509_name *head = cur;
458
0
    mbedtls_x509_name *prev, *allocated;
459
460
    /* don't use recursion, we'd risk stack overflow if not optimized */
461
0
    while (1) {
462
        /*
463
         * parse SET
464
         */
465
0
        if ((ret = mbedtls_asn1_get_tag(p, end, &set_len,
466
0
                                        MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET)) != 0) {
467
0
            ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME, ret);
468
0
            goto error;
469
0
        }
470
471
0
        end_set  = *p + set_len;
472
473
0
        while (1) {
474
0
            if ((ret = x509_get_attr_type_value(p, end_set, cur)) != 0) {
475
0
                goto error;
476
0
            }
477
478
0
            if (*p == end_set) {
479
0
                break;
480
0
            }
481
482
            /* Mark this item as being no the only one in a set */
483
0
            cur->next_merged = 1;
484
485
0
            cur->next = mbedtls_calloc(1, sizeof(mbedtls_x509_name));
486
487
0
            if (cur->next == NULL) {
488
0
                ret = MBEDTLS_ERR_X509_ALLOC_FAILED;
489
0
                goto error;
490
0
            }
491
492
0
            cur = cur->next;
493
0
        }
494
495
        /*
496
         * continue until end of SEQUENCE is reached
497
         */
498
0
        if (*p == end) {
499
0
            return 0;
500
0
        }
501
502
0
        cur->next = mbedtls_calloc(1, sizeof(mbedtls_x509_name));
503
504
0
        if (cur->next == NULL) {
505
0
            ret = MBEDTLS_ERR_X509_ALLOC_FAILED;
506
0
            goto error;
507
0
        }
508
509
0
        cur = cur->next;
510
0
    }
511
512
0
error:
513
    /* Skip the first element as we did not allocate it */
514
0
    allocated = head->next;
515
516
0
    while (allocated != NULL) {
517
0
        prev = allocated;
518
0
        allocated = allocated->next;
519
520
0
        mbedtls_platform_zeroize(prev, sizeof(*prev));
521
0
        mbedtls_free(prev);
522
0
    }
523
524
0
    mbedtls_platform_zeroize(head, sizeof(*head));
525
526
0
    return ret;
527
0
}
528
529
static int x509_parse_int(unsigned char **p, size_t n, int *res)
530
0
{
531
0
    *res = 0;
532
533
0
    for (; n > 0; --n) {
534
0
        if ((**p < '0') || (**p > '9')) {
535
0
            return MBEDTLS_ERR_X509_INVALID_DATE;
536
0
        }
537
538
0
        *res *= 10;
539
0
        *res += (*(*p)++ - '0');
540
0
    }
541
542
0
    return 0;
543
0
}
544
545
static int x509_date_is_valid(const mbedtls_x509_time *t)
546
0
{
547
0
    int ret = MBEDTLS_ERR_X509_INVALID_DATE;
548
0
    int month_len;
549
550
0
    CHECK_RANGE(0, 9999, t->year);
551
0
    CHECK_RANGE(0, 23,   t->hour);
552
0
    CHECK_RANGE(0, 59,   t->min);
553
0
    CHECK_RANGE(0, 59,   t->sec);
554
555
0
    switch (t->mon) {
556
0
        case 1: case 3: case 5: case 7: case 8: case 10: case 12:
557
0
            month_len = 31;
558
0
            break;
559
0
        case 4: case 6: case 9: case 11:
560
0
            month_len = 30;
561
0
            break;
562
0
        case 2:
563
0
            if ((!(t->year % 4) && t->year % 100) ||
564
0
                !(t->year % 400)) {
565
0
                month_len = 29;
566
0
            } else {
567
0
                month_len = 28;
568
0
            }
569
0
            break;
570
0
        default:
571
0
            return ret;
572
0
    }
573
0
    CHECK_RANGE(1, month_len, t->day);
574
575
0
    return 0;
576
0
}
577
578
/*
579
 * Parse an ASN1_UTC_TIME (yearlen=2) or ASN1_GENERALIZED_TIME (yearlen=4)
580
 * field.
581
 */
582
static int x509_parse_time(unsigned char **p, size_t len, size_t yearlen,
583
                           mbedtls_x509_time *tm)
584
0
{
585
0
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
586
587
    /*
588
     * Minimum length is 10 or 12 depending on yearlen
589
     */
590
0
    if (len < yearlen + 8) {
591
0
        return MBEDTLS_ERR_X509_INVALID_DATE;
592
0
    }
593
0
    len -= yearlen + 8;
594
595
    /*
596
     * Parse year, month, day, hour, minute
597
     */
598
0
    CHECK(x509_parse_int(p, yearlen, &tm->year));
599
0
    if (2 == yearlen) {
600
0
        if (tm->year < 50) {
601
0
            tm->year += 100;
602
0
        }
603
604
0
        tm->year += 1900;
605
0
    }
606
607
0
    CHECK(x509_parse_int(p, 2, &tm->mon));
608
0
    CHECK(x509_parse_int(p, 2, &tm->day));
609
0
    CHECK(x509_parse_int(p, 2, &tm->hour));
610
0
    CHECK(x509_parse_int(p, 2, &tm->min));
611
612
    /*
613
     * Parse seconds if present
614
     */
615
0
    if (len >= 2) {
616
0
        CHECK(x509_parse_int(p, 2, &tm->sec));
617
0
        len -= 2;
618
0
    } else {
619
0
        return MBEDTLS_ERR_X509_INVALID_DATE;
620
0
    }
621
622
    /*
623
     * Parse trailing 'Z' if present
624
     */
625
0
    if (1 == len && 'Z' == **p) {
626
0
        (*p)++;
627
0
        len--;
628
0
    }
629
630
    /*
631
     * We should have parsed all characters at this point
632
     */
633
0
    if (0 != len) {
634
0
        return MBEDTLS_ERR_X509_INVALID_DATE;
635
0
    }
636
637
0
    CHECK(x509_date_is_valid(tm));
638
639
0
    return 0;
640
0
}
641
642
/*
643
 *  Time ::= CHOICE {
644
 *       utcTime        UTCTime,
645
 *       generalTime    GeneralizedTime }
646
 */
647
int mbedtls_x509_get_time(unsigned char **p, const unsigned char *end,
648
                          mbedtls_x509_time *tm)
649
0
{
650
0
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
651
0
    size_t len, year_len;
652
0
    unsigned char tag;
653
654
0
    if ((end - *p) < 1) {
655
0
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_DATE,
656
0
                                 MBEDTLS_ERR_ASN1_OUT_OF_DATA);
657
0
    }
658
659
0
    tag = **p;
660
661
0
    if (tag == MBEDTLS_ASN1_UTC_TIME) {
662
0
        year_len = 2;
663
0
    } else if (tag == MBEDTLS_ASN1_GENERALIZED_TIME) {
664
0
        year_len = 4;
665
0
    } else {
666
0
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_DATE,
667
0
                                 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
668
0
    }
669
670
0
    (*p)++;
671
0
    ret = mbedtls_asn1_get_len(p, end, &len);
672
673
0
    if (ret != 0) {
674
0
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_DATE, ret);
675
0
    }
676
677
0
    return x509_parse_time(p, len, year_len, tm);
678
0
}
679
680
int mbedtls_x509_get_sig(unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig)
681
0
{
682
0
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
683
0
    size_t len;
684
0
    int tag_type;
685
686
0
    if ((end - *p) < 1) {
687
0
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_SIGNATURE,
688
0
                                 MBEDTLS_ERR_ASN1_OUT_OF_DATA);
689
0
    }
690
691
0
    tag_type = **p;
692
693
0
    if ((ret = mbedtls_asn1_get_bitstring_null(p, end, &len)) != 0) {
694
0
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_SIGNATURE, ret);
695
0
    }
696
697
0
    sig->tag = tag_type;
698
0
    sig->len = len;
699
0
    sig->p = *p;
700
701
0
    *p += len;
702
703
0
    return 0;
704
0
}
705
706
/*
707
 * Get signature algorithm from alg OID and optional parameters
708
 */
709
int mbedtls_x509_get_sig_alg(const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params,
710
                             mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg,
711
                             void **sig_opts)
712
0
{
713
0
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
714
715
0
    if (*sig_opts != NULL) {
716
0
        return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
717
0
    }
718
719
0
    if ((ret = mbedtls_oid_get_sig_alg(sig_oid, md_alg, pk_alg)) != 0) {
720
0
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG, ret);
721
0
    }
722
723
0
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
724
0
    if (*pk_alg == MBEDTLS_PK_RSASSA_PSS) {
725
0
        mbedtls_pk_rsassa_pss_options *pss_opts;
726
727
0
        pss_opts = mbedtls_calloc(1, sizeof(mbedtls_pk_rsassa_pss_options));
728
0
        if (pss_opts == NULL) {
729
0
            return MBEDTLS_ERR_X509_ALLOC_FAILED;
730
0
        }
731
732
0
        ret = mbedtls_x509_get_rsassa_pss_params(sig_params,
733
0
                                                 md_alg,
734
0
                                                 &pss_opts->mgf1_hash_id,
735
0
                                                 &pss_opts->expected_salt_len);
736
0
        if (ret != 0) {
737
0
            mbedtls_free(pss_opts);
738
0
            return ret;
739
0
        }
740
741
0
        *sig_opts = (void *) pss_opts;
742
0
    } else
743
0
#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
744
0
    {
745
        /* Make sure parameters are absent or NULL */
746
0
        if ((sig_params->tag != MBEDTLS_ASN1_NULL && sig_params->tag != 0) ||
747
0
            sig_params->len != 0) {
748
0
            return MBEDTLS_ERR_X509_INVALID_ALG;
749
0
        }
750
0
    }
751
752
0
    return 0;
753
0
}
754
755
/*
756
 * X.509 Extensions (No parsing of extensions, pointer should
757
 * be either manually updated or extensions should be parsed!)
758
 */
759
int mbedtls_x509_get_ext(unsigned char **p, const unsigned char *end,
760
                         mbedtls_x509_buf *ext, int tag)
761
0
{
762
0
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
763
0
    size_t len;
764
765
    /* Extension structure use EXPLICIT tagging. That is, the actual
766
     * `Extensions` structure is wrapped by a tag-length pair using
767
     * the respective context-specific tag. */
768
0
    ret = mbedtls_asn1_get_tag(p, end, &ext->len,
769
0
                               MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag);
770
0
    if (ret != 0) {
771
0
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
772
0
    }
773
774
0
    ext->tag = MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag;
775
0
    ext->p   = *p;
776
0
    end      = *p + ext->len;
777
778
    /*
779
     * Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
780
     */
781
0
    if ((ret = mbedtls_asn1_get_tag(p, end, &len,
782
0
                                    MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
783
0
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
784
0
    }
785
786
0
    if (end != *p + len) {
787
0
        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
788
0
                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
789
0
    }
790
791
0
    return 0;
792
0
}
793
794
/*
795
 * Store the name in printable form into buf; no more
796
 * than size characters will be written
797
 */
798
int mbedtls_x509_dn_gets(char *buf, size_t size, const mbedtls_x509_name *dn)
799
0
{
800
0
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
801
0
    size_t i, j, n;
802
0
    unsigned char c, merge = 0;
803
0
    const mbedtls_x509_name *name;
804
0
    const char *short_name = NULL;
805
0
    char s[MBEDTLS_X509_MAX_DN_NAME_SIZE], *p;
806
807
0
    memset(s, 0, sizeof(s));
808
809
0
    name = dn;
810
0
    p = buf;
811
0
    n = size;
812
813
0
    while (name != NULL) {
814
0
        if (!name->oid.p) {
815
0
            name = name->next;
816
0
            continue;
817
0
        }
818
819
0
        if (name != dn) {
820
0
            ret = mbedtls_snprintf(p, n, merge ? " + " : ", ");
821
0
            MBEDTLS_X509_SAFE_SNPRINTF;
822
0
        }
823
824
0
        ret = mbedtls_oid_get_attr_short_name(&name->oid, &short_name);
825
826
0
        if (ret == 0) {
827
0
            ret = mbedtls_snprintf(p, n, "%s=", short_name);
828
0
        } else {
829
0
            ret = mbedtls_snprintf(p, n, "\?\?=");
830
0
        }
831
0
        MBEDTLS_X509_SAFE_SNPRINTF;
832
833
0
        for (i = 0, j = 0; i < name->val.len; i++, j++) {
834
0
            if (j >= sizeof(s) - 1) {
835
0
                return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
836
0
            }
837
838
0
            c = name->val.p[i];
839
            // Special characters requiring escaping, RFC 1779
840
0
            if (c && strchr(",=+<>#;\"\\", c)) {
841
0
                if (j + 1 >= sizeof(s) - 1) {
842
0
                    return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
843
0
                }
844
0
                s[j++] = '\\';
845
0
            }
846
0
            if (c < 32 || c >= 127) {
847
0
                s[j] = '?';
848
0
            } else {
849
0
                s[j] = c;
850
0
            }
851
0
        }
852
0
        s[j] = '\0';
853
0
        ret = mbedtls_snprintf(p, n, "%s", s);
854
0
        MBEDTLS_X509_SAFE_SNPRINTF;
855
856
0
        merge = name->next_merged;
857
0
        name = name->next;
858
0
    }
859
860
0
    return (int) (size - n);
861
0
}
862
863
/*
864
 * Store the serial in printable form into buf; no more
865
 * than size characters will be written
866
 */
867
int mbedtls_x509_serial_gets(char *buf, size_t size, const mbedtls_x509_buf *serial)
868
0
{
869
0
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
870
0
    size_t i, n, nr;
871
0
    char *p;
872
873
0
    p = buf;
874
0
    n = size;
875
876
0
    nr = (serial->len <= 32)
877
0
        ? serial->len  : 28;
878
879
0
    for (i = 0; i < nr; i++) {
880
0
        if (i == 0 && nr > 1 && serial->p[i] == 0x0) {
881
0
            continue;
882
0
        }
883
884
0
        ret = mbedtls_snprintf(p, n, "%02X%s",
885
0
                               serial->p[i], (i < nr - 1) ? ":" : "");
886
0
        MBEDTLS_X509_SAFE_SNPRINTF;
887
0
    }
888
889
0
    if (nr != serial->len) {
890
0
        ret = mbedtls_snprintf(p, n, "....");
891
0
        MBEDTLS_X509_SAFE_SNPRINTF;
892
0
    }
893
894
0
    return (int) (size - n);
895
0
}
896
897
/*
898
 * Helper for writing signature algorithms
899
 */
900
int mbedtls_x509_sig_alg_gets(char *buf, size_t size, const mbedtls_x509_buf *sig_oid,
901
                              mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg,
902
                              const void *sig_opts)
903
0
{
904
0
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
905
0
    char *p = buf;
906
0
    size_t n = size;
907
0
    const char *desc = NULL;
908
909
0
    ret = mbedtls_oid_get_sig_alg_desc(sig_oid, &desc);
910
0
    if (ret != 0) {
911
0
        ret = mbedtls_snprintf(p, n, "???");
912
0
    } else {
913
0
        ret = mbedtls_snprintf(p, n, "%s", desc);
914
0
    }
915
0
    MBEDTLS_X509_SAFE_SNPRINTF;
916
917
0
#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
918
0
    if (pk_alg == MBEDTLS_PK_RSASSA_PSS) {
919
0
        const mbedtls_pk_rsassa_pss_options *pss_opts;
920
0
        const mbedtls_md_info_t *md_info, *mgf_md_info;
921
922
0
        pss_opts = (const mbedtls_pk_rsassa_pss_options *) sig_opts;
923
924
0
        md_info = mbedtls_md_info_from_type(md_alg);
925
0
        mgf_md_info = mbedtls_md_info_from_type(pss_opts->mgf1_hash_id);
926
927
0
        ret = mbedtls_snprintf(p, n, " (%s, MGF1-%s, 0x%02X)",
928
0
                               md_info ? mbedtls_md_get_name(md_info) : "???",
929
0
                               mgf_md_info ? mbedtls_md_get_name(mgf_md_info) : "???",
930
0
                               (unsigned int) pss_opts->expected_salt_len);
931
0
        MBEDTLS_X509_SAFE_SNPRINTF;
932
0
    }
933
#else
934
    ((void) pk_alg);
935
    ((void) md_alg);
936
    ((void) sig_opts);
937
#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
938
939
0
    return (int) (size - n);
940
0
}
941
942
/*
943
 * Helper for writing "RSA key size", "EC key size", etc
944
 */
945
int mbedtls_x509_key_size_helper(char *buf, size_t buf_size, const char *name)
946
0
{
947
0
    char *p = buf;
948
0
    size_t n = buf_size;
949
0
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
950
951
0
    ret = mbedtls_snprintf(p, n, "%s key size", name);
952
0
    MBEDTLS_X509_SAFE_SNPRINTF;
953
954
0
    return 0;
955
0
}
956
957
#if defined(MBEDTLS_HAVE_TIME_DATE)
958
/*
959
 * Set the time structure to the current time.
960
 * Return 0 on success, non-zero on failure.
961
 */
962
static int x509_get_current_time(mbedtls_x509_time *now)
963
0
{
964
0
    struct tm *lt, tm_buf;
965
0
    mbedtls_time_t tt;
966
0
    int ret = 0;
967
968
0
    tt = mbedtls_time(NULL);
969
0
    lt = mbedtls_platform_gmtime_r(&tt, &tm_buf);
970
971
0
    if (lt == NULL) {
972
0
        ret = -1;
973
0
    } else {
974
0
        now->year = lt->tm_year + 1900;
975
0
        now->mon  = lt->tm_mon  + 1;
976
0
        now->day  = lt->tm_mday;
977
0
        now->hour = lt->tm_hour;
978
0
        now->min  = lt->tm_min;
979
0
        now->sec  = lt->tm_sec;
980
0
    }
981
982
0
    return ret;
983
0
}
984
985
/*
986
 * Return 0 if before <= after, 1 otherwise
987
 */
988
static int x509_check_time(const mbedtls_x509_time *before, const mbedtls_x509_time *after)
989
0
{
990
0
    if (before->year  > after->year) {
991
0
        return 1;
992
0
    }
993
994
0
    if (before->year == after->year &&
995
0
        before->mon   > after->mon) {
996
0
        return 1;
997
0
    }
998
999
0
    if (before->year == after->year &&
1000
0
        before->mon  == after->mon  &&
1001
0
        before->day   > after->day) {
1002
0
        return 1;
1003
0
    }
1004
1005
0
    if (before->year == after->year &&
1006
0
        before->mon  == after->mon  &&
1007
0
        before->day  == after->day  &&
1008
0
        before->hour  > after->hour) {
1009
0
        return 1;
1010
0
    }
1011
1012
0
    if (before->year == after->year &&
1013
0
        before->mon  == after->mon  &&
1014
0
        before->day  == after->day  &&
1015
0
        before->hour == after->hour &&
1016
0
        before->min   > after->min) {
1017
0
        return 1;
1018
0
    }
1019
1020
0
    if (before->year == after->year &&
1021
0
        before->mon  == after->mon  &&
1022
0
        before->day  == after->day  &&
1023
0
        before->hour == after->hour &&
1024
0
        before->min  == after->min  &&
1025
0
        before->sec   > after->sec) {
1026
0
        return 1;
1027
0
    }
1028
1029
0
    return 0;
1030
0
}
1031
1032
int mbedtls_x509_time_is_past(const mbedtls_x509_time *to)
1033
0
{
1034
0
    mbedtls_x509_time now;
1035
1036
0
    if (x509_get_current_time(&now) != 0) {
1037
0
        return 1;
1038
0
    }
1039
1040
0
    return x509_check_time(&now, to);
1041
0
}
1042
1043
int mbedtls_x509_time_is_future(const mbedtls_x509_time *from)
1044
0
{
1045
0
    mbedtls_x509_time now;
1046
1047
0
    if (x509_get_current_time(&now) != 0) {
1048
0
        return 1;
1049
0
    }
1050
1051
0
    return x509_check_time(from, &now);
1052
0
}
1053
1054
#else  /* MBEDTLS_HAVE_TIME_DATE */
1055
1056
int mbedtls_x509_time_is_past(const mbedtls_x509_time *to)
1057
{
1058
    ((void) to);
1059
    return 0;
1060
}
1061
1062
int mbedtls_x509_time_is_future(const mbedtls_x509_time *from)
1063
{
1064
    ((void) from);
1065
    return 0;
1066
}
1067
#endif /* MBEDTLS_HAVE_TIME_DATE */
1068
1069
#if defined(MBEDTLS_SELF_TEST)
1070
1071
#include "mbedtls/x509_crt.h"
1072
#include "mbedtls/certs.h"
1073
1074
/*
1075
 * Checkup routine
1076
 */
1077
int mbedtls_x509_self_test(int verbose)
1078
0
{
1079
0
    int ret = 0;
1080
0
#if defined(MBEDTLS_CERTS_C) && defined(MBEDTLS_SHA256_C)
1081
0
    uint32_t flags;
1082
0
    mbedtls_x509_crt cacert;
1083
0
    mbedtls_x509_crt clicert;
1084
1085
0
    if (verbose != 0) {
1086
0
        mbedtls_printf("  X.509 certificate load: ");
1087
0
    }
1088
1089
0
    mbedtls_x509_crt_init(&cacert);
1090
0
    mbedtls_x509_crt_init(&clicert);
1091
1092
0
    ret = mbedtls_x509_crt_parse(&clicert, (const unsigned char *) mbedtls_test_cli_crt,
1093
0
                                 mbedtls_test_cli_crt_len);
1094
0
    if (ret != 0) {
1095
0
        if (verbose != 0) {
1096
0
            mbedtls_printf("failed\n");
1097
0
        }
1098
1099
0
        goto cleanup;
1100
0
    }
1101
1102
0
    ret = mbedtls_x509_crt_parse(&cacert, (const unsigned char *) mbedtls_test_ca_crt,
1103
0
                                 mbedtls_test_ca_crt_len);
1104
0
    if (ret != 0) {
1105
0
        if (verbose != 0) {
1106
0
            mbedtls_printf("failed\n");
1107
0
        }
1108
1109
0
        goto cleanup;
1110
0
    }
1111
1112
0
    if (verbose != 0) {
1113
0
        mbedtls_printf("passed\n  X.509 signature verify: ");
1114
0
    }
1115
1116
0
    ret = mbedtls_x509_crt_verify(&clicert, &cacert, NULL, NULL, &flags, NULL, NULL);
1117
0
    if (ret != 0) {
1118
0
        if (verbose != 0) {
1119
0
            mbedtls_printf("failed\n");
1120
0
        }
1121
1122
0
        goto cleanup;
1123
0
    }
1124
1125
0
    if (verbose != 0) {
1126
0
        mbedtls_printf("passed\n\n");
1127
0
    }
1128
1129
0
cleanup:
1130
0
    mbedtls_x509_crt_free(&cacert);
1131
0
    mbedtls_x509_crt_free(&clicert);
1132
#else
1133
    ((void) verbose);
1134
#endif /* MBEDTLS_CERTS_C && MBEDTLS_SHA256_C */
1135
0
    return ret;
1136
0
}
1137
1138
#endif /* MBEDTLS_SELF_TEST */
1139
1140
#endif /* MBEDTLS_X509_USE_C */