xref: /third_party/mbedtls/library/x509.c (revision a8e1175b)
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 "x509_internal.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/asn1write.h"
35
36#include "mbedtls/platform.h"
37
38#if defined(MBEDTLS_HAVE_TIME)
39#include "mbedtls/platform_time.h"
40#endif
41#if defined(MBEDTLS_HAVE_TIME_DATE)
42#include "mbedtls/platform_util.h"
43#include <time.h>
44#endif
45
46#define CHECK(code)                                     \
47    do {                                                \
48        if ((ret = (code)) != 0) {                      \
49            return ret;                                 \
50        }                                               \
51    } while (0)
52
53#define CHECK_RANGE(min, max, val)                      \
54    do {                                                \
55        if ((val) < (min) || (val) > (max)) {           \
56            return ret;                                 \
57        }                                               \
58    } while (0)
59
60/*
61 *  CertificateSerialNumber  ::=  INTEGER
62 */
63int mbedtls_x509_get_serial(unsigned char **p, const unsigned char *end,
64                            mbedtls_x509_buf *serial)
65{
66    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
67
68    if ((end - *p) < 1) {
69        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_SERIAL,
70                                 MBEDTLS_ERR_ASN1_OUT_OF_DATA);
71    }
72
73    if (**p != (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_PRIMITIVE | 2) &&
74        **p !=   MBEDTLS_ASN1_INTEGER) {
75        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_SERIAL,
76                                 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
77    }
78
79    serial->tag = *(*p)++;
80
81    if ((ret = mbedtls_asn1_get_len(p, end, &serial->len)) != 0) {
82        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_SERIAL, ret);
83    }
84
85    serial->p = *p;
86    *p += serial->len;
87
88    return 0;
89}
90
91/* Get an algorithm identifier without parameters (eg for signatures)
92 *
93 *  AlgorithmIdentifier  ::=  SEQUENCE  {
94 *       algorithm               OBJECT IDENTIFIER,
95 *       parameters              ANY DEFINED BY algorithm OPTIONAL  }
96 */
97int mbedtls_x509_get_alg_null(unsigned char **p, const unsigned char *end,
98                              mbedtls_x509_buf *alg)
99{
100    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
101
102    if ((ret = mbedtls_asn1_get_alg_null(p, end, alg)) != 0) {
103        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
104    }
105
106    return 0;
107}
108
109/*
110 * Parse an algorithm identifier with (optional) parameters
111 */
112int mbedtls_x509_get_alg(unsigned char **p, const unsigned char *end,
113                         mbedtls_x509_buf *alg, mbedtls_x509_buf *params)
114{
115    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
116
117    if ((ret = mbedtls_asn1_get_alg(p, end, alg, params)) != 0) {
118        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
119    }
120
121    return 0;
122}
123
124#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
125/*
126 * Convert md type to string
127 */
128#if !defined(MBEDTLS_X509_REMOVE_INFO) && defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
129
130static inline const char *md_type_to_string(mbedtls_md_type_t md_alg)
131{
132    switch (md_alg) {
133#if defined(MBEDTLS_MD_CAN_MD5)
134        case MBEDTLS_MD_MD5:
135            return "MD5";
136#endif
137#if defined(MBEDTLS_MD_CAN_SHA1)
138        case MBEDTLS_MD_SHA1:
139            return "SHA1";
140#endif
141#if defined(MBEDTLS_MD_CAN_SHA224)
142        case MBEDTLS_MD_SHA224:
143            return "SHA224";
144#endif
145#if defined(MBEDTLS_MD_CAN_SHA256)
146        case MBEDTLS_MD_SHA256:
147            return "SHA256";
148#endif
149#if defined(MBEDTLS_MD_CAN_SHA384)
150        case MBEDTLS_MD_SHA384:
151            return "SHA384";
152#endif
153#if defined(MBEDTLS_MD_CAN_SHA512)
154        case MBEDTLS_MD_SHA512:
155            return "SHA512";
156#endif
157#if defined(MBEDTLS_MD_CAN_RIPEMD160)
158        case MBEDTLS_MD_RIPEMD160:
159            return "RIPEMD160";
160#endif
161        case MBEDTLS_MD_NONE:
162            return NULL;
163        default:
164            return NULL;
165    }
166}
167
168#endif /* !defined(MBEDTLS_X509_REMOVE_INFO) && defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) */
169/*
170 * HashAlgorithm ::= AlgorithmIdentifier
171 *
172 * AlgorithmIdentifier  ::=  SEQUENCE  {
173 *      algorithm               OBJECT IDENTIFIER,
174 *      parameters              ANY DEFINED BY algorithm OPTIONAL  }
175 *
176 * For HashAlgorithm, parameters MUST be NULL or absent.
177 */
178static int x509_get_hash_alg(const mbedtls_x509_buf *alg, mbedtls_md_type_t *md_alg)
179{
180    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
181    unsigned char *p;
182    const unsigned char *end;
183    mbedtls_x509_buf md_oid;
184    size_t len;
185
186    /* Make sure we got a SEQUENCE and setup bounds */
187    if (alg->tag != (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) {
188        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
189                                 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
190    }
191
192    p = alg->p;
193    end = p + alg->len;
194
195    if (p >= end) {
196        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
197                                 MBEDTLS_ERR_ASN1_OUT_OF_DATA);
198    }
199
200    /* Parse md_oid */
201    md_oid.tag = *p;
202
203    if ((ret = mbedtls_asn1_get_tag(&p, end, &md_oid.len, MBEDTLS_ASN1_OID)) != 0) {
204        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
205    }
206
207    md_oid.p = p;
208    p += md_oid.len;
209
210    /* Get md_alg from md_oid */
211    if ((ret = mbedtls_oid_get_md_alg(&md_oid, md_alg)) != 0) {
212        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
213    }
214
215    /* Make sure params is absent of NULL */
216    if (p == end) {
217        return 0;
218    }
219
220    if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_NULL)) != 0 || len != 0) {
221        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
222    }
223
224    if (p != end) {
225        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
226                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
227    }
228
229    return 0;
230}
231
232/*
233 *    RSASSA-PSS-params  ::=  SEQUENCE  {
234 *       hashAlgorithm     [0] HashAlgorithm DEFAULT sha1Identifier,
235 *       maskGenAlgorithm  [1] MaskGenAlgorithm DEFAULT mgf1SHA1Identifier,
236 *       saltLength        [2] INTEGER DEFAULT 20,
237 *       trailerField      [3] INTEGER DEFAULT 1  }
238 *    -- Note that the tags in this Sequence are explicit.
239 *
240 * RFC 4055 (which defines use of RSASSA-PSS in PKIX) states that the value
241 * of trailerField MUST be 1, and PKCS#1 v2.2 doesn't even define any other
242 * option. Enforce this at parsing time.
243 */
244int mbedtls_x509_get_rsassa_pss_params(const mbedtls_x509_buf *params,
245                                       mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md,
246                                       int *salt_len)
247{
248    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
249    unsigned char *p;
250    const unsigned char *end, *end2;
251    size_t len;
252    mbedtls_x509_buf alg_id, alg_params;
253
254    /* First set everything to defaults */
255    *md_alg = MBEDTLS_MD_SHA1;
256    *mgf_md = MBEDTLS_MD_SHA1;
257    *salt_len = 20;
258
259    /* Make sure params is a SEQUENCE and setup bounds */
260    if (params->tag != (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) {
261        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
262                                 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
263    }
264
265    p = (unsigned char *) params->p;
266    end = p + params->len;
267
268    if (p == end) {
269        return 0;
270    }
271
272    /*
273     * HashAlgorithm
274     */
275    if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
276                                    MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED |
277                                    0)) == 0) {
278        end2 = p + len;
279
280        /* HashAlgorithm ::= AlgorithmIdentifier (without parameters) */
281        if ((ret = mbedtls_x509_get_alg_null(&p, end2, &alg_id)) != 0) {
282            return ret;
283        }
284
285        if ((ret = mbedtls_oid_get_md_alg(&alg_id, md_alg)) != 0) {
286            return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
287        }
288
289        if (p != end2) {
290            return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
291                                     MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
292        }
293    } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
294        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
295    }
296
297    if (p == end) {
298        return 0;
299    }
300
301    /*
302     * MaskGenAlgorithm
303     */
304    if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
305                                    MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED |
306                                    1)) == 0) {
307        end2 = p + len;
308
309        /* MaskGenAlgorithm ::= AlgorithmIdentifier (params = HashAlgorithm) */
310        if ((ret = mbedtls_x509_get_alg(&p, end2, &alg_id, &alg_params)) != 0) {
311            return ret;
312        }
313
314        /* Only MFG1 is recognised for now */
315        if (MBEDTLS_OID_CMP(MBEDTLS_OID_MGF1, &alg_id) != 0) {
316            return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE,
317                                     MBEDTLS_ERR_OID_NOT_FOUND);
318        }
319
320        /* Parse HashAlgorithm */
321        if ((ret = x509_get_hash_alg(&alg_params, mgf_md)) != 0) {
322            return ret;
323        }
324
325        if (p != end2) {
326            return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
327                                     MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
328        }
329    } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
330        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
331    }
332
333    if (p == end) {
334        return 0;
335    }
336
337    /*
338     * salt_len
339     */
340    if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
341                                    MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED |
342                                    2)) == 0) {
343        end2 = p + len;
344
345        if ((ret = mbedtls_asn1_get_int(&p, end2, salt_len)) != 0) {
346            return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
347        }
348
349        if (p != end2) {
350            return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
351                                     MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
352        }
353    } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
354        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
355    }
356
357    if (p == end) {
358        return 0;
359    }
360
361    /*
362     * trailer_field (if present, must be 1)
363     */
364    if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
365                                    MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED |
366                                    3)) == 0) {
367        int trailer_field;
368
369        end2 = p + len;
370
371        if ((ret = mbedtls_asn1_get_int(&p, end2, &trailer_field)) != 0) {
372            return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
373        }
374
375        if (p != end2) {
376            return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
377                                     MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
378        }
379
380        if (trailer_field != 1) {
381            return MBEDTLS_ERR_X509_INVALID_ALG;
382        }
383    } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
384        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
385    }
386
387    if (p != end) {
388        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
389                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
390    }
391
392    return 0;
393}
394#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
395
396/*
397 *  AttributeTypeAndValue ::= SEQUENCE {
398 *    type     AttributeType,
399 *    value    AttributeValue }
400 *
401 *  AttributeType ::= OBJECT IDENTIFIER
402 *
403 *  AttributeValue ::= ANY DEFINED BY AttributeType
404 */
405static int x509_get_attr_type_value(unsigned char **p,
406                                    const unsigned char *end,
407                                    mbedtls_x509_name *cur)
408{
409    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
410    size_t len;
411    mbedtls_x509_buf *oid;
412    mbedtls_x509_buf *val;
413
414    if ((ret = mbedtls_asn1_get_tag(p, end, &len,
415                                    MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
416        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME, ret);
417    }
418
419    end = *p + len;
420
421    if ((end - *p) < 1) {
422        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME,
423                                 MBEDTLS_ERR_ASN1_OUT_OF_DATA);
424    }
425
426    oid = &cur->oid;
427    oid->tag = **p;
428
429    if ((ret = mbedtls_asn1_get_tag(p, end, &oid->len, MBEDTLS_ASN1_OID)) != 0) {
430        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME, ret);
431    }
432
433    oid->p = *p;
434    *p += oid->len;
435
436    if ((end - *p) < 1) {
437        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME,
438                                 MBEDTLS_ERR_ASN1_OUT_OF_DATA);
439    }
440
441    if (**p != MBEDTLS_ASN1_BMP_STRING && **p != MBEDTLS_ASN1_UTF8_STRING      &&
442        **p != MBEDTLS_ASN1_T61_STRING && **p != MBEDTLS_ASN1_PRINTABLE_STRING &&
443        **p != MBEDTLS_ASN1_IA5_STRING && **p != MBEDTLS_ASN1_UNIVERSAL_STRING &&
444        **p != MBEDTLS_ASN1_BIT_STRING) {
445        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME,
446                                 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
447    }
448
449    val = &cur->val;
450    val->tag = *(*p)++;
451
452    if ((ret = mbedtls_asn1_get_len(p, end, &val->len)) != 0) {
453        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME, ret);
454    }
455
456    val->p = *p;
457    *p += val->len;
458
459    if (*p != end) {
460        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME,
461                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
462    }
463
464    cur->next = NULL;
465
466    return 0;
467}
468
469/*
470 *  Name ::= CHOICE { -- only one possibility for now --
471 *       rdnSequence  RDNSequence }
472 *
473 *  RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
474 *
475 *  RelativeDistinguishedName ::=
476 *    SET OF AttributeTypeAndValue
477 *
478 *  AttributeTypeAndValue ::= SEQUENCE {
479 *    type     AttributeType,
480 *    value    AttributeValue }
481 *
482 *  AttributeType ::= OBJECT IDENTIFIER
483 *
484 *  AttributeValue ::= ANY DEFINED BY AttributeType
485 *
486 * The data structure is optimized for the common case where each RDN has only
487 * one element, which is represented as a list of AttributeTypeAndValue.
488 * For the general case we still use a flat list, but we mark elements of the
489 * same set so that they are "merged" together in the functions that consume
490 * this list, eg mbedtls_x509_dn_gets().
491 *
492 * On success, this function may allocate a linked list starting at cur->next
493 * that must later be free'd by the caller using mbedtls_free(). In error
494 * cases, this function frees all allocated memory internally and the caller
495 * has no freeing responsibilities.
496 */
497int mbedtls_x509_get_name(unsigned char **p, const unsigned char *end,
498                          mbedtls_x509_name *cur)
499{
500    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
501    size_t set_len;
502    const unsigned char *end_set;
503    mbedtls_x509_name *head = cur;
504
505    /* don't use recursion, we'd risk stack overflow if not optimized */
506    while (1) {
507        /*
508         * parse SET
509         */
510        if ((ret = mbedtls_asn1_get_tag(p, end, &set_len,
511                                        MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET)) != 0) {
512            ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME, ret);
513            goto error;
514        }
515
516        end_set  = *p + set_len;
517
518        while (1) {
519            if ((ret = x509_get_attr_type_value(p, end_set, cur)) != 0) {
520                goto error;
521            }
522
523            if (*p == end_set) {
524                break;
525            }
526
527            /* Mark this item as being no the only one in a set */
528            cur->next_merged = 1;
529
530            cur->next = mbedtls_calloc(1, sizeof(mbedtls_x509_name));
531
532            if (cur->next == NULL) {
533                ret = MBEDTLS_ERR_X509_ALLOC_FAILED;
534                goto error;
535            }
536
537            cur = cur->next;
538        }
539
540        /*
541         * continue until end of SEQUENCE is reached
542         */
543        if (*p == end) {
544            return 0;
545        }
546
547        cur->next = mbedtls_calloc(1, sizeof(mbedtls_x509_name));
548
549        if (cur->next == NULL) {
550            ret = MBEDTLS_ERR_X509_ALLOC_FAILED;
551            goto error;
552        }
553
554        cur = cur->next;
555    }
556
557error:
558    /* Skip the first element as we did not allocate it */
559    mbedtls_asn1_free_named_data_list_shallow(head->next);
560    head->next = NULL;
561
562    return ret;
563}
564
565static int x509_date_is_valid(const mbedtls_x509_time *t)
566{
567    unsigned int month_days;
568    unsigned int year;
569    switch (t->mon) {
570        case 1: case 3: case 5: case 7: case 8: case 10: case 12:
571            month_days = 31;
572            break;
573        case 4: case 6: case 9: case 11:
574            month_days = 30;
575            break;
576        case 2:
577            year = (unsigned int) t->year;
578            month_days = ((year & 3) || (!(year % 100)
579                                         && (year % 400)))
580                          ? 28 : 29;
581            break;
582        default:
583            return MBEDTLS_ERR_X509_INVALID_DATE;
584    }
585
586    if ((unsigned int) (t->day - 1) >= month_days ||      /* (1 - days in month) */
587        /* (unsigned int) (t->mon - 1) >= 12 || */  /* (1 - 12) checked above */
588        (unsigned int) t->year > 9999 ||         /* (0 - 9999) */
589        (unsigned int) t->hour > 23 ||           /* (0 - 23) */
590        (unsigned int) t->min  > 59 ||           /* (0 - 59) */
591        (unsigned int) t->sec  > 59) {           /* (0 - 59) */
592        return MBEDTLS_ERR_X509_INVALID_DATE;
593    }
594
595    return 0;
596}
597
598static int x509_parse2_int(const unsigned char *p)
599{
600    uint32_t d1 = p[0] - '0';
601    uint32_t d2 = p[1] - '0';
602    return (d1 < 10 && d2 < 10) ? (int) (d1 * 10 + d2) : -1;
603}
604
605/*
606 * Parse an ASN1_UTC_TIME (yearlen=2) or ASN1_GENERALIZED_TIME (yearlen=4)
607 * field.
608 */
609static int x509_parse_time(const unsigned char *p, mbedtls_x509_time *tm,
610                           size_t yearlen)
611{
612    int x;
613
614    /*
615     * Parse year, month, day, hour, minute, second
616     */
617    tm->year = x509_parse2_int(p);
618    if (tm->year < 0) {
619        return MBEDTLS_ERR_X509_INVALID_DATE;
620    }
621
622    if (4 == yearlen) {
623        x = tm->year * 100;
624        p += 2;
625        tm->year = x509_parse2_int(p);
626        if (tm->year < 0) {
627            return MBEDTLS_ERR_X509_INVALID_DATE;
628        }
629    } else {
630        x = (tm->year < 50) ? 2000 : 1900;
631    }
632    tm->year += x;
633
634    tm->mon  = x509_parse2_int(p + 2);
635    tm->day  = x509_parse2_int(p + 4);
636    tm->hour = x509_parse2_int(p + 6);
637    tm->min  = x509_parse2_int(p + 8);
638    tm->sec  = x509_parse2_int(p + 10);
639
640    return x509_date_is_valid(tm);
641}
642
643/*
644 *  Time ::= CHOICE {
645 *       utcTime        UTCTime,
646 *       generalTime    GeneralizedTime }
647 */
648int mbedtls_x509_get_time(unsigned char **p, const unsigned char *end,
649                          mbedtls_x509_time *tm)
650{
651    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
652    size_t len, year_len;
653    unsigned char tag;
654
655    if ((end - *p) < 1) {
656        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_DATE,
657                                 MBEDTLS_ERR_ASN1_OUT_OF_DATA);
658    }
659
660    tag = **p;
661
662    if (tag == MBEDTLS_ASN1_UTC_TIME) {
663        year_len = 2;
664    } else if (tag == MBEDTLS_ASN1_GENERALIZED_TIME) {
665        year_len = 4;
666    } else {
667        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_DATE,
668                                 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
669    }
670
671    (*p)++;
672    ret = mbedtls_asn1_get_len(p, end, &len);
673
674    if (ret != 0) {
675        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_DATE, ret);
676    }
677
678    /* len is 12 or 14 depending on year_len, plus optional trailing 'Z' */
679    if (len != year_len + 10 &&
680        !(len == year_len + 11 && (*p)[(len - 1)] == 'Z')) {
681        return MBEDTLS_ERR_X509_INVALID_DATE;
682    }
683
684    (*p) += len;
685    return x509_parse_time(*p - len, tm, year_len);
686}
687
688int mbedtls_x509_get_sig(unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig)
689{
690    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
691    size_t len;
692    int tag_type;
693
694    if ((end - *p) < 1) {
695        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_SIGNATURE,
696                                 MBEDTLS_ERR_ASN1_OUT_OF_DATA);
697    }
698
699    tag_type = **p;
700
701    if ((ret = mbedtls_asn1_get_bitstring_null(p, end, &len)) != 0) {
702        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_SIGNATURE, ret);
703    }
704
705    sig->tag = tag_type;
706    sig->len = len;
707    sig->p = *p;
708
709    *p += len;
710
711    return 0;
712}
713
714/*
715 * Get signature algorithm from alg OID and optional parameters
716 */
717int mbedtls_x509_get_sig_alg(const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params,
718                             mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg,
719                             void **sig_opts)
720{
721    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
722
723    if (*sig_opts != NULL) {
724        return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
725    }
726
727    if ((ret = mbedtls_oid_get_sig_alg(sig_oid, md_alg, pk_alg)) != 0) {
728        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG, ret);
729    }
730
731#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
732    if (*pk_alg == MBEDTLS_PK_RSASSA_PSS) {
733        mbedtls_pk_rsassa_pss_options *pss_opts;
734
735        pss_opts = mbedtls_calloc(1, sizeof(mbedtls_pk_rsassa_pss_options));
736        if (pss_opts == NULL) {
737            return MBEDTLS_ERR_X509_ALLOC_FAILED;
738        }
739
740        ret = mbedtls_x509_get_rsassa_pss_params(sig_params,
741                                                 md_alg,
742                                                 &pss_opts->mgf1_hash_id,
743                                                 &pss_opts->expected_salt_len);
744        if (ret != 0) {
745            mbedtls_free(pss_opts);
746            return ret;
747        }
748
749        *sig_opts = (void *) pss_opts;
750    } else
751#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
752    {
753        /* Make sure parameters are absent or NULL */
754        if ((sig_params->tag != MBEDTLS_ASN1_NULL && sig_params->tag != 0) ||
755            sig_params->len != 0) {
756            return MBEDTLS_ERR_X509_INVALID_ALG;
757        }
758    }
759
760    return 0;
761}
762
763/*
764 * X.509 Extensions (No parsing of extensions, pointer should
765 * be either manually updated or extensions should be parsed!)
766 */
767int mbedtls_x509_get_ext(unsigned char **p, const unsigned char *end,
768                         mbedtls_x509_buf *ext, int tag)
769{
770    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
771    size_t len;
772
773    /* Extension structure use EXPLICIT tagging. That is, the actual
774     * `Extensions` structure is wrapped by a tag-length pair using
775     * the respective context-specific tag. */
776    ret = mbedtls_asn1_get_tag(p, end, &ext->len,
777                               MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag);
778    if (ret != 0) {
779        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
780    }
781
782    ext->tag = MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag;
783    ext->p   = *p;
784    end      = *p + ext->len;
785
786    /*
787     * Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
788     */
789    if ((ret = mbedtls_asn1_get_tag(p, end, &len,
790                                    MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
791        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
792    }
793
794    if (end != *p + len) {
795        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
796                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
797    }
798
799    return 0;
800}
801
802static char nibble_to_hex_digit(int i)
803{
804    return (i < 10) ? (i + '0') : (i - 10 + 'A');
805}
806
807/*
808 * Store the name in printable form into buf; no more
809 * than size characters will be written
810 */
811int mbedtls_x509_dn_gets(char *buf, size_t size, const mbedtls_x509_name *dn)
812{
813    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
814    size_t i, j, n, asn1_len_size, asn1_tag_size, asn1_tag_len_buf_start;
815    /* 6 is enough as our asn1 write functions only write one byte for the tag and at most five bytes for the length*/
816    unsigned char asn1_tag_len_buf[6];
817    unsigned char *asn1_len_p;
818    unsigned char c, merge = 0;
819    const mbedtls_x509_name *name;
820    const char *short_name = NULL;
821    char lowbits, highbits;
822    char s[MBEDTLS_X509_MAX_DN_NAME_SIZE], *p;
823    int print_hexstring;
824
825    memset(s, 0, sizeof(s));
826
827    name = dn;
828    p = buf;
829    n = size;
830
831    while (name != NULL) {
832        if (!name->oid.p) {
833            name = name->next;
834            continue;
835        }
836
837        if (name != dn) {
838            ret = mbedtls_snprintf(p, n, merge ? " + " : ", ");
839            MBEDTLS_X509_SAFE_SNPRINTF;
840        }
841
842        print_hexstring = (name->val.tag != MBEDTLS_ASN1_UTF8_STRING) &&
843                          (name->val.tag != MBEDTLS_ASN1_PRINTABLE_STRING) &&
844                          (name->val.tag != MBEDTLS_ASN1_IA5_STRING);
845
846        if ((ret = mbedtls_oid_get_attr_short_name(&name->oid, &short_name)) == 0) {
847            ret = mbedtls_snprintf(p, n, "%s=", short_name);
848        } else {
849            if ((ret = mbedtls_oid_get_numeric_string(p, n, &name->oid)) > 0) {
850                n -= ret;
851                p += ret;
852                ret = mbedtls_snprintf(p, n, "=");
853                print_hexstring = 1;
854            } else if (ret == MBEDTLS_ERR_OID_BUF_TOO_SMALL) {
855                return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
856            } else {
857                ret = mbedtls_snprintf(p, n, "\?\?=");
858            }
859        }
860        MBEDTLS_X509_SAFE_SNPRINTF;
861
862        if (print_hexstring) {
863            s[0] = '#';
864
865            asn1_len_p = asn1_tag_len_buf + sizeof(asn1_tag_len_buf);
866            if ((ret = mbedtls_asn1_write_len(&asn1_len_p, asn1_tag_len_buf, name->val.len)) < 0) {
867                return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
868            }
869            asn1_len_size = ret;
870            if ((ret = mbedtls_asn1_write_tag(&asn1_len_p, asn1_tag_len_buf, name->val.tag)) < 0) {
871                return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
872            }
873            asn1_tag_size = ret;
874            asn1_tag_len_buf_start = sizeof(asn1_tag_len_buf) - asn1_len_size - asn1_tag_size;
875            for (i = 0, j = 1; i < asn1_len_size + asn1_tag_size; i++) {
876                if (j + 1 >= sizeof(s) - 1) {
877                    return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
878                }
879                c = asn1_tag_len_buf[asn1_tag_len_buf_start+i];
880                lowbits = (c & 0x0F);
881                highbits = c >> 4;
882                s[j++] = nibble_to_hex_digit(highbits);
883                s[j++] = nibble_to_hex_digit(lowbits);
884            }
885            for (i = 0; i < name->val.len; i++) {
886                if (j + 1 >= sizeof(s) - 1) {
887                    return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
888                }
889                c = name->val.p[i];
890                lowbits = (c & 0x0F);
891                highbits = c >> 4;
892                s[j++] = nibble_to_hex_digit(highbits);
893                s[j++] = nibble_to_hex_digit(lowbits);
894            }
895        } else {
896            for (i = 0, j = 0; i < name->val.len; i++, j++) {
897                if (j >= sizeof(s) - 1) {
898                    return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
899                }
900
901                c = name->val.p[i];
902                // Special characters requiring escaping, RFC 4514 Section 2.4
903                if (c == '\0') {
904                    return MBEDTLS_ERR_X509_INVALID_NAME;
905                } else {
906                    if (strchr(",=+<>;\"\\", c) ||
907                        ((i == 0) && strchr("# ", c)) ||
908                        ((i == name->val.len-1) && (c == ' '))) {
909                        if (j + 1 >= sizeof(s) - 1) {
910                            return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
911                        }
912                        s[j++] = '\\';
913                    }
914                }
915                if (c < 32 || c >= 127) {
916                    if (j + 3 >= sizeof(s) - 1) {
917                        return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
918                    }
919                    s[j++] = '\\';
920                    lowbits = (c & 0x0F);
921                    highbits = c >> 4;
922                    s[j++] = nibble_to_hex_digit(highbits);
923                    s[j] = nibble_to_hex_digit(lowbits);
924                } else {
925                    s[j] = c;
926                }
927            }
928        }
929        s[j] = '\0';
930        ret = mbedtls_snprintf(p, n, "%s", s);
931        MBEDTLS_X509_SAFE_SNPRINTF;
932
933        merge = name->next_merged;
934        name = name->next;
935    }
936
937    return (int) (size - n);
938}
939
940/*
941 * Store the serial in printable form into buf; no more
942 * than size characters will be written
943 */
944int mbedtls_x509_serial_gets(char *buf, size_t size, const mbedtls_x509_buf *serial)
945{
946    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
947    size_t i, n, nr;
948    char *p;
949
950    p = buf;
951    n = size;
952
953    nr = (serial->len <= 32)
954        ? serial->len  : 28;
955
956    for (i = 0; i < nr; i++) {
957        if (i == 0 && nr > 1 && serial->p[i] == 0x0) {
958            continue;
959        }
960
961        ret = mbedtls_snprintf(p, n, "%02X%s",
962                               serial->p[i], (i < nr - 1) ? ":" : "");
963        MBEDTLS_X509_SAFE_SNPRINTF;
964    }
965
966    if (nr != serial->len) {
967        ret = mbedtls_snprintf(p, n, "....");
968        MBEDTLS_X509_SAFE_SNPRINTF;
969    }
970
971    return (int) (size - n);
972}
973
974#if !defined(MBEDTLS_X509_REMOVE_INFO)
975/*
976 * Helper for writing signature algorithms
977 */
978int mbedtls_x509_sig_alg_gets(char *buf, size_t size, const mbedtls_x509_buf *sig_oid,
979                              mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg,
980                              const void *sig_opts)
981{
982    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
983    char *p = buf;
984    size_t n = size;
985    const char *desc = NULL;
986
987    ret = mbedtls_oid_get_sig_alg_desc(sig_oid, &desc);
988    if (ret != 0) {
989        ret = mbedtls_snprintf(p, n, "???");
990    } else {
991        ret = mbedtls_snprintf(p, n, "%s", desc);
992    }
993    MBEDTLS_X509_SAFE_SNPRINTF;
994
995#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
996    if (pk_alg == MBEDTLS_PK_RSASSA_PSS) {
997        const mbedtls_pk_rsassa_pss_options *pss_opts;
998
999        pss_opts = (const mbedtls_pk_rsassa_pss_options *) sig_opts;
1000
1001        const char *name = md_type_to_string(md_alg);
1002        const char *mgf_name = md_type_to_string(pss_opts->mgf1_hash_id);
1003
1004        ret = mbedtls_snprintf(p, n, " (%s, MGF1-%s, 0x%02X)",
1005                               name ? name : "???",
1006                               mgf_name ? mgf_name : "???",
1007                               (unsigned int) pss_opts->expected_salt_len);
1008        MBEDTLS_X509_SAFE_SNPRINTF;
1009    }
1010#else
1011    ((void) pk_alg);
1012    ((void) md_alg);
1013    ((void) sig_opts);
1014#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
1015
1016    return (int) (size - n);
1017}
1018#endif /* MBEDTLS_X509_REMOVE_INFO */
1019
1020/*
1021 * Helper for writing "RSA key size", "EC key size", etc
1022 */
1023int mbedtls_x509_key_size_helper(char *buf, size_t buf_size, const char *name)
1024{
1025    char *p = buf;
1026    size_t n = buf_size;
1027    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1028
1029    ret = mbedtls_snprintf(p, n, "%s key size", name);
1030    MBEDTLS_X509_SAFE_SNPRINTF;
1031
1032    return 0;
1033}
1034
1035int mbedtls_x509_time_cmp(const mbedtls_x509_time *t1,
1036                          const mbedtls_x509_time *t2)
1037{
1038    int x;
1039
1040    x = (((t1->year << 9) | (t1->mon << 5) | (t1->day)) -
1041         ((t2->year << 9) | (t2->mon << 5) | (t2->day)));
1042    if (x != 0) {
1043        return x;
1044    }
1045
1046    x = (((t1->hour << 12) | (t1->min << 6) | (t1->sec)) -
1047         ((t2->hour << 12) | (t2->min << 6) | (t2->sec)));
1048    return x;
1049}
1050
1051#if defined(MBEDTLS_HAVE_TIME_DATE)
1052int mbedtls_x509_time_gmtime(mbedtls_time_t tt, mbedtls_x509_time *now)
1053{
1054    struct tm tm;
1055
1056    if (mbedtls_platform_gmtime_r(&tt, &tm) == NULL) {
1057        return -1;
1058    }
1059
1060    now->year = tm.tm_year + 1900;
1061    now->mon  = tm.tm_mon  + 1;
1062    now->day  = tm.tm_mday;
1063    now->hour = tm.tm_hour;
1064    now->min  = tm.tm_min;
1065    now->sec  = tm.tm_sec;
1066    return 0;
1067}
1068
1069static int x509_get_current_time(mbedtls_x509_time *now)
1070{
1071    return mbedtls_x509_time_gmtime(mbedtls_time(NULL), now);
1072}
1073
1074int mbedtls_x509_time_is_past(const mbedtls_x509_time *to)
1075{
1076    mbedtls_x509_time now;
1077
1078    if (x509_get_current_time(&now) != 0) {
1079        return 1;
1080    }
1081
1082    return mbedtls_x509_time_cmp(to, &now) < 0;
1083}
1084
1085int mbedtls_x509_time_is_future(const mbedtls_x509_time *from)
1086{
1087    mbedtls_x509_time now;
1088
1089    if (x509_get_current_time(&now) != 0) {
1090        return 1;
1091    }
1092
1093    return mbedtls_x509_time_cmp(from, &now) > 0;
1094}
1095
1096#else  /* MBEDTLS_HAVE_TIME_DATE */
1097
1098int mbedtls_x509_time_is_past(const mbedtls_x509_time *to)
1099{
1100    ((void) to);
1101    return 0;
1102}
1103
1104int mbedtls_x509_time_is_future(const mbedtls_x509_time *from)
1105{
1106    ((void) from);
1107    return 0;
1108}
1109#endif /* MBEDTLS_HAVE_TIME_DATE */
1110
1111/* Common functions for parsing CRT and CSR. */
1112#if defined(MBEDTLS_X509_CRT_PARSE_C) || defined(MBEDTLS_X509_CSR_PARSE_C)
1113/*
1114 * OtherName ::= SEQUENCE {
1115 *      type-id    OBJECT IDENTIFIER,
1116 *      value      [0] EXPLICIT ANY DEFINED BY type-id }
1117 *
1118 * HardwareModuleName ::= SEQUENCE {
1119 *                           hwType OBJECT IDENTIFIER,
1120 *                           hwSerialNum OCTET STRING }
1121 *
1122 * NOTE: we currently only parse and use otherName of type HwModuleName,
1123 * as defined in RFC 4108.
1124 */
1125static int x509_get_other_name(const mbedtls_x509_buf *subject_alt_name,
1126                               mbedtls_x509_san_other_name *other_name)
1127{
1128    int ret = 0;
1129    size_t len;
1130    unsigned char *p = subject_alt_name->p;
1131    const unsigned char *end = p + subject_alt_name->len;
1132    mbedtls_x509_buf cur_oid;
1133
1134    if ((subject_alt_name->tag &
1135         (MBEDTLS_ASN1_TAG_CLASS_MASK | MBEDTLS_ASN1_TAG_VALUE_MASK)) !=
1136        (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_OTHER_NAME)) {
1137        /*
1138         * The given subject alternative name is not of type "othername".
1139         */
1140        return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
1141    }
1142
1143    if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
1144                                    MBEDTLS_ASN1_OID)) != 0) {
1145        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
1146    }
1147
1148    cur_oid.tag = MBEDTLS_ASN1_OID;
1149    cur_oid.p = p;
1150    cur_oid.len = len;
1151
1152    /*
1153     * Only HwModuleName is currently supported.
1154     */
1155    if (MBEDTLS_OID_CMP(MBEDTLS_OID_ON_HW_MODULE_NAME, &cur_oid) != 0) {
1156        return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
1157    }
1158    other_name->type_id = cur_oid;
1159
1160    p += len;
1161    if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
1162                                    MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC)) !=
1163        0) {
1164        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
1165    }
1166
1167    if (end != p + len) {
1168        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
1169                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
1170    }
1171
1172    if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
1173                                    MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
1174        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
1175    }
1176
1177    if (end != p + len) {
1178        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
1179                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
1180    }
1181
1182    if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OID)) != 0) {
1183        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
1184    }
1185
1186    other_name->value.hardware_module_name.oid.tag = MBEDTLS_ASN1_OID;
1187    other_name->value.hardware_module_name.oid.p = p;
1188    other_name->value.hardware_module_name.oid.len = len;
1189
1190    p += len;
1191    if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
1192                                    MBEDTLS_ASN1_OCTET_STRING)) != 0) {
1193        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
1194    }
1195
1196    other_name->value.hardware_module_name.val.tag = MBEDTLS_ASN1_OCTET_STRING;
1197    other_name->value.hardware_module_name.val.p = p;
1198    other_name->value.hardware_module_name.val.len = len;
1199    p += len;
1200    if (p != end) {
1201        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
1202                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
1203    }
1204    return 0;
1205}
1206
1207/* Check mbedtls_x509_get_subject_alt_name for detailed description.
1208 *
1209 * In some cases while parsing subject alternative names the sequence tag is optional
1210 * (e.g. CertSerialNumber). This function is designed to handle such case.
1211 */
1212int mbedtls_x509_get_subject_alt_name_ext(unsigned char **p,
1213                                          const unsigned char *end,
1214                                          mbedtls_x509_sequence *subject_alt_name)
1215{
1216    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1217    size_t tag_len;
1218    mbedtls_asn1_sequence *cur = subject_alt_name;
1219
1220    while (*p < end) {
1221        mbedtls_x509_subject_alternative_name tmp_san_name;
1222        mbedtls_x509_buf tmp_san_buf;
1223        memset(&tmp_san_name, 0, sizeof(tmp_san_name));
1224
1225        tmp_san_buf.tag = **p;
1226        (*p)++;
1227
1228        if ((ret = mbedtls_asn1_get_len(p, end, &tag_len)) != 0) {
1229            return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
1230        }
1231
1232        tmp_san_buf.p = *p;
1233        tmp_san_buf.len = tag_len;
1234
1235        if ((tmp_san_buf.tag & MBEDTLS_ASN1_TAG_CLASS_MASK) !=
1236            MBEDTLS_ASN1_CONTEXT_SPECIFIC) {
1237            return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
1238                                     MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
1239        }
1240
1241        /*
1242         * Check that the SAN is structured correctly by parsing it.
1243         * The SAN structure is discarded afterwards.
1244         */
1245        ret = mbedtls_x509_parse_subject_alt_name(&tmp_san_buf, &tmp_san_name);
1246        /*
1247         * In case the extension is malformed, return an error,
1248         * and clear the allocated sequences.
1249         */
1250        if (ret != 0 && ret != MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) {
1251            mbedtls_asn1_sequence_free(subject_alt_name->next);
1252            subject_alt_name->next = NULL;
1253            return ret;
1254        }
1255
1256        mbedtls_x509_free_subject_alt_name(&tmp_san_name);
1257        /* Allocate and assign next pointer */
1258        if (cur->buf.p != NULL) {
1259            if (cur->next != NULL) {
1260                return MBEDTLS_ERR_X509_INVALID_EXTENSIONS;
1261            }
1262
1263            cur->next = mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence));
1264
1265            if (cur->next == NULL) {
1266                return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
1267                                         MBEDTLS_ERR_ASN1_ALLOC_FAILED);
1268            }
1269
1270            cur = cur->next;
1271        }
1272
1273        cur->buf = tmp_san_buf;
1274        *p += tmp_san_buf.len;
1275    }
1276
1277    /* Set final sequence entry's next pointer to NULL */
1278    cur->next = NULL;
1279
1280    if (*p != end) {
1281        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
1282                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
1283    }
1284
1285    return 0;
1286}
1287
1288/*
1289 * SubjectAltName ::= GeneralNames
1290 *
1291 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
1292 *
1293 * GeneralName ::= CHOICE {
1294 *      otherName                       [0]     OtherName,
1295 *      rfc822Name                      [1]     IA5String,
1296 *      dNSName                         [2]     IA5String,
1297 *      x400Address                     [3]     ORAddress,
1298 *      directoryName                   [4]     Name,
1299 *      ediPartyName                    [5]     EDIPartyName,
1300 *      uniformResourceIdentifier       [6]     IA5String,
1301 *      iPAddress                       [7]     OCTET STRING,
1302 *      registeredID                    [8]     OBJECT IDENTIFIER }
1303 *
1304 * OtherName ::= SEQUENCE {
1305 *      type-id    OBJECT IDENTIFIER,
1306 *      value      [0] EXPLICIT ANY DEFINED BY type-id }
1307 *
1308 * EDIPartyName ::= SEQUENCE {
1309 *      nameAssigner            [0]     DirectoryString OPTIONAL,
1310 *      partyName               [1]     DirectoryString }
1311 *
1312 * We list all types, but use the following GeneralName types from RFC 5280:
1313 * "dnsName", "uniformResourceIdentifier" and "hardware_module_name"
1314 * of type "otherName", as defined in RFC 4108.
1315 */
1316int mbedtls_x509_get_subject_alt_name(unsigned char **p,
1317                                      const unsigned char *end,
1318                                      mbedtls_x509_sequence *subject_alt_name)
1319{
1320    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1321    size_t len;
1322
1323    /* Get main sequence tag */
1324    if ((ret = mbedtls_asn1_get_tag(p, end, &len,
1325                                    MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
1326        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
1327    }
1328
1329    if (*p + len != end) {
1330        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
1331                                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
1332    }
1333
1334    return mbedtls_x509_get_subject_alt_name_ext(p, end, subject_alt_name);
1335}
1336
1337int mbedtls_x509_get_ns_cert_type(unsigned char **p,
1338                                  const unsigned char *end,
1339                                  unsigned char *ns_cert_type)
1340{
1341    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1342    mbedtls_x509_bitstring bs = { 0, 0, NULL };
1343
1344    if ((ret = mbedtls_asn1_get_bitstring(p, end, &bs)) != 0) {
1345        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
1346    }
1347
1348    /* A bitstring with no flags set is still technically valid, as it will mean
1349       that the certificate has no designated purpose at the time of creation. */
1350    if (bs.len == 0) {
1351        *ns_cert_type = 0;
1352        return 0;
1353    }
1354
1355    if (bs.len != 1) {
1356        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
1357                                 MBEDTLS_ERR_ASN1_INVALID_LENGTH);
1358    }
1359
1360    /* Get actual bitstring */
1361    *ns_cert_type = *bs.p;
1362    return 0;
1363}
1364
1365int mbedtls_x509_get_key_usage(unsigned char **p,
1366                               const unsigned char *end,
1367                               unsigned int *key_usage)
1368{
1369    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1370    size_t i;
1371    mbedtls_x509_bitstring bs = { 0, 0, NULL };
1372
1373    if ((ret = mbedtls_asn1_get_bitstring(p, end, &bs)) != 0) {
1374        return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
1375    }
1376
1377    /* A bitstring with no flags set is still technically valid, as it will mean
1378       that the certificate has no designated purpose at the time of creation. */
1379    if (bs.len == 0) {
1380        *key_usage = 0;
1381        return 0;
1382    }
1383
1384    /* Get actual bitstring */
1385    *key_usage = 0;
1386    for (i = 0; i < bs.len && i < sizeof(unsigned int); i++) {
1387        *key_usage |= (unsigned int) bs.p[i] << (8*i);
1388    }
1389
1390    return 0;
1391}
1392
1393int mbedtls_x509_parse_subject_alt_name(const mbedtls_x509_buf *san_buf,
1394                                        mbedtls_x509_subject_alternative_name *san)
1395{
1396    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1397    switch (san_buf->tag &
1398            (MBEDTLS_ASN1_TAG_CLASS_MASK |
1399             MBEDTLS_ASN1_TAG_VALUE_MASK)) {
1400        /*
1401         * otherName
1402         */
1403        case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_OTHER_NAME):
1404        {
1405            mbedtls_x509_san_other_name other_name;
1406
1407            ret = x509_get_other_name(san_buf, &other_name);
1408            if (ret != 0) {
1409                return ret;
1410            }
1411
1412            memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name));
1413            san->type = MBEDTLS_X509_SAN_OTHER_NAME;
1414            memcpy(&san->san.other_name,
1415                   &other_name, sizeof(other_name));
1416
1417        }
1418        break;
1419        /*
1420         * uniformResourceIdentifier
1421         */
1422        case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER):
1423        {
1424            memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name));
1425            san->type = MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER;
1426
1427            memcpy(&san->san.unstructured_name,
1428                   san_buf, sizeof(*san_buf));
1429
1430        }
1431        break;
1432        /*
1433         * dNSName
1434         */
1435        case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_DNS_NAME):
1436        {
1437            memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name));
1438            san->type = MBEDTLS_X509_SAN_DNS_NAME;
1439
1440            memcpy(&san->san.unstructured_name,
1441                   san_buf, sizeof(*san_buf));
1442        }
1443        break;
1444        /*
1445         * IP address
1446         */
1447        case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_IP_ADDRESS):
1448        {
1449            memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name));
1450            san->type = MBEDTLS_X509_SAN_IP_ADDRESS;
1451            // Only IPv6 (16 bytes) and IPv4 (4 bytes) types are supported
1452            if (san_buf->len == 4 || san_buf->len == 16) {
1453                memcpy(&san->san.unstructured_name,
1454                       san_buf, sizeof(*san_buf));
1455            } else {
1456                return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
1457            }
1458        }
1459        break;
1460        /*
1461         * rfc822Name
1462         */
1463        case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_RFC822_NAME):
1464        {
1465            memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name));
1466            san->type = MBEDTLS_X509_SAN_RFC822_NAME;
1467            memcpy(&san->san.unstructured_name, san_buf, sizeof(*san_buf));
1468        }
1469        break;
1470        /*
1471         * directoryName
1472         */
1473        case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_DIRECTORY_NAME):
1474        {
1475            size_t name_len;
1476            unsigned char *p = san_buf->p;
1477            memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name));
1478            san->type = MBEDTLS_X509_SAN_DIRECTORY_NAME;
1479
1480            ret = mbedtls_asn1_get_tag(&p, p + san_buf->len, &name_len,
1481                                       MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
1482
1483            if (ret != 0) {
1484                return ret;
1485            }
1486
1487            if ((ret = mbedtls_x509_get_name(&p, p + name_len,
1488                                             &san->san.directory_name)) != 0) {
1489                return ret;
1490            }
1491        }
1492        break;
1493        /*
1494         * Type not supported
1495         */
1496        default:
1497            return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
1498    }
1499    return 0;
1500}
1501
1502void mbedtls_x509_free_subject_alt_name(mbedtls_x509_subject_alternative_name *san)
1503{
1504    if (san->type == MBEDTLS_X509_SAN_DIRECTORY_NAME) {
1505        mbedtls_asn1_free_named_data_list_shallow(san->san.directory_name.next);
1506    }
1507}
1508
1509#if !defined(MBEDTLS_X509_REMOVE_INFO)
1510int mbedtls_x509_info_subject_alt_name(char **buf, size_t *size,
1511                                       const mbedtls_x509_sequence
1512                                       *subject_alt_name,
1513                                       const char *prefix)
1514{
1515    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1516    size_t i;
1517    size_t n = *size;
1518    char *p = *buf;
1519    const mbedtls_x509_sequence *cur = subject_alt_name;
1520    mbedtls_x509_subject_alternative_name san;
1521    int parse_ret;
1522
1523    while (cur != NULL) {
1524        memset(&san, 0, sizeof(san));
1525        parse_ret = mbedtls_x509_parse_subject_alt_name(&cur->buf, &san);
1526        if (parse_ret != 0) {
1527            if (parse_ret == MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) {
1528                ret = mbedtls_snprintf(p, n, "\n%s    <unsupported>", prefix);
1529                MBEDTLS_X509_SAFE_SNPRINTF;
1530            } else {
1531                ret = mbedtls_snprintf(p, n, "\n%s    <malformed>", prefix);
1532                MBEDTLS_X509_SAFE_SNPRINTF;
1533            }
1534            cur = cur->next;
1535            continue;
1536        }
1537
1538        switch (san.type) {
1539            /*
1540             * otherName
1541             */
1542            case MBEDTLS_X509_SAN_OTHER_NAME:
1543            {
1544                mbedtls_x509_san_other_name *other_name = &san.san.other_name;
1545
1546                ret = mbedtls_snprintf(p, n, "\n%s    otherName :", prefix);
1547                MBEDTLS_X509_SAFE_SNPRINTF;
1548
1549                if (MBEDTLS_OID_CMP(MBEDTLS_OID_ON_HW_MODULE_NAME,
1550                                    &other_name->type_id) == 0) {
1551                    ret = mbedtls_snprintf(p, n, "\n%s        hardware module name :", prefix);
1552                    MBEDTLS_X509_SAFE_SNPRINTF;
1553                    ret =
1554                        mbedtls_snprintf(p, n, "\n%s            hardware type          : ", prefix);
1555                    MBEDTLS_X509_SAFE_SNPRINTF;
1556
1557                    ret = mbedtls_oid_get_numeric_string(p,
1558                                                         n,
1559                                                         &other_name->value.hardware_module_name.oid);
1560                    MBEDTLS_X509_SAFE_SNPRINTF;
1561
1562                    ret =
1563                        mbedtls_snprintf(p, n, "\n%s            hardware serial number : ", prefix);
1564                    MBEDTLS_X509_SAFE_SNPRINTF;
1565
1566                    for (i = 0; i < other_name->value.hardware_module_name.val.len; i++) {
1567                        ret = mbedtls_snprintf(p,
1568                                               n,
1569                                               "%02X",
1570                                               other_name->value.hardware_module_name.val.p[i]);
1571                        MBEDTLS_X509_SAFE_SNPRINTF;
1572                    }
1573                }/* MBEDTLS_OID_ON_HW_MODULE_NAME */
1574            }
1575            break;
1576            /*
1577             * uniformResourceIdentifier
1578             */
1579            case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER:
1580            {
1581                ret = mbedtls_snprintf(p, n, "\n%s    uniformResourceIdentifier : ", prefix);
1582                MBEDTLS_X509_SAFE_SNPRINTF;
1583                if (san.san.unstructured_name.len >= n) {
1584                    if (n > 0) {
1585                        *p = '\0';
1586                    }
1587                    return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
1588                }
1589
1590                memcpy(p, san.san.unstructured_name.p, san.san.unstructured_name.len);
1591                p += san.san.unstructured_name.len;
1592                n -= san.san.unstructured_name.len;
1593            }
1594            break;
1595            /*
1596             * dNSName
1597             * RFC822 Name
1598             */
1599            case MBEDTLS_X509_SAN_DNS_NAME:
1600            case MBEDTLS_X509_SAN_RFC822_NAME:
1601            {
1602                const char *dns_name = "dNSName";
1603                const char *rfc822_name = "rfc822Name";
1604
1605                ret = mbedtls_snprintf(p, n,
1606                                       "\n%s    %s : ",
1607                                       prefix,
1608                                       san.type ==
1609                                       MBEDTLS_X509_SAN_DNS_NAME ? dns_name : rfc822_name);
1610                MBEDTLS_X509_SAFE_SNPRINTF;
1611                if (san.san.unstructured_name.len >= n) {
1612                    if (n > 0) {
1613                        *p = '\0';
1614                    }
1615                    return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
1616                }
1617
1618                memcpy(p, san.san.unstructured_name.p, san.san.unstructured_name.len);
1619                p += san.san.unstructured_name.len;
1620                n -= san.san.unstructured_name.len;
1621            }
1622            break;
1623            /*
1624             * iPAddress
1625             */
1626            case MBEDTLS_X509_SAN_IP_ADDRESS:
1627            {
1628                ret = mbedtls_snprintf(p, n, "\n%s    %s : ",
1629                                       prefix, "iPAddress");
1630                MBEDTLS_X509_SAFE_SNPRINTF;
1631                if (san.san.unstructured_name.len >= n) {
1632                    if (n > 0) {
1633                        *p = '\0';
1634                    }
1635                    return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
1636                }
1637
1638                unsigned char *ip = san.san.unstructured_name.p;
1639                // Only IPv6 (16 bytes) and IPv4 (4 bytes) types are supported
1640                if (san.san.unstructured_name.len == 4) {
1641                    ret = mbedtls_snprintf(p, n, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]);
1642                    MBEDTLS_X509_SAFE_SNPRINTF;
1643                } else if (san.san.unstructured_name.len == 16) {
1644                    ret = mbedtls_snprintf(p, n,
1645                                           "%X%X:%X%X:%X%X:%X%X:%X%X:%X%X:%X%X:%X%X",
1646                                           ip[0], ip[1], ip[2], ip[3], ip[4], ip[5], ip[6],
1647                                           ip[7], ip[8], ip[9], ip[10], ip[11], ip[12], ip[13],
1648                                           ip[14], ip[15]);
1649                    MBEDTLS_X509_SAFE_SNPRINTF;
1650                } else {
1651                    if (n > 0) {
1652                        *p = '\0';
1653                    }
1654                    return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
1655                }
1656            }
1657            break;
1658            /*
1659             * directoryName
1660             */
1661            case MBEDTLS_X509_SAN_DIRECTORY_NAME:
1662            {
1663                ret = mbedtls_snprintf(p, n, "\n%s    directoryName : ", prefix);
1664                if (ret < 0 || (size_t) ret >= n) {
1665                    mbedtls_x509_free_subject_alt_name(&san);
1666                }
1667
1668                MBEDTLS_X509_SAFE_SNPRINTF;
1669                ret = mbedtls_x509_dn_gets(p, n, &san.san.directory_name);
1670
1671                if (ret < 0) {
1672                    mbedtls_x509_free_subject_alt_name(&san);
1673                    if (n > 0) {
1674                        *p = '\0';
1675                    }
1676                    return ret;
1677                }
1678
1679                p += ret;
1680                n -= ret;
1681            }
1682            break;
1683            /*
1684             * Type not supported, skip item.
1685             */
1686            default:
1687                ret = mbedtls_snprintf(p, n, "\n%s    <unsupported>", prefix);
1688                MBEDTLS_X509_SAFE_SNPRINTF;
1689                break;
1690        }
1691
1692        /* So far memory is freed only in the case of directoryName
1693         * parsing succeeding, as mbedtls_x509_get_name allocates memory. */
1694        mbedtls_x509_free_subject_alt_name(&san);
1695        cur = cur->next;
1696    }
1697
1698    *p = '\0';
1699
1700    *size = n;
1701    *buf = p;
1702
1703    return 0;
1704}
1705
1706#define PRINT_ITEM(i)                                   \
1707    do {                                                \
1708        ret = mbedtls_snprintf(p, n, "%s" i, sep);      \
1709        MBEDTLS_X509_SAFE_SNPRINTF;                     \
1710        sep = ", ";                                     \
1711    } while (0)
1712
1713#define CERT_TYPE(type, name)                           \
1714    do {                                                \
1715        if (ns_cert_type & (type)) {                    \
1716            PRINT_ITEM(name);                           \
1717        }                                               \
1718    } while (0)
1719
1720int mbedtls_x509_info_cert_type(char **buf, size_t *size,
1721                                unsigned char ns_cert_type)
1722{
1723    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1724    size_t n = *size;
1725    char *p = *buf;
1726    const char *sep = "";
1727
1728    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT,         "SSL Client");
1729    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER,         "SSL Server");
1730    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_EMAIL,              "Email");
1731    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING,     "Object Signing");
1732    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_RESERVED,           "Reserved");
1733    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_SSL_CA,             "SSL CA");
1734    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA,           "Email CA");
1735    CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA,  "Object Signing CA");
1736
1737    *size = n;
1738    *buf = p;
1739
1740    return 0;
1741}
1742
1743#define KEY_USAGE(code, name)       \
1744    do {                            \
1745        if ((key_usage) & (code)) { \
1746            PRINT_ITEM(name);       \
1747        }                           \
1748    } while (0)
1749
1750int mbedtls_x509_info_key_usage(char **buf, size_t *size,
1751                                unsigned int key_usage)
1752{
1753    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1754    size_t n = *size;
1755    char *p = *buf;
1756    const char *sep = "";
1757
1758    KEY_USAGE(MBEDTLS_X509_KU_DIGITAL_SIGNATURE,    "Digital Signature");
1759    KEY_USAGE(MBEDTLS_X509_KU_NON_REPUDIATION,      "Non Repudiation");
1760    KEY_USAGE(MBEDTLS_X509_KU_KEY_ENCIPHERMENT,     "Key Encipherment");
1761    KEY_USAGE(MBEDTLS_X509_KU_DATA_ENCIPHERMENT,    "Data Encipherment");
1762    KEY_USAGE(MBEDTLS_X509_KU_KEY_AGREEMENT,        "Key Agreement");
1763    KEY_USAGE(MBEDTLS_X509_KU_KEY_CERT_SIGN,        "Key Cert Sign");
1764    KEY_USAGE(MBEDTLS_X509_KU_CRL_SIGN,             "CRL Sign");
1765    KEY_USAGE(MBEDTLS_X509_KU_ENCIPHER_ONLY,        "Encipher Only");
1766    KEY_USAGE(MBEDTLS_X509_KU_DECIPHER_ONLY,        "Decipher Only");
1767
1768    *size = n;
1769    *buf = p;
1770
1771    return 0;
1772}
1773#endif /* MBEDTLS_X509_REMOVE_INFO */
1774#endif /* MBEDTLS_X509_CRT_PARSE_C || MBEDTLS_X509_CSR_PARSE_C */
1775#endif /* MBEDTLS_X509_USE_C */
1776