LCOV - code coverage report
Current view: top level - os_stub/mbedtlslib/mbedtls/library - x509.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 27.3 % 726 198
Test Date: 2025-06-29 08:09:00 Functions: 54.3 % 35 19

            Line data    Source code
       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        12810 : int mbedtls_x509_get_serial(unsigned char **p, const unsigned char *end,
      64              :                             mbedtls_x509_buf *serial)
      65              : {
      66        12810 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
      67              : 
      68        12810 :     if ((end - *p) < 1) {
      69            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_SERIAL,
      70              :                                  MBEDTLS_ERR_ASN1_OUT_OF_DATA);
      71              :     }
      72              : 
      73        12810 :     if (**p != (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_PRIMITIVE | 2) &&
      74        12810 :         **p !=   MBEDTLS_ASN1_INTEGER) {
      75            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_SERIAL,
      76              :                                  MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
      77              :     }
      78              : 
      79        12810 :     serial->tag = *(*p)++;
      80              : 
      81        12810 :     if ((ret = mbedtls_asn1_get_len(p, end, &serial->len)) != 0) {
      82            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_SERIAL, ret);
      83              :     }
      84              : 
      85        12810 :     serial->p = *p;
      86        12810 :     *p += serial->len;
      87              : 
      88        12810 :     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            0 : int mbedtls_x509_get_alg_null(unsigned char **p, const unsigned char *end,
      98              :                               mbedtls_x509_buf *alg)
      99              : {
     100            0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     101              : 
     102            0 :     if ((ret = mbedtls_asn1_get_alg_null(p, end, alg)) != 0) {
     103            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
     104              :     }
     105              : 
     106            0 :     return 0;
     107              : }
     108              : 
     109              : /*
     110              :  * Parse an algorithm identifier with (optional) parameters
     111              :  */
     112        25620 : int mbedtls_x509_get_alg(unsigned char **p, const unsigned char *end,
     113              :                          mbedtls_x509_buf *alg, mbedtls_x509_buf *params)
     114              : {
     115        25620 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     116              : 
     117        25620 :     if ((ret = mbedtls_asn1_get_alg(p, end, alg, params)) != 0) {
     118            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
     119              :     }
     120              : 
     121        25620 :     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            0 : static inline const char *md_type_to_string(mbedtls_md_type_t md_alg)
     130              : {
     131            0 :     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            0 :         case MBEDTLS_MD_SHA256:
     146            0 :             return "SHA256";
     147              : #endif
     148              : #if defined(MBEDTLS_MD_CAN_SHA384)
     149            0 :         case MBEDTLS_MD_SHA384:
     150            0 :             return "SHA384";
     151              : #endif
     152              : #if defined(MBEDTLS_MD_CAN_SHA512)
     153            0 :         case MBEDTLS_MD_SHA512:
     154            0 :             return "SHA512";
     155              : #endif
     156              : #if defined(MBEDTLS_MD_CAN_RIPEMD160)
     157              :         case MBEDTLS_MD_RIPEMD160:
     158              :             return "RIPEMD160";
     159              : #endif
     160            0 :         case MBEDTLS_MD_NONE:
     161            0 :             return NULL;
     162            0 :         default:
     163            0 :             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            0 : static int x509_get_hash_alg(const mbedtls_x509_buf *alg, mbedtls_md_type_t *md_alg)
     180              : {
     181            0 :     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            0 :     if (alg->tag != (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) {
     189            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
     190              :                                  MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
     191              :     }
     192              : 
     193            0 :     p = alg->p;
     194            0 :     end = p + alg->len;
     195              : 
     196            0 :     if (p >= end) {
     197            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
     198              :                                  MBEDTLS_ERR_ASN1_OUT_OF_DATA);
     199              :     }
     200              : 
     201              :     /* Parse md_oid */
     202            0 :     md_oid.tag = *p;
     203              : 
     204            0 :     if ((ret = mbedtls_asn1_get_tag(&p, end, &md_oid.len, MBEDTLS_ASN1_OID)) != 0) {
     205            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
     206              :     }
     207              : 
     208            0 :     md_oid.p = p;
     209            0 :     p += md_oid.len;
     210              : 
     211              :     /* Get md_alg from md_oid */
     212            0 :     if ((ret = mbedtls_oid_get_md_alg(&md_oid, md_alg)) != 0) {
     213            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
     214              :     }
     215              : 
     216              :     /* Make sure params is absent of NULL */
     217            0 :     if (p == end) {
     218            0 :         return 0;
     219              :     }
     220              : 
     221            0 :     if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_NULL)) != 0 || len != 0) {
     222            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
     223              :     }
     224              : 
     225            0 :     if (p != end) {
     226            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
     227              :                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
     228              :     }
     229              : 
     230            0 :     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            0 : 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            0 :     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            0 :     *md_alg = MBEDTLS_MD_SHA1;
     257            0 :     *mgf_md = MBEDTLS_MD_SHA1;
     258            0 :     *salt_len = 20;
     259              : 
     260              :     /* Make sure params is a SEQUENCE and setup bounds */
     261            0 :     if (params->tag != (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) {
     262            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
     263              :                                  MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
     264              :     }
     265              : 
     266            0 :     p = (unsigned char *) params->p;
     267            0 :     end = p + params->len;
     268              : 
     269            0 :     if (p == end) {
     270            0 :         return 0;
     271              :     }
     272              : 
     273              :     /*
     274              :      * HashAlgorithm
     275              :      */
     276            0 :     if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
     277              :                                     MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED |
     278              :                                     0)) == 0) {
     279            0 :         end2 = p + len;
     280              : 
     281              :         /* HashAlgorithm ::= AlgorithmIdentifier (without parameters) */
     282            0 :         if ((ret = mbedtls_x509_get_alg_null(&p, end2, &alg_id)) != 0) {
     283            0 :             return ret;
     284              :         }
     285              : 
     286            0 :         if ((ret = mbedtls_oid_get_md_alg(&alg_id, md_alg)) != 0) {
     287            0 :             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
     288              :         }
     289              : 
     290            0 :         if (p != end2) {
     291            0 :             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
     292              :                                      MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
     293              :         }
     294            0 :     } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
     295            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
     296              :     }
     297              : 
     298            0 :     if (p == end) {
     299            0 :         return 0;
     300              :     }
     301              : 
     302              :     /*
     303              :      * MaskGenAlgorithm
     304              :      */
     305            0 :     if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
     306              :                                     MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED |
     307              :                                     1)) == 0) {
     308            0 :         end2 = p + len;
     309              : 
     310              :         /* MaskGenAlgorithm ::= AlgorithmIdentifier (params = HashAlgorithm) */
     311            0 :         if ((ret = mbedtls_x509_get_alg(&p, end2, &alg_id, &alg_params)) != 0) {
     312            0 :             return ret;
     313              :         }
     314              : 
     315              :         /* Only MFG1 is recognised for now */
     316            0 :         if (MBEDTLS_OID_CMP(MBEDTLS_OID_MGF1, &alg_id) != 0) {
     317            0 :             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE,
     318              :                                      MBEDTLS_ERR_OID_NOT_FOUND);
     319              :         }
     320              : 
     321              :         /* Parse HashAlgorithm */
     322            0 :         if ((ret = x509_get_hash_alg(&alg_params, mgf_md)) != 0) {
     323            0 :             return ret;
     324              :         }
     325              : 
     326            0 :         if (p != end2) {
     327            0 :             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
     328              :                                      MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
     329              :         }
     330            0 :     } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
     331            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
     332              :     }
     333              : 
     334            0 :     if (p == end) {
     335            0 :         return 0;
     336              :     }
     337              : 
     338              :     /*
     339              :      * salt_len
     340              :      */
     341            0 :     if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
     342              :                                     MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED |
     343              :                                     2)) == 0) {
     344            0 :         end2 = p + len;
     345              : 
     346            0 :         if ((ret = mbedtls_asn1_get_int(&p, end2, salt_len)) != 0) {
     347            0 :             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
     348              :         }
     349              : 
     350            0 :         if (p != end2) {
     351            0 :             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
     352              :                                      MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
     353              :         }
     354            0 :     } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
     355            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
     356              :     }
     357              : 
     358            0 :     if (p == end) {
     359            0 :         return 0;
     360              :     }
     361              : 
     362              :     /*
     363              :      * trailer_field (if present, must be 1)
     364              :      */
     365            0 :     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            0 :         end2 = p + len;
     371              : 
     372            0 :         if ((ret = mbedtls_asn1_get_int(&p, end2, &trailer_field)) != 0) {
     373            0 :             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
     374              :         }
     375              : 
     376            0 :         if (p != end2) {
     377            0 :             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
     378              :                                      MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
     379              :         }
     380              : 
     381            0 :         if (trailer_field != 1) {
     382            0 :             return MBEDTLS_ERR_X509_INVALID_ALG;
     383              :         }
     384            0 :     } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
     385            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
     386              :     }
     387              : 
     388            0 :     if (p != end) {
     389            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
     390              :                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
     391              :     }
     392              : 
     393            0 :     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        25740 : static int x509_get_attr_type_value(unsigned char **p,
     407              :                                     const unsigned char *end,
     408              :                                     mbedtls_x509_name *cur)
     409              : {
     410        25740 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     411              :     size_t len;
     412              :     mbedtls_x509_buf *oid;
     413              :     mbedtls_x509_buf *val;
     414              : 
     415        25740 :     if ((ret = mbedtls_asn1_get_tag(p, end, &len,
     416              :                                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
     417            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME, ret);
     418              :     }
     419              : 
     420        25740 :     end = *p + len;
     421              : 
     422        25740 :     if ((end - *p) < 1) {
     423            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME,
     424              :                                  MBEDTLS_ERR_ASN1_OUT_OF_DATA);
     425              :     }
     426              : 
     427        25740 :     oid = &cur->oid;
     428        25740 :     oid->tag = **p;
     429              : 
     430        25740 :     if ((ret = mbedtls_asn1_get_tag(p, end, &oid->len, MBEDTLS_ASN1_OID)) != 0) {
     431            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME, ret);
     432              :     }
     433              : 
     434        25740 :     oid->p = *p;
     435        25740 :     *p += oid->len;
     436              : 
     437        25740 :     if ((end - *p) < 1) {
     438            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME,
     439              :                                  MBEDTLS_ERR_ASN1_OUT_OF_DATA);
     440              :     }
     441              : 
     442        25740 :     if (**p != MBEDTLS_ASN1_BMP_STRING && **p != MBEDTLS_ASN1_UTF8_STRING      &&
     443          190 :         **p != MBEDTLS_ASN1_T61_STRING && **p != MBEDTLS_ASN1_PRINTABLE_STRING &&
     444            0 :         **p != MBEDTLS_ASN1_IA5_STRING && **p != MBEDTLS_ASN1_UNIVERSAL_STRING &&
     445            0 :         **p != MBEDTLS_ASN1_BIT_STRING) {
     446            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME,
     447              :                                  MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
     448              :     }
     449              : 
     450        25740 :     val = &cur->val;
     451        25740 :     val->tag = *(*p)++;
     452              : 
     453        25740 :     if ((ret = mbedtls_asn1_get_len(p, end, &val->len)) != 0) {
     454            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME, ret);
     455              :     }
     456              : 
     457        25740 :     val->p = *p;
     458        25740 :     *p += val->len;
     459              : 
     460        25740 :     if (*p != end) {
     461            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME,
     462              :                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
     463              :     }
     464              : 
     465        25740 :     cur->next = NULL;
     466              : 
     467        25740 :     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        25620 : int mbedtls_x509_get_name(unsigned char **p, const unsigned char *end,
     499              :                           mbedtls_x509_name *cur)
     500              : {
     501        25620 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     502              :     size_t set_len;
     503              :     const unsigned char *end_set;
     504        25620 :     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        25740 :         if ((ret = mbedtls_asn1_get_tag(p, end, &set_len,
     512              :                                         MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET)) != 0) {
     513            0 :             ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME, ret);
     514            0 :             goto error;
     515              :         }
     516              : 
     517        25740 :         end_set  = *p + set_len;
     518              : 
     519              :         while (1) {
     520        25740 :             if ((ret = x509_get_attr_type_value(p, end_set, cur)) != 0) {
     521            0 :                 goto error;
     522              :             }
     523              : 
     524        25740 :             if (*p == end_set) {
     525        25740 :                 break;
     526              :             }
     527              : 
     528              :             /* Mark this item as being no the only one in a set */
     529            0 :             cur->next_merged = 1;
     530              : 
     531            0 :             cur->next = mbedtls_calloc(1, sizeof(mbedtls_x509_name));
     532              : 
     533            0 :             if (cur->next == NULL) {
     534            0 :                 ret = MBEDTLS_ERR_X509_ALLOC_FAILED;
     535            0 :                 goto error;
     536              :             }
     537              : 
     538            0 :             cur = cur->next;
     539              :         }
     540              : 
     541              :         /*
     542              :          * continue until end of SEQUENCE is reached
     543              :          */
     544        25740 :         if (*p == end) {
     545        25620 :             return 0;
     546              :         }
     547              : 
     548          120 :         cur->next = mbedtls_calloc(1, sizeof(mbedtls_x509_name));
     549              : 
     550          120 :         if (cur->next == NULL) {
     551            0 :             ret = MBEDTLS_ERR_X509_ALLOC_FAILED;
     552            0 :             goto error;
     553              :         }
     554              : 
     555          120 :         cur = cur->next;
     556              :     }
     557              : 
     558            0 : error:
     559              :     /* Skip the first element as we did not allocate it */
     560            0 :     mbedtls_asn1_free_named_data_list_shallow(head->next);
     561            0 :     head->next = NULL;
     562              : 
     563            0 :     return ret;
     564              : }
     565              : 
     566        25620 : static int x509_date_is_valid(const mbedtls_x509_time *t)
     567              : {
     568              :     unsigned int month_days;
     569              :     unsigned int year;
     570        25620 :     switch (t->mon) {
     571         4165 :         case 1: case 3: case 5: case 7: case 8: case 10: case 12:
     572         4165 :             month_days = 31;
     573         4165 :             break;
     574        21455 :         case 4: case 6: case 9: case 11:
     575        21455 :             month_days = 30;
     576        21455 :             break;
     577            0 :         case 2:
     578            0 :             year = (unsigned int) t->year;
     579            0 :             month_days = ((year & 3) || (!(year % 100)
     580            0 :                                          && (year % 400)))
     581            0 :                           ? 28 : 29;
     582            0 :             break;
     583            0 :         default:
     584            0 :             return MBEDTLS_ERR_X509_INVALID_DATE;
     585              :     }
     586              : 
     587        25620 :     if ((unsigned int) (t->day - 1) >= month_days ||      /* (1 - days in month) */
     588              :         /* (unsigned int) (t->mon - 1) >= 12 || */  /* (1 - 12) checked above */
     589        25620 :         (unsigned int) t->year > 9999 ||         /* (0 - 9999) */
     590        25620 :         (unsigned int) t->hour > 23 ||           /* (0 - 23) */
     591        25620 :         (unsigned int) t->min  > 59 ||           /* (0 - 59) */
     592        25620 :         (unsigned int) t->sec  > 59) {           /* (0 - 59) */
     593            0 :         return MBEDTLS_ERR_X509_INVALID_DATE;
     594              :     }
     595              : 
     596        25620 :     return 0;
     597              : }
     598              : 
     599       153720 : static int x509_parse2_int(const unsigned char *p)
     600              : {
     601       153720 :     uint32_t d1 = p[0] - '0';
     602       153720 :     uint32_t d2 = p[1] - '0';
     603       153720 :     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        25620 : 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        25620 :     tm->year = x509_parse2_int(p);
     619        25620 :     if (tm->year < 0) {
     620            0 :         return MBEDTLS_ERR_X509_INVALID_DATE;
     621              :     }
     622              : 
     623        25620 :     if (4 == yearlen) {
     624            0 :         x = tm->year * 100;
     625            0 :         p += 2;
     626            0 :         tm->year = x509_parse2_int(p);
     627            0 :         if (tm->year < 0) {
     628            0 :             return MBEDTLS_ERR_X509_INVALID_DATE;
     629              :         }
     630              :     } else {
     631        25620 :         x = (tm->year < 50) ? 2000 : 1900;
     632              :     }
     633        25620 :     tm->year += x;
     634              : 
     635        25620 :     tm->mon  = x509_parse2_int(p + 2);
     636        25620 :     tm->day  = x509_parse2_int(p + 4);
     637        25620 :     tm->hour = x509_parse2_int(p + 6);
     638        25620 :     tm->min  = x509_parse2_int(p + 8);
     639        25620 :     tm->sec  = x509_parse2_int(p + 10);
     640              : 
     641        25620 :     return x509_date_is_valid(tm);
     642              : }
     643              : 
     644              : /*
     645              :  *  Time ::= CHOICE {
     646              :  *       utcTime        UTCTime,
     647              :  *       generalTime    GeneralizedTime }
     648              :  */
     649        25620 : int mbedtls_x509_get_time(unsigned char **p, const unsigned char *end,
     650              :                           mbedtls_x509_time *tm)
     651              : {
     652        25620 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     653              :     size_t len, year_len;
     654              :     unsigned char tag;
     655              : 
     656        25620 :     if ((end - *p) < 1) {
     657            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_DATE,
     658              :                                  MBEDTLS_ERR_ASN1_OUT_OF_DATA);
     659              :     }
     660              : 
     661        25620 :     tag = **p;
     662              : 
     663        25620 :     if (tag == MBEDTLS_ASN1_UTC_TIME) {
     664        25620 :         year_len = 2;
     665            0 :     } else if (tag == MBEDTLS_ASN1_GENERALIZED_TIME) {
     666            0 :         year_len = 4;
     667              :     } else {
     668            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_DATE,
     669              :                                  MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
     670              :     }
     671              : 
     672        25620 :     (*p)++;
     673        25620 :     ret = mbedtls_asn1_get_len(p, end, &len);
     674              : 
     675        25620 :     if (ret != 0) {
     676            0 :         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        25620 :     if (len != year_len + 10 &&
     681        25620 :         !(len == year_len + 11 && (*p)[(len - 1)] == 'Z')) {
     682            0 :         return MBEDTLS_ERR_X509_INVALID_DATE;
     683              :     }
     684              : 
     685        25620 :     (*p) += len;
     686        25620 :     return x509_parse_time(*p - len, tm, year_len);
     687              : }
     688              : 
     689        12810 : int mbedtls_x509_get_sig(unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig)
     690              : {
     691        12810 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     692              :     size_t len;
     693              :     int tag_type;
     694              : 
     695        12810 :     if ((end - *p) < 1) {
     696            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_SIGNATURE,
     697              :                                  MBEDTLS_ERR_ASN1_OUT_OF_DATA);
     698              :     }
     699              : 
     700        12810 :     tag_type = **p;
     701              : 
     702        12810 :     if ((ret = mbedtls_asn1_get_bitstring_null(p, end, &len)) != 0) {
     703            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_SIGNATURE, ret);
     704              :     }
     705              : 
     706        12810 :     sig->tag = tag_type;
     707        12810 :     sig->len = len;
     708        12810 :     sig->p = *p;
     709              : 
     710        12810 :     *p += len;
     711              : 
     712        12810 :     return 0;
     713              : }
     714              : 
     715              : /*
     716              :  * Get signature algorithm from alg OID and optional parameters
     717              :  */
     718        12810 : 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        12810 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     723              : 
     724        12810 :     if (*sig_opts != NULL) {
     725            0 :         return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
     726              :     }
     727              : 
     728        12810 :     if ((ret = mbedtls_oid_get_sig_alg(sig_oid, md_alg, pk_alg)) != 0) {
     729            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG, ret);
     730              :     }
     731              : 
     732              : #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
     733        12810 :     if (*pk_alg == MBEDTLS_PK_RSASSA_PSS) {
     734              :         mbedtls_pk_rsassa_pss_options *pss_opts;
     735              : 
     736            0 :         pss_opts = mbedtls_calloc(1, sizeof(mbedtls_pk_rsassa_pss_options));
     737            0 :         if (pss_opts == NULL) {
     738            0 :             return MBEDTLS_ERR_X509_ALLOC_FAILED;
     739              :         }
     740              : 
     741            0 :         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            0 :         if (ret != 0) {
     746            0 :             mbedtls_free(pss_opts);
     747            0 :             return ret;
     748              :         }
     749              : 
     750            0 :         *sig_opts = (void *) pss_opts;
     751              :     } else
     752              : #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
     753              :     {
     754              :         /* Make sure parameters are absent or NULL */
     755        12810 :         if ((sig_params->tag != MBEDTLS_ASN1_NULL && sig_params->tag != 0) ||
     756        12810 :             sig_params->len != 0) {
     757            0 :             return MBEDTLS_ERR_X509_INVALID_ALG;
     758              :         }
     759              :     }
     760              : 
     761        12810 :     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        12810 : int mbedtls_x509_get_ext(unsigned char **p, const unsigned char *end,
     769              :                          mbedtls_x509_buf *ext, int tag)
     770              : {
     771        12810 :     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        12810 :     ret = mbedtls_asn1_get_tag(p, end, &ext->len,
     778              :                                MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag);
     779        12810 :     if (ret != 0) {
     780            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
     781              :     }
     782              : 
     783        12810 :     ext->tag = MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag;
     784        12810 :     ext->p   = *p;
     785        12810 :     end      = *p + ext->len;
     786              : 
     787              :     /*
     788              :      * Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
     789              :      */
     790        12810 :     if ((ret = mbedtls_asn1_get_tag(p, end, &len,
     791              :                                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
     792            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
     793              :     }
     794              : 
     795        12810 :     if (end != *p + len) {
     796            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
     797              :                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
     798              :     }
     799              : 
     800        12810 :     return 0;
     801              : }
     802              : 
     803            0 : static char nibble_to_hex_digit(int i)
     804              : {
     805            0 :     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            0 : int mbedtls_x509_dn_gets(char *buf, size_t size, const mbedtls_x509_name *dn)
     813              : {
     814            0 :     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            0 :     unsigned char c, merge = 0;
     820              :     const mbedtls_x509_name *name;
     821            0 :     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            0 :     memset(s, 0, sizeof(s));
     827              : 
     828            0 :     name = dn;
     829            0 :     p = buf;
     830            0 :     n = size;
     831              : 
     832            0 :     while (name != NULL) {
     833            0 :         if (!name->oid.p) {
     834            0 :             name = name->next;
     835            0 :             continue;
     836              :         }
     837              : 
     838            0 :         if (name != dn) {
     839            0 :             ret = mbedtls_snprintf(p, n, merge ? " + " : ", ");
     840            0 :             MBEDTLS_X509_SAFE_SNPRINTF;
     841              :         }
     842              : 
     843            0 :         print_hexstring = (name->val.tag != MBEDTLS_ASN1_UTF8_STRING) &&
     844            0 :                           (name->val.tag != MBEDTLS_ASN1_PRINTABLE_STRING) &&
     845            0 :                           (name->val.tag != MBEDTLS_ASN1_IA5_STRING);
     846              : 
     847            0 :         if ((ret = mbedtls_oid_get_attr_short_name(&name->oid, &short_name)) == 0) {
     848            0 :             ret = mbedtls_snprintf(p, n, "%s=", short_name);
     849              :         } else {
     850            0 :             if ((ret = mbedtls_oid_get_numeric_string(p, n, &name->oid)) > 0) {
     851            0 :                 n -= ret;
     852            0 :                 p += ret;
     853            0 :                 ret = mbedtls_snprintf(p, n, "=");
     854            0 :                 print_hexstring = 1;
     855            0 :             } else if (ret == MBEDTLS_ERR_OID_BUF_TOO_SMALL) {
     856            0 :                 return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
     857              :             } else {
     858            0 :                 ret = mbedtls_snprintf(p, n, "\?\?=");
     859              :             }
     860              :         }
     861            0 :         MBEDTLS_X509_SAFE_SNPRINTF;
     862              : 
     863            0 :         if (print_hexstring) {
     864            0 :             s[0] = '#';
     865              : 
     866            0 :             asn1_len_p = asn1_tag_len_buf + sizeof(asn1_tag_len_buf);
     867            0 :             if ((ret = mbedtls_asn1_write_len(&asn1_len_p, asn1_tag_len_buf, name->val.len)) < 0) {
     868            0 :                 return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     869              :             }
     870            0 :             asn1_len_size = ret;
     871            0 :             if ((ret = mbedtls_asn1_write_tag(&asn1_len_p, asn1_tag_len_buf, name->val.tag)) < 0) {
     872            0 :                 return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     873              :             }
     874            0 :             asn1_tag_size = ret;
     875            0 :             asn1_tag_len_buf_start = sizeof(asn1_tag_len_buf) - asn1_len_size - asn1_tag_size;
     876            0 :             for (i = 0, j = 1; i < asn1_len_size + asn1_tag_size; i++) {
     877            0 :                 if (j + 1 >= sizeof(s) - 1) {
     878            0 :                     return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
     879              :                 }
     880            0 :                 c = asn1_tag_len_buf[asn1_tag_len_buf_start+i];
     881            0 :                 lowbits = (c & 0x0F);
     882            0 :                 highbits = c >> 4;
     883            0 :                 s[j++] = nibble_to_hex_digit(highbits);
     884            0 :                 s[j++] = nibble_to_hex_digit(lowbits);
     885              :             }
     886            0 :             for (i = 0; i < name->val.len; i++) {
     887            0 :                 if (j + 1 >= sizeof(s) - 1) {
     888            0 :                     return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
     889              :                 }
     890            0 :                 c = name->val.p[i];
     891            0 :                 lowbits = (c & 0x0F);
     892            0 :                 highbits = c >> 4;
     893            0 :                 s[j++] = nibble_to_hex_digit(highbits);
     894            0 :                 s[j++] = nibble_to_hex_digit(lowbits);
     895              :             }
     896              :         } else {
     897            0 :             for (i = 0, j = 0; i < name->val.len; i++, j++) {
     898            0 :                 if (j >= sizeof(s) - 1) {
     899            0 :                     return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
     900              :                 }
     901              : 
     902            0 :                 c = name->val.p[i];
     903              :                 // Special characters requiring escaping, RFC 4514 Section 2.4
     904            0 :                 if (c == '\0') {
     905            0 :                     return MBEDTLS_ERR_X509_INVALID_NAME;
     906              :                 } else {
     907            0 :                     if (strchr(",=+<>;\"\\", c) ||
     908            0 :                         ((i == 0) && strchr("# ", c)) ||
     909            0 :                         ((i == name->val.len-1) && (c == ' '))) {
     910            0 :                         if (j + 1 >= sizeof(s) - 1) {
     911            0 :                             return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
     912              :                         }
     913            0 :                         s[j++] = '\\';
     914              :                     }
     915              :                 }
     916            0 :                 if (c < 32 || c >= 127) {
     917            0 :                     if (j + 3 >= sizeof(s) - 1) {
     918            0 :                         return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
     919              :                     }
     920            0 :                     s[j++] = '\\';
     921            0 :                     lowbits = (c & 0x0F);
     922            0 :                     highbits = c >> 4;
     923            0 :                     s[j++] = nibble_to_hex_digit(highbits);
     924            0 :                     s[j] = nibble_to_hex_digit(lowbits);
     925              :                 } else {
     926            0 :                     s[j] = c;
     927              :                 }
     928              :             }
     929              :         }
     930            0 :         s[j] = '\0';
     931            0 :         ret = mbedtls_snprintf(p, n, "%s", s);
     932            0 :         MBEDTLS_X509_SAFE_SNPRINTF;
     933              : 
     934            0 :         merge = name->next_merged;
     935            0 :         name = name->next;
     936              :     }
     937              : 
     938            0 :     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            0 : int mbedtls_x509_serial_gets(char *buf, size_t size, const mbedtls_x509_buf *serial)
     946              : {
     947            0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     948              :     size_t i, n, nr;
     949              :     char *p;
     950              : 
     951            0 :     p = buf;
     952            0 :     n = size;
     953              : 
     954            0 :     nr = (serial->len <= 32)
     955            0 :         ? serial->len  : 28;
     956              : 
     957            0 :     for (i = 0; i < nr; i++) {
     958            0 :         if (i == 0 && nr > 1 && serial->p[i] == 0x0) {
     959            0 :             continue;
     960              :         }
     961              : 
     962            0 :         ret = mbedtls_snprintf(p, n, "%02X%s",
     963            0 :                                serial->p[i], (i < nr - 1) ? ":" : "");
     964            0 :         MBEDTLS_X509_SAFE_SNPRINTF;
     965              :     }
     966              : 
     967            0 :     if (nr != serial->len) {
     968            0 :         ret = mbedtls_snprintf(p, n, "....");
     969            0 :         MBEDTLS_X509_SAFE_SNPRINTF;
     970              :     }
     971              : 
     972            0 :     return (int) (size - n);
     973              : }
     974              : 
     975              : #if !defined(MBEDTLS_X509_REMOVE_INFO)
     976              : /*
     977              :  * Helper for writing signature algorithms
     978              :  */
     979            0 : 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            0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     984            0 :     char *p = buf;
     985            0 :     size_t n = size;
     986            0 :     const char *desc = NULL;
     987              : 
     988            0 :     ret = mbedtls_oid_get_sig_alg_desc(sig_oid, &desc);
     989            0 :     if (ret != 0) {
     990            0 :         ret = mbedtls_snprintf(p, n, "???");
     991              :     } else {
     992            0 :         ret = mbedtls_snprintf(p, n, "%s", desc);
     993              :     }
     994            0 :     MBEDTLS_X509_SAFE_SNPRINTF;
     995              : 
     996              : #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
     997            0 :     if (pk_alg == MBEDTLS_PK_RSASSA_PSS) {
     998              :         const mbedtls_pk_rsassa_pss_options *pss_opts;
     999              : 
    1000            0 :         pss_opts = (const mbedtls_pk_rsassa_pss_options *) sig_opts;
    1001              : 
    1002            0 :         const char *name = md_type_to_string(md_alg);
    1003            0 :         const char *mgf_name = md_type_to_string(pss_opts->mgf1_hash_id);
    1004              : 
    1005            0 :         ret = mbedtls_snprintf(p, n, " (%s, MGF1-%s, 0x%02X)",
    1006              :                                name ? name : "???",
    1007              :                                mgf_name ? mgf_name : "???",
    1008            0 :                                (unsigned int) pss_opts->expected_salt_len);
    1009            0 :         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            0 :     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            0 : int mbedtls_x509_key_size_helper(char *buf, size_t buf_size, const char *name)
    1025              : {
    1026            0 :     char *p = buf;
    1027            0 :     size_t n = buf_size;
    1028            0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1029              : 
    1030            0 :     ret = mbedtls_snprintf(p, n, "%s key size", name);
    1031            0 :     MBEDTLS_X509_SAFE_SNPRINTF;
    1032              : 
    1033            0 :     return 0;
    1034              : }
    1035              : 
    1036        11413 : int mbedtls_x509_time_cmp(const mbedtls_x509_time *t1,
    1037              :                           const mbedtls_x509_time *t2)
    1038              : {
    1039              :     int x;
    1040              : 
    1041        11413 :     x = (((t1->year << 9) | (t1->mon << 5) | (t1->day)) -
    1042        11413 :          ((t2->year << 9) | (t2->mon << 5) | (t2->day)));
    1043        11413 :     if (x != 0) {
    1044        11413 :         return x;
    1045              :     }
    1046              : 
    1047            0 :     x = (((t1->hour << 12) | (t1->min << 6) | (t1->sec)) -
    1048            0 :          ((t2->hour << 12) | (t2->min << 6) | (t2->sec)));
    1049            0 :     return x;
    1050              : }
    1051              : 
    1052              : #if defined(MBEDTLS_HAVE_TIME_DATE)
    1053         2375 : int mbedtls_x509_time_gmtime(mbedtls_time_t tt, mbedtls_x509_time *now)
    1054              : {
    1055              :     struct tm tm;
    1056              : 
    1057         2375 :     if (mbedtls_platform_gmtime_r(&tt, &tm) == NULL) {
    1058            0 :         return -1;
    1059              :     }
    1060              : 
    1061         2375 :     now->year = tm.tm_year + 1900;
    1062         2375 :     now->mon  = tm.tm_mon  + 1;
    1063         2375 :     now->day  = tm.tm_mday;
    1064         2375 :     now->hour = tm.tm_hour;
    1065         2375 :     now->min  = tm.tm_min;
    1066         2375 :     now->sec  = tm.tm_sec;
    1067         2375 :     return 0;
    1068              : }
    1069              : 
    1070            0 : static int x509_get_current_time(mbedtls_x509_time *now)
    1071              : {
    1072            0 :     return mbedtls_x509_time_gmtime(mbedtls_time(NULL), now);
    1073              : }
    1074              : 
    1075            0 : int mbedtls_x509_time_is_past(const mbedtls_x509_time *to)
    1076              : {
    1077              :     mbedtls_x509_time now;
    1078              : 
    1079            0 :     if (x509_get_current_time(&now) != 0) {
    1080            0 :         return 1;
    1081              :     }
    1082              : 
    1083            0 :     return mbedtls_x509_time_cmp(to, &now) < 0;
    1084              : }
    1085              : 
    1086            0 : int mbedtls_x509_time_is_future(const mbedtls_x509_time *from)
    1087              : {
    1088              :     mbedtls_x509_time now;
    1089              : 
    1090            0 :     if (x509_get_current_time(&now) != 0) {
    1091            0 :         return 1;
    1092              :     }
    1093              : 
    1094            0 :     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         8598 : static int x509_get_other_name(const mbedtls_x509_buf *subject_alt_name,
    1127              :                                mbedtls_x509_san_other_name *other_name)
    1128              : {
    1129         8598 :     int ret = 0;
    1130              :     size_t len;
    1131         8598 :     unsigned char *p = subject_alt_name->p;
    1132         8598 :     const unsigned char *end = p + subject_alt_name->len;
    1133              :     mbedtls_x509_buf cur_oid;
    1134              : 
    1135         8598 :     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            0 :         return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
    1142              :     }
    1143              : 
    1144         8598 :     if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
    1145              :                                     MBEDTLS_ASN1_OID)) != 0) {
    1146            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
    1147              :     }
    1148              : 
    1149         8598 :     cur_oid.tag = MBEDTLS_ASN1_OID;
    1150         8598 :     cur_oid.p = p;
    1151         8598 :     cur_oid.len = len;
    1152              : 
    1153              :     /*
    1154              :      * Only HwModuleName is currently supported.
    1155              :      */
    1156         8598 :     if (MBEDTLS_OID_CMP(MBEDTLS_OID_ON_HW_MODULE_NAME, &cur_oid) != 0) {
    1157         8598 :         return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
    1158              :     }
    1159            0 :     other_name->type_id = cur_oid;
    1160              : 
    1161            0 :     p += len;
    1162            0 :     if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
    1163              :                                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC)) !=
    1164              :         0) {
    1165            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
    1166              :     }
    1167              : 
    1168            0 :     if (end != p + len) {
    1169            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
    1170              :                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
    1171              :     }
    1172              : 
    1173            0 :     if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
    1174              :                                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
    1175            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
    1176              :     }
    1177              : 
    1178            0 :     if (end != p + len) {
    1179            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
    1180              :                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
    1181              :     }
    1182              : 
    1183            0 :     if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OID)) != 0) {
    1184            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
    1185              :     }
    1186              : 
    1187            0 :     other_name->value.hardware_module_name.oid.tag = MBEDTLS_ASN1_OID;
    1188            0 :     other_name->value.hardware_module_name.oid.p = p;
    1189            0 :     other_name->value.hardware_module_name.oid.len = len;
    1190              : 
    1191            0 :     p += len;
    1192            0 :     if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
    1193              :                                     MBEDTLS_ASN1_OCTET_STRING)) != 0) {
    1194            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
    1195              :     }
    1196              : 
    1197            0 :     other_name->value.hardware_module_name.val.tag = MBEDTLS_ASN1_OCTET_STRING;
    1198            0 :     other_name->value.hardware_module_name.val.p = p;
    1199            0 :     other_name->value.hardware_module_name.val.len = len;
    1200            0 :     p += len;
    1201            0 :     if (p != end) {
    1202            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
    1203              :                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
    1204              :     }
    1205            0 :     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         8638 : 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         8638 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1218              :     size_t tag_len;
    1219         8638 :     mbedtls_asn1_sequence *cur = subject_alt_name;
    1220              : 
    1221        18776 :     while (*p < end) {
    1222              :         mbedtls_x509_subject_alternative_name tmp_san_name;
    1223              :         mbedtls_x509_buf tmp_san_buf;
    1224        10138 :         memset(&tmp_san_name, 0, sizeof(tmp_san_name));
    1225              : 
    1226        10138 :         tmp_san_buf.tag = **p;
    1227        10138 :         (*p)++;
    1228              : 
    1229        10138 :         if ((ret = mbedtls_asn1_get_len(p, end, &tag_len)) != 0) {
    1230            0 :             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
    1231              :         }
    1232              : 
    1233        10138 :         tmp_san_buf.p = *p;
    1234        10138 :         tmp_san_buf.len = tag_len;
    1235              : 
    1236        10138 :         if ((tmp_san_buf.tag & MBEDTLS_ASN1_TAG_CLASS_MASK) !=
    1237              :             MBEDTLS_ASN1_CONTEXT_SPECIFIC) {
    1238            0 :             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        10138 :         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        10138 :         if (ret != 0 && ret != MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) {
    1252            0 :             mbedtls_asn1_sequence_free(subject_alt_name->next);
    1253            0 :             subject_alt_name->next = NULL;
    1254            0 :             return ret;
    1255              :         }
    1256              : 
    1257        10138 :         mbedtls_x509_free_subject_alt_name(&tmp_san_name);
    1258              :         /* Allocate and assign next pointer */
    1259        10138 :         if (cur->buf.p != NULL) {
    1260         1500 :             if (cur->next != NULL) {
    1261            0 :                 return MBEDTLS_ERR_X509_INVALID_EXTENSIONS;
    1262              :             }
    1263              : 
    1264         1500 :             cur->next = mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence));
    1265              : 
    1266         1500 :             if (cur->next == NULL) {
    1267            0 :                 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
    1268              :                                          MBEDTLS_ERR_ASN1_ALLOC_FAILED);
    1269              :             }
    1270              : 
    1271         1500 :             cur = cur->next;
    1272              :         }
    1273              : 
    1274        10138 :         cur->buf = tmp_san_buf;
    1275        10138 :         *p += tmp_san_buf.len;
    1276              :     }
    1277              : 
    1278              :     /* Set final sequence entry's next pointer to NULL */
    1279         8638 :     cur->next = NULL;
    1280              : 
    1281         8638 :     if (*p != end) {
    1282            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
    1283              :                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
    1284              :     }
    1285              : 
    1286         8638 :     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         8638 : int mbedtls_x509_get_subject_alt_name(unsigned char **p,
    1318              :                                       const unsigned char *end,
    1319              :                                       mbedtls_x509_sequence *subject_alt_name)
    1320              : {
    1321         8638 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1322              :     size_t len;
    1323              : 
    1324              :     /* Get main sequence tag */
    1325         8638 :     if ((ret = mbedtls_asn1_get_tag(p, end, &len,
    1326              :                                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
    1327            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
    1328              :     }
    1329              : 
    1330         8638 :     if (*p + len != end) {
    1331            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
    1332              :                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
    1333              :     }
    1334              : 
    1335         8638 :     return mbedtls_x509_get_subject_alt_name_ext(p, end, subject_alt_name);
    1336              : }
    1337              : 
    1338            0 : int mbedtls_x509_get_ns_cert_type(unsigned char **p,
    1339              :                                   const unsigned char *end,
    1340              :                                   unsigned char *ns_cert_type)
    1341              : {
    1342            0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1343            0 :     mbedtls_x509_bitstring bs = { 0, 0, NULL };
    1344              : 
    1345            0 :     if ((ret = mbedtls_asn1_get_bitstring(p, end, &bs)) != 0) {
    1346            0 :         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            0 :     if (bs.len == 0) {
    1352            0 :         *ns_cert_type = 0;
    1353            0 :         return 0;
    1354              :     }
    1355              : 
    1356            0 :     if (bs.len != 1) {
    1357            0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
    1358              :                                  MBEDTLS_ERR_ASN1_INVALID_LENGTH);
    1359              :     }
    1360              : 
    1361              :     /* Get actual bitstring */
    1362            0 :     *ns_cert_type = *bs.p;
    1363            0 :     return 0;
    1364              : }
    1365              : 
    1366        10540 : int mbedtls_x509_get_key_usage(unsigned char **p,
    1367              :                                const unsigned char *end,
    1368              :                                unsigned int *key_usage)
    1369              : {
    1370        10540 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1371              :     size_t i;
    1372        10540 :     mbedtls_x509_bitstring bs = { 0, 0, NULL };
    1373              : 
    1374        10540 :     if ((ret = mbedtls_asn1_get_bitstring(p, end, &bs)) != 0) {
    1375            0 :         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        10540 :     if (bs.len == 0) {
    1381            0 :         *key_usage = 0;
    1382            0 :         return 0;
    1383              :     }
    1384              : 
    1385              :     /* Get actual bitstring */
    1386        10540 :     *key_usage = 0;
    1387        21080 :     for (i = 0; i < bs.len && i < sizeof(unsigned int); i++) {
    1388        10540 :         *key_usage |= (unsigned int) bs.p[i] << (8*i);
    1389              :     }
    1390              : 
    1391        10540 :     return 0;
    1392              : }
    1393              : 
    1394        10138 : int mbedtls_x509_parse_subject_alt_name(const mbedtls_x509_buf *san_buf,
    1395              :                                         mbedtls_x509_subject_alternative_name *san)
    1396              : {
    1397        10138 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1398        10138 :     switch (san_buf->tag &
    1399              :             (MBEDTLS_ASN1_TAG_CLASS_MASK |
    1400              :              MBEDTLS_ASN1_TAG_VALUE_MASK)) {
    1401              :         /*
    1402              :          * otherName
    1403              :          */
    1404         8598 :         case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_OTHER_NAME):
    1405              :         {
    1406              :             mbedtls_x509_san_other_name other_name;
    1407              : 
    1408         8598 :             ret = x509_get_other_name(san_buf, &other_name);
    1409         8598 :             if (ret != 0) {
    1410         8598 :                 return ret;
    1411              :             }
    1412              : 
    1413            0 :             memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name));
    1414            0 :             san->type = MBEDTLS_X509_SAN_OTHER_NAME;
    1415            0 :             memcpy(&san->san.other_name,
    1416              :                    &other_name, sizeof(other_name));
    1417              : 
    1418              :         }
    1419            0 :         break;
    1420              :         /*
    1421              :          * uniformResourceIdentifier
    1422              :          */
    1423            0 :         case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER):
    1424              :         {
    1425            0 :             memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name));
    1426            0 :             san->type = MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER;
    1427              : 
    1428            0 :             memcpy(&san->san.unstructured_name,
    1429              :                    san_buf, sizeof(*san_buf));
    1430              : 
    1431              :         }
    1432            0 :         break;
    1433              :         /*
    1434              :          * dNSName
    1435              :          */
    1436         1540 :         case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_DNS_NAME):
    1437              :         {
    1438         1540 :             memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name));
    1439         1540 :             san->type = MBEDTLS_X509_SAN_DNS_NAME;
    1440              : 
    1441         1540 :             memcpy(&san->san.unstructured_name,
    1442              :                    san_buf, sizeof(*san_buf));
    1443              :         }
    1444         1540 :         break;
    1445              :         /*
    1446              :          * IP address
    1447              :          */
    1448            0 :         case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_IP_ADDRESS):
    1449              :         {
    1450            0 :             memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name));
    1451            0 :             san->type = MBEDTLS_X509_SAN_IP_ADDRESS;
    1452              :             // Only IPv6 (16 bytes) and IPv4 (4 bytes) types are supported
    1453            0 :             if (san_buf->len == 4 || san_buf->len == 16) {
    1454            0 :                 memcpy(&san->san.unstructured_name,
    1455              :                        san_buf, sizeof(*san_buf));
    1456              :             } else {
    1457            0 :                 return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
    1458              :             }
    1459              :         }
    1460            0 :         break;
    1461              :         /*
    1462              :          * rfc822Name
    1463              :          */
    1464            0 :         case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_RFC822_NAME):
    1465              :         {
    1466            0 :             memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name));
    1467            0 :             san->type = MBEDTLS_X509_SAN_RFC822_NAME;
    1468            0 :             memcpy(&san->san.unstructured_name, san_buf, sizeof(*san_buf));
    1469              :         }
    1470            0 :         break;
    1471              :         /*
    1472              :          * directoryName
    1473              :          */
    1474            0 :         case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_DIRECTORY_NAME):
    1475              :         {
    1476              :             size_t name_len;
    1477            0 :             unsigned char *p = san_buf->p;
    1478            0 :             memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name));
    1479            0 :             san->type = MBEDTLS_X509_SAN_DIRECTORY_NAME;
    1480              : 
    1481            0 :             ret = mbedtls_asn1_get_tag(&p, p + san_buf->len, &name_len,
    1482              :                                        MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
    1483              : 
    1484            0 :             if (ret != 0) {
    1485            0 :                 return ret;
    1486              :             }
    1487              : 
    1488            0 :             if ((ret = mbedtls_x509_get_name(&p, p + name_len,
    1489              :                                              &san->san.directory_name)) != 0) {
    1490            0 :                 return ret;
    1491              :             }
    1492              :         }
    1493            0 :         break;
    1494              :         /*
    1495              :          * Type not supported
    1496              :          */
    1497            0 :         default:
    1498            0 :             return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
    1499              :     }
    1500         1540 :     return 0;
    1501              : }
    1502              : 
    1503        10138 : void mbedtls_x509_free_subject_alt_name(mbedtls_x509_subject_alternative_name *san)
    1504              : {
    1505        10138 :     if (san->type == MBEDTLS_X509_SAN_DIRECTORY_NAME) {
    1506            0 :         mbedtls_asn1_free_named_data_list_shallow(san->san.directory_name.next);
    1507              :     }
    1508        10138 : }
    1509              : 
    1510              : #if !defined(MBEDTLS_X509_REMOVE_INFO)
    1511            0 : 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            0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1517              :     size_t i;
    1518            0 :     size_t n = *size;
    1519            0 :     char *p = *buf;
    1520            0 :     const mbedtls_x509_sequence *cur = subject_alt_name;
    1521              :     mbedtls_x509_subject_alternative_name san;
    1522              :     int parse_ret;
    1523              : 
    1524            0 :     while (cur != NULL) {
    1525            0 :         memset(&san, 0, sizeof(san));
    1526            0 :         parse_ret = mbedtls_x509_parse_subject_alt_name(&cur->buf, &san);
    1527            0 :         if (parse_ret != 0) {
    1528            0 :             if (parse_ret == MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) {
    1529            0 :                 ret = mbedtls_snprintf(p, n, "\n%s    <unsupported>", prefix);
    1530            0 :                 MBEDTLS_X509_SAFE_SNPRINTF;
    1531              :             } else {
    1532            0 :                 ret = mbedtls_snprintf(p, n, "\n%s    <malformed>", prefix);
    1533            0 :                 MBEDTLS_X509_SAFE_SNPRINTF;
    1534              :             }
    1535            0 :             cur = cur->next;
    1536            0 :             continue;
    1537              :         }
    1538              : 
    1539            0 :         switch (san.type) {
    1540              :             /*
    1541              :              * otherName
    1542              :              */
    1543            0 :             case MBEDTLS_X509_SAN_OTHER_NAME:
    1544              :             {
    1545            0 :                 mbedtls_x509_san_other_name *other_name = &san.san.other_name;
    1546              : 
    1547            0 :                 ret = mbedtls_snprintf(p, n, "\n%s    otherName :", prefix);
    1548            0 :                 MBEDTLS_X509_SAFE_SNPRINTF;
    1549              : 
    1550            0 :                 if (MBEDTLS_OID_CMP(MBEDTLS_OID_ON_HW_MODULE_NAME,
    1551              :                                     &other_name->type_id) == 0) {
    1552            0 :                     ret = mbedtls_snprintf(p, n, "\n%s        hardware module name :", prefix);
    1553            0 :                     MBEDTLS_X509_SAFE_SNPRINTF;
    1554              :                     ret =
    1555            0 :                         mbedtls_snprintf(p, n, "\n%s            hardware type          : ", prefix);
    1556            0 :                     MBEDTLS_X509_SAFE_SNPRINTF;
    1557              : 
    1558            0 :                     ret = mbedtls_oid_get_numeric_string(p,
    1559              :                                                          n,
    1560            0 :                                                          &other_name->value.hardware_module_name.oid);
    1561            0 :                     MBEDTLS_X509_SAFE_SNPRINTF;
    1562              : 
    1563              :                     ret =
    1564            0 :                         mbedtls_snprintf(p, n, "\n%s            hardware serial number : ", prefix);
    1565            0 :                     MBEDTLS_X509_SAFE_SNPRINTF;
    1566              : 
    1567            0 :                     for (i = 0; i < other_name->value.hardware_module_name.val.len; i++) {
    1568            0 :                         ret = mbedtls_snprintf(p,
    1569              :                                                n,
    1570              :                                                "%02X",
    1571            0 :                                                other_name->value.hardware_module_name.val.p[i]);
    1572            0 :                         MBEDTLS_X509_SAFE_SNPRINTF;
    1573              :                     }
    1574              :                 }/* MBEDTLS_OID_ON_HW_MODULE_NAME */
    1575              :             }
    1576            0 :             break;
    1577              :             /*
    1578              :              * uniformResourceIdentifier
    1579              :              */
    1580            0 :             case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER:
    1581              :             {
    1582            0 :                 ret = mbedtls_snprintf(p, n, "\n%s    uniformResourceIdentifier : ", prefix);
    1583            0 :                 MBEDTLS_X509_SAFE_SNPRINTF;
    1584            0 :                 if (san.san.unstructured_name.len >= n) {
    1585            0 :                     if (n > 0) {
    1586            0 :                         *p = '\0';
    1587              :                     }
    1588            0 :                     return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
    1589              :                 }
    1590              : 
    1591            0 :                 memcpy(p, san.san.unstructured_name.p, san.san.unstructured_name.len);
    1592            0 :                 p += san.san.unstructured_name.len;
    1593            0 :                 n -= san.san.unstructured_name.len;
    1594              :             }
    1595            0 :             break;
    1596              :             /*
    1597              :              * dNSName
    1598              :              * RFC822 Name
    1599              :              */
    1600            0 :             case MBEDTLS_X509_SAN_DNS_NAME:
    1601              :             case MBEDTLS_X509_SAN_RFC822_NAME:
    1602              :             {
    1603            0 :                 const char *dns_name = "dNSName";
    1604            0 :                 const char *rfc822_name = "rfc822Name";
    1605              : 
    1606            0 :                 ret = mbedtls_snprintf(p, n,
    1607              :                                        "\n%s    %s : ",
    1608              :                                        prefix,
    1609            0 :                                        san.type ==
    1610              :                                        MBEDTLS_X509_SAN_DNS_NAME ? dns_name : rfc822_name);
    1611            0 :                 MBEDTLS_X509_SAFE_SNPRINTF;
    1612            0 :                 if (san.san.unstructured_name.len >= n) {
    1613            0 :                     if (n > 0) {
    1614            0 :                         *p = '\0';
    1615              :                     }
    1616            0 :                     return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
    1617              :                 }
    1618              : 
    1619            0 :                 memcpy(p, san.san.unstructured_name.p, san.san.unstructured_name.len);
    1620            0 :                 p += san.san.unstructured_name.len;
    1621            0 :                 n -= san.san.unstructured_name.len;
    1622              :             }
    1623            0 :             break;
    1624              :             /*
    1625              :              * iPAddress
    1626              :              */
    1627            0 :             case MBEDTLS_X509_SAN_IP_ADDRESS:
    1628              :             {
    1629            0 :                 ret = mbedtls_snprintf(p, n, "\n%s    %s : ",
    1630              :                                        prefix, "iPAddress");
    1631            0 :                 MBEDTLS_X509_SAFE_SNPRINTF;
    1632            0 :                 if (san.san.unstructured_name.len >= n) {
    1633            0 :                     if (n > 0) {
    1634            0 :                         *p = '\0';
    1635              :                     }
    1636            0 :                     return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
    1637              :                 }
    1638              : 
    1639            0 :                 unsigned char *ip = san.san.unstructured_name.p;
    1640              :                 // Only IPv6 (16 bytes) and IPv4 (4 bytes) types are supported
    1641            0 :                 if (san.san.unstructured_name.len == 4) {
    1642            0 :                     ret = mbedtls_snprintf(p, n, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]);
    1643            0 :                     MBEDTLS_X509_SAFE_SNPRINTF;
    1644            0 :                 } else if (san.san.unstructured_name.len == 16) {
    1645            0 :                     ret = mbedtls_snprintf(p, n,
    1646              :                                            "%X%X:%X%X:%X%X:%X%X:%X%X:%X%X:%X%X:%X%X",
    1647            0 :                                            ip[0], ip[1], ip[2], ip[3], ip[4], ip[5], ip[6],
    1648            0 :                                            ip[7], ip[8], ip[9], ip[10], ip[11], ip[12], ip[13],
    1649            0 :                                            ip[14], ip[15]);
    1650            0 :                     MBEDTLS_X509_SAFE_SNPRINTF;
    1651              :                 } else {
    1652            0 :                     if (n > 0) {
    1653            0 :                         *p = '\0';
    1654              :                     }
    1655            0 :                     return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
    1656              :                 }
    1657              :             }
    1658            0 :             break;
    1659              :             /*
    1660              :              * directoryName
    1661              :              */
    1662            0 :             case MBEDTLS_X509_SAN_DIRECTORY_NAME:
    1663              :             {
    1664            0 :                 ret = mbedtls_snprintf(p, n, "\n%s    directoryName : ", prefix);
    1665            0 :                 if (ret < 0 || (size_t) ret >= n) {
    1666            0 :                     mbedtls_x509_free_subject_alt_name(&san);
    1667              :                 }
    1668              : 
    1669            0 :                 MBEDTLS_X509_SAFE_SNPRINTF;
    1670            0 :                 ret = mbedtls_x509_dn_gets(p, n, &san.san.directory_name);
    1671              : 
    1672            0 :                 if (ret < 0) {
    1673            0 :                     mbedtls_x509_free_subject_alt_name(&san);
    1674            0 :                     if (n > 0) {
    1675            0 :                         *p = '\0';
    1676              :                     }
    1677            0 :                     return ret;
    1678              :                 }
    1679              : 
    1680            0 :                 p += ret;
    1681            0 :                 n -= ret;
    1682              :             }
    1683            0 :             break;
    1684              :             /*
    1685              :              * Type not supported, skip item.
    1686              :              */
    1687            0 :             default:
    1688            0 :                 ret = mbedtls_snprintf(p, n, "\n%s    <unsupported>", prefix);
    1689            0 :                 MBEDTLS_X509_SAFE_SNPRINTF;
    1690            0 :                 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            0 :         mbedtls_x509_free_subject_alt_name(&san);
    1696            0 :         cur = cur->next;
    1697              :     }
    1698              : 
    1699            0 :     *p = '\0';
    1700              : 
    1701            0 :     *size = n;
    1702            0 :     *buf = p;
    1703              : 
    1704            0 :     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            0 : int mbedtls_x509_info_cert_type(char **buf, size_t *size,
    1722              :                                 unsigned char ns_cert_type)
    1723              : {
    1724            0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1725            0 :     size_t n = *size;
    1726            0 :     char *p = *buf;
    1727            0 :     const char *sep = "";
    1728              : 
    1729            0 :     CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT,         "SSL Client");
    1730            0 :     CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER,         "SSL Server");
    1731            0 :     CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_EMAIL,              "Email");
    1732            0 :     CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING,     "Object Signing");
    1733            0 :     CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_RESERVED,           "Reserved");
    1734            0 :     CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_SSL_CA,             "SSL CA");
    1735            0 :     CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA,           "Email CA");
    1736            0 :     CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA,  "Object Signing CA");
    1737              : 
    1738            0 :     *size = n;
    1739            0 :     *buf = p;
    1740              : 
    1741            0 :     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            0 : int mbedtls_x509_info_key_usage(char **buf, size_t *size,
    1752              :                                 unsigned int key_usage)
    1753              : {
    1754            0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1755            0 :     size_t n = *size;
    1756            0 :     char *p = *buf;
    1757            0 :     const char *sep = "";
    1758              : 
    1759            0 :     KEY_USAGE(MBEDTLS_X509_KU_DIGITAL_SIGNATURE,    "Digital Signature");
    1760            0 :     KEY_USAGE(MBEDTLS_X509_KU_NON_REPUDIATION,      "Non Repudiation");
    1761            0 :     KEY_USAGE(MBEDTLS_X509_KU_KEY_ENCIPHERMENT,     "Key Encipherment");
    1762            0 :     KEY_USAGE(MBEDTLS_X509_KU_DATA_ENCIPHERMENT,    "Data Encipherment");
    1763            0 :     KEY_USAGE(MBEDTLS_X509_KU_KEY_AGREEMENT,        "Key Agreement");
    1764            0 :     KEY_USAGE(MBEDTLS_X509_KU_KEY_CERT_SIGN,        "Key Cert Sign");
    1765            0 :     KEY_USAGE(MBEDTLS_X509_KU_CRL_SIGN,             "CRL Sign");
    1766            0 :     KEY_USAGE(MBEDTLS_X509_KU_ENCIPHER_ONLY,        "Encipher Only");
    1767            0 :     KEY_USAGE(MBEDTLS_X509_KU_DECIPHER_ONLY,        "Decipher Only");
    1768              : 
    1769            0 :     *size = n;
    1770            0 :     *buf = p;
    1771              : 
    1772            0 :     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 */
        

Generated by: LCOV version 2.0-1