quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

x509.c (57491B)


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