LCOV - code coverage report
Current view: top level - externals/mbedtls/library - x509.c (source / functions) Coverage Total Hit
Test: lcov.info Lines: 18.0 % 584 105
Test Date: 2026-03-12 12:01:18 Functions: 33.3 % 30 10
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 8.7 % 423 37

             Branch data     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                 :           4 : int mbedtls_x509_get_serial(unsigned char **p, const unsigned char *end,
      64                 :             :                             mbedtls_x509_buf *serial)
      65                 :             : {
      66                 :           4 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
      67                 :             : 
      68         [ -  + ]:           4 :     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         [ -  + ]:           4 :     if (**p != (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_PRIMITIVE | 2) &&
      74                 :             :         **p !=   MBEDTLS_ASN1_INTEGER) {
      75                 :           0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_SERIAL,
      76                 :             :                                  MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
      77                 :             :     }
      78                 :             : 
      79                 :           4 :     serial->tag = *(*p)++;
      80                 :             : 
      81         [ -  + ]:           4 :     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                 :           4 :     serial->p = *p;
      86                 :           4 :     *p += serial->len;
      87                 :             : 
      88                 :           4 :     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                 :             :     return 0;
     107                 :             : }
     108                 :             : 
     109                 :             : /*
     110                 :             :  * Parse an algorithm identifier with (optional) parameters
     111                 :             :  */
     112                 :           8 : int mbedtls_x509_get_alg(unsigned char **p, const unsigned char *end,
     113                 :             :                          mbedtls_x509_buf *alg, mbedtls_x509_buf *params)
     114                 :             : {
     115                 :           8 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     116                 :             : 
     117         [ -  + ]:           8 :     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                 :             :     return 0;
     122                 :             : }
     123                 :             : 
     124                 :             : /*
     125                 :             :  * Convert md type to string
     126                 :             :  */
     127                 :             : #if !defined(MBEDTLS_X509_REMOVE_INFO) && defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
     128                 :             : 
     129                 :             : static inline const char *md_type_to_string(mbedtls_md_type_t md_alg)
     130                 :             : {
     131                 :             :     switch (md_alg) {
     132                 :             : #if defined(MBEDTLS_MD_CAN_MD5)
     133                 :             :         case MBEDTLS_MD_MD5:
     134                 :             :             return "MD5";
     135                 :             : #endif
     136                 :             : #if defined(MBEDTLS_MD_CAN_SHA1)
     137                 :             :         case MBEDTLS_MD_SHA1:
     138                 :             :             return "SHA1";
     139                 :             : #endif
     140                 :             : #if defined(MBEDTLS_MD_CAN_SHA224)
     141                 :             :         case MBEDTLS_MD_SHA224:
     142                 :             :             return "SHA224";
     143                 :             : #endif
     144                 :             : #if defined(MBEDTLS_MD_CAN_SHA256)
     145                 :             :         case MBEDTLS_MD_SHA256:
     146                 :             :             return "SHA256";
     147                 :             : #endif
     148                 :             : #if defined(MBEDTLS_MD_CAN_SHA384)
     149                 :             :         case MBEDTLS_MD_SHA384:
     150                 :             :             return "SHA384";
     151                 :             : #endif
     152                 :             : #if defined(MBEDTLS_MD_CAN_SHA512)
     153                 :             :         case MBEDTLS_MD_SHA512:
     154                 :             :             return "SHA512";
     155                 :             : #endif
     156                 :             : #if defined(MBEDTLS_MD_CAN_RIPEMD160)
     157                 :             :         case MBEDTLS_MD_RIPEMD160:
     158                 :             :             return "RIPEMD160";
     159                 :             : #endif
     160                 :             :         case MBEDTLS_MD_NONE:
     161                 :             :             return NULL;
     162                 :             :         default:
     163                 :             :             return NULL;
     164                 :             :     }
     165                 :             : }
     166                 :             : 
     167                 :             : #endif /* !defined(MBEDTLS_X509_REMOVE_INFO) && defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) */
     168                 :             : 
     169                 :             : #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
     170                 :             : /*
     171                 :             :  * HashAlgorithm ::= AlgorithmIdentifier
     172                 :             :  *
     173                 :             :  * AlgorithmIdentifier  ::=  SEQUENCE  {
     174                 :             :  *      algorithm               OBJECT IDENTIFIER,
     175                 :             :  *      parameters              ANY DEFINED BY algorithm OPTIONAL  }
     176                 :             :  *
     177                 :             :  * For HashAlgorithm, parameters MUST be NULL or absent.
     178                 :             :  */
     179                 :             : static int x509_get_hash_alg(const mbedtls_x509_buf *alg, mbedtls_md_type_t *md_alg)
     180                 :             : {
     181                 :             :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     182                 :             :     unsigned char *p;
     183                 :             :     const unsigned char *end;
     184                 :             :     mbedtls_x509_buf md_oid;
     185                 :             :     size_t len;
     186                 :             : 
     187                 :             :     /* Make sure we got a SEQUENCE and setup bounds */
     188                 :             :     if (alg->tag != (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) {
     189                 :             :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
     190                 :             :                                  MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
     191                 :             :     }
     192                 :             : 
     193                 :             :     p = alg->p;
     194                 :             :     end = p + alg->len;
     195                 :             : 
     196                 :             :     if (p >= end) {
     197                 :             :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
     198                 :             :                                  MBEDTLS_ERR_ASN1_OUT_OF_DATA);
     199                 :             :     }
     200                 :             : 
     201                 :             :     /* Parse md_oid */
     202                 :             :     md_oid.tag = *p;
     203                 :             : 
     204                 :             :     if ((ret = mbedtls_asn1_get_tag(&p, end, &md_oid.len, MBEDTLS_ASN1_OID)) != 0) {
     205                 :             :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
     206                 :             :     }
     207                 :             : 
     208                 :             :     md_oid.p = p;
     209                 :             :     p += md_oid.len;
     210                 :             : 
     211                 :             :     /* Get md_alg from md_oid */
     212                 :             :     if ((ret = mbedtls_oid_get_md_alg(&md_oid, md_alg)) != 0) {
     213                 :             :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
     214                 :             :     }
     215                 :             : 
     216                 :             :     /* Make sure params is absent of NULL */
     217                 :             :     if (p == end) {
     218                 :             :         return 0;
     219                 :             :     }
     220                 :             : 
     221                 :             :     if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_NULL)) != 0 || len != 0) {
     222                 :             :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
     223                 :             :     }
     224                 :             : 
     225                 :             :     if (p != end) {
     226                 :             :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
     227                 :             :                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
     228                 :             :     }
     229                 :             : 
     230                 :             :     return 0;
     231                 :             : }
     232                 :             : 
     233                 :             : /*
     234                 :             :  *    RSASSA-PSS-params  ::=  SEQUENCE  {
     235                 :             :  *       hashAlgorithm     [0] HashAlgorithm DEFAULT sha1Identifier,
     236                 :             :  *       maskGenAlgorithm  [1] MaskGenAlgorithm DEFAULT mgf1SHA1Identifier,
     237                 :             :  *       saltLength        [2] INTEGER DEFAULT 20,
     238                 :             :  *       trailerField      [3] INTEGER DEFAULT 1  }
     239                 :             :  *    -- Note that the tags in this Sequence are explicit.
     240                 :             :  *
     241                 :             :  * RFC 4055 (which defines use of RSASSA-PSS in PKIX) states that the value
     242                 :             :  * of trailerField MUST be 1, and PKCS#1 v2.2 doesn't even define any other
     243                 :             :  * option. Enforce this at parsing time.
     244                 :             :  */
     245                 :             : int mbedtls_x509_get_rsassa_pss_params(const mbedtls_x509_buf *params,
     246                 :             :                                        mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md,
     247                 :             :                                        int *salt_len)
     248                 :             : {
     249                 :             :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     250                 :             :     unsigned char *p;
     251                 :             :     const unsigned char *end, *end2;
     252                 :             :     size_t len;
     253                 :             :     mbedtls_x509_buf alg_id, alg_params;
     254                 :             : 
     255                 :             :     /* First set everything to defaults */
     256                 :             :     *md_alg = MBEDTLS_MD_SHA1;
     257                 :             :     *mgf_md = MBEDTLS_MD_SHA1;
     258                 :             :     *salt_len = 20;
     259                 :             : 
     260                 :             :     /* Make sure params is a SEQUENCE and setup bounds */
     261                 :             :     if (params->tag != (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) {
     262                 :             :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
     263                 :             :                                  MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
     264                 :             :     }
     265                 :             : 
     266                 :             :     p = (unsigned char *) params->p;
     267                 :             :     end = p + params->len;
     268                 :             : 
     269                 :             :     if (p == end) {
     270                 :             :         return 0;
     271                 :             :     }
     272                 :             : 
     273                 :             :     /*
     274                 :             :      * HashAlgorithm
     275                 :             :      */
     276                 :             :     if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
     277                 :             :                                     MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED |
     278                 :             :                                     0)) == 0) {
     279                 :             :         end2 = p + len;
     280                 :             : 
     281                 :             :         /* HashAlgorithm ::= AlgorithmIdentifier (without parameters) */
     282                 :             :         if ((ret = mbedtls_x509_get_alg_null(&p, end2, &alg_id)) != 0) {
     283                 :             :             return ret;
     284                 :             :         }
     285                 :             : 
     286                 :             :         if ((ret = mbedtls_oid_get_md_alg(&alg_id, md_alg)) != 0) {
     287                 :             :             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
     288                 :             :         }
     289                 :             : 
     290                 :             :         if (p != end2) {
     291                 :             :             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
     292                 :             :                                      MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
     293                 :             :         }
     294                 :             :     } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
     295                 :             :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
     296                 :             :     }
     297                 :             : 
     298                 :             :     if (p == end) {
     299                 :             :         return 0;
     300                 :             :     }
     301                 :             : 
     302                 :             :     /*
     303                 :             :      * MaskGenAlgorithm
     304                 :             :      */
     305                 :             :     if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
     306                 :             :                                     MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED |
     307                 :             :                                     1)) == 0) {
     308                 :             :         end2 = p + len;
     309                 :             : 
     310                 :             :         /* MaskGenAlgorithm ::= AlgorithmIdentifier (params = HashAlgorithm) */
     311                 :             :         if ((ret = mbedtls_x509_get_alg(&p, end2, &alg_id, &alg_params)) != 0) {
     312                 :             :             return ret;
     313                 :             :         }
     314                 :             : 
     315                 :             :         /* Only MFG1 is recognised for now */
     316                 :             :         if (MBEDTLS_OID_CMP(MBEDTLS_OID_MGF1, &alg_id) != 0) {
     317                 :             :             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE,
     318                 :             :                                      MBEDTLS_ERR_OID_NOT_FOUND);
     319                 :             :         }
     320                 :             : 
     321                 :             :         /* Parse HashAlgorithm */
     322                 :             :         if ((ret = x509_get_hash_alg(&alg_params, mgf_md)) != 0) {
     323                 :             :             return ret;
     324                 :             :         }
     325                 :             : 
     326                 :             :         if (p != end2) {
     327                 :             :             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
     328                 :             :                                      MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
     329                 :             :         }
     330                 :             :     } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
     331                 :             :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
     332                 :             :     }
     333                 :             : 
     334                 :             :     if (p == end) {
     335                 :             :         return 0;
     336                 :             :     }
     337                 :             : 
     338                 :             :     /*
     339                 :             :      * salt_len
     340                 :             :      */
     341                 :             :     if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
     342                 :             :                                     MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED |
     343                 :             :                                     2)) == 0) {
     344                 :             :         end2 = p + len;
     345                 :             : 
     346                 :             :         if ((ret = mbedtls_asn1_get_int(&p, end2, salt_len)) != 0) {
     347                 :             :             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
     348                 :             :         }
     349                 :             : 
     350                 :             :         if (p != end2) {
     351                 :             :             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
     352                 :             :                                      MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
     353                 :             :         }
     354                 :             :     } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
     355                 :             :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
     356                 :             :     }
     357                 :             : 
     358                 :             :     if (p == end) {
     359                 :             :         return 0;
     360                 :             :     }
     361                 :             : 
     362                 :             :     /*
     363                 :             :      * trailer_field (if present, must be 1)
     364                 :             :      */
     365                 :             :     if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
     366                 :             :                                     MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED |
     367                 :             :                                     3)) == 0) {
     368                 :             :         int trailer_field;
     369                 :             : 
     370                 :             :         end2 = p + len;
     371                 :             : 
     372                 :             :         if ((ret = mbedtls_asn1_get_int(&p, end2, &trailer_field)) != 0) {
     373                 :             :             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
     374                 :             :         }
     375                 :             : 
     376                 :             :         if (p != end2) {
     377                 :             :             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
     378                 :             :                                      MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
     379                 :             :         }
     380                 :             : 
     381                 :             :         if (trailer_field != 1) {
     382                 :             :             return MBEDTLS_ERR_X509_INVALID_ALG;
     383                 :             :         }
     384                 :             :     } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
     385                 :             :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
     386                 :             :     }
     387                 :             : 
     388                 :             :     if (p != end) {
     389                 :             :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
     390                 :             :                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
     391                 :             :     }
     392                 :             : 
     393                 :             :     return 0;
     394                 :             : }
     395                 :             : #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
     396                 :             : 
     397                 :             : /*
     398                 :             :  *  AttributeTypeAndValue ::= SEQUENCE {
     399                 :             :  *    type     AttributeType,
     400                 :             :  *    value    AttributeValue }
     401                 :             :  *
     402                 :             :  *  AttributeType ::= OBJECT IDENTIFIER
     403                 :             :  *
     404                 :             :  *  AttributeValue ::= ANY DEFINED BY AttributeType
     405                 :             :  */
     406                 :           8 : static int x509_get_attr_type_value(unsigned char **p,
     407                 :             :                                     const unsigned char *end,
     408                 :             :                                     mbedtls_x509_name *cur)
     409                 :             : {
     410                 :           8 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     411                 :           8 :     size_t len;
     412                 :           8 :     mbedtls_x509_buf *oid;
     413                 :           8 :     mbedtls_x509_buf *val;
     414                 :             : 
     415         [ -  + ]:           8 :     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                 :           8 :     end = *p + len;
     421                 :             : 
     422         [ -  + ]:           8 :     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                 :           8 :     oid = &cur->oid;
     428                 :           8 :     oid->tag = **p;
     429                 :             : 
     430         [ -  + ]:           8 :     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                 :           8 :     oid->p = *p;
     435                 :           8 :     *p += oid->len;
     436                 :             : 
     437         [ -  + ]:           8 :     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         [ -  + ]:           8 :     if (**p != MBEDTLS_ASN1_BMP_STRING && **p != MBEDTLS_ASN1_UTF8_STRING      &&
     443                 :             :         **p != MBEDTLS_ASN1_T61_STRING && **p != MBEDTLS_ASN1_PRINTABLE_STRING &&
     444                 :             :         **p != MBEDTLS_ASN1_IA5_STRING && **p != MBEDTLS_ASN1_UNIVERSAL_STRING &&
     445                 :             :         **p != MBEDTLS_ASN1_BIT_STRING) {
     446                 :           0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME,
     447                 :             :                                  MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
     448                 :             :     }
     449                 :             : 
     450                 :           8 :     val = &cur->val;
     451                 :           8 :     val->tag = *(*p)++;
     452                 :             : 
     453         [ -  + ]:           8 :     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                 :           8 :     val->p = *p;
     458                 :           8 :     *p += val->len;
     459                 :             : 
     460         [ -  + ]:           8 :     if (*p != end) {
     461                 :           0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME,
     462                 :             :                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
     463                 :             :     }
     464                 :             : 
     465                 :           8 :     cur->next = NULL;
     466                 :             : 
     467                 :           8 :     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                 :           8 : int mbedtls_x509_get_name(unsigned char **p, const unsigned char *end,
     499                 :             :                           mbedtls_x509_name *cur)
     500                 :             : {
     501                 :           8 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     502                 :           8 :     size_t set_len;
     503                 :           8 :     const unsigned char *end_set;
     504                 :           8 :     mbedtls_x509_name *head = cur;
     505                 :             : 
     506                 :             :     /* don't use recursion, we'd risk stack overflow if not optimized */
     507                 :           8 :     while (1) {
     508                 :             :         /*
     509                 :             :          * parse SET
     510                 :             :          */
     511         [ -  + ]:           8 :         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                 :           8 :         end_set  = *p + set_len;
     518                 :             : 
     519                 :           8 :         while (1) {
     520         [ -  + ]:           8 :             if ((ret = x509_get_attr_type_value(p, end_set, cur)) != 0) {
     521                 :           0 :                 goto error;
     522                 :             :             }
     523                 :             : 
     524         [ -  + ]:           8 :             if (*p == end_set) {
     525                 :             :                 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                 :             :             cur = cur->next;
     539                 :             :         }
     540                 :             : 
     541                 :             :         /*
     542                 :             :          * continue until end of SEQUENCE is reached
     543                 :             :          */
     544         [ -  + ]:           8 :         if (*p == end) {
     545                 :             :             return 0;
     546                 :             :         }
     547                 :             : 
     548                 :           0 :         cur->next = mbedtls_calloc(1, sizeof(mbedtls_x509_name));
     549                 :             : 
     550         [ #  # ]:           0 :         if (cur->next == NULL) {
     551                 :           0 :             ret = MBEDTLS_ERR_X509_ALLOC_FAILED;
     552                 :           0 :             goto error;
     553                 :             :         }
     554                 :             : 
     555                 :             :         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                 :           8 : static int x509_date_is_valid(const mbedtls_x509_time *t)
     567                 :             : {
     568                 :           8 :     unsigned int month_days;
     569                 :           8 :     unsigned int year;
     570   [ -  -  +  - ]:           8 :     switch (t->mon) {
     571                 :             :         case 1: case 3: case 5: case 7: case 8: case 10: case 12:
     572                 :             :             month_days = 31;
     573                 :             :             break;
     574                 :           0 :         case 4: case 6: case 9: case 11:
     575                 :           0 :             month_days = 30;
     576                 :           0 :             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                 :             :             break;
     583                 :             :         default:
     584                 :             :             return MBEDTLS_ERR_X509_INVALID_DATE;
     585                 :             :     }
     586                 :             : 
     587         [ +  - ]:           8 :     if ((unsigned int) (t->day - 1) >= month_days ||      /* (1 - days in month) */
     588                 :             :         /* (unsigned int) (t->mon - 1) >= 12 || */  /* (1 - 12) checked above */
     589         [ +  - ]:           8 :         (unsigned int) t->year > 9999 ||         /* (0 - 9999) */
     590         [ +  - ]:           8 :         (unsigned int) t->hour > 23 ||           /* (0 - 23) */
     591         [ +  - ]:           8 :         (unsigned int) t->min  > 59 ||           /* (0 - 59) */
     592         [ -  + ]:           8 :         (unsigned int) t->sec  > 59) {           /* (0 - 59) */
     593                 :           0 :         return MBEDTLS_ERR_X509_INVALID_DATE;
     594                 :             :     }
     595                 :             : 
     596                 :             :     return 0;
     597                 :             : }
     598                 :             : 
     599                 :          48 : static int x509_parse2_int(const unsigned char *p)
     600                 :             : {
     601                 :          48 :     uint32_t d1 = p[0] - '0';
     602                 :          48 :     uint32_t d2 = p[1] - '0';
     603         [ +  - ]:          48 :     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                 :           8 : static int x509_parse_time(const unsigned char *p, mbedtls_x509_time *tm,
     611                 :             :                            size_t yearlen)
     612                 :             : {
     613                 :           8 :     int x;
     614                 :             : 
     615                 :             :     /*
     616                 :             :      * Parse year, month, day, hour, minute, second
     617                 :             :      */
     618                 :           8 :     tm->year = x509_parse2_int(p);
     619         [ -  + ]:           8 :     if (tm->year < 0) {
     620                 :             :         return MBEDTLS_ERR_X509_INVALID_DATE;
     621                 :             :     }
     622                 :             : 
     623         [ -  + ]:           8 :     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                 :             :             return MBEDTLS_ERR_X509_INVALID_DATE;
     629                 :             :         }
     630                 :             :     } else {
     631         [ -  + ]:           8 :         x = (tm->year < 50) ? 2000 : 1900;
     632                 :             :     }
     633                 :           8 :     tm->year += x;
     634                 :             : 
     635                 :           8 :     tm->mon  = x509_parse2_int(p + 2);
     636                 :           8 :     tm->day  = x509_parse2_int(p + 4);
     637                 :           8 :     tm->hour = x509_parse2_int(p + 6);
     638                 :           8 :     tm->min  = x509_parse2_int(p + 8);
     639                 :           8 :     tm->sec  = x509_parse2_int(p + 10);
     640                 :             : 
     641                 :           8 :     return x509_date_is_valid(tm);
     642                 :             : }
     643                 :             : 
     644                 :             : /*
     645                 :             :  *  Time ::= CHOICE {
     646                 :             :  *       utcTime        UTCTime,
     647                 :             :  *       generalTime    GeneralizedTime }
     648                 :             :  */
     649                 :           8 : int mbedtls_x509_get_time(unsigned char **p, const unsigned char *end,
     650                 :             :                           mbedtls_x509_time *tm)
     651                 :             : {
     652                 :           8 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     653                 :           8 :     size_t len, year_len;
     654                 :           8 :     unsigned char tag;
     655                 :             : 
     656         [ -  + ]:           8 :     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                 :           8 :     tag = **p;
     662                 :             : 
     663         [ -  + ]:           8 :     if (tag == MBEDTLS_ASN1_UTC_TIME) {
     664                 :             :         year_len = 2;
     665         [ #  # ]:           0 :     } else if (tag == MBEDTLS_ASN1_GENERALIZED_TIME) {
     666                 :             :         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                 :           8 :     (*p)++;
     673                 :           8 :     ret = mbedtls_asn1_get_len(p, end, &len);
     674                 :             : 
     675         [ -  + ]:           8 :     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         [ +  - ]:           8 :     if (len != year_len + 10 &&
     681   [ +  -  +  - ]:           8 :         !(len == year_len + 11 && (*p)[(len - 1)] == 'Z')) {
     682                 :             :         return MBEDTLS_ERR_X509_INVALID_DATE;
     683                 :             :     }
     684                 :             : 
     685                 :           8 :     (*p) += len;
     686                 :           8 :     return x509_parse_time(*p - len, tm, year_len);
     687                 :             : }
     688                 :             : 
     689                 :           4 : int mbedtls_x509_get_sig(unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig)
     690                 :             : {
     691                 :           4 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     692                 :           4 :     size_t len;
     693                 :           4 :     int tag_type;
     694                 :             : 
     695         [ -  + ]:           4 :     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                 :           4 :     tag_type = **p;
     701                 :             : 
     702         [ -  + ]:           4 :     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                 :           4 :     sig->tag = tag_type;
     707                 :           4 :     sig->len = len;
     708                 :           4 :     sig->p = *p;
     709                 :             : 
     710                 :           4 :     *p += len;
     711                 :             : 
     712                 :           4 :     return 0;
     713                 :             : }
     714                 :             : 
     715                 :             : /*
     716                 :             :  * Get signature algorithm from alg OID and optional parameters
     717                 :             :  */
     718                 :           4 : 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                 :           4 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     723                 :             : 
     724         [ +  - ]:           4 :     if (*sig_opts != NULL) {
     725                 :             :         return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
     726                 :             :     }
     727                 :             : 
     728         [ -  + ]:           4 :     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                 :             :     if (*pk_alg == MBEDTLS_PK_RSASSA_PSS) {
     734                 :             :         mbedtls_pk_rsassa_pss_options *pss_opts;
     735                 :             : 
     736                 :             :         pss_opts = mbedtls_calloc(1, sizeof(mbedtls_pk_rsassa_pss_options));
     737                 :             :         if (pss_opts == NULL) {
     738                 :             :             return MBEDTLS_ERR_X509_ALLOC_FAILED;
     739                 :             :         }
     740                 :             : 
     741                 :             :         ret = mbedtls_x509_get_rsassa_pss_params(sig_params,
     742                 :             :                                                  md_alg,
     743                 :             :                                                  &pss_opts->mgf1_hash_id,
     744                 :             :                                                  &pss_opts->expected_salt_len);
     745                 :             :         if (ret != 0) {
     746                 :             :             mbedtls_free(pss_opts);
     747                 :             :             return ret;
     748                 :             :         }
     749                 :             : 
     750                 :             :         *sig_opts = (void *) pss_opts;
     751                 :             :     } else
     752                 :             : #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
     753                 :             :     {
     754                 :             :         /* Make sure parameters are absent or NULL */
     755         [ +  - ]:           4 :         if ((sig_params->tag != MBEDTLS_ASN1_NULL && sig_params->tag != 0) ||
     756         [ -  + ]:           4 :             sig_params->len != 0) {
     757                 :           0 :             return MBEDTLS_ERR_X509_INVALID_ALG;
     758                 :             :         }
     759                 :             :     }
     760                 :             : 
     761                 :             :     return 0;
     762                 :             : }
     763                 :             : 
     764                 :             : /*
     765                 :             :  * X.509 Extensions (No parsing of extensions, pointer should
     766                 :             :  * be either manually updated or extensions should be parsed!)
     767                 :             :  */
     768                 :           0 : int mbedtls_x509_get_ext(unsigned char **p, const unsigned char *end,
     769                 :             :                          mbedtls_x509_buf *ext, int tag)
     770                 :             : {
     771                 :           0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     772                 :           0 :     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                 :           0 :     ret = mbedtls_asn1_get_tag(p, end, &ext->len,
     778                 :             :                                MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag);
     779         [ #  # ]:           0 :     if (ret != 0) {
     780                 :           0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
     781                 :             :     }
     782                 :             : 
     783                 :           0 :     ext->tag = MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag;
     784                 :           0 :     ext->p   = *p;
     785                 :           0 :     end      = *p + ext->len;
     786                 :             : 
     787                 :             :     /*
     788                 :             :      * Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
     789                 :             :      */
     790         [ #  # ]:           0 :     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         [ #  # ]:           0 :     if (end != *p + len) {
     796                 :           0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
     797                 :             :                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
     798                 :             :     }
     799                 :             : 
     800                 :             :     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                 :           0 :     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                 :           0 :     unsigned char asn1_tag_len_buf[6];
     818                 :           0 :     unsigned char *asn1_len_p;
     819                 :           0 :     unsigned char c, merge = 0;
     820                 :           0 :     const mbedtls_x509_name *name;
     821                 :           0 :     const char *short_name = NULL;
     822                 :           0 :     char lowbits, highbits;
     823                 :           0 :     char s[MBEDTLS_X509_MAX_DN_NAME_SIZE], *p;
     824                 :           0 :     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                 :             :                           (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                 :             :                 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                 :             :                 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                 :             :                 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                 :             :                     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                 :             :                     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                 :             :                     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                 :             :                     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                 :             :                             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                 :             :                         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                 :           0 :     size_t i, n, nr;
     949                 :           0 :     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                 :             :     if (pk_alg == MBEDTLS_PK_RSASSA_PSS) {
     998                 :             :         const mbedtls_pk_rsassa_pss_options *pss_opts;
     999                 :             : 
    1000                 :             :         pss_opts = (const mbedtls_pk_rsassa_pss_options *) sig_opts;
    1001                 :             : 
    1002                 :             :         const char *name = md_type_to_string(md_alg);
    1003                 :             :         const char *mgf_name = md_type_to_string(pss_opts->mgf1_hash_id);
    1004                 :             : 
    1005                 :             :         ret = mbedtls_snprintf(p, n, " (%s, MGF1-%s, 0x%02X)",
    1006                 :             :                                name ? name : "???",
    1007                 :             :                                mgf_name ? mgf_name : "???",
    1008                 :             :                                (unsigned int) pss_opts->expected_salt_len);
    1009                 :             :         MBEDTLS_X509_SAFE_SNPRINTF;
    1010                 :             :     }
    1011                 :             : #else
    1012                 :           0 :     ((void) pk_alg);
    1013                 :           0 :     ((void) md_alg);
    1014                 :           0 :     ((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                 :           0 : int mbedtls_x509_time_cmp(const mbedtls_x509_time *t1,
    1037                 :             :                           const mbedtls_x509_time *t2)
    1038                 :             : {
    1039                 :           0 :     int x;
    1040                 :             : 
    1041                 :           0 :     x = (((t1->year << 9) | (t1->mon << 5) | (t1->day)) -
    1042                 :           0 :          ((t2->year << 9) | (t2->mon << 5) | (t2->day)));
    1043         [ #  # ]:           0 :     if (x != 0) {
    1044                 :             :         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                 :             : int mbedtls_x509_time_gmtime(mbedtls_time_t tt, mbedtls_x509_time *now)
    1054                 :             : {
    1055                 :             :     struct tm tm;
    1056                 :             : 
    1057                 :             :     if (mbedtls_platform_gmtime_r(&tt, &tm) == NULL) {
    1058                 :             :         return -1;
    1059                 :             :     }
    1060                 :             : 
    1061                 :             :     now->year = tm.tm_year + 1900;
    1062                 :             :     now->mon  = tm.tm_mon  + 1;
    1063                 :             :     now->day  = tm.tm_mday;
    1064                 :             :     now->hour = tm.tm_hour;
    1065                 :             :     now->min  = tm.tm_min;
    1066                 :             :     now->sec  = tm.tm_sec;
    1067                 :             :     return 0;
    1068                 :             : }
    1069                 :             : 
    1070                 :             : static int x509_get_current_time(mbedtls_x509_time *now)
    1071                 :             : {
    1072                 :             :     return mbedtls_x509_time_gmtime(mbedtls_time(NULL), now);
    1073                 :             : }
    1074                 :             : 
    1075                 :             : int mbedtls_x509_time_is_past(const mbedtls_x509_time *to)
    1076                 :             : {
    1077                 :             :     mbedtls_x509_time now;
    1078                 :             : 
    1079                 :             :     if (x509_get_current_time(&now) != 0) {
    1080                 :             :         return 1;
    1081                 :             :     }
    1082                 :             : 
    1083                 :             :     return mbedtls_x509_time_cmp(to, &now) < 0;
    1084                 :             : }
    1085                 :             : 
    1086                 :             : int mbedtls_x509_time_is_future(const mbedtls_x509_time *from)
    1087                 :             : {
    1088                 :             :     mbedtls_x509_time now;
    1089                 :             : 
    1090                 :             :     if (x509_get_current_time(&now) != 0) {
    1091                 :             :         return 1;
    1092                 :             :     }
    1093                 :             : 
    1094                 :             :     return mbedtls_x509_time_cmp(from, &now) > 0;
    1095                 :             : }
    1096                 :             : 
    1097                 :             : #else  /* MBEDTLS_HAVE_TIME_DATE */
    1098                 :             : 
    1099                 :           0 : int mbedtls_x509_time_is_past(const mbedtls_x509_time *to)
    1100                 :             : {
    1101                 :           0 :     ((void) to);
    1102                 :           0 :     return 0;
    1103                 :             : }
    1104                 :             : 
    1105                 :           0 : int mbedtls_x509_time_is_future(const mbedtls_x509_time *from)
    1106                 :             : {
    1107                 :           0 :     ((void) from);
    1108                 :           0 :     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                 :           0 : static int x509_get_other_name(const mbedtls_x509_buf *subject_alt_name,
    1127                 :             :                                mbedtls_x509_san_other_name *other_name)
    1128                 :             : {
    1129                 :           0 :     int ret = 0;
    1130                 :           0 :     size_t len;
    1131                 :           0 :     unsigned char *p = subject_alt_name->p;
    1132                 :           0 :     const unsigned char *end = p + subject_alt_name->len;
    1133                 :           0 :     mbedtls_x509_buf cur_oid;
    1134                 :             : 
    1135         [ #  # ]:           0 :     if ((subject_alt_name->tag &
    1136                 :             :          (MBEDTLS_ASN1_TAG_CLASS_MASK | MBEDTLS_ASN1_TAG_VALUE_MASK)) !=
    1137                 :             :         (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_OTHER_NAME)) {
    1138                 :             :         /*
    1139                 :             :          * The given subject alternative name is not of type "othername".
    1140                 :             :          */
    1141                 :             :         return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
    1142                 :             :     }
    1143                 :             : 
    1144         [ #  # ]:           0 :     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                 :           0 :     cur_oid.tag = MBEDTLS_ASN1_OID;
    1150                 :           0 :     cur_oid.p = p;
    1151                 :           0 :     cur_oid.len = len;
    1152                 :             : 
    1153                 :             :     /*
    1154                 :             :      * Only HwModuleName is currently supported.
    1155                 :             :      */
    1156   [ #  #  #  # ]:           0 :     if (MBEDTLS_OID_CMP(MBEDTLS_OID_ON_HW_MODULE_NAME, &cur_oid) != 0) {
    1157                 :             :         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                 :             :     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                 :           0 : 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                 :           0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1218                 :           0 :     size_t tag_len;
    1219                 :           0 :     mbedtls_asn1_sequence *cur = subject_alt_name;
    1220                 :             : 
    1221         [ #  # ]:           0 :     while (*p < end) {
    1222                 :           0 :         mbedtls_x509_subject_alternative_name tmp_san_name;
    1223                 :           0 :         mbedtls_x509_buf tmp_san_buf;
    1224                 :           0 :         memset(&tmp_san_name, 0, sizeof(tmp_san_name));
    1225                 :             : 
    1226                 :           0 :         tmp_san_buf.tag = **p;
    1227                 :           0 :         (*p)++;
    1228                 :             : 
    1229         [ #  # ]:           0 :         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                 :           0 :         tmp_san_buf.p = *p;
    1234                 :           0 :         tmp_san_buf.len = tag_len;
    1235                 :             : 
    1236         [ #  # ]:           0 :         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                 :           0 :         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         [ #  # ]:           0 :         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                 :           0 :         mbedtls_x509_free_subject_alt_name(&tmp_san_name);
    1258                 :             :         /* Allocate and assign next pointer */
    1259         [ #  # ]:           0 :         if (cur->buf.p != NULL) {
    1260         [ #  # ]:           0 :             if (cur->next != NULL) {
    1261                 :             :                 return MBEDTLS_ERR_X509_INVALID_EXTENSIONS;
    1262                 :             :             }
    1263                 :             : 
    1264                 :           0 :             cur->next = mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence));
    1265                 :             : 
    1266         [ #  # ]:           0 :             if (cur->next == NULL) {
    1267                 :           0 :                 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
    1268                 :             :                                          MBEDTLS_ERR_ASN1_ALLOC_FAILED);
    1269                 :             :             }
    1270                 :             : 
    1271                 :             :             cur = cur->next;
    1272                 :             :         }
    1273                 :             : 
    1274                 :           0 :         cur->buf = tmp_san_buf;
    1275                 :           0 :         *p += tmp_san_buf.len;
    1276                 :             :     }
    1277                 :             : 
    1278                 :             :     /* Set final sequence entry's next pointer to NULL */
    1279                 :           0 :     cur->next = NULL;
    1280                 :             : 
    1281         [ #  # ]:           0 :     if (*p != end) {
    1282                 :           0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
    1283                 :             :                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
    1284                 :             :     }
    1285                 :             : 
    1286                 :             :     return 0;
    1287                 :             : }
    1288                 :             : 
    1289                 :             : /*
    1290                 :             :  * SubjectAltName ::= GeneralNames
    1291                 :             :  *
    1292                 :             :  * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
    1293                 :             :  *
    1294                 :             :  * GeneralName ::= CHOICE {
    1295                 :             :  *      otherName                       [0]     OtherName,
    1296                 :             :  *      rfc822Name                      [1]     IA5String,
    1297                 :             :  *      dNSName                         [2]     IA5String,
    1298                 :             :  *      x400Address                     [3]     ORAddress,
    1299                 :             :  *      directoryName                   [4]     Name,
    1300                 :             :  *      ediPartyName                    [5]     EDIPartyName,
    1301                 :             :  *      uniformResourceIdentifier       [6]     IA5String,
    1302                 :             :  *      iPAddress                       [7]     OCTET STRING,
    1303                 :             :  *      registeredID                    [8]     OBJECT IDENTIFIER }
    1304                 :             :  *
    1305                 :             :  * OtherName ::= SEQUENCE {
    1306                 :             :  *      type-id    OBJECT IDENTIFIER,
    1307                 :             :  *      value      [0] EXPLICIT ANY DEFINED BY type-id }
    1308                 :             :  *
    1309                 :             :  * EDIPartyName ::= SEQUENCE {
    1310                 :             :  *      nameAssigner            [0]     DirectoryString OPTIONAL,
    1311                 :             :  *      partyName               [1]     DirectoryString }
    1312                 :             :  *
    1313                 :             :  * We list all types, but use the following GeneralName types from RFC 5280:
    1314                 :             :  * "dnsName", "uniformResourceIdentifier" and "hardware_module_name"
    1315                 :             :  * of type "otherName", as defined in RFC 4108.
    1316                 :             :  */
    1317                 :           0 : int mbedtls_x509_get_subject_alt_name(unsigned char **p,
    1318                 :             :                                       const unsigned char *end,
    1319                 :             :                                       mbedtls_x509_sequence *subject_alt_name)
    1320                 :             : {
    1321                 :           0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1322                 :           0 :     size_t len;
    1323                 :             : 
    1324                 :             :     /* Get main sequence tag */
    1325         [ #  # ]:           0 :     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         [ #  # ]:           0 :     if (*p + len != end) {
    1331                 :           0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
    1332                 :             :                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
    1333                 :             :     }
    1334                 :             : 
    1335                 :           0 :     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                 :           0 : int mbedtls_x509_get_key_usage(unsigned char **p,
    1367                 :             :                                const unsigned char *end,
    1368                 :             :                                unsigned int *key_usage)
    1369                 :             : {
    1370                 :           0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1371                 :           0 :     size_t i;
    1372                 :           0 :     mbedtls_x509_bitstring bs = { 0, 0, NULL };
    1373                 :             : 
    1374         [ #  # ]:           0 :     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         [ #  # ]:           0 :     if (bs.len == 0) {
    1381                 :           0 :         *key_usage = 0;
    1382                 :           0 :         return 0;
    1383                 :             :     }
    1384                 :             : 
    1385                 :             :     /* Get actual bitstring */
    1386                 :           0 :     *key_usage = 0;
    1387   [ #  #  #  # ]:           0 :     for (i = 0; i < bs.len && i < sizeof(unsigned int); i++) {
    1388                 :           0 :         *key_usage |= (unsigned int) bs.p[i] << (8*i);
    1389                 :             :     }
    1390                 :             : 
    1391                 :             :     return 0;
    1392                 :             : }
    1393                 :             : 
    1394                 :           0 : int mbedtls_x509_parse_subject_alt_name(const mbedtls_x509_buf *san_buf,
    1395                 :             :                                         mbedtls_x509_subject_alternative_name *san)
    1396                 :             : {
    1397                 :           0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1398   [ #  #  #  #  :           0 :     switch (san_buf->tag &
                #  #  # ]
    1399                 :             :             (MBEDTLS_ASN1_TAG_CLASS_MASK |
    1400                 :             :              MBEDTLS_ASN1_TAG_VALUE_MASK)) {
    1401                 :             :         /*
    1402                 :             :          * otherName
    1403                 :             :          */
    1404                 :           0 :         case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_OTHER_NAME):
    1405                 :             :         {
    1406                 :           0 :             mbedtls_x509_san_other_name other_name;
    1407                 :             : 
    1408                 :           0 :             ret = x509_get_other_name(san_buf, &other_name);
    1409         [ #  # ]:           0 :             if (ret != 0) {
    1410                 :           0 :                 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                 :             :         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                 :             :         case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_DNS_NAME):
    1437                 :             :         {
    1438                 :           0 :             memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name));
    1439                 :           0 :             san->type = MBEDTLS_X509_SAN_DNS_NAME;
    1440                 :             : 
    1441                 :           0 :             memcpy(&san->san.unstructured_name,
    1442                 :             :                    san_buf, sizeof(*san_buf));
    1443                 :             :         }
    1444                 :           0 :         break;
    1445                 :             :         /*
    1446                 :             :          * IP address
    1447                 :             :          */
    1448                 :             :         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                 :             :                 return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
    1458                 :             :             }
    1459                 :             :         }
    1460                 :           0 :         break;
    1461                 :             :         /*
    1462                 :             :          * rfc822Name
    1463                 :             :          */
    1464                 :             :         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                 :           0 :             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                 :             :                 return ret;
    1491                 :             :             }
    1492                 :             :         }
    1493                 :           0 :         break;
    1494                 :             :         /*
    1495                 :             :          * Type not supported
    1496                 :             :          */
    1497                 :             :         default:
    1498                 :             :             return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
    1499                 :             :     }
    1500                 :             :     return 0;
    1501                 :             : }
    1502                 :             : 
    1503                 :           0 : void mbedtls_x509_free_subject_alt_name(mbedtls_x509_subject_alternative_name *san)
    1504                 :             : {
    1505         [ #  # ]:           0 :     if (san->type == MBEDTLS_X509_SAN_DIRECTORY_NAME) {
    1506                 :           0 :         mbedtls_asn1_free_named_data_list_shallow(san->san.directory_name.next);
    1507                 :             :     }
    1508                 :           0 : }
    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                 :           0 :     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                 :           0 :     mbedtls_x509_subject_alternative_name san;
    1522                 :           0 :     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         [ #  # ]:           0 :                     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                 :             :                                                          &other_name->value.hardware_module_name.oid);
    1561         [ #  # ]:           0 :                     MBEDTLS_X509_SAFE_SNPRINTF;
    1562                 :             : 
    1563         [ #  # ]:           0 :                     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                 :             :             break;
    1577                 :             :             /*
    1578                 :             :              * uniformResourceIdentifier
    1579                 :             :              */
    1580                 :             :             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                 :             :                                        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                 :             :             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                 :             :             break;
    1659                 :             :             /*
    1660                 :             :              * directoryName
    1661                 :             :              */
    1662                 :             :             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                 :             :             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