LCOV - code coverage report
Current view: top level - externals/mbedtls/library - x509_crt.c (source / functions) Coverage Total Hit
Test: lcov.info Lines: 13.9 % 796 111
Test Date: 2026-01-29 09:48:10 Functions: 17.6 % 51 9
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 7.7 % 647 50

             Branch data     Line data    Source code
       1                 :             : /*
       2                 :             :  *  X.509 certificate 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                 :             :  *  [SIRO] https://cabforum.org/wp-content/uploads/Chunghwatelecom201503cabforumV4.pdf
      18                 :             :  */
      19                 :             : 
      20                 :             : #include "common.h"
      21                 :             : 
      22                 :             : #if defined(MBEDTLS_X509_CRT_PARSE_C)
      23                 :             : 
      24                 :             : #include "mbedtls/x509_crt.h"
      25                 :             : #include "x509_internal.h"
      26                 :             : #include "mbedtls/error.h"
      27                 :             : #include "mbedtls/oid.h"
      28                 :             : #include "mbedtls/platform_util.h"
      29                 :             : 
      30                 :             : #include <string.h>
      31                 :             : 
      32                 :             : #if defined(MBEDTLS_PEM_PARSE_C)
      33                 :             : #include "mbedtls/pem.h"
      34                 :             : #endif
      35                 :             : 
      36                 :             : #if defined(MBEDTLS_USE_PSA_CRYPTO)
      37                 :             : #include "psa/crypto.h"
      38                 :             : #include "psa_util_internal.h"
      39                 :             : #include "mbedtls/psa_util.h"
      40                 :             : #endif /* MBEDTLS_USE_PSA_CRYPTO */
      41                 :             : #include "pk_internal.h"
      42                 :             : 
      43                 :             : #include "mbedtls/platform.h"
      44                 :             : 
      45                 :             : #if defined(MBEDTLS_THREADING_C)
      46                 :             : #include "mbedtls/threading.h"
      47                 :             : #endif
      48                 :             : 
      49                 :             : #if defined(MBEDTLS_HAVE_TIME)
      50                 :             : #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
      51                 :             : #ifndef WIN32_LEAN_AND_MEAN
      52                 :             : #define WIN32_LEAN_AND_MEAN
      53                 :             : #endif
      54                 :             : #include <windows.h>
      55                 :             : #else
      56                 :             : #include <time.h>
      57                 :             : #endif
      58                 :             : #endif
      59                 :             : 
      60                 :             : #if defined(MBEDTLS_FS_IO)
      61                 :             : #include <stdio.h>
      62                 :             : #if !defined(_WIN32) || defined(EFIX64) || defined(EFI32)
      63                 :             : #include <sys/types.h>
      64                 :             : #include <sys/stat.h>
      65                 :             : #if defined(__MBED__)
      66                 :             : #include <platform/mbed_retarget.h>
      67                 :             : #else
      68                 :             : #include <dirent.h>
      69                 :             : #endif /* __MBED__ */
      70                 :             : #include <errno.h>
      71                 :             : #endif /* !_WIN32 || EFIX64 || EFI32 */
      72                 :             : #endif
      73                 :             : 
      74                 :             : /*
      75                 :             :  * Item in a verification chain: cert and flags for it
      76                 :             :  */
      77                 :             : typedef struct {
      78                 :             :     mbedtls_x509_crt *crt;
      79                 :             :     uint32_t flags;
      80                 :             : } x509_crt_verify_chain_item;
      81                 :             : 
      82                 :             : /*
      83                 :             :  * Max size of verification chain: end-entity + intermediates + trusted root
      84                 :             :  */
      85                 :             : #define X509_MAX_VERIFY_CHAIN_SIZE    (MBEDTLS_X509_MAX_INTERMEDIATE_CA + 2)
      86                 :             : 
      87                 :             : /* Default profile. Do not remove items unless there are serious security
      88                 :             :  * concerns. */
      89                 :             : const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default =
      90                 :             : {
      91                 :             :     /* Hashes from SHA-256 and above. Note that this selection
      92                 :             :      * should be aligned with ssl_preset_default_hashes in ssl_tls.c. */
      93                 :             :     MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA256) |
      94                 :             :     MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA384) |
      95                 :             :     MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA512),
      96                 :             :     0xFFFFFFF, /* Any PK alg    */
      97                 :             : #if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
      98                 :             :     /* Curves at or above 128-bit security level. Note that this selection
      99                 :             :      * should be aligned with ssl_preset_default_curves in ssl_tls.c. */
     100                 :             :     MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP256R1) |
     101                 :             :     MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP384R1) |
     102                 :             :     MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP521R1) |
     103                 :             :     MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_BP256R1) |
     104                 :             :     MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_BP384R1) |
     105                 :             :     MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_BP512R1) |
     106                 :             :     0,
     107                 :             : #else /* MBEDTLS_PK_HAVE_ECC_KEYS */
     108                 :             :     0,
     109                 :             : #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
     110                 :             :     2048,
     111                 :             : };
     112                 :             : 
     113                 :             : /* Next-generation profile. Currently identical to the default, but may
     114                 :             :  * be tightened at any time. */
     115                 :             : const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_next =
     116                 :             : {
     117                 :             :     /* Hashes from SHA-256 and above. */
     118                 :             :     MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA256) |
     119                 :             :     MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA384) |
     120                 :             :     MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA512),
     121                 :             :     0xFFFFFFF, /* Any PK alg    */
     122                 :             : #if defined(MBEDTLS_ECP_C)
     123                 :             :     /* Curves at or above 128-bit security level. */
     124                 :             :     MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP256R1) |
     125                 :             :     MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP384R1) |
     126                 :             :     MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP521R1) |
     127                 :             :     MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_BP256R1) |
     128                 :             :     MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_BP384R1) |
     129                 :             :     MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_BP512R1) |
     130                 :             :     MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP256K1),
     131                 :             : #else
     132                 :             :     0,
     133                 :             : #endif
     134                 :             :     2048,
     135                 :             : };
     136                 :             : 
     137                 :             : /*
     138                 :             :  * NSA Suite B Profile
     139                 :             :  */
     140                 :             : const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb =
     141                 :             : {
     142                 :             :     /* Only SHA-256 and 384 */
     143                 :             :     MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA256) |
     144                 :             :     MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA384),
     145                 :             :     /* Only ECDSA */
     146                 :             :     MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_ECDSA) |
     147                 :             :     MBEDTLS_X509_ID_FLAG(MBEDTLS_PK_ECKEY),
     148                 :             : #if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
     149                 :             :     /* Only NIST P-256 and P-384 */
     150                 :             :     MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP256R1) |
     151                 :             :     MBEDTLS_X509_ID_FLAG(MBEDTLS_ECP_DP_SECP384R1),
     152                 :             : #else /* MBEDTLS_PK_HAVE_ECC_KEYS */
     153                 :             :     0,
     154                 :             : #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
     155                 :             :     0,
     156                 :             : };
     157                 :             : 
     158                 :             : /*
     159                 :             :  * Empty / all-forbidden profile
     160                 :             :  */
     161                 :             : const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_none =
     162                 :             : {
     163                 :             :     0,
     164                 :             :     0,
     165                 :             :     0,
     166                 :             :     (uint32_t) -1,
     167                 :             : };
     168                 :             : 
     169                 :             : /*
     170                 :             :  * Check md_alg against profile
     171                 :             :  * Return 0 if md_alg is acceptable for this profile, -1 otherwise
     172                 :             :  */
     173                 :           0 : static int x509_profile_check_md_alg(const mbedtls_x509_crt_profile *profile,
     174                 :             :                                      mbedtls_md_type_t md_alg)
     175                 :             : {
     176         [ #  # ]:           0 :     if (md_alg == MBEDTLS_MD_NONE) {
     177                 :             :         return -1;
     178                 :             :     }
     179                 :             : 
     180         [ #  # ]:           0 :     if ((profile->allowed_mds & MBEDTLS_X509_ID_FLAG(md_alg)) != 0) {
     181                 :           0 :         return 0;
     182                 :             :     }
     183                 :             : 
     184                 :             :     return -1;
     185                 :             : }
     186                 :             : 
     187                 :             : /*
     188                 :             :  * Check pk_alg against profile
     189                 :             :  * Return 0 if pk_alg is acceptable for this profile, -1 otherwise
     190                 :             :  */
     191                 :           0 : static int x509_profile_check_pk_alg(const mbedtls_x509_crt_profile *profile,
     192                 :             :                                      mbedtls_pk_type_t pk_alg)
     193                 :             : {
     194         [ #  # ]:           0 :     if (pk_alg == MBEDTLS_PK_NONE) {
     195                 :             :         return -1;
     196                 :             :     }
     197                 :             : 
     198         [ #  # ]:           0 :     if ((profile->allowed_pks & MBEDTLS_X509_ID_FLAG(pk_alg)) != 0) {
     199                 :           0 :         return 0;
     200                 :             :     }
     201                 :             : 
     202                 :             :     return -1;
     203                 :             : }
     204                 :             : 
     205                 :             : /*
     206                 :             :  * Check key against profile
     207                 :             :  * Return 0 if pk is acceptable for this profile, -1 otherwise
     208                 :             :  */
     209                 :           0 : static int x509_profile_check_key(const mbedtls_x509_crt_profile *profile,
     210                 :             :                                   const mbedtls_pk_context *pk)
     211                 :             : {
     212                 :           0 :     const mbedtls_pk_type_t pk_alg = mbedtls_pk_get_type(pk);
     213                 :             : 
     214                 :             : #if defined(MBEDTLS_RSA_C)
     215                 :             :     if (pk_alg == MBEDTLS_PK_RSA || pk_alg == MBEDTLS_PK_RSASSA_PSS) {
     216                 :             :         if (mbedtls_pk_get_bitlen(pk) >= profile->rsa_min_bitlen) {
     217                 :             :             return 0;
     218                 :             :         }
     219                 :             : 
     220                 :             :         return -1;
     221                 :             :     }
     222                 :             : #endif /* MBEDTLS_RSA_C */
     223                 :             : 
     224                 :             : #if defined(MBEDTLS_PK_HAVE_ECC_KEYS)
     225                 :           0 :     if (pk_alg == MBEDTLS_PK_ECDSA ||
     226   [ #  #  #  # ]:           0 :         pk_alg == MBEDTLS_PK_ECKEY ||
     227                 :             :         pk_alg == MBEDTLS_PK_ECKEY_DH) {
     228                 :           0 :         const mbedtls_ecp_group_id gid = mbedtls_pk_get_ec_group_id(pk);
     229                 :             : 
     230         [ #  # ]:           0 :         if (gid == MBEDTLS_ECP_DP_NONE) {
     231                 :             :             return -1;
     232                 :             :         }
     233                 :             : 
     234         [ #  # ]:           0 :         if ((profile->allowed_curves & MBEDTLS_X509_ID_FLAG(gid)) != 0) {
     235                 :             :             return 0;
     236                 :             :         }
     237                 :             : 
     238                 :             :         return -1;
     239                 :             :     }
     240                 :             : #endif /* MBEDTLS_PK_HAVE_ECC_KEYS */
     241                 :             : 
     242                 :             :     return -1;
     243                 :             : }
     244                 :             : 
     245                 :             : /*
     246                 :             :  * Like memcmp, but case-insensitive and always returns -1 if different
     247                 :             :  */
     248                 :           0 : static int x509_memcasecmp(const void *s1, const void *s2, size_t len)
     249                 :             : {
     250                 :           0 :     size_t i;
     251                 :           0 :     unsigned char diff;
     252                 :           0 :     const unsigned char *n1 = s1, *n2 = s2;
     253                 :             : 
     254         [ #  # ]:           0 :     for (i = 0; i < len; i++) {
     255                 :           0 :         diff = n1[i] ^ n2[i];
     256                 :             : 
     257         [ #  # ]:           0 :         if (diff == 0) {
     258                 :           0 :             continue;
     259                 :             :         }
     260                 :             : 
     261         [ #  # ]:           0 :         if (diff == 32 &&
     262         [ #  # ]:           0 :             ((n1[i] >= 'a' && n1[i] <= 'z') ||
     263                 :             :              (n1[i] >= 'A' && n1[i] <= 'Z'))) {
     264                 :           0 :             continue;
     265                 :             :         }
     266                 :             : 
     267                 :             :         return -1;
     268                 :             :     }
     269                 :             : 
     270                 :             :     return 0;
     271                 :             : }
     272                 :             : 
     273                 :             : /*
     274                 :             :  * Return 0 if name matches wildcard, -1 otherwise
     275                 :             :  */
     276                 :           0 : static int x509_check_wildcard(const char *cn, const mbedtls_x509_buf *name)
     277                 :             : {
     278                 :           0 :     size_t i;
     279                 :           0 :     size_t cn_idx = 0, cn_len = strlen(cn);
     280                 :             : 
     281                 :             :     /* We can't have a match if there is no wildcard to match */
     282   [ #  #  #  #  :           0 :     if (name->len < 3 || name->p[0] != '*' || name->p[1] != '.') {
                   #  # ]
     283                 :             :         return -1;
     284                 :             :     }
     285                 :             : 
     286         [ #  # ]:           0 :     for (i = 0; i < cn_len; ++i) {
     287         [ #  # ]:           0 :         if (cn[i] == '.') {
     288                 :             :             cn_idx = i;
     289                 :             :             break;
     290                 :             :         }
     291                 :             :     }
     292                 :             : 
     293         [ #  # ]:           0 :     if (cn_idx == 0) {
     294                 :             :         return -1;
     295                 :             :     }
     296                 :             : 
     297         [ #  # ]:           0 :     if (cn_len - cn_idx == name->len - 1 &&
     298         [ #  # ]:           0 :         x509_memcasecmp(name->p + 1, cn + cn_idx, name->len - 1) == 0) {
     299                 :           0 :         return 0;
     300                 :             :     }
     301                 :             : 
     302                 :             :     return -1;
     303                 :             : }
     304                 :             : 
     305                 :             : /*
     306                 :             :  * Compare two X.509 strings, case-insensitive, and allowing for some encoding
     307                 :             :  * variations (but not all).
     308                 :             :  *
     309                 :             :  * Return 0 if equal, -1 otherwise.
     310                 :             :  */
     311                 :           0 : static int x509_string_cmp(const mbedtls_x509_buf *a, const mbedtls_x509_buf *b)
     312                 :             : {
     313         [ #  # ]:           0 :     if (a->tag == b->tag &&
     314         [ #  # ]:           0 :         a->len == b->len &&
     315         [ #  # ]:           0 :         memcmp(a->p, b->p, b->len) == 0) {
     316                 :             :         return 0;
     317                 :             :     }
     318                 :             : 
     319         [ #  # ]:           0 :     if ((a->tag == MBEDTLS_ASN1_UTF8_STRING || a->tag == MBEDTLS_ASN1_PRINTABLE_STRING) &&
     320         [ #  # ]:           0 :         (b->tag == MBEDTLS_ASN1_UTF8_STRING || b->tag == MBEDTLS_ASN1_PRINTABLE_STRING) &&
     321         [ #  # ]:           0 :         a->len == b->len &&
     322         [ #  # ]:           0 :         x509_memcasecmp(a->p, b->p, b->len) == 0) {
     323                 :           0 :         return 0;
     324                 :             :     }
     325                 :             : 
     326                 :             :     return -1;
     327                 :             : }
     328                 :             : 
     329                 :             : /*
     330                 :             :  * Compare two X.509 Names (aka rdnSequence).
     331                 :             :  *
     332                 :             :  * See RFC 5280 section 7.1, though we don't implement the whole algorithm:
     333                 :             :  * we sometimes return unequal when the full algorithm would return equal,
     334                 :             :  * but never the other way. (In particular, we don't do Unicode normalisation
     335                 :             :  * or space folding.)
     336                 :             :  *
     337                 :             :  * Return 0 if equal, -1 otherwise.
     338                 :             :  */
     339                 :           0 : static int x509_name_cmp(const mbedtls_x509_name *a, const mbedtls_x509_name *b)
     340                 :             : {
     341                 :             :     /* Avoid recursion, it might not be optimised by the compiler */
     342         [ #  # ]:           0 :     while (a != NULL || b != NULL) {
     343         [ #  # ]:           0 :         if (a == NULL || b == NULL) {
     344                 :             :             return -1;
     345                 :             :         }
     346                 :             : 
     347                 :             :         /* type */
     348         [ #  # ]:           0 :         if (a->oid.tag != b->oid.tag ||
     349         [ #  # ]:           0 :             a->oid.len != b->oid.len ||
     350         [ #  # ]:           0 :             memcmp(a->oid.p, b->oid.p, b->oid.len) != 0) {
     351                 :             :             return -1;
     352                 :             :         }
     353                 :             : 
     354                 :             :         /* value */
     355         [ #  # ]:           0 :         if (x509_string_cmp(&a->val, &b->val) != 0) {
     356                 :             :             return -1;
     357                 :             :         }
     358                 :             : 
     359                 :             :         /* structure of the list of sets */
     360         [ #  # ]:           0 :         if (a->next_merged != b->next_merged) {
     361                 :             :             return -1;
     362                 :             :         }
     363                 :             : 
     364                 :           0 :         a = a->next;
     365                 :           0 :         b = b->next;
     366                 :             :     }
     367                 :             : 
     368                 :             :     /* a == NULL == b */
     369                 :             :     return 0;
     370                 :             : }
     371                 :             : 
     372                 :             : /*
     373                 :             :  * Reset (init or clear) a verify_chain
     374                 :             :  */
     375                 :           0 : static void x509_crt_verify_chain_reset(
     376                 :             :     mbedtls_x509_crt_verify_chain *ver_chain)
     377                 :             : {
     378                 :           0 :     size_t i;
     379                 :             : 
     380         [ #  # ]:           0 :     for (i = 0; i < MBEDTLS_X509_MAX_VERIFY_CHAIN_SIZE; i++) {
     381                 :           0 :         ver_chain->items[i].crt = NULL;
     382                 :           0 :         ver_chain->items[i].flags = (uint32_t) -1;
     383                 :             :     }
     384                 :             : 
     385                 :           0 :     ver_chain->len = 0;
     386                 :             : 
     387                 :             : #if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
     388                 :             :     ver_chain->trust_ca_cb_result = NULL;
     389                 :             : #endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
     390                 :           0 : }
     391                 :             : 
     392                 :             : /*
     393                 :             :  *  Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
     394                 :             :  */
     395                 :           4 : static int x509_get_version(unsigned char **p,
     396                 :             :                             const unsigned char *end,
     397                 :             :                             int *ver)
     398                 :             : {
     399                 :           4 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     400                 :           4 :     size_t len;
     401                 :             : 
     402         [ -  + ]:           4 :     if ((ret = mbedtls_asn1_get_tag(p, end, &len,
     403                 :             :                                     MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED |
     404                 :             :                                     0)) != 0) {
     405         [ #  # ]:           0 :         if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
     406                 :           0 :             *ver = 0;
     407                 :           0 :             return 0;
     408                 :             :         }
     409                 :             : 
     410                 :           0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret);
     411                 :             :     }
     412                 :             : 
     413                 :           4 :     end = *p + len;
     414                 :             : 
     415         [ -  + ]:           4 :     if ((ret = mbedtls_asn1_get_int(p, end, ver)) != 0) {
     416                 :           0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_VERSION, ret);
     417                 :             :     }
     418                 :             : 
     419         [ +  - ]:           4 :     if (*p != end) {
     420                 :           0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_VERSION,
     421                 :             :                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
     422                 :             :     }
     423                 :             : 
     424                 :             :     return 0;
     425                 :             : }
     426                 :             : 
     427                 :             : /*
     428                 :             :  *  Validity ::= SEQUENCE {
     429                 :             :  *       notBefore      Time,
     430                 :             :  *       notAfter       Time }
     431                 :             :  */
     432                 :           4 : static int x509_get_dates(unsigned char **p,
     433                 :             :                           const unsigned char *end,
     434                 :             :                           mbedtls_x509_time *from,
     435                 :             :                           mbedtls_x509_time *to)
     436                 :             : {
     437                 :           4 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     438                 :           4 :     size_t len;
     439                 :             : 
     440         [ -  + ]:           4 :     if ((ret = mbedtls_asn1_get_tag(p, end, &len,
     441                 :             :                                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
     442                 :           0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_DATE, ret);
     443                 :             :     }
     444                 :             : 
     445                 :           4 :     end = *p + len;
     446                 :             : 
     447         [ +  - ]:           4 :     if ((ret = mbedtls_x509_get_time(p, end, from)) != 0) {
     448                 :             :         return ret;
     449                 :             :     }
     450                 :             : 
     451         [ +  - ]:           4 :     if ((ret = mbedtls_x509_get_time(p, end, to)) != 0) {
     452                 :             :         return ret;
     453                 :             :     }
     454                 :             : 
     455         [ -  + ]:           4 :     if (*p != end) {
     456                 :           0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_DATE,
     457                 :             :                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
     458                 :             :     }
     459                 :             : 
     460                 :             :     return 0;
     461                 :             : }
     462                 :             : 
     463                 :             : /*
     464                 :             :  * X.509 v2/v3 unique identifier (not parsed)
     465                 :             :  */
     466                 :           8 : static int x509_get_uid(unsigned char **p,
     467                 :             :                         const unsigned char *end,
     468                 :             :                         mbedtls_x509_buf *uid, int n)
     469                 :             : {
     470                 :           8 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     471                 :             : 
     472         [ +  - ]:           8 :     if (*p == end) {
     473                 :             :         return 0;
     474                 :             :     }
     475                 :             : 
     476                 :           0 :     uid->tag = **p;
     477                 :             : 
     478         [ #  # ]:           0 :     if ((ret = mbedtls_asn1_get_tag(p, end, &uid->len,
     479                 :             :                                     MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED |
     480                 :             :                                     n)) != 0) {
     481         [ #  # ]:           0 :         if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
     482                 :             :             return 0;
     483                 :             :         }
     484                 :             : 
     485                 :           0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret);
     486                 :             :     }
     487                 :             : 
     488                 :           0 :     uid->p = *p;
     489                 :           0 :     *p += uid->len;
     490                 :             : 
     491                 :           0 :     return 0;
     492                 :             : }
     493                 :             : 
     494                 :           0 : static int x509_get_basic_constraints(unsigned char **p,
     495                 :             :                                       const unsigned char *end,
     496                 :             :                                       int *ca_istrue,
     497                 :             :                                       int *max_pathlen)
     498                 :             : {
     499                 :           0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     500                 :           0 :     size_t len;
     501                 :             : 
     502                 :             :     /*
     503                 :             :      * BasicConstraints ::= SEQUENCE {
     504                 :             :      *      cA                      BOOLEAN DEFAULT FALSE,
     505                 :             :      *      pathLenConstraint       INTEGER (0..MAX) OPTIONAL }
     506                 :             :      */
     507                 :           0 :     *ca_istrue = 0; /* DEFAULT FALSE */
     508                 :           0 :     *max_pathlen = 0; /* endless */
     509                 :             : 
     510         [ #  # ]:           0 :     if ((ret = mbedtls_asn1_get_tag(p, end, &len,
     511                 :             :                                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
     512                 :           0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
     513                 :             :     }
     514                 :             : 
     515         [ #  # ]:           0 :     if (*p == end) {
     516                 :             :         return 0;
     517                 :             :     }
     518                 :             : 
     519         [ #  # ]:           0 :     if ((ret = mbedtls_asn1_get_bool(p, end, ca_istrue)) != 0) {
     520         [ #  # ]:           0 :         if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
     521                 :           0 :             ret = mbedtls_asn1_get_int(p, end, ca_istrue);
     522                 :             :         }
     523                 :             : 
     524         [ #  # ]:           0 :         if (ret != 0) {
     525                 :           0 :             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
     526                 :             :         }
     527                 :             : 
     528         [ #  # ]:           0 :         if (*ca_istrue != 0) {
     529                 :           0 :             *ca_istrue = 1;
     530                 :             :         }
     531                 :             :     }
     532                 :             : 
     533         [ #  # ]:           0 :     if (*p == end) {
     534                 :             :         return 0;
     535                 :             :     }
     536                 :             : 
     537         [ #  # ]:           0 :     if ((ret = mbedtls_asn1_get_int(p, end, max_pathlen)) != 0) {
     538                 :           0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
     539                 :             :     }
     540                 :             : 
     541         [ #  # ]:           0 :     if (*p != end) {
     542                 :           0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
     543                 :             :                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
     544                 :             :     }
     545                 :             : 
     546                 :             :     /* Do not accept max_pathlen equal to INT_MAX to avoid a signed integer
     547                 :             :      * overflow, which is an undefined behavior. */
     548         [ #  # ]:           0 :     if (*max_pathlen == INT_MAX) {
     549                 :           0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
     550                 :             :                                  MBEDTLS_ERR_ASN1_INVALID_LENGTH);
     551                 :             :     }
     552                 :             : 
     553                 :           0 :     (*max_pathlen)++;
     554                 :             : 
     555                 :           0 :     return 0;
     556                 :             : }
     557                 :             : 
     558                 :             : /*
     559                 :             :  * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
     560                 :             :  *
     561                 :             :  * KeyPurposeId ::= OBJECT IDENTIFIER
     562                 :             :  */
     563                 :           0 : static int x509_get_ext_key_usage(unsigned char **p,
     564                 :             :                                   const unsigned char *end,
     565                 :             :                                   mbedtls_x509_sequence *ext_key_usage)
     566                 :             : {
     567                 :           0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     568                 :             : 
     569         [ #  # ]:           0 :     if ((ret = mbedtls_asn1_get_sequence_of(p, end, ext_key_usage, MBEDTLS_ASN1_OID)) != 0) {
     570                 :           0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
     571                 :             :     }
     572                 :             : 
     573                 :             :     /* Sequence length must be >= 1 */
     574         [ #  # ]:           0 :     if (ext_key_usage->buf.p == NULL) {
     575                 :           0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
     576                 :             :                                  MBEDTLS_ERR_ASN1_INVALID_LENGTH);
     577                 :             :     }
     578                 :             : 
     579                 :             :     return 0;
     580                 :             : }
     581                 :             : 
     582                 :             : /*
     583                 :             :  * SubjectKeyIdentifier ::= KeyIdentifier
     584                 :             :  *
     585                 :             :  * KeyIdentifier ::= OCTET STRING
     586                 :             :  */
     587                 :           0 : static int x509_get_subject_key_id(unsigned char **p,
     588                 :             :                                    const unsigned char *end,
     589                 :             :                                    mbedtls_x509_buf *subject_key_id)
     590                 :             : {
     591                 :           0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     592                 :           0 :     size_t len = 0u;
     593                 :             : 
     594         [ #  # ]:           0 :     if ((ret = mbedtls_asn1_get_tag(p, end, &len,
     595                 :             :                                     MBEDTLS_ASN1_OCTET_STRING)) != 0) {
     596                 :           0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
     597                 :             :     }
     598                 :             : 
     599                 :           0 :     subject_key_id->len = len;
     600                 :           0 :     subject_key_id->tag = MBEDTLS_ASN1_OCTET_STRING;
     601                 :           0 :     subject_key_id->p = *p;
     602                 :           0 :     *p += len;
     603                 :             : 
     604         [ #  # ]:           0 :     if (*p != end) {
     605                 :           0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
     606                 :             :                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
     607                 :             :     }
     608                 :             : 
     609                 :             :     return 0;
     610                 :             : }
     611                 :             : 
     612                 :             : /*
     613                 :             :  * AuthorityKeyIdentifier ::= SEQUENCE {
     614                 :             :  *        keyIdentifier [0] KeyIdentifier OPTIONAL,
     615                 :             :  *        authorityCertIssuer [1] GeneralNames OPTIONAL,
     616                 :             :  *        authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL }
     617                 :             :  *
     618                 :             :  *    KeyIdentifier ::= OCTET STRING
     619                 :             :  */
     620                 :           0 : static int x509_get_authority_key_id(unsigned char **p,
     621                 :             :                                      unsigned char *end,
     622                 :             :                                      mbedtls_x509_authority *authority_key_id)
     623                 :             : {
     624                 :           0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     625                 :           0 :     size_t len = 0u;
     626                 :             : 
     627         [ #  # ]:           0 :     if ((ret = mbedtls_asn1_get_tag(p, end, &len,
     628                 :             :                                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
     629                 :           0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
     630                 :             :     }
     631                 :             : 
     632         [ #  # ]:           0 :     if (*p + len != end) {
     633                 :           0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
     634                 :             :                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
     635                 :             :     }
     636                 :             : 
     637                 :           0 :     ret = mbedtls_asn1_get_tag(p, end, &len,
     638                 :             :                                MBEDTLS_ASN1_CONTEXT_SPECIFIC);
     639                 :             : 
     640                 :             :     /* KeyIdentifier is an OPTIONAL field */
     641         [ #  # ]:           0 :     if (ret == 0) {
     642                 :           0 :         authority_key_id->keyIdentifier.len = len;
     643                 :           0 :         authority_key_id->keyIdentifier.p = *p;
     644                 :             :         /* Setting tag of the keyIdentfier intentionally to 0x04.
     645                 :             :          * Although the .keyIdentfier field is CONTEXT_SPECIFIC ([0] OPTIONAL),
     646                 :             :          * its tag with the content is the payload of on OCTET STRING primitive */
     647                 :           0 :         authority_key_id->keyIdentifier.tag = MBEDTLS_ASN1_OCTET_STRING;
     648                 :             : 
     649                 :           0 :         *p += len;
     650         [ #  # ]:           0 :     } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
     651                 :           0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
     652                 :             :     }
     653                 :             : 
     654         [ #  # ]:           0 :     if (*p < end) {
     655                 :             :         /* Getting authorityCertIssuer using the required specific class tag [1] */
     656         [ #  # ]:           0 :         if ((ret = mbedtls_asn1_get_tag(p, end, &len,
     657                 :             :                                         MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED |
     658                 :             :                                         1)) != 0) {
     659                 :             :             /* authorityCertIssuer and authorityCertSerialNumber MUST both
     660                 :             :                be present or both be absent. At this point we expect to have both. */
     661                 :           0 :             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
     662                 :             :         }
     663                 :             :         /* "end" also includes the CertSerialNumber field so "len" shall be used */
     664                 :           0 :         ret = mbedtls_x509_get_subject_alt_name_ext(p,
     665                 :           0 :                                                     (*p+len),
     666                 :             :                                                     &authority_key_id->authorityCertIssuer);
     667         [ #  # ]:           0 :         if (ret != 0) {
     668                 :             :             return ret;
     669                 :             :         }
     670                 :             : 
     671                 :             :         /* Getting authorityCertSerialNumber using the required specific class tag [2] */
     672         [ #  # ]:           0 :         if ((ret = mbedtls_asn1_get_tag(p, end, &len,
     673                 :             :                                         MBEDTLS_ASN1_CONTEXT_SPECIFIC | 2)) != 0) {
     674                 :           0 :             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
     675                 :             :         }
     676                 :           0 :         authority_key_id->authorityCertSerialNumber.len = len;
     677                 :           0 :         authority_key_id->authorityCertSerialNumber.p = *p;
     678                 :           0 :         authority_key_id->authorityCertSerialNumber.tag = MBEDTLS_ASN1_INTEGER;
     679                 :           0 :         *p += len;
     680                 :             :     }
     681                 :             : 
     682         [ #  # ]:           0 :     if (*p != end) {
     683                 :           0 :         return MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
     684                 :             :                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
     685                 :             :     }
     686                 :             : 
     687                 :             :     return 0;
     688                 :             : }
     689                 :             : 
     690                 :             : /*
     691                 :             :  * id-ce-certificatePolicies OBJECT IDENTIFIER ::=  { id-ce 32 }
     692                 :             :  *
     693                 :             :  * anyPolicy OBJECT IDENTIFIER ::= { id-ce-certificatePolicies 0 }
     694                 :             :  *
     695                 :             :  * certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
     696                 :             :  *
     697                 :             :  * PolicyInformation ::= SEQUENCE {
     698                 :             :  *     policyIdentifier   CertPolicyId,
     699                 :             :  *     policyQualifiers   SEQUENCE SIZE (1..MAX) OF
     700                 :             :  *                             PolicyQualifierInfo OPTIONAL }
     701                 :             :  *
     702                 :             :  * CertPolicyId ::= OBJECT IDENTIFIER
     703                 :             :  *
     704                 :             :  * PolicyQualifierInfo ::= SEQUENCE {
     705                 :             :  *      policyQualifierId  PolicyQualifierId,
     706                 :             :  *      qualifier          ANY DEFINED BY policyQualifierId }
     707                 :             :  *
     708                 :             :  * -- policyQualifierIds for Internet policy qualifiers
     709                 :             :  *
     710                 :             :  * id-qt          OBJECT IDENTIFIER ::=  { id-pkix 2 }
     711                 :             :  * id-qt-cps      OBJECT IDENTIFIER ::=  { id-qt 1 }
     712                 :             :  * id-qt-unotice  OBJECT IDENTIFIER ::=  { id-qt 2 }
     713                 :             :  *
     714                 :             :  * PolicyQualifierId ::= OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice )
     715                 :             :  *
     716                 :             :  * Qualifier ::= CHOICE {
     717                 :             :  *      cPSuri           CPSuri,
     718                 :             :  *      userNotice       UserNotice }
     719                 :             :  *
     720                 :             :  * CPSuri ::= IA5String
     721                 :             :  *
     722                 :             :  * UserNotice ::= SEQUENCE {
     723                 :             :  *      noticeRef        NoticeReference OPTIONAL,
     724                 :             :  *      explicitText     DisplayText OPTIONAL }
     725                 :             :  *
     726                 :             :  * NoticeReference ::= SEQUENCE {
     727                 :             :  *      organization     DisplayText,
     728                 :             :  *      noticeNumbers    SEQUENCE OF INTEGER }
     729                 :             :  *
     730                 :             :  * DisplayText ::= CHOICE {
     731                 :             :  *      ia5String        IA5String      (SIZE (1..200)),
     732                 :             :  *      visibleString    VisibleString  (SIZE (1..200)),
     733                 :             :  *      bmpString        BMPString      (SIZE (1..200)),
     734                 :             :  *      utf8String       UTF8String     (SIZE (1..200)) }
     735                 :             :  *
     736                 :             :  * NOTE: we only parse and use anyPolicy without qualifiers at this point
     737                 :             :  * as defined in RFC 5280.
     738                 :             :  */
     739                 :           0 : static int x509_get_certificate_policies(unsigned char **p,
     740                 :             :                                          const unsigned char *end,
     741                 :             :                                          mbedtls_x509_sequence *certificate_policies)
     742                 :             : {
     743                 :           0 :     int ret, parse_ret = 0;
     744                 :           0 :     size_t len;
     745                 :           0 :     mbedtls_asn1_buf *buf;
     746                 :           0 :     mbedtls_asn1_sequence *cur = certificate_policies;
     747                 :             : 
     748                 :             :     /* Get main sequence tag */
     749                 :           0 :     ret = mbedtls_asn1_get_tag(p, end, &len,
     750                 :             :                                MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
     751         [ #  # ]:           0 :     if (ret != 0) {
     752                 :           0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
     753                 :             :     }
     754                 :             : 
     755         [ #  # ]:           0 :     if (*p + len != end) {
     756                 :           0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
     757                 :             :                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
     758                 :             :     }
     759                 :             : 
     760                 :             :     /*
     761                 :             :      * Cannot be an empty sequence.
     762                 :             :      */
     763         [ #  # ]:           0 :     if (len == 0) {
     764                 :           0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
     765                 :             :                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
     766                 :             :     }
     767                 :             : 
     768         [ #  # ]:           0 :     while (*p < end) {
     769                 :           0 :         mbedtls_x509_buf policy_oid;
     770                 :           0 :         const unsigned char *policy_end;
     771                 :             : 
     772                 :             :         /*
     773                 :             :          * Get the policy sequence
     774                 :             :          */
     775         [ #  # ]:           0 :         if ((ret = mbedtls_asn1_get_tag(p, end, &len,
     776                 :             :                                         MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
     777                 :           0 :             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
     778                 :             :         }
     779                 :             : 
     780                 :           0 :         policy_end = *p + len;
     781                 :             : 
     782         [ #  # ]:           0 :         if ((ret = mbedtls_asn1_get_tag(p, policy_end, &len,
     783                 :             :                                         MBEDTLS_ASN1_OID)) != 0) {
     784                 :           0 :             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
     785                 :             :         }
     786                 :             : 
     787                 :           0 :         policy_oid.tag = MBEDTLS_ASN1_OID;
     788                 :           0 :         policy_oid.len = len;
     789                 :           0 :         policy_oid.p = *p;
     790                 :             : 
     791                 :             :         /*
     792                 :             :          * Only AnyPolicy is currently supported when enforcing policy.
     793                 :             :          */
     794   [ #  #  #  # ]:           0 :         if (MBEDTLS_OID_CMP(MBEDTLS_OID_ANY_POLICY, &policy_oid) != 0) {
     795                 :             :             /*
     796                 :             :              * Set the parsing return code but continue parsing, in case this
     797                 :             :              * extension is critical.
     798                 :             :              */
     799                 :             :             parse_ret = MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
     800                 :             :         }
     801                 :             : 
     802                 :             :         /* Allocate and assign next pointer */
     803         [ #  # ]:           0 :         if (cur->buf.p != NULL) {
     804         [ #  # ]:           0 :             if (cur->next != NULL) {
     805                 :             :                 return MBEDTLS_ERR_X509_INVALID_EXTENSIONS;
     806                 :             :             }
     807                 :             : 
     808                 :           0 :             cur->next = mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence));
     809                 :             : 
     810         [ #  # ]:           0 :             if (cur->next == NULL) {
     811                 :           0 :                 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
     812                 :             :                                          MBEDTLS_ERR_ASN1_ALLOC_FAILED);
     813                 :             :             }
     814                 :             : 
     815                 :             :             cur = cur->next;
     816                 :             :         }
     817                 :             : 
     818                 :           0 :         buf = &(cur->buf);
     819                 :           0 :         buf->tag = policy_oid.tag;
     820                 :           0 :         buf->p = policy_oid.p;
     821                 :           0 :         buf->len = policy_oid.len;
     822                 :             : 
     823                 :           0 :         *p += len;
     824                 :             : 
     825                 :             :         /*
     826                 :             :          * If there is an optional qualifier, then *p < policy_end
     827                 :             :          * Check the Qualifier len to verify it doesn't exceed policy_end.
     828                 :             :          */
     829         [ #  # ]:           0 :         if (*p < policy_end) {
     830         [ #  # ]:           0 :             if ((ret = mbedtls_asn1_get_tag(p, policy_end, &len,
     831                 :             :                                             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) !=
     832                 :             :                 0) {
     833                 :           0 :                 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
     834                 :             :             }
     835                 :             :             /*
     836                 :             :              * Skip the optional policy qualifiers.
     837                 :             :              */
     838                 :           0 :             *p += len;
     839                 :             :         }
     840                 :             : 
     841         [ #  # ]:           0 :         if (*p != policy_end) {
     842                 :           0 :             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
     843                 :             :                                      MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
     844                 :             :         }
     845                 :             :     }
     846                 :             : 
     847                 :             :     /* Set final sequence entry's next pointer to NULL */
     848                 :           0 :     cur->next = NULL;
     849                 :             : 
     850         [ #  # ]:           0 :     if (*p != end) {
     851                 :           0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
     852                 :             :                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
     853                 :             :     }
     854                 :             : 
     855                 :             :     return parse_ret;
     856                 :             : }
     857                 :             : 
     858                 :             : /*
     859                 :             :  * X.509 v3 extensions
     860                 :             :  *
     861                 :             :  */
     862                 :           4 : static int x509_get_crt_ext(unsigned char **p,
     863                 :             :                             const unsigned char *end,
     864                 :             :                             mbedtls_x509_crt *crt,
     865                 :             :                             mbedtls_x509_crt_ext_cb_t cb,
     866                 :             :                             void *p_ctx)
     867                 :             : {
     868                 :           4 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     869                 :           4 :     size_t len;
     870                 :           4 :     unsigned char *end_ext_data, *start_ext_octet, *end_ext_octet;
     871                 :             : 
     872         [ +  - ]:           4 :     if (*p == end) {
     873                 :             :         return 0;
     874                 :             :     }
     875                 :             : 
     876         [ #  # ]:           0 :     if ((ret = mbedtls_x509_get_ext(p, end, &crt->v3_ext, 3)) != 0) {
     877                 :             :         return ret;
     878                 :             :     }
     879                 :             : 
     880                 :           0 :     end = crt->v3_ext.p + crt->v3_ext.len;
     881         [ #  # ]:           0 :     while (*p < end) {
     882                 :             :         /*
     883                 :             :          * Extension  ::=  SEQUENCE  {
     884                 :             :          *      extnID      OBJECT IDENTIFIER,
     885                 :             :          *      critical    BOOLEAN DEFAULT FALSE,
     886                 :             :          *      extnValue   OCTET STRING  }
     887                 :             :          */
     888                 :           0 :         mbedtls_x509_buf extn_oid = { 0, 0, NULL };
     889                 :           0 :         int is_critical = 0; /* DEFAULT FALSE */
     890                 :           0 :         int ext_type = 0;
     891                 :             : 
     892         [ #  # ]:           0 :         if ((ret = mbedtls_asn1_get_tag(p, end, &len,
     893                 :             :                                         MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
     894                 :           0 :             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
     895                 :             :         }
     896                 :             : 
     897                 :           0 :         end_ext_data = *p + len;
     898                 :             : 
     899                 :             :         /* Get extension ID */
     900         [ #  # ]:           0 :         if ((ret = mbedtls_asn1_get_tag(p, end_ext_data, &extn_oid.len,
     901                 :             :                                         MBEDTLS_ASN1_OID)) != 0) {
     902                 :           0 :             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
     903                 :             :         }
     904                 :             : 
     905                 :           0 :         extn_oid.tag = MBEDTLS_ASN1_OID;
     906                 :           0 :         extn_oid.p = *p;
     907                 :           0 :         *p += extn_oid.len;
     908                 :             : 
     909                 :             :         /* Get optional critical */
     910   [ #  #  #  # ]:           0 :         if ((ret = mbedtls_asn1_get_bool(p, end_ext_data, &is_critical)) != 0 &&
     911                 :             :             (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)) {
     912                 :           0 :             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
     913                 :             :         }
     914                 :             : 
     915                 :             :         /* Data should be octet string type */
     916         [ #  # ]:           0 :         if ((ret = mbedtls_asn1_get_tag(p, end_ext_data, &len,
     917                 :             :                                         MBEDTLS_ASN1_OCTET_STRING)) != 0) {
     918                 :           0 :             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
     919                 :             :         }
     920                 :             : 
     921                 :           0 :         start_ext_octet = *p;
     922                 :           0 :         end_ext_octet = *p + len;
     923                 :             : 
     924         [ #  # ]:           0 :         if (end_ext_octet != end_ext_data) {
     925                 :           0 :             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
     926                 :             :                                      MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
     927                 :             :         }
     928                 :             : 
     929                 :             :         /*
     930                 :             :          * Detect supported extensions
     931                 :             :          */
     932                 :           0 :         ret = mbedtls_oid_get_x509_ext_type(&extn_oid, &ext_type);
     933                 :             : 
     934         [ #  # ]:           0 :         if (ret != 0) {
     935                 :             :             /* Give the callback (if any) a chance to handle the extension */
     936         [ #  # ]:           0 :             if (cb != NULL) {
     937                 :           0 :                 ret = cb(p_ctx, crt, &extn_oid, is_critical, *p, end_ext_octet);
     938   [ #  #  #  # ]:           0 :                 if (ret != 0 && is_critical) {
     939                 :           0 :                     return ret;
     940                 :             :                 }
     941                 :           0 :                 *p = end_ext_octet;
     942                 :           0 :                 continue;
     943                 :             :             }
     944                 :             : 
     945                 :             :             /* No parser found, skip extension */
     946                 :           0 :             *p = end_ext_octet;
     947                 :             : 
     948         [ #  # ]:           0 :             if (is_critical) {
     949                 :             :                 /* Data is marked as critical: fail */
     950                 :           0 :                 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
     951                 :             :                                          MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
     952                 :             :             }
     953                 :           0 :             continue;
     954                 :             :         }
     955                 :             : 
     956                 :             :         /* Forbid repeated extensions */
     957         [ #  # ]:           0 :         if ((crt->ext_types & ext_type) != 0) {
     958                 :             :             return MBEDTLS_ERR_X509_INVALID_EXTENSIONS;
     959                 :             :         }
     960                 :             : 
     961                 :           0 :         crt->ext_types |= ext_type;
     962                 :             : 
     963   [ #  #  #  #  :           0 :         switch (ext_type) {
             #  #  #  #  
                      # ]
     964                 :           0 :             case MBEDTLS_X509_EXT_BASIC_CONSTRAINTS:
     965                 :             :                 /* Parse basic constraints */
     966         [ #  # ]:           0 :                 if ((ret = x509_get_basic_constraints(p, end_ext_octet,
     967                 :             :                                                       &crt->ca_istrue, &crt->max_pathlen)) != 0) {
     968                 :           0 :                     return ret;
     969                 :             :                 }
     970                 :             :                 break;
     971                 :             : 
     972                 :           0 :             case MBEDTLS_X509_EXT_KEY_USAGE:
     973                 :             :                 /* Parse key usage */
     974         [ #  # ]:           0 :                 if ((ret = mbedtls_x509_get_key_usage(p, end_ext_octet,
     975                 :             :                                                       &crt->key_usage)) != 0) {
     976                 :           0 :                     return ret;
     977                 :             :                 }
     978                 :             :                 break;
     979                 :             : 
     980                 :           0 :             case MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE:
     981                 :             :                 /* Parse extended key usage */
     982         [ #  # ]:           0 :                 if ((ret = x509_get_ext_key_usage(p, end_ext_octet,
     983                 :             :                                                   &crt->ext_key_usage)) != 0) {
     984                 :           0 :                     return ret;
     985                 :             :                 }
     986                 :             :                 break;
     987                 :             : 
     988                 :           0 :             case MBEDTLS_X509_EXT_SUBJECT_KEY_IDENTIFIER:
     989                 :             :                 /* Parse subject key identifier */
     990         [ #  # ]:           0 :                 if ((ret = x509_get_subject_key_id(p, end_ext_data,
     991                 :             :                                                    &crt->subject_key_id)) != 0) {
     992                 :           0 :                     return ret;
     993                 :             :                 }
     994                 :             :                 break;
     995                 :             : 
     996                 :           0 :             case MBEDTLS_X509_EXT_AUTHORITY_KEY_IDENTIFIER:
     997                 :             :                 /* Parse authority key identifier */
     998         [ #  # ]:           0 :                 if ((ret = x509_get_authority_key_id(p, end_ext_octet,
     999                 :             :                                                      &crt->authority_key_id)) != 0) {
    1000                 :           0 :                     return ret;
    1001                 :             :                 }
    1002                 :             :                 break;
    1003                 :           0 :             case MBEDTLS_X509_EXT_SUBJECT_ALT_NAME:
    1004                 :             :                 /* Parse subject alt name
    1005                 :             :                  * SubjectAltName ::= GeneralNames
    1006                 :             :                  */
    1007         [ #  # ]:           0 :                 if ((ret = mbedtls_x509_get_subject_alt_name(p, end_ext_octet,
    1008                 :             :                                                              &crt->subject_alt_names)) != 0) {
    1009                 :           0 :                     return ret;
    1010                 :             :                 }
    1011                 :             :                 break;
    1012                 :             : 
    1013                 :           0 :             case MBEDTLS_X509_EXT_NS_CERT_TYPE:
    1014                 :             :                 /* Parse netscape certificate type */
    1015         [ #  # ]:           0 :                 if ((ret = mbedtls_x509_get_ns_cert_type(p, end_ext_octet,
    1016                 :             :                                                          &crt->ns_cert_type)) != 0) {
    1017                 :           0 :                     return ret;
    1018                 :             :                 }
    1019                 :             :                 break;
    1020                 :             : 
    1021                 :           0 :             case MBEDTLS_OID_X509_EXT_CERTIFICATE_POLICIES:
    1022                 :             :                 /* Parse certificate policies type */
    1023         [ #  # ]:           0 :                 if ((ret = x509_get_certificate_policies(p, end_ext_octet,
    1024                 :             :                                                          &crt->certificate_policies)) != 0) {
    1025                 :             :                     /* Give the callback (if any) a chance to handle the extension
    1026                 :             :                      * if it contains unsupported policies */
    1027   [ #  #  #  # ]:           0 :                     if (ret == MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE && cb != NULL &&
    1028                 :           0 :                         cb(p_ctx, crt, &extn_oid, is_critical,
    1029                 :             :                            start_ext_octet, end_ext_octet) == 0) {
    1030                 :             :                         break;
    1031                 :             :                     }
    1032                 :             : 
    1033         [ #  # ]:           0 :                     if (is_critical) {
    1034                 :           0 :                         return ret;
    1035                 :             :                     } else
    1036                 :             :                     /*
    1037                 :             :                      * If MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE is returned, then we
    1038                 :             :                      * cannot interpret or enforce the policy. However, it is up to
    1039                 :             :                      * the user to choose how to enforce the policies,
    1040                 :             :                      * unless the extension is critical.
    1041                 :             :                      */
    1042         [ #  # ]:           0 :                     if (ret != MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) {
    1043                 :           0 :                         return ret;
    1044                 :             :                     }
    1045                 :             :                 }
    1046                 :             :                 break;
    1047                 :             : 
    1048                 :           0 :             default:
    1049                 :             :                 /*
    1050                 :             :                  * If this is a non-critical extension, which the oid layer
    1051                 :             :                  * supports, but there isn't an x509 parser for it,
    1052                 :             :                  * skip the extension.
    1053                 :             :                  */
    1054         [ #  # ]:           0 :                 if (is_critical) {
    1055                 :             :                     return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
    1056                 :             :                 } else {
    1057                 :           0 :                     *p = end_ext_octet;
    1058                 :             :                 }
    1059                 :             :         }
    1060                 :             :     }
    1061                 :             : 
    1062         [ #  # ]:           0 :     if (*p != end) {
    1063                 :           0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
    1064                 :             :                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
    1065                 :             :     }
    1066                 :             : 
    1067                 :             :     return 0;
    1068                 :             : }
    1069                 :             : 
    1070                 :             : /*
    1071                 :             :  * Parse and fill a single X.509 certificate in DER format
    1072                 :             :  */
    1073                 :           4 : static int x509_crt_parse_der_core(mbedtls_x509_crt *crt,
    1074                 :             :                                    const unsigned char *buf,
    1075                 :             :                                    size_t buflen,
    1076                 :             :                                    int make_copy,
    1077                 :             :                                    mbedtls_x509_crt_ext_cb_t cb,
    1078                 :             :                                    void *p_ctx)
    1079                 :             : {
    1080                 :           4 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1081                 :           4 :     size_t len;
    1082                 :           4 :     unsigned char *p, *end, *crt_end;
    1083                 :           4 :     mbedtls_x509_buf sig_params1, sig_params2, sig_oid2;
    1084                 :             : 
    1085         [ +  - ]:           4 :     memset(&sig_params1, 0, sizeof(mbedtls_x509_buf));
    1086                 :           4 :     memset(&sig_params2, 0, sizeof(mbedtls_x509_buf));
    1087                 :           4 :     memset(&sig_oid2, 0, sizeof(mbedtls_x509_buf));
    1088                 :             : 
    1089                 :             :     /*
    1090                 :             :      * Check for valid input
    1091                 :             :      */
    1092         [ +  - ]:           4 :     if (crt == NULL || buf == NULL) {
    1093                 :             :         return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
    1094                 :             :     }
    1095                 :             : 
    1096                 :             :     /* Use the original buffer until we figure out actual length. */
    1097                 :           4 :     p = (unsigned char *) buf;
    1098                 :           4 :     len = buflen;
    1099                 :           4 :     end = p + len;
    1100                 :             : 
    1101                 :             :     /*
    1102                 :             :      * Certificate  ::=  SEQUENCE  {
    1103                 :             :      *      tbsCertificate       TBSCertificate,
    1104                 :             :      *      signatureAlgorithm   AlgorithmIdentifier,
    1105                 :             :      *      signatureValue       BIT STRING  }
    1106                 :             :      */
    1107         [ -  + ]:           4 :     if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
    1108                 :             :                                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
    1109                 :           0 :         mbedtls_x509_crt_free(crt);
    1110                 :           0 :         return MBEDTLS_ERR_X509_INVALID_FORMAT;
    1111                 :             :     }
    1112                 :             : 
    1113                 :           4 :     end = crt_end = p + len;
    1114                 :           4 :     crt->raw.len = (size_t) (crt_end - buf);
    1115         [ -  + ]:           4 :     if (make_copy != 0) {
    1116                 :             :         /* Create and populate a new buffer for the raw field. */
    1117                 :           0 :         crt->raw.p = p = mbedtls_calloc(1, crt->raw.len);
    1118         [ #  # ]:           0 :         if (crt->raw.p == NULL) {
    1119                 :             :             return MBEDTLS_ERR_X509_ALLOC_FAILED;
    1120                 :             :         }
    1121                 :             : 
    1122                 :           0 :         memcpy(crt->raw.p, buf, crt->raw.len);
    1123                 :           0 :         crt->own_buffer = 1;
    1124                 :             : 
    1125                 :           0 :         p += crt->raw.len - len;
    1126                 :           0 :         end = crt_end = p + len;
    1127                 :             :     } else {
    1128                 :           4 :         crt->raw.p = (unsigned char *) buf;
    1129                 :           4 :         crt->own_buffer = 0;
    1130                 :             :     }
    1131                 :             : 
    1132                 :             :     /*
    1133                 :             :      * TBSCertificate  ::=  SEQUENCE  {
    1134                 :             :      */
    1135                 :           4 :     crt->tbs.p = p;
    1136                 :             : 
    1137         [ -  + ]:           4 :     if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
    1138                 :             :                                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
    1139                 :           0 :         mbedtls_x509_crt_free(crt);
    1140                 :           0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret);
    1141                 :             :     }
    1142                 :             : 
    1143                 :           4 :     end = p + len;
    1144                 :           4 :     crt->tbs.len = (size_t) (end - crt->tbs.p);
    1145                 :             : 
    1146                 :             :     /*
    1147                 :             :      * Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
    1148                 :             :      *
    1149                 :             :      * CertificateSerialNumber  ::=  INTEGER
    1150                 :             :      *
    1151                 :             :      * signature            AlgorithmIdentifier
    1152                 :             :      */
    1153         [ +  - ]:           4 :     if ((ret = x509_get_version(&p, end, &crt->version)) != 0 ||
    1154         [ +  - ]:           4 :         (ret = mbedtls_x509_get_serial(&p, end, &crt->serial)) != 0 ||
    1155         [ -  + ]:           4 :         (ret = mbedtls_x509_get_alg(&p, end, &crt->sig_oid,
    1156                 :             :                                     &sig_params1)) != 0) {
    1157                 :           0 :         mbedtls_x509_crt_free(crt);
    1158                 :           0 :         return ret;
    1159                 :             :     }
    1160                 :             : 
    1161         [ -  + ]:           4 :     if (crt->version < 0 || crt->version > 2) {
    1162                 :           0 :         mbedtls_x509_crt_free(crt);
    1163                 :           0 :         return MBEDTLS_ERR_X509_UNKNOWN_VERSION;
    1164                 :             :     }
    1165                 :             : 
    1166                 :           4 :     crt->version++;
    1167                 :             : 
    1168         [ -  + ]:           4 :     if ((ret = mbedtls_x509_get_sig_alg(&crt->sig_oid, &sig_params1,
    1169                 :             :                                         &crt->sig_md, &crt->sig_pk,
    1170                 :             :                                         &crt->sig_opts)) != 0) {
    1171                 :           0 :         mbedtls_x509_crt_free(crt);
    1172                 :           0 :         return ret;
    1173                 :             :     }
    1174                 :             : 
    1175                 :             :     /*
    1176                 :             :      * issuer               Name
    1177                 :             :      */
    1178                 :           4 :     crt->issuer_raw.p = p;
    1179                 :             : 
    1180         [ -  + ]:           4 :     if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
    1181                 :             :                                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
    1182                 :           0 :         mbedtls_x509_crt_free(crt);
    1183                 :           0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret);
    1184                 :             :     }
    1185                 :             : 
    1186         [ -  + ]:           4 :     if ((ret = mbedtls_x509_get_name(&p, p + len, &crt->issuer)) != 0) {
    1187                 :           0 :         mbedtls_x509_crt_free(crt);
    1188                 :           0 :         return ret;
    1189                 :             :     }
    1190                 :             : 
    1191                 :           4 :     crt->issuer_raw.len = (size_t) (p - crt->issuer_raw.p);
    1192                 :             : 
    1193                 :             :     /*
    1194                 :             :      * Validity ::= SEQUENCE {
    1195                 :             :      *      notBefore      Time,
    1196                 :             :      *      notAfter       Time }
    1197                 :             :      *
    1198                 :             :      */
    1199         [ -  + ]:           4 :     if ((ret = x509_get_dates(&p, end, &crt->valid_from,
    1200                 :             :                               &crt->valid_to)) != 0) {
    1201                 :           0 :         mbedtls_x509_crt_free(crt);
    1202                 :           0 :         return ret;
    1203                 :             :     }
    1204                 :             : 
    1205                 :             :     /*
    1206                 :             :      * subject              Name
    1207                 :             :      */
    1208                 :           4 :     crt->subject_raw.p = p;
    1209                 :             : 
    1210         [ -  + ]:           4 :     if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
    1211                 :             :                                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
    1212                 :           0 :         mbedtls_x509_crt_free(crt);
    1213                 :           0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret);
    1214                 :             :     }
    1215                 :             : 
    1216   [ +  -  -  + ]:           4 :     if (len && (ret = mbedtls_x509_get_name(&p, p + len, &crt->subject)) != 0) {
    1217                 :           0 :         mbedtls_x509_crt_free(crt);
    1218                 :           0 :         return ret;
    1219                 :             :     }
    1220                 :             : 
    1221                 :           4 :     crt->subject_raw.len = (size_t) (p - crt->subject_raw.p);
    1222                 :             : 
    1223                 :             :     /*
    1224                 :             :      * SubjectPublicKeyInfo
    1225                 :             :      */
    1226                 :           4 :     crt->pk_raw.p = p;
    1227         [ -  + ]:           4 :     if ((ret = mbedtls_pk_parse_subpubkey(&p, end, &crt->pk)) != 0) {
    1228                 :           0 :         mbedtls_x509_crt_free(crt);
    1229                 :           0 :         return ret;
    1230                 :             :     }
    1231                 :           4 :     crt->pk_raw.len = (size_t) (p - crt->pk_raw.p);
    1232                 :             : 
    1233                 :             :     /*
    1234                 :             :      *  issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
    1235                 :             :      *                       -- If present, version shall be v2 or v3
    1236                 :             :      *  subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
    1237                 :             :      *                       -- If present, version shall be v2 or v3
    1238                 :             :      *  extensions      [3]  EXPLICIT Extensions OPTIONAL
    1239                 :             :      *                       -- If present, version shall be v3
    1240                 :             :      */
    1241         [ +  - ]:           4 :     if (crt->version == 2 || crt->version == 3) {
    1242                 :           4 :         ret = x509_get_uid(&p, end, &crt->issuer_id,  1);
    1243         [ -  + ]:           4 :         if (ret != 0) {
    1244                 :           0 :             mbedtls_x509_crt_free(crt);
    1245                 :           0 :             return ret;
    1246                 :             :         }
    1247                 :             :     }
    1248                 :             : 
    1249         [ +  - ]:           4 :     if (crt->version == 2 || crt->version == 3) {
    1250                 :           4 :         ret = x509_get_uid(&p, end, &crt->subject_id,  2);
    1251         [ -  + ]:           4 :         if (ret != 0) {
    1252                 :           0 :             mbedtls_x509_crt_free(crt);
    1253                 :           0 :             return ret;
    1254                 :             :         }
    1255                 :             :     }
    1256                 :             : 
    1257         [ +  - ]:           4 :     if (crt->version == 3) {
    1258                 :           4 :         ret = x509_get_crt_ext(&p, end, crt, cb, p_ctx);
    1259         [ -  + ]:           4 :         if (ret != 0) {
    1260                 :           0 :             mbedtls_x509_crt_free(crt);
    1261                 :           0 :             return ret;
    1262                 :             :         }
    1263                 :             :     }
    1264                 :             : 
    1265         [ -  + ]:           4 :     if (p != end) {
    1266                 :           0 :         mbedtls_x509_crt_free(crt);
    1267                 :           0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT,
    1268                 :             :                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
    1269                 :             :     }
    1270                 :             : 
    1271                 :           4 :     end = crt_end;
    1272                 :             : 
    1273                 :             :     /*
    1274                 :             :      *  }
    1275                 :             :      *  -- end of TBSCertificate
    1276                 :             :      *
    1277                 :             :      *  signatureAlgorithm   AlgorithmIdentifier,
    1278                 :             :      *  signatureValue       BIT STRING
    1279                 :             :      */
    1280         [ -  + ]:           4 :     if ((ret = mbedtls_x509_get_alg(&p, end, &sig_oid2, &sig_params2)) != 0) {
    1281                 :           0 :         mbedtls_x509_crt_free(crt);
    1282                 :           0 :         return ret;
    1283                 :             :     }
    1284                 :             : 
    1285         [ +  - ]:           4 :     if (crt->sig_oid.len != sig_oid2.len ||
    1286         [ +  - ]:           4 :         memcmp(crt->sig_oid.p, sig_oid2.p, crt->sig_oid.len) != 0 ||
    1287         [ +  - ]:           4 :         sig_params1.tag != sig_params2.tag ||
    1288   [ +  -  -  + ]:           4 :         sig_params1.len != sig_params2.len ||
    1289                 :           0 :         (sig_params1.len != 0 &&
    1290         [ #  # ]:           0 :          memcmp(sig_params1.p, sig_params2.p, sig_params1.len) != 0)) {
    1291                 :           0 :         mbedtls_x509_crt_free(crt);
    1292                 :           0 :         return MBEDTLS_ERR_X509_SIG_MISMATCH;
    1293                 :             :     }
    1294                 :             : 
    1295         [ -  + ]:           4 :     if ((ret = mbedtls_x509_get_sig(&p, end, &crt->sig)) != 0) {
    1296                 :           0 :         mbedtls_x509_crt_free(crt);
    1297                 :           0 :         return ret;
    1298                 :             :     }
    1299                 :             : 
    1300         [ -  + ]:           4 :     if (p != end) {
    1301                 :           0 :         mbedtls_x509_crt_free(crt);
    1302                 :           0 :         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT,
    1303                 :             :                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
    1304                 :             :     }
    1305                 :             : 
    1306                 :             :     return 0;
    1307                 :             : }
    1308                 :             : 
    1309                 :             : /*
    1310                 :             :  * Parse one X.509 certificate in DER format from a buffer and add them to a
    1311                 :             :  * chained list
    1312                 :             :  */
    1313                 :           4 : static int mbedtls_x509_crt_parse_der_internal(mbedtls_x509_crt *chain,
    1314                 :             :                                                const unsigned char *buf,
    1315                 :             :                                                size_t buflen,
    1316                 :             :                                                int make_copy,
    1317                 :             :                                                mbedtls_x509_crt_ext_cb_t cb,
    1318                 :             :                                                void *p_ctx)
    1319                 :             : {
    1320                 :           4 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1321                 :           4 :     mbedtls_x509_crt *crt = chain, *prev = NULL;
    1322                 :             : 
    1323                 :             :     /*
    1324                 :             :      * Check for valid input
    1325                 :             :      */
    1326         [ +  - ]:           4 :     if (crt == NULL || buf == NULL) {
    1327                 :             :         return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
    1328                 :             :     }
    1329                 :             : 
    1330   [ -  +  -  - ]:           4 :     while (crt->version != 0 && crt->next != NULL) {
    1331                 :             :         prev = crt;
    1332                 :             :         crt = crt->next;
    1333                 :             :     }
    1334                 :             : 
    1335                 :             :     /*
    1336                 :             :      * Add new certificate on the end of the chain if needed.
    1337                 :             :      */
    1338   [ -  +  -  - ]:           4 :     if (crt->version != 0 && crt->next == NULL) {
    1339                 :           0 :         crt->next = mbedtls_calloc(1, sizeof(mbedtls_x509_crt));
    1340                 :             : 
    1341         [ #  # ]:           0 :         if (crt->next == NULL) {
    1342                 :             :             return MBEDTLS_ERR_X509_ALLOC_FAILED;
    1343                 :             :         }
    1344                 :             : 
    1345                 :           0 :         prev = crt;
    1346                 :           0 :         mbedtls_x509_crt_init(crt->next);
    1347                 :           0 :         crt = crt->next;
    1348                 :             :     }
    1349                 :             : 
    1350                 :           4 :     ret = x509_crt_parse_der_core(crt, buf, buflen, make_copy, cb, p_ctx);
    1351         [ -  + ]:           4 :     if (ret != 0) {
    1352         [ #  # ]:           0 :         if (prev) {
    1353                 :           0 :             prev->next = NULL;
    1354                 :             :         }
    1355                 :             : 
    1356         [ #  # ]:           0 :         if (crt != chain) {
    1357                 :           0 :             mbedtls_free(crt);
    1358                 :             :         }
    1359                 :             : 
    1360                 :           0 :         return ret;
    1361                 :             :     }
    1362                 :             : 
    1363                 :             :     return 0;
    1364                 :             : }
    1365                 :             : 
    1366                 :           4 : int mbedtls_x509_crt_parse_der_nocopy(mbedtls_x509_crt *chain,
    1367                 :             :                                       const unsigned char *buf,
    1368                 :             :                                       size_t buflen)
    1369                 :             : {
    1370                 :           4 :     return mbedtls_x509_crt_parse_der_internal(chain, buf, buflen, 0, NULL, NULL);
    1371                 :             : }
    1372                 :             : 
    1373                 :           0 : int mbedtls_x509_crt_parse_der_with_ext_cb(mbedtls_x509_crt *chain,
    1374                 :             :                                            const unsigned char *buf,
    1375                 :             :                                            size_t buflen,
    1376                 :             :                                            int make_copy,
    1377                 :             :                                            mbedtls_x509_crt_ext_cb_t cb,
    1378                 :             :                                            void *p_ctx)
    1379                 :             : {
    1380                 :           0 :     return mbedtls_x509_crt_parse_der_internal(chain, buf, buflen, make_copy, cb, p_ctx);
    1381                 :             : }
    1382                 :             : 
    1383                 :           0 : int mbedtls_x509_crt_parse_der(mbedtls_x509_crt *chain,
    1384                 :             :                                const unsigned char *buf,
    1385                 :             :                                size_t buflen)
    1386                 :             : {
    1387                 :           0 :     return mbedtls_x509_crt_parse_der_internal(chain, buf, buflen, 1, NULL, NULL);
    1388                 :             : }
    1389                 :             : 
    1390                 :             : /*
    1391                 :             :  * Parse one or more PEM certificates from a buffer and add them to the chained
    1392                 :             :  * list
    1393                 :             :  */
    1394                 :           0 : int mbedtls_x509_crt_parse(mbedtls_x509_crt *chain,
    1395                 :             :                            const unsigned char *buf,
    1396                 :             :                            size_t buflen)
    1397                 :             : {
    1398                 :             : #if defined(MBEDTLS_PEM_PARSE_C)
    1399                 :             :     int success = 0, first_error = 0, total_failed = 0;
    1400                 :             :     int buf_format = MBEDTLS_X509_FORMAT_DER;
    1401                 :             : #endif
    1402                 :             : 
    1403                 :             :     /*
    1404                 :             :      * Check for valid input
    1405                 :             :      */
    1406         [ #  # ]:           0 :     if (chain == NULL || buf == NULL) {
    1407                 :             :         return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
    1408                 :             :     }
    1409                 :             : 
    1410                 :             :     /*
    1411                 :             :      * Determine buffer content. Buffer contains either one DER certificate or
    1412                 :             :      * one or more PEM certificates.
    1413                 :             :      */
    1414                 :             : #if defined(MBEDTLS_PEM_PARSE_C)
    1415                 :             :     if (buflen != 0 && buf[buflen - 1] == '\0' &&
    1416                 :             :         strstr((const char *) buf, "-----BEGIN CERTIFICATE-----") != NULL) {
    1417                 :             :         buf_format = MBEDTLS_X509_FORMAT_PEM;
    1418                 :             :     }
    1419                 :             : 
    1420                 :             :     if (buf_format == MBEDTLS_X509_FORMAT_DER) {
    1421                 :             :         return mbedtls_x509_crt_parse_der(chain, buf, buflen);
    1422                 :             :     }
    1423                 :             : #else
    1424                 :           0 :     return mbedtls_x509_crt_parse_der(chain, buf, buflen);
    1425                 :             : #endif
    1426                 :             : 
    1427                 :             : #if defined(MBEDTLS_PEM_PARSE_C)
    1428                 :             :     if (buf_format == MBEDTLS_X509_FORMAT_PEM) {
    1429                 :             :         int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1430                 :             :         mbedtls_pem_context pem;
    1431                 :             : 
    1432                 :             :         /* 1 rather than 0 since the terminating NULL byte is counted in */
    1433                 :             :         while (buflen > 1) {
    1434                 :             :             size_t use_len;
    1435                 :             :             mbedtls_pem_init(&pem);
    1436                 :             : 
    1437                 :             :             /* If we get there, we know the string is null-terminated */
    1438                 :             :             ret = mbedtls_pem_read_buffer(&pem,
    1439                 :             :                                           "-----BEGIN CERTIFICATE-----",
    1440                 :             :                                           "-----END CERTIFICATE-----",
    1441                 :             :                                           buf, NULL, 0, &use_len);
    1442                 :             : 
    1443                 :             :             if (ret == 0) {
    1444                 :             :                 /*
    1445                 :             :                  * Was PEM encoded
    1446                 :             :                  */
    1447                 :             :                 buflen -= use_len;
    1448                 :             :                 buf += use_len;
    1449                 :             :             } else if (ret == MBEDTLS_ERR_PEM_BAD_INPUT_DATA) {
    1450                 :             :                 return ret;
    1451                 :             :             } else if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) {
    1452                 :             :                 mbedtls_pem_free(&pem);
    1453                 :             : 
    1454                 :             :                 /*
    1455                 :             :                  * PEM header and footer were found
    1456                 :             :                  */
    1457                 :             :                 buflen -= use_len;
    1458                 :             :                 buf += use_len;
    1459                 :             : 
    1460                 :             :                 if (first_error == 0) {
    1461                 :             :                     first_error = ret;
    1462                 :             :                 }
    1463                 :             : 
    1464                 :             :                 total_failed++;
    1465                 :             :                 continue;
    1466                 :             :             } else {
    1467                 :             :                 break;
    1468                 :             :             }
    1469                 :             : 
    1470                 :             :             ret = mbedtls_x509_crt_parse_der(chain, pem.buf, pem.buflen);
    1471                 :             : 
    1472                 :             :             mbedtls_pem_free(&pem);
    1473                 :             : 
    1474                 :             :             if (ret != 0) {
    1475                 :             :                 /*
    1476                 :             :                  * Quit parsing on a memory error
    1477                 :             :                  */
    1478                 :             :                 if (ret == MBEDTLS_ERR_X509_ALLOC_FAILED) {
    1479                 :             :                     return ret;
    1480                 :             :                 }
    1481                 :             : 
    1482                 :             :                 if (first_error == 0) {
    1483                 :             :                     first_error = ret;
    1484                 :             :                 }
    1485                 :             : 
    1486                 :             :                 total_failed++;
    1487                 :             :                 continue;
    1488                 :             :             }
    1489                 :             : 
    1490                 :             :             success = 1;
    1491                 :             :         }
    1492                 :             :     }
    1493                 :             : 
    1494                 :             :     if (success) {
    1495                 :             :         return total_failed;
    1496                 :             :     } else if (first_error) {
    1497                 :             :         return first_error;
    1498                 :             :     } else {
    1499                 :             :         return MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT;
    1500                 :             :     }
    1501                 :             : #endif /* MBEDTLS_PEM_PARSE_C */
    1502                 :             : }
    1503                 :             : 
    1504                 :             : #if defined(MBEDTLS_FS_IO)
    1505                 :             : /*
    1506                 :             :  * Load one or more certificates and add them to the chained list
    1507                 :             :  */
    1508                 :             : int mbedtls_x509_crt_parse_file(mbedtls_x509_crt *chain, const char *path)
    1509                 :             : {
    1510                 :             :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1511                 :             :     size_t n;
    1512                 :             :     unsigned char *buf;
    1513                 :             : 
    1514                 :             :     if ((ret = mbedtls_pk_load_file(path, &buf, &n)) != 0) {
    1515                 :             :         return ret;
    1516                 :             :     }
    1517                 :             : 
    1518                 :             :     ret = mbedtls_x509_crt_parse(chain, buf, n);
    1519                 :             : 
    1520                 :             :     mbedtls_zeroize_and_free(buf, n);
    1521                 :             : 
    1522                 :             :     return ret;
    1523                 :             : }
    1524                 :             : 
    1525                 :             : int mbedtls_x509_crt_parse_path(mbedtls_x509_crt *chain, const char *path)
    1526                 :             : {
    1527                 :             :     int ret = 0;
    1528                 :             : #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
    1529                 :             :     int w_ret;
    1530                 :             :     WCHAR szDir[MAX_PATH];
    1531                 :             :     char filename[MAX_PATH];
    1532                 :             :     char *p;
    1533                 :             :     size_t len = strlen(path);
    1534                 :             : 
    1535                 :             :     WIN32_FIND_DATAW file_data;
    1536                 :             :     HANDLE hFind;
    1537                 :             : 
    1538                 :             :     if (len > MAX_PATH - 3) {
    1539                 :             :         return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
    1540                 :             :     }
    1541                 :             : 
    1542                 :             :     memset(szDir, 0, sizeof(szDir));
    1543                 :             :     memset(filename, 0, MAX_PATH);
    1544                 :             :     memcpy(filename, path, len);
    1545                 :             :     filename[len++] = '\\';
    1546                 :             :     p = filename + len;
    1547                 :             :     filename[len++] = '*';
    1548                 :             : 
    1549                 :             :     /*
    1550                 :             :      * Note this function uses the code page CP_ACP which is the system default
    1551                 :             :      * ANSI codepage. The input string is always described in BYTES and the
    1552                 :             :      * output length is described in WCHARs.
    1553                 :             :      */
    1554                 :             :     w_ret = MultiByteToWideChar(CP_ACP, 0, filename, (int) len, szDir,
    1555                 :             :                                 MAX_PATH - 3);
    1556                 :             :     if (w_ret == 0) {
    1557                 :             :         return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
    1558                 :             :     }
    1559                 :             : 
    1560                 :             :     hFind = FindFirstFileW(szDir, &file_data);
    1561                 :             :     if (hFind == INVALID_HANDLE_VALUE) {
    1562                 :             :         return MBEDTLS_ERR_X509_FILE_IO_ERROR;
    1563                 :             :     }
    1564                 :             : 
    1565                 :             :     len = MAX_PATH - len;
    1566                 :             :     do {
    1567                 :             :         memset(p, 0, len);
    1568                 :             : 
    1569                 :             :         if (file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
    1570                 :             :             continue;
    1571                 :             :         }
    1572                 :             :         w_ret = WideCharToMultiByte(CP_ACP, 0, file_data.cFileName,
    1573                 :             :                                     -1, p, (int) len, NULL, NULL);
    1574                 :             :         if (w_ret == 0) {
    1575                 :             :             ret = MBEDTLS_ERR_X509_FILE_IO_ERROR;
    1576                 :             :             goto cleanup;
    1577                 :             :         }
    1578                 :             : 
    1579                 :             :         w_ret = mbedtls_x509_crt_parse_file(chain, filename);
    1580                 :             :         if (w_ret < 0) {
    1581                 :             :             ret++;
    1582                 :             :         } else {
    1583                 :             :             ret += w_ret;
    1584                 :             :         }
    1585                 :             :     } while (FindNextFileW(hFind, &file_data) != 0);
    1586                 :             : 
    1587                 :             :     if (GetLastError() != ERROR_NO_MORE_FILES) {
    1588                 :             :         ret = MBEDTLS_ERR_X509_FILE_IO_ERROR;
    1589                 :             :     }
    1590                 :             : 
    1591                 :             : cleanup:
    1592                 :             :     FindClose(hFind);
    1593                 :             : #else /* _WIN32 */
    1594                 :             :     int t_ret;
    1595                 :             :     int snp_ret;
    1596                 :             :     struct stat sb;
    1597                 :             :     struct dirent *entry;
    1598                 :             :     char entry_name[MBEDTLS_X509_MAX_FILE_PATH_LEN];
    1599                 :             :     DIR *dir = opendir(path);
    1600                 :             : 
    1601                 :             :     if (dir == NULL) {
    1602                 :             :         return MBEDTLS_ERR_X509_FILE_IO_ERROR;
    1603                 :             :     }
    1604                 :             : 
    1605                 :             : #if defined(MBEDTLS_THREADING_C)
    1606                 :             :     if ((ret = mbedtls_mutex_lock(&mbedtls_threading_readdir_mutex)) != 0) {
    1607                 :             :         closedir(dir);
    1608                 :             :         return ret;
    1609                 :             :     }
    1610                 :             : #endif /* MBEDTLS_THREADING_C */
    1611                 :             : 
    1612                 :             :     memset(&sb, 0, sizeof(sb));
    1613                 :             : 
    1614                 :             :     while ((entry = readdir(dir)) != NULL) {
    1615                 :             :         snp_ret = mbedtls_snprintf(entry_name, sizeof(entry_name),
    1616                 :             :                                    "%s/%s", path, entry->d_name);
    1617                 :             : 
    1618                 :             :         if (snp_ret < 0 || (size_t) snp_ret >= sizeof(entry_name)) {
    1619                 :             :             ret = MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
    1620                 :             :             goto cleanup;
    1621                 :             :         } else if (stat(entry_name, &sb) == -1) {
    1622                 :             :             if (errno == ENOENT) {
    1623                 :             :                 /* Broken symbolic link - ignore this entry.
    1624                 :             :                     stat(2) will return this error for either (a) a dangling
    1625                 :             :                     symlink or (b) a missing file.
    1626                 :             :                     Given that we have just obtained the filename from readdir,
    1627                 :             :                     assume that it does exist and therefore treat this as a
    1628                 :             :                     dangling symlink. */
    1629                 :             :                 continue;
    1630                 :             :             } else {
    1631                 :             :                 /* Some other file error; report the error. */
    1632                 :             :                 ret = MBEDTLS_ERR_X509_FILE_IO_ERROR;
    1633                 :             :                 goto cleanup;
    1634                 :             :             }
    1635                 :             :         }
    1636                 :             : 
    1637                 :             :         if (!S_ISREG(sb.st_mode)) {
    1638                 :             :             continue;
    1639                 :             :         }
    1640                 :             : 
    1641                 :             :         // Ignore parse errors
    1642                 :             :         //
    1643                 :             :         t_ret = mbedtls_x509_crt_parse_file(chain, entry_name);
    1644                 :             :         if (t_ret < 0) {
    1645                 :             :             ret++;
    1646                 :             :         } else {
    1647                 :             :             ret += t_ret;
    1648                 :             :         }
    1649                 :             :     }
    1650                 :             : 
    1651                 :             : cleanup:
    1652                 :             :     closedir(dir);
    1653                 :             : 
    1654                 :             : #if defined(MBEDTLS_THREADING_C)
    1655                 :             :     if (mbedtls_mutex_unlock(&mbedtls_threading_readdir_mutex) != 0) {
    1656                 :             :         ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
    1657                 :             :     }
    1658                 :             : #endif /* MBEDTLS_THREADING_C */
    1659                 :             : 
    1660                 :             : #endif /* _WIN32 */
    1661                 :             : 
    1662                 :             :     return ret;
    1663                 :             : }
    1664                 :             : #endif /* MBEDTLS_FS_IO */
    1665                 :             : 
    1666                 :             : #if !defined(MBEDTLS_X509_REMOVE_INFO)
    1667                 :             : #define PRINT_ITEM(i)                               \
    1668                 :             :     do {                                            \
    1669                 :             :         ret = mbedtls_snprintf(p, n, "%s" i, sep);  \
    1670                 :             :         MBEDTLS_X509_SAFE_SNPRINTF;                 \
    1671                 :             :         sep = ", ";                                 \
    1672                 :             :     } while (0)
    1673                 :             : 
    1674                 :             : #define CERT_TYPE(type, name)          \
    1675                 :             :     do {                               \
    1676                 :             :         if (ns_cert_type & (type)) {   \
    1677                 :             :             PRINT_ITEM(name);          \
    1678                 :             :         }                              \
    1679                 :             :     } while (0)
    1680                 :             : 
    1681                 :             : #define KEY_USAGE(code, name)      \
    1682                 :             :     do {                           \
    1683                 :             :         if (key_usage & (code)) {  \
    1684                 :             :             PRINT_ITEM(name);      \
    1685                 :             :         }                          \
    1686                 :             :     } while (0)
    1687                 :             : 
    1688                 :           0 : static int x509_info_ext_key_usage(char **buf, size_t *size,
    1689                 :             :                                    const mbedtls_x509_sequence *extended_key_usage)
    1690                 :             : {
    1691                 :           0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1692                 :           0 :     const char *desc;
    1693                 :           0 :     size_t n = *size;
    1694                 :           0 :     char *p = *buf;
    1695                 :           0 :     const mbedtls_x509_sequence *cur = extended_key_usage;
    1696                 :           0 :     const char *sep = "";
    1697                 :             : 
    1698         [ #  # ]:           0 :     while (cur != NULL) {
    1699         [ #  # ]:           0 :         if (mbedtls_oid_get_extended_key_usage(&cur->buf, &desc) != 0) {
    1700                 :           0 :             desc = "???";
    1701                 :             :         }
    1702                 :             : 
    1703         [ #  # ]:           0 :         ret = mbedtls_snprintf(p, n, "%s%s", sep, desc);
    1704         [ #  # ]:           0 :         MBEDTLS_X509_SAFE_SNPRINTF;
    1705                 :             : 
    1706                 :           0 :         sep = ", ";
    1707                 :             : 
    1708                 :           0 :         cur = cur->next;
    1709                 :             :     }
    1710                 :             : 
    1711                 :           0 :     *size = n;
    1712                 :           0 :     *buf = p;
    1713                 :             : 
    1714                 :           0 :     return 0;
    1715                 :             : }
    1716                 :             : 
    1717                 :           0 : static int x509_info_cert_policies(char **buf, size_t *size,
    1718                 :             :                                    const mbedtls_x509_sequence *certificate_policies)
    1719                 :             : {
    1720                 :           0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1721                 :           0 :     const char *desc;
    1722                 :           0 :     size_t n = *size;
    1723                 :           0 :     char *p = *buf;
    1724                 :           0 :     const mbedtls_x509_sequence *cur = certificate_policies;
    1725                 :           0 :     const char *sep = "";
    1726                 :             : 
    1727         [ #  # ]:           0 :     while (cur != NULL) {
    1728         [ #  # ]:           0 :         if (mbedtls_oid_get_certificate_policies(&cur->buf, &desc) != 0) {
    1729                 :           0 :             desc = "???";
    1730                 :             :         }
    1731                 :             : 
    1732         [ #  # ]:           0 :         ret = mbedtls_snprintf(p, n, "%s%s", sep, desc);
    1733         [ #  # ]:           0 :         MBEDTLS_X509_SAFE_SNPRINTF;
    1734                 :             : 
    1735                 :           0 :         sep = ", ";
    1736                 :             : 
    1737                 :           0 :         cur = cur->next;
    1738                 :             :     }
    1739                 :             : 
    1740                 :           0 :     *size = n;
    1741                 :           0 :     *buf = p;
    1742                 :             : 
    1743                 :           0 :     return 0;
    1744                 :             : }
    1745                 :             : 
    1746                 :             : /*
    1747                 :             :  * Return an informational string about the certificate.
    1748                 :             :  */
    1749                 :             : #define BEFORE_COLON    18
    1750                 :             : #define BC              "18"
    1751                 :           0 : int mbedtls_x509_crt_info(char *buf, size_t size, const char *prefix,
    1752                 :             :                           const mbedtls_x509_crt *crt)
    1753                 :             : {
    1754                 :           0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1755                 :           0 :     size_t n;
    1756                 :           0 :     char *p;
    1757                 :           0 :     char key_size_str[BEFORE_COLON];
    1758                 :             : 
    1759                 :           0 :     p = buf;
    1760                 :           0 :     n = size;
    1761                 :             : 
    1762         [ #  # ]:           0 :     if (NULL == crt) {
    1763         [ #  # ]:           0 :         ret = mbedtls_snprintf(p, n, "\nCertificate is uninitialised!\n");
    1764         [ #  # ]:           0 :         MBEDTLS_X509_SAFE_SNPRINTF;
    1765                 :             : 
    1766                 :           0 :         return (int) (size - n);
    1767                 :             :     }
    1768                 :             : 
    1769                 :           0 :     ret = mbedtls_snprintf(p, n, "%scert. version     : %d\n",
    1770         [ #  # ]:           0 :                            prefix, crt->version);
    1771         [ #  # ]:           0 :     MBEDTLS_X509_SAFE_SNPRINTF;
    1772         [ #  # ]:           0 :     ret = mbedtls_snprintf(p, n, "%sserial number     : ",
    1773                 :             :                            prefix);
    1774         [ #  # ]:           0 :     MBEDTLS_X509_SAFE_SNPRINTF;
    1775                 :             : 
    1776                 :           0 :     ret = mbedtls_x509_serial_gets(p, n, &crt->serial);
    1777         [ #  # ]:           0 :     MBEDTLS_X509_SAFE_SNPRINTF;
    1778                 :             : 
    1779         [ #  # ]:           0 :     ret = mbedtls_snprintf(p, n, "\n%sissuer name       : ", prefix);
    1780         [ #  # ]:           0 :     MBEDTLS_X509_SAFE_SNPRINTF;
    1781                 :           0 :     ret = mbedtls_x509_dn_gets(p, n, &crt->issuer);
    1782         [ #  # ]:           0 :     MBEDTLS_X509_SAFE_SNPRINTF;
    1783                 :             : 
    1784         [ #  # ]:           0 :     ret = mbedtls_snprintf(p, n, "\n%ssubject name      : ", prefix);
    1785         [ #  # ]:           0 :     MBEDTLS_X509_SAFE_SNPRINTF;
    1786                 :           0 :     ret = mbedtls_x509_dn_gets(p, n, &crt->subject);
    1787         [ #  # ]:           0 :     MBEDTLS_X509_SAFE_SNPRINTF;
    1788                 :             : 
    1789                 :           0 :     ret = mbedtls_snprintf(p, n, "\n%sissued  on        : " \
    1790                 :             :                                  "%04d-%02d-%02d %02d:%02d:%02d", prefix,
    1791                 :           0 :                            crt->valid_from.year, crt->valid_from.mon,
    1792                 :           0 :                            crt->valid_from.day,  crt->valid_from.hour,
    1793         [ #  # ]:           0 :                            crt->valid_from.min,  crt->valid_from.sec);
    1794         [ #  # ]:           0 :     MBEDTLS_X509_SAFE_SNPRINTF;
    1795                 :             : 
    1796                 :           0 :     ret = mbedtls_snprintf(p, n, "\n%sexpires on        : " \
    1797                 :             :                                  "%04d-%02d-%02d %02d:%02d:%02d", prefix,
    1798                 :           0 :                            crt->valid_to.year, crt->valid_to.mon,
    1799                 :           0 :                            crt->valid_to.day,  crt->valid_to.hour,
    1800         [ #  # ]:           0 :                            crt->valid_to.min,  crt->valid_to.sec);
    1801         [ #  # ]:           0 :     MBEDTLS_X509_SAFE_SNPRINTF;
    1802                 :             : 
    1803         [ #  # ]:           0 :     ret = mbedtls_snprintf(p, n, "\n%ssigned using      : ", prefix);
    1804         [ #  # ]:           0 :     MBEDTLS_X509_SAFE_SNPRINTF;
    1805                 :             : 
    1806                 :           0 :     ret = mbedtls_x509_sig_alg_gets(p, n, &crt->sig_oid, crt->sig_pk,
    1807                 :           0 :                                     crt->sig_md, crt->sig_opts);
    1808         [ #  # ]:           0 :     MBEDTLS_X509_SAFE_SNPRINTF;
    1809                 :             : 
    1810                 :             :     /* Key size */
    1811         [ #  # ]:           0 :     if ((ret = mbedtls_x509_key_size_helper(key_size_str, BEFORE_COLON,
    1812                 :             :                                             mbedtls_pk_get_name(&crt->pk))) != 0) {
    1813                 :             :         return ret;
    1814                 :             :     }
    1815                 :             : 
    1816         [ #  # ]:           0 :     ret = mbedtls_snprintf(p, n, "\n%s%-" BC "s: %d bits", prefix, key_size_str,
    1817                 :           0 :                            (int) mbedtls_pk_get_bitlen(&crt->pk));
    1818         [ #  # ]:           0 :     MBEDTLS_X509_SAFE_SNPRINTF;
    1819                 :             : 
    1820                 :             :     /*
    1821                 :             :      * Optional extensions
    1822                 :             :      */
    1823                 :             : 
    1824         [ #  # ]:           0 :     if (crt->ext_types & MBEDTLS_X509_EXT_BASIC_CONSTRAINTS) {
    1825         [ #  # ]:           0 :         ret = mbedtls_snprintf(p, n, "\n%sbasic constraints : CA=%s", prefix,
    1826         [ #  # ]:           0 :                                crt->ca_istrue ? "true" : "false");
    1827         [ #  # ]:           0 :         MBEDTLS_X509_SAFE_SNPRINTF;
    1828                 :             : 
    1829         [ #  # ]:           0 :         if (crt->max_pathlen > 0) {
    1830         [ #  # ]:           0 :             ret = mbedtls_snprintf(p, n, ", max_pathlen=%d", crt->max_pathlen - 1);
    1831         [ #  # ]:           0 :             MBEDTLS_X509_SAFE_SNPRINTF;
    1832                 :             :         }
    1833                 :             :     }
    1834                 :             : 
    1835         [ #  # ]:           0 :     if (crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME) {
    1836         [ #  # ]:           0 :         ret = mbedtls_snprintf(p, n, "\n%ssubject alt name  :", prefix);
    1837         [ #  # ]:           0 :         MBEDTLS_X509_SAFE_SNPRINTF;
    1838                 :             : 
    1839         [ #  # ]:           0 :         if ((ret = mbedtls_x509_info_subject_alt_name(&p, &n,
    1840                 :             :                                                       &crt->subject_alt_names,
    1841                 :             :                                                       prefix)) != 0) {
    1842                 :             :             return ret;
    1843                 :             :         }
    1844                 :             :     }
    1845                 :             : 
    1846         [ #  # ]:           0 :     if (crt->ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE) {
    1847         [ #  # ]:           0 :         ret = mbedtls_snprintf(p, n, "\n%scert. type        : ", prefix);
    1848   [ #  #  #  # ]:           0 :         MBEDTLS_X509_SAFE_SNPRINTF;
    1849                 :             : 
    1850         [ #  # ]:           0 :         if ((ret = mbedtls_x509_info_cert_type(&p, &n, crt->ns_cert_type)) != 0) {
    1851                 :             :             return ret;
    1852                 :             :         }
    1853                 :             :     }
    1854                 :             : 
    1855         [ #  # ]:           0 :     if (crt->ext_types & MBEDTLS_X509_EXT_KEY_USAGE) {
    1856         [ #  # ]:           0 :         ret = mbedtls_snprintf(p, n, "\n%skey usage         : ", prefix);
    1857   [ #  #  #  # ]:           0 :         MBEDTLS_X509_SAFE_SNPRINTF;
    1858                 :             : 
    1859         [ #  # ]:           0 :         if ((ret = mbedtls_x509_info_key_usage(&p, &n, crt->key_usage)) != 0) {
    1860                 :             :             return ret;
    1861                 :             :         }
    1862                 :             :     }
    1863                 :             : 
    1864         [ #  # ]:           0 :     if (crt->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE) {
    1865         [ #  # ]:           0 :         ret = mbedtls_snprintf(p, n, "\n%sext key usage     : ", prefix);
    1866   [ #  #  #  # ]:           0 :         MBEDTLS_X509_SAFE_SNPRINTF;
    1867                 :             : 
    1868         [ #  # ]:           0 :         if ((ret = x509_info_ext_key_usage(&p, &n,
    1869                 :             :                                            &crt->ext_key_usage)) != 0) {
    1870                 :             :             return ret;
    1871                 :             :         }
    1872                 :             :     }
    1873                 :             : 
    1874         [ #  # ]:           0 :     if (crt->ext_types & MBEDTLS_OID_X509_EXT_CERTIFICATE_POLICIES) {
    1875         [ #  # ]:           0 :         ret = mbedtls_snprintf(p, n, "\n%scertificate policies : ", prefix);
    1876   [ #  #  #  # ]:           0 :         MBEDTLS_X509_SAFE_SNPRINTF;
    1877                 :             : 
    1878         [ #  # ]:           0 :         if ((ret = x509_info_cert_policies(&p, &n,
    1879                 :             :                                            &crt->certificate_policies)) != 0) {
    1880                 :             :             return ret;
    1881                 :             :         }
    1882                 :             :     }
    1883                 :             : 
    1884         [ #  # ]:           0 :     ret = mbedtls_snprintf(p, n, "\n");
    1885   [ #  #  #  # ]:           0 :     MBEDTLS_X509_SAFE_SNPRINTF;
    1886                 :             : 
    1887                 :           0 :     return (int) (size - n);
    1888                 :             : }
    1889                 :             : 
    1890                 :             : struct x509_crt_verify_string {
    1891                 :             :     int code;
    1892                 :             :     const char *string;
    1893                 :             : };
    1894                 :             : 
    1895                 :             : #define X509_CRT_ERROR_INFO(err, err_str, info) { err, info },
    1896                 :             : static const struct x509_crt_verify_string x509_crt_verify_strings[] = {
    1897                 :             :     MBEDTLS_X509_CRT_ERROR_INFO_LIST
    1898                 :             :     { 0, NULL }
    1899                 :             : };
    1900                 :             : #undef X509_CRT_ERROR_INFO
    1901                 :             : 
    1902                 :           0 : int mbedtls_x509_crt_verify_info(char *buf, size_t size, const char *prefix,
    1903                 :             :                                  uint32_t flags)
    1904                 :             : {
    1905                 :           0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1906                 :           0 :     const struct x509_crt_verify_string *cur;
    1907                 :           0 :     char *p = buf;
    1908                 :           0 :     size_t n = size;
    1909                 :             : 
    1910         [ #  # ]:           0 :     for (cur = x509_crt_verify_strings; cur->string != NULL; cur++) {
    1911         [ #  # ]:           0 :         if ((flags & cur->code) == 0) {
    1912                 :           0 :             continue;
    1913                 :             :         }
    1914                 :             : 
    1915         [ #  # ]:           0 :         ret = mbedtls_snprintf(p, n, "%s%s\n", prefix, cur->string);
    1916         [ #  # ]:           0 :         MBEDTLS_X509_SAFE_SNPRINTF;
    1917                 :           0 :         flags ^= cur->code;
    1918                 :             :     }
    1919                 :             : 
    1920         [ #  # ]:           0 :     if (flags != 0) {
    1921         [ #  # ]:           0 :         ret = mbedtls_snprintf(p, n, "%sUnknown reason "
    1922                 :             :                                      "(this should not happen)\n", prefix);
    1923         [ #  # ]:           0 :         MBEDTLS_X509_SAFE_SNPRINTF;
    1924                 :             :     }
    1925                 :             : 
    1926                 :           0 :     return (int) (size - n);
    1927                 :             : }
    1928                 :             : #endif /* MBEDTLS_X509_REMOVE_INFO */
    1929                 :             : 
    1930                 :           0 : int mbedtls_x509_crt_check_key_usage(const mbedtls_x509_crt *crt,
    1931                 :             :                                      unsigned int usage)
    1932                 :             : {
    1933                 :           0 :     unsigned int usage_must, usage_may;
    1934                 :           0 :     unsigned int may_mask = MBEDTLS_X509_KU_ENCIPHER_ONLY
    1935                 :             :                             | MBEDTLS_X509_KU_DECIPHER_ONLY;
    1936                 :             : 
    1937         [ #  # ]:           0 :     if ((crt->ext_types & MBEDTLS_X509_EXT_KEY_USAGE) == 0) {
    1938                 :             :         return 0;
    1939                 :             :     }
    1940                 :             : 
    1941                 :           0 :     usage_must = usage & ~may_mask;
    1942                 :             : 
    1943         [ #  # ]:           0 :     if (((crt->key_usage & ~may_mask) & usage_must) != usage_must) {
    1944                 :             :         return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
    1945                 :             :     }
    1946                 :             : 
    1947                 :           0 :     usage_may = usage & may_mask;
    1948                 :             : 
    1949         [ #  # ]:           0 :     if (((crt->key_usage & may_mask) | usage_may) != usage_may) {
    1950                 :           0 :         return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
    1951                 :             :     }
    1952                 :             : 
    1953                 :             :     return 0;
    1954                 :             : }
    1955                 :             : 
    1956                 :           0 : int mbedtls_x509_crt_check_extended_key_usage(const mbedtls_x509_crt *crt,
    1957                 :             :                                               const char *usage_oid,
    1958                 :             :                                               size_t usage_len)
    1959                 :             : {
    1960                 :           0 :     const mbedtls_x509_sequence *cur;
    1961                 :             : 
    1962                 :             :     /* Extension is not mandatory, absent means no restriction */
    1963         [ #  # ]:           0 :     if ((crt->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE) == 0) {
    1964                 :             :         return 0;
    1965                 :             :     }
    1966                 :             : 
    1967                 :             :     /*
    1968                 :             :      * Look for the requested usage (or wildcard ANY) in our list
    1969                 :             :      */
    1970         [ #  # ]:           0 :     for (cur = &crt->ext_key_usage; cur != NULL; cur = cur->next) {
    1971                 :           0 :         const mbedtls_x509_buf *cur_oid = &cur->buf;
    1972                 :             : 
    1973         [ #  # ]:           0 :         if (cur_oid->len == usage_len &&
    1974         [ #  # ]:           0 :             memcmp(cur_oid->p, usage_oid, usage_len) == 0) {
    1975                 :             :             return 0;
    1976                 :             :         }
    1977                 :             : 
    1978   [ #  #  #  # ]:           0 :         if (MBEDTLS_OID_CMP(MBEDTLS_OID_ANY_EXTENDED_KEY_USAGE, cur_oid) == 0) {
    1979                 :             :             return 0;
    1980                 :             :         }
    1981                 :             :     }
    1982                 :             : 
    1983                 :             :     return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
    1984                 :             : }
    1985                 :             : 
    1986                 :             : #if defined(MBEDTLS_X509_CRL_PARSE_C)
    1987                 :             : /*
    1988                 :             :  * Return 1 if the certificate is revoked, or 0 otherwise.
    1989                 :             :  */
    1990                 :             : int mbedtls_x509_crt_is_revoked(const mbedtls_x509_crt *crt, const mbedtls_x509_crl *crl)
    1991                 :             : {
    1992                 :             :     const mbedtls_x509_crl_entry *cur = &crl->entry;
    1993                 :             : 
    1994                 :             :     while (cur != NULL && cur->serial.len != 0) {
    1995                 :             :         if (crt->serial.len == cur->serial.len &&
    1996                 :             :             memcmp(crt->serial.p, cur->serial.p, crt->serial.len) == 0) {
    1997                 :             :             return 1;
    1998                 :             :         }
    1999                 :             : 
    2000                 :             :         cur = cur->next;
    2001                 :             :     }
    2002                 :             : 
    2003                 :             :     return 0;
    2004                 :             : }
    2005                 :             : 
    2006                 :             : /*
    2007                 :             :  * Check that the given certificate is not revoked according to the CRL.
    2008                 :             :  * Skip validation if no CRL for the given CA is present.
    2009                 :             :  */
    2010                 :             : static int x509_crt_verifycrl(mbedtls_x509_crt *crt, mbedtls_x509_crt *ca,
    2011                 :             :                               mbedtls_x509_crl *crl_list,
    2012                 :             :                               const mbedtls_x509_crt_profile *profile,
    2013                 :             :                               const mbedtls_x509_time *now)
    2014                 :             : {
    2015                 :             :     int flags = 0;
    2016                 :             :     unsigned char hash[MBEDTLS_MD_MAX_SIZE];
    2017                 :             : #if defined(MBEDTLS_USE_PSA_CRYPTO)
    2018                 :             :     psa_algorithm_t psa_algorithm;
    2019                 :             : #else
    2020                 :             :     const mbedtls_md_info_t *md_info;
    2021                 :             : #endif /* MBEDTLS_USE_PSA_CRYPTO */
    2022                 :             :     size_t hash_length;
    2023                 :             : 
    2024                 :             :     if (ca == NULL) {
    2025                 :             :         return flags;
    2026                 :             :     }
    2027                 :             : 
    2028                 :             :     while (crl_list != NULL) {
    2029                 :             :         if (crl_list->version == 0 ||
    2030                 :             :             x509_name_cmp(&crl_list->issuer, &ca->subject) != 0) {
    2031                 :             :             crl_list = crl_list->next;
    2032                 :             :             continue;
    2033                 :             :         }
    2034                 :             : 
    2035                 :             :         /*
    2036                 :             :          * Check if the CA is configured to sign CRLs
    2037                 :             :          */
    2038                 :             :         if (mbedtls_x509_crt_check_key_usage(ca,
    2039                 :             :                                              MBEDTLS_X509_KU_CRL_SIGN) != 0) {
    2040                 :             :             flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
    2041                 :             :             break;
    2042                 :             :         }
    2043                 :             : 
    2044                 :             :         /*
    2045                 :             :          * Check if CRL is correctly signed by the trusted CA
    2046                 :             :          */
    2047                 :             :         if (x509_profile_check_md_alg(profile, crl_list->sig_md) != 0) {
    2048                 :             :             flags |= MBEDTLS_X509_BADCRL_BAD_MD;
    2049                 :             :         }
    2050                 :             : 
    2051                 :             :         if (x509_profile_check_pk_alg(profile, crl_list->sig_pk) != 0) {
    2052                 :             :             flags |= MBEDTLS_X509_BADCRL_BAD_PK;
    2053                 :             :         }
    2054                 :             : 
    2055                 :             : #if defined(MBEDTLS_USE_PSA_CRYPTO)
    2056                 :             :         psa_algorithm = mbedtls_md_psa_alg_from_type(crl_list->sig_md);
    2057                 :             :         if (psa_hash_compute(psa_algorithm,
    2058                 :             :                              crl_list->tbs.p,
    2059                 :             :                              crl_list->tbs.len,
    2060                 :             :                              hash,
    2061                 :             :                              sizeof(hash),
    2062                 :             :                              &hash_length) != PSA_SUCCESS) {
    2063                 :             :             /* Note: this can't happen except after an internal error */
    2064                 :             :             flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
    2065                 :             :             break;
    2066                 :             :         }
    2067                 :             : #else
    2068                 :             :         md_info = mbedtls_md_info_from_type(crl_list->sig_md);
    2069                 :             :         hash_length = mbedtls_md_get_size(md_info);
    2070                 :             :         if (mbedtls_md(md_info,
    2071                 :             :                        crl_list->tbs.p,
    2072                 :             :                        crl_list->tbs.len,
    2073                 :             :                        hash) != 0) {
    2074                 :             :             /* Note: this can't happen except after an internal error */
    2075                 :             :             flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
    2076                 :             :             break;
    2077                 :             :         }
    2078                 :             : #endif /* MBEDTLS_USE_PSA_CRYPTO */
    2079                 :             : 
    2080                 :             :         if (x509_profile_check_key(profile, &ca->pk) != 0) {
    2081                 :             :             flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
    2082                 :             :         }
    2083                 :             : 
    2084                 :             :         if (mbedtls_pk_verify_ext(crl_list->sig_pk, crl_list->sig_opts, &ca->pk,
    2085                 :             :                                   crl_list->sig_md, hash, hash_length,
    2086                 :             :                                   crl_list->sig.p, crl_list->sig.len) != 0) {
    2087                 :             :             flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
    2088                 :             :             break;
    2089                 :             :         }
    2090                 :             : 
    2091                 :             : #if defined(MBEDTLS_HAVE_TIME_DATE)
    2092                 :             :         /*
    2093                 :             :          * Check for validity of CRL (Do not drop out)
    2094                 :             :          */
    2095                 :             :         if (mbedtls_x509_time_cmp(&crl_list->next_update, now) < 0) {
    2096                 :             :             flags |= MBEDTLS_X509_BADCRL_EXPIRED;
    2097                 :             :         }
    2098                 :             : 
    2099                 :             :         if (mbedtls_x509_time_cmp(&crl_list->this_update, now) > 0) {
    2100                 :             :             flags |= MBEDTLS_X509_BADCRL_FUTURE;
    2101                 :             :         }
    2102                 :             : #else
    2103                 :             :         ((void) now);
    2104                 :             : #endif
    2105                 :             : 
    2106                 :             :         /*
    2107                 :             :          * Check if certificate is revoked
    2108                 :             :          */
    2109                 :             :         if (mbedtls_x509_crt_is_revoked(crt, crl_list)) {
    2110                 :             :             flags |= MBEDTLS_X509_BADCERT_REVOKED;
    2111                 :             :             break;
    2112                 :             :         }
    2113                 :             : 
    2114                 :             :         crl_list = crl_list->next;
    2115                 :             :     }
    2116                 :             : 
    2117                 :             :     return flags;
    2118                 :             : }
    2119                 :             : #endif /* MBEDTLS_X509_CRL_PARSE_C */
    2120                 :             : 
    2121                 :             : /*
    2122                 :             :  * Check the signature of a certificate by its parent
    2123                 :             :  */
    2124                 :           0 : static int x509_crt_check_signature(const mbedtls_x509_crt *child,
    2125                 :             :                                     mbedtls_x509_crt *parent,
    2126                 :             :                                     mbedtls_x509_crt_restart_ctx *rs_ctx)
    2127                 :             : {
    2128                 :           0 :     size_t hash_len;
    2129                 :           0 :     unsigned char hash[MBEDTLS_MD_MAX_SIZE];
    2130                 :             : #if !defined(MBEDTLS_USE_PSA_CRYPTO)
    2131                 :           0 :     const mbedtls_md_info_t *md_info;
    2132                 :           0 :     md_info = mbedtls_md_info_from_type(child->sig_md);
    2133                 :           0 :     hash_len = mbedtls_md_get_size(md_info);
    2134                 :             : 
    2135                 :             :     /* Note: hash errors can happen only after an internal error */
    2136         [ #  # ]:           0 :     if (mbedtls_md(md_info, child->tbs.p, child->tbs.len, hash) != 0) {
    2137                 :             :         return -1;
    2138                 :             :     }
    2139                 :             : #else
    2140                 :             :     psa_algorithm_t hash_alg = mbedtls_md_psa_alg_from_type(child->sig_md);
    2141                 :             :     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
    2142                 :             : 
    2143                 :             :     status = psa_hash_compute(hash_alg,
    2144                 :             :                               child->tbs.p,
    2145                 :             :                               child->tbs.len,
    2146                 :             :                               hash,
    2147                 :             :                               sizeof(hash),
    2148                 :             :                               &hash_len);
    2149                 :             :     if (status != PSA_SUCCESS) {
    2150                 :             :         return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED;
    2151                 :             :     }
    2152                 :             : 
    2153                 :             : #endif /* MBEDTLS_USE_PSA_CRYPTO */
    2154                 :             :     /* Skip expensive computation on obvious mismatch */
    2155         [ #  # ]:           0 :     if (!mbedtls_pk_can_do(&parent->pk, child->sig_pk)) {
    2156                 :             :         return -1;
    2157                 :             :     }
    2158                 :             : 
    2159                 :             : #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
    2160                 :             :     if (rs_ctx != NULL && child->sig_pk == MBEDTLS_PK_ECDSA) {
    2161                 :             :         return mbedtls_pk_verify_restartable(&parent->pk,
    2162                 :             :                                              child->sig_md, hash, hash_len,
    2163                 :             :                                              child->sig.p, child->sig.len, &rs_ctx->pk);
    2164                 :             :     }
    2165                 :             : #else
    2166                 :           0 :     (void) rs_ctx;
    2167                 :             : #endif
    2168                 :             : 
    2169                 :           0 :     return mbedtls_pk_verify_ext(child->sig_pk, child->sig_opts, &parent->pk,
    2170                 :           0 :                                  child->sig_md, hash, hash_len,
    2171                 :           0 :                                  child->sig.p, child->sig.len);
    2172                 :             : }
    2173                 :             : 
    2174                 :             : /*
    2175                 :             :  * Check if 'parent' is a suitable parent (signing CA) for 'child'.
    2176                 :             :  * Return 0 if yes, -1 if not.
    2177                 :             :  *
    2178                 :             :  * top means parent is a locally-trusted certificate
    2179                 :             :  */
    2180                 :           0 : static int x509_crt_check_parent(const mbedtls_x509_crt *child,
    2181                 :             :                                  const mbedtls_x509_crt *parent,
    2182                 :             :                                  int top)
    2183                 :             : {
    2184                 :           0 :     int need_ca_bit;
    2185                 :             : 
    2186                 :             :     /* Parent must be the issuer */
    2187         [ #  # ]:           0 :     if (x509_name_cmp(&child->issuer, &parent->subject) != 0) {
    2188                 :             :         return -1;
    2189                 :             :     }
    2190                 :             : 
    2191                 :             :     /* Parent must have the basicConstraints CA bit set as a general rule */
    2192                 :           0 :     need_ca_bit = 1;
    2193                 :             : 
    2194                 :             :     /* Exception: v1/v2 certificates that are locally trusted. */
    2195   [ #  #  #  # ]:           0 :     if (top && parent->version < 3) {
    2196                 :             :         need_ca_bit = 0;
    2197                 :             :     }
    2198                 :             : 
    2199         [ #  # ]:           0 :     if (need_ca_bit && !parent->ca_istrue) {
    2200                 :             :         return -1;
    2201                 :             :     }
    2202                 :             : 
    2203                 :           0 :     if (need_ca_bit &&
    2204         [ #  # ]:           0 :         mbedtls_x509_crt_check_key_usage(parent, MBEDTLS_X509_KU_KEY_CERT_SIGN) != 0) {
    2205                 :           0 :         return -1;
    2206                 :             :     }
    2207                 :             : 
    2208                 :             :     return 0;
    2209                 :             : }
    2210                 :             : 
    2211                 :             : /*
    2212                 :             :  * Find a suitable parent for child in candidates, or return NULL.
    2213                 :             :  *
    2214                 :             :  * Here suitable is defined as:
    2215                 :             :  *  1. subject name matches child's issuer
    2216                 :             :  *  2. if necessary, the CA bit is set and key usage allows signing certs
    2217                 :             :  *  3. for trusted roots, the signature is correct
    2218                 :             :  *     (for intermediates, the signature is checked and the result reported)
    2219                 :             :  *  4. pathlen constraints are satisfied
    2220                 :             :  *
    2221                 :             :  * If there's a suitable candidate which is also time-valid, return the first
    2222                 :             :  * such. Otherwise, return the first suitable candidate (or NULL if there is
    2223                 :             :  * none).
    2224                 :             :  *
    2225                 :             :  * The rationale for this rule is that someone could have a list of trusted
    2226                 :             :  * roots with two versions on the same root with different validity periods.
    2227                 :             :  * (At least one user reported having such a list and wanted it to just work.)
    2228                 :             :  * The reason we don't just require time-validity is that generally there is
    2229                 :             :  * only one version, and if it's expired we want the flags to state that
    2230                 :             :  * rather than NOT_TRUSTED, as would be the case if we required it here.
    2231                 :             :  *
    2232                 :             :  * The rationale for rule 3 (signature for trusted roots) is that users might
    2233                 :             :  * have two versions of the same CA with different keys in their list, and the
    2234                 :             :  * way we select the correct one is by checking the signature (as we don't
    2235                 :             :  * rely on key identifier extensions). (This is one way users might choose to
    2236                 :             :  * handle key rollover, another relies on self-issued certs, see [SIRO].)
    2237                 :             :  *
    2238                 :             :  * Arguments:
    2239                 :             :  *  - [in] child: certificate for which we're looking for a parent
    2240                 :             :  *  - [in] candidates: chained list of potential parents
    2241                 :             :  *  - [out] r_parent: parent found (or NULL)
    2242                 :             :  *  - [out] r_signature_is_good: 1 if child signature by parent is valid, or 0
    2243                 :             :  *  - [in] top: 1 if candidates consists of trusted roots, ie we're at the top
    2244                 :             :  *         of the chain, 0 otherwise
    2245                 :             :  *  - [in] path_cnt: number of intermediates seen so far
    2246                 :             :  *  - [in] self_cnt: number of self-signed intermediates seen so far
    2247                 :             :  *         (will never be greater than path_cnt)
    2248                 :             :  *  - [in-out] rs_ctx: context for restarting operations
    2249                 :             :  *
    2250                 :             :  * Return value:
    2251                 :             :  *  - 0 on success
    2252                 :             :  *  - MBEDTLS_ERR_ECP_IN_PROGRESS otherwise
    2253                 :             :  */
    2254                 :           0 : static int x509_crt_find_parent_in(
    2255                 :             :     mbedtls_x509_crt *child,
    2256                 :             :     mbedtls_x509_crt *candidates,
    2257                 :             :     mbedtls_x509_crt **r_parent,
    2258                 :             :     int *r_signature_is_good,
    2259                 :             :     int top,
    2260                 :             :     unsigned path_cnt,
    2261                 :             :     unsigned self_cnt,
    2262                 :             :     mbedtls_x509_crt_restart_ctx *rs_ctx,
    2263                 :             :     const mbedtls_x509_time *now)
    2264                 :             : {
    2265                 :           0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    2266                 :           0 :     mbedtls_x509_crt *parent, *fallback_parent;
    2267                 :           0 :     int signature_is_good = 0, fallback_signature_is_good;
    2268                 :             : 
    2269                 :             : #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
    2270                 :             :     /* did we have something in progress? */
    2271                 :             :     if (rs_ctx != NULL && rs_ctx->parent != NULL) {
    2272                 :             :         /* restore saved state */
    2273                 :             :         parent = rs_ctx->parent;
    2274                 :             :         fallback_parent = rs_ctx->fallback_parent;
    2275                 :             :         fallback_signature_is_good = rs_ctx->fallback_signature_is_good;
    2276                 :             : 
    2277                 :             :         /* clear saved state */
    2278                 :             :         rs_ctx->parent = NULL;
    2279                 :             :         rs_ctx->fallback_parent = NULL;
    2280                 :             :         rs_ctx->fallback_signature_is_good = 0;
    2281                 :             : 
    2282                 :             :         /* resume where we left */
    2283                 :             :         goto check_signature;
    2284                 :             :     }
    2285                 :             : #endif
    2286                 :             : 
    2287                 :           0 :     fallback_parent = NULL;
    2288                 :           0 :     fallback_signature_is_good = 0;
    2289                 :             : 
    2290         [ #  # ]:           0 :     for (parent = candidates; parent != NULL; parent = parent->next) {
    2291                 :             :         /* basic parenting skills (name, CA bit, key usage) */
    2292         [ #  # ]:           0 :         if (x509_crt_check_parent(child, parent, top) != 0) {
    2293                 :           0 :             continue;
    2294                 :             :         }
    2295                 :             : 
    2296                 :             :         /* +1 because stored max_pathlen is 1 higher that the actual value */
    2297         [ #  # ]:           0 :         if (parent->max_pathlen > 0 &&
    2298         [ #  # ]:           0 :             (size_t) parent->max_pathlen < 1 + path_cnt - self_cnt) {
    2299                 :           0 :             continue;
    2300                 :             :         }
    2301                 :             : 
    2302                 :             :         /* Signature */
    2303                 :             : #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
    2304                 :             : check_signature:
    2305                 :             : #endif
    2306                 :           0 :         ret = x509_crt_check_signature(child, parent, rs_ctx);
    2307                 :             : 
    2308                 :             : #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
    2309                 :             :         if (rs_ctx != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS) {
    2310                 :             :             /* save state */
    2311                 :             :             rs_ctx->parent = parent;
    2312                 :             :             rs_ctx->fallback_parent = fallback_parent;
    2313                 :             :             rs_ctx->fallback_signature_is_good = fallback_signature_is_good;
    2314                 :             : 
    2315                 :             :             return ret;
    2316                 :             :         }
    2317                 :             : #else
    2318                 :           0 :         (void) ret;
    2319                 :             : #endif
    2320                 :             : 
    2321                 :           0 :         signature_is_good = ret == 0;
    2322         [ #  # ]:           0 :         if (top && !signature_is_good) {
    2323                 :           0 :             continue;
    2324                 :             :         }
    2325                 :             : 
    2326                 :             : #if defined(MBEDTLS_HAVE_TIME_DATE)
    2327                 :             :         /* optional time check */
    2328                 :             :         if (mbedtls_x509_time_cmp(&parent->valid_to, now) < 0 ||    /* past */
    2329                 :             :             mbedtls_x509_time_cmp(&parent->valid_from, now) > 0) {  /* future */
    2330                 :             :             if (fallback_parent == NULL) {
    2331                 :             :                 fallback_parent = parent;
    2332                 :             :                 fallback_signature_is_good = signature_is_good;
    2333                 :             :             }
    2334                 :             : 
    2335                 :             :             continue;
    2336                 :             :         }
    2337                 :             : #else
    2338                 :           0 :         ((void) now);
    2339                 :             : #endif
    2340                 :             : 
    2341                 :           0 :         *r_parent = parent;
    2342                 :           0 :         *r_signature_is_good = signature_is_good;
    2343                 :             : 
    2344                 :           0 :         break;
    2345                 :             :     }
    2346                 :             : 
    2347         [ #  # ]:           0 :     if (parent == NULL) {
    2348                 :           0 :         *r_parent = fallback_parent;
    2349                 :           0 :         *r_signature_is_good = fallback_signature_is_good;
    2350                 :             :     }
    2351                 :             : 
    2352                 :           0 :     return 0;
    2353                 :             : }
    2354                 :             : 
    2355                 :             : /*
    2356                 :             :  * Find a parent in trusted CAs or the provided chain, or return NULL.
    2357                 :             :  *
    2358                 :             :  * Searches in trusted CAs first, and return the first suitable parent found
    2359                 :             :  * (see find_parent_in() for definition of suitable).
    2360                 :             :  *
    2361                 :             :  * Arguments:
    2362                 :             :  *  - [in] child: certificate for which we're looking for a parent, followed
    2363                 :             :  *         by a chain of possible intermediates
    2364                 :             :  *  - [in] trust_ca: list of locally trusted certificates
    2365                 :             :  *  - [out] parent: parent found (or NULL)
    2366                 :             :  *  - [out] parent_is_trusted: 1 if returned `parent` is trusted, or 0
    2367                 :             :  *  - [out] signature_is_good: 1 if child signature by parent is valid, or 0
    2368                 :             :  *  - [in] path_cnt: number of links in the chain so far (EE -> ... -> child)
    2369                 :             :  *  - [in] self_cnt: number of self-signed certs in the chain so far
    2370                 :             :  *         (will always be no greater than path_cnt)
    2371                 :             :  *  - [in-out] rs_ctx: context for restarting operations
    2372                 :             :  *
    2373                 :             :  * Return value:
    2374                 :             :  *  - 0 on success
    2375                 :             :  *  - MBEDTLS_ERR_ECP_IN_PROGRESS otherwise
    2376                 :             :  */
    2377                 :           0 : static int x509_crt_find_parent(
    2378                 :             :     mbedtls_x509_crt *child,
    2379                 :             :     mbedtls_x509_crt *trust_ca,
    2380                 :             :     mbedtls_x509_crt **parent,
    2381                 :             :     int *parent_is_trusted,
    2382                 :             :     int *signature_is_good,
    2383                 :             :     unsigned path_cnt,
    2384                 :             :     unsigned self_cnt,
    2385                 :             :     mbedtls_x509_crt_restart_ctx *rs_ctx,
    2386                 :             :     const mbedtls_x509_time *now)
    2387                 :             : {
    2388                 :           0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    2389                 :           0 :     mbedtls_x509_crt *search_list;
    2390                 :             : 
    2391                 :           0 :     *parent_is_trusted = 1;
    2392                 :             : 
    2393                 :             : #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
    2394                 :             :     /* restore then clear saved state if we have some stored */
    2395                 :             :     if (rs_ctx != NULL && rs_ctx->parent_is_trusted != -1) {
    2396                 :             :         *parent_is_trusted = rs_ctx->parent_is_trusted;
    2397                 :             :         rs_ctx->parent_is_trusted = -1;
    2398                 :             :     }
    2399                 :             : #endif
    2400                 :             : 
    2401                 :           0 :     while (1) {
    2402         [ #  # ]:           0 :         search_list = *parent_is_trusted ? trust_ca : child->next;
    2403                 :             : 
    2404                 :           0 :         ret = x509_crt_find_parent_in(child, search_list,
    2405                 :             :                                       parent, signature_is_good,
    2406                 :             :                                       *parent_is_trusted,
    2407                 :             :                                       path_cnt, self_cnt, rs_ctx, now);
    2408                 :             : 
    2409                 :             : #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
    2410                 :             :         if (rs_ctx != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS) {
    2411                 :             :             /* save state */
    2412                 :             :             rs_ctx->parent_is_trusted = *parent_is_trusted;
    2413                 :             :             return ret;
    2414                 :             :         }
    2415                 :             : #else
    2416                 :           0 :         (void) ret;
    2417                 :             : #endif
    2418                 :             : 
    2419                 :             :         /* stop here if found or already in second iteration */
    2420   [ #  #  #  # ]:           0 :         if (*parent != NULL || *parent_is_trusted == 0) {
    2421                 :             :             break;
    2422                 :             :         }
    2423                 :             : 
    2424                 :             :         /* prepare second iteration */
    2425                 :           0 :         *parent_is_trusted = 0;
    2426                 :             :     }
    2427                 :             : 
    2428                 :             :     /* extra precaution against mistakes in the caller */
    2429         [ #  # ]:           0 :     if (*parent == NULL) {
    2430                 :           0 :         *parent_is_trusted = 0;
    2431                 :           0 :         *signature_is_good = 0;
    2432                 :             :     }
    2433                 :             : 
    2434                 :           0 :     return 0;
    2435                 :             : }
    2436                 :             : 
    2437                 :             : /*
    2438                 :             :  * Check if an end-entity certificate is locally trusted
    2439                 :             :  *
    2440                 :             :  * Currently we require such certificates to be self-signed (actually only
    2441                 :             :  * check for self-issued as self-signatures are not checked)
    2442                 :             :  */
    2443                 :           0 : static int x509_crt_check_ee_locally_trusted(
    2444                 :             :     mbedtls_x509_crt *crt,
    2445                 :             :     mbedtls_x509_crt *trust_ca)
    2446                 :             : {
    2447                 :           0 :     mbedtls_x509_crt *cur;
    2448                 :             : 
    2449                 :             :     /* must be self-issued */
    2450         [ #  # ]:           0 :     if (x509_name_cmp(&crt->issuer, &crt->subject) != 0) {
    2451                 :             :         return -1;
    2452                 :             :     }
    2453                 :             : 
    2454                 :             :     /* look for an exact match with trusted cert */
    2455         [ #  # ]:           0 :     for (cur = trust_ca; cur != NULL; cur = cur->next) {
    2456         [ #  # ]:           0 :         if (crt->raw.len == cur->raw.len &&
    2457         [ #  # ]:           0 :             memcmp(crt->raw.p, cur->raw.p, crt->raw.len) == 0) {
    2458                 :             :             return 0;
    2459                 :             :         }
    2460                 :             :     }
    2461                 :             : 
    2462                 :             :     /* too bad */
    2463                 :             :     return -1;
    2464                 :             : }
    2465                 :             : 
    2466                 :             : /*
    2467                 :             :  * Build and verify a certificate chain
    2468                 :             :  *
    2469                 :             :  * Given a peer-provided list of certificates EE, C1, ..., Cn and
    2470                 :             :  * a list of trusted certs R1, ... Rp, try to build and verify a chain
    2471                 :             :  *      EE, Ci1, ... Ciq [, Rj]
    2472                 :             :  * such that every cert in the chain is a child of the next one,
    2473                 :             :  * jumping to a trusted root as early as possible.
    2474                 :             :  *
    2475                 :             :  * Verify that chain and return it with flags for all issues found.
    2476                 :             :  *
    2477                 :             :  * Special cases:
    2478                 :             :  * - EE == Rj -> return a one-element list containing it
    2479                 :             :  * - EE, Ci1, ..., Ciq cannot be continued with a trusted root
    2480                 :             :  *   -> return that chain with NOT_TRUSTED set on Ciq
    2481                 :             :  *
    2482                 :             :  * Tests for (aspects of) this function should include at least:
    2483                 :             :  * - trusted EE
    2484                 :             :  * - EE -> trusted root
    2485                 :             :  * - EE -> intermediate CA -> trusted root
    2486                 :             :  * - if relevant: EE untrusted
    2487                 :             :  * - if relevant: EE -> intermediate, untrusted
    2488                 :             :  * with the aspect under test checked at each relevant level (EE, int, root).
    2489                 :             :  * For some aspects longer chains are required, but usually length 2 is
    2490                 :             :  * enough (but length 1 is not in general).
    2491                 :             :  *
    2492                 :             :  * Arguments:
    2493                 :             :  *  - [in] crt: the cert list EE, C1, ..., Cn
    2494                 :             :  *  - [in] trust_ca: the trusted list R1, ..., Rp
    2495                 :             :  *  - [in] ca_crl, profile: as in verify_with_profile()
    2496                 :             :  *  - [out] ver_chain: the built and verified chain
    2497                 :             :  *      Only valid when return value is 0, may contain garbage otherwise!
    2498                 :             :  *      Restart note: need not be the same when calling again to resume.
    2499                 :             :  *  - [in-out] rs_ctx: context for restarting operations
    2500                 :             :  *
    2501                 :             :  * Return value:
    2502                 :             :  *  - non-zero if the chain could not be fully built and examined
    2503                 :             :  *  - 0 is the chain was successfully built and examined,
    2504                 :             :  *      even if it was found to be invalid
    2505                 :             :  */
    2506                 :           0 : static int x509_crt_verify_chain(
    2507                 :             :     mbedtls_x509_crt *crt,
    2508                 :             :     mbedtls_x509_crt *trust_ca,
    2509                 :             :     mbedtls_x509_crl *ca_crl,
    2510                 :             :     mbedtls_x509_crt_ca_cb_t f_ca_cb,
    2511                 :             :     void *p_ca_cb,
    2512                 :             :     const mbedtls_x509_crt_profile *profile,
    2513                 :             :     mbedtls_x509_crt_verify_chain *ver_chain,
    2514                 :             :     mbedtls_x509_crt_restart_ctx *rs_ctx)
    2515                 :             : {
    2516                 :             :     /* Don't initialize any of those variables here, so that the compiler can
    2517                 :             :      * catch potential issues with jumping ahead when restarting */
    2518                 :           0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    2519                 :           0 :     uint32_t *flags;
    2520                 :           0 :     mbedtls_x509_crt_verify_chain_item *cur;
    2521                 :           0 :     mbedtls_x509_crt *child;
    2522                 :           0 :     mbedtls_x509_crt *parent;
    2523                 :           0 :     int parent_is_trusted;
    2524                 :           0 :     int child_is_trusted;
    2525                 :           0 :     int signature_is_good;
    2526                 :           0 :     unsigned self_cnt;
    2527                 :           0 :     mbedtls_x509_crt *cur_trust_ca = NULL;
    2528                 :           0 :     mbedtls_x509_time now;
    2529                 :             : 
    2530                 :             : #if defined(MBEDTLS_HAVE_TIME_DATE)
    2531                 :             :     if (mbedtls_x509_time_gmtime(mbedtls_time(NULL), &now) != 0) {
    2532                 :             :         return MBEDTLS_ERR_X509_FATAL_ERROR;
    2533                 :             :     }
    2534                 :             : #endif
    2535                 :             : 
    2536                 :             : #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
    2537                 :             :     /* resume if we had an operation in progress */
    2538                 :             :     if (rs_ctx != NULL && rs_ctx->in_progress == x509_crt_rs_find_parent) {
    2539                 :             :         /* restore saved state */
    2540                 :             :         *ver_chain = rs_ctx->ver_chain; /* struct copy */
    2541                 :             :         self_cnt = rs_ctx->self_cnt;
    2542                 :             : 
    2543                 :             :         /* restore derived state */
    2544                 :             :         cur = &ver_chain->items[ver_chain->len - 1];
    2545                 :             :         child = cur->crt;
    2546                 :             :         flags = &cur->flags;
    2547                 :             : 
    2548                 :             :         goto find_parent;
    2549                 :             :     }
    2550                 :             : #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
    2551                 :             : 
    2552                 :           0 :     child = crt;
    2553                 :           0 :     self_cnt = 0;
    2554                 :           0 :     parent_is_trusted = 0;
    2555                 :           0 :     child_is_trusted = 0;
    2556                 :             : 
    2557                 :           0 :     while (1) {
    2558                 :             :         /* Add certificate to the verification chain */
    2559                 :           0 :         cur = &ver_chain->items[ver_chain->len];
    2560                 :           0 :         cur->crt = child;
    2561                 :           0 :         cur->flags = 0;
    2562                 :           0 :         ver_chain->len++;
    2563                 :           0 :         flags = &cur->flags;
    2564                 :             : 
    2565                 :             : #if defined(MBEDTLS_HAVE_TIME_DATE)
    2566                 :             :         /* Check time-validity (all certificates) */
    2567                 :             :         if (mbedtls_x509_time_cmp(&child->valid_to, &now) < 0) {
    2568                 :             :             *flags |= MBEDTLS_X509_BADCERT_EXPIRED;
    2569                 :             :         }
    2570                 :             : 
    2571                 :             :         if (mbedtls_x509_time_cmp(&child->valid_from, &now) > 0) {
    2572                 :             :             *flags |= MBEDTLS_X509_BADCERT_FUTURE;
    2573                 :             :         }
    2574                 :             : #endif
    2575                 :             : 
    2576                 :             :         /* Stop here for trusted roots (but not for trusted EE certs) */
    2577         [ #  # ]:           0 :         if (child_is_trusted) {
    2578                 :             :             return 0;
    2579                 :             :         }
    2580                 :             : 
    2581                 :             :         /* Check signature algorithm: MD & PK algs */
    2582         [ #  # ]:           0 :         if (x509_profile_check_md_alg(profile, child->sig_md) != 0) {
    2583                 :           0 :             *flags |= MBEDTLS_X509_BADCERT_BAD_MD;
    2584                 :             :         }
    2585                 :             : 
    2586         [ #  # ]:           0 :         if (x509_profile_check_pk_alg(profile, child->sig_pk) != 0) {
    2587                 :           0 :             *flags |= MBEDTLS_X509_BADCERT_BAD_PK;
    2588                 :             :         }
    2589                 :             : 
    2590                 :             :         /* Special case: EE certs that are locally trusted */
    2591   [ #  #  #  # ]:           0 :         if (ver_chain->len == 1 &&
    2592                 :           0 :             x509_crt_check_ee_locally_trusted(child, trust_ca) == 0) {
    2593                 :             :             return 0;
    2594                 :             :         }
    2595                 :             : 
    2596                 :             : #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
    2597                 :             : find_parent:
    2598                 :             : #endif
    2599                 :             : 
    2600                 :             :         /* Obtain list of potential trusted signers from CA callback,
    2601                 :             :          * or use statically provided list. */
    2602                 :             : #if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
    2603                 :             :         if (f_ca_cb != NULL) {
    2604                 :             :             mbedtls_x509_crt_free(ver_chain->trust_ca_cb_result);
    2605                 :             :             mbedtls_free(ver_chain->trust_ca_cb_result);
    2606                 :             :             ver_chain->trust_ca_cb_result = NULL;
    2607                 :             : 
    2608                 :             :             ret = f_ca_cb(p_ca_cb, child, &ver_chain->trust_ca_cb_result);
    2609                 :             :             if (ret != 0) {
    2610                 :             :                 return MBEDTLS_ERR_X509_FATAL_ERROR;
    2611                 :             :             }
    2612                 :             : 
    2613                 :             :             cur_trust_ca = ver_chain->trust_ca_cb_result;
    2614                 :             :         } else
    2615                 :             : #endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
    2616                 :             :         {
    2617                 :           0 :             ((void) f_ca_cb);
    2618                 :           0 :             ((void) p_ca_cb);
    2619                 :           0 :             cur_trust_ca = trust_ca;
    2620                 :             :         }
    2621                 :             : 
    2622                 :             :         /* Look for a parent in trusted CAs or up the chain */
    2623                 :           0 :         ret = x509_crt_find_parent(child, cur_trust_ca, &parent,
    2624                 :             :                                    &parent_is_trusted, &signature_is_good,
    2625                 :             :                                    ver_chain->len - 1, self_cnt, rs_ctx,
    2626                 :             :                                    &now);
    2627                 :             : 
    2628                 :             : #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
    2629                 :             :         if (rs_ctx != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS) {
    2630                 :             :             /* save state */
    2631                 :             :             rs_ctx->in_progress = x509_crt_rs_find_parent;
    2632                 :             :             rs_ctx->self_cnt = self_cnt;
    2633                 :             :             rs_ctx->ver_chain = *ver_chain; /* struct copy */
    2634                 :             : 
    2635                 :             :             return ret;
    2636                 :             :         }
    2637                 :             : #else
    2638                 :           0 :         (void) ret;
    2639                 :             : #endif
    2640                 :             : 
    2641                 :             :         /* No parent? We're done here */
    2642         [ #  # ]:           0 :         if (parent == NULL) {
    2643                 :           0 :             *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
    2644                 :           0 :             return 0;
    2645                 :             :         }
    2646                 :             : 
    2647                 :             :         /* Count intermediate self-issued (not necessarily self-signed) certs.
    2648                 :             :          * These can occur with some strategies for key rollover, see [SIRO],
    2649                 :             :          * and should be excluded from max_pathlen checks. */
    2650   [ #  #  #  # ]:           0 :         if (ver_chain->len != 1 &&
    2651                 :           0 :             x509_name_cmp(&child->issuer, &child->subject) == 0) {
    2652                 :           0 :             self_cnt++;
    2653                 :             :         }
    2654                 :             : 
    2655                 :             :         /* path_cnt is 0 for the first intermediate CA,
    2656                 :             :          * and if parent is trusted it's not an intermediate CA */
    2657   [ #  #  #  # ]:           0 :         if (!parent_is_trusted &&
    2658                 :             :             ver_chain->len > MBEDTLS_X509_MAX_INTERMEDIATE_CA) {
    2659                 :             :             /* return immediately to avoid overflow the chain array */
    2660                 :             :             return MBEDTLS_ERR_X509_FATAL_ERROR;
    2661                 :             :         }
    2662                 :             : 
    2663                 :             :         /* signature was checked while searching parent */
    2664         [ #  # ]:           0 :         if (!signature_is_good) {
    2665                 :           0 :             *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
    2666                 :             :         }
    2667                 :             : 
    2668                 :             :         /* check size of signing key */
    2669         [ #  # ]:           0 :         if (x509_profile_check_key(profile, &parent->pk) != 0) {
    2670                 :           0 :             *flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
    2671                 :             :         }
    2672                 :             : 
    2673                 :             : #if defined(MBEDTLS_X509_CRL_PARSE_C)
    2674                 :             :         /* Check trusted CA's CRL for the given crt */
    2675                 :             :         *flags |= x509_crt_verifycrl(child, parent, ca_crl, profile, &now);
    2676                 :             : #else
    2677                 :           0 :         (void) ca_crl;
    2678                 :             : #endif
    2679                 :             : 
    2680                 :             :         /* prepare for next iteration */
    2681                 :           0 :         child = parent;
    2682                 :           0 :         parent = NULL;
    2683                 :           0 :         child_is_trusted = parent_is_trusted;
    2684                 :           0 :         signature_is_good = 0;
    2685                 :             :     }
    2686                 :             : }
    2687                 :             : 
    2688                 :             : #ifdef _WIN32
    2689                 :             : #ifdef _MSC_VER
    2690                 :             : #pragma comment(lib, "ws2_32.lib")
    2691                 :             : #include <winsock2.h>
    2692                 :             : #include <ws2tcpip.h>
    2693                 :             : #elif (defined(__MINGW32__) || defined(__MINGW64__)) && _WIN32_WINNT >= 0x0600
    2694                 :             : #include <winsock2.h>
    2695                 :             : #include <ws2tcpip.h>
    2696                 :             : #else
    2697                 :             : /* inet_pton() is not supported, fallback to software version */
    2698                 :             : #define MBEDTLS_TEST_SW_INET_PTON
    2699                 :             : #endif
    2700                 :             : #elif defined(__sun)
    2701                 :             : /* Solaris requires -lsocket -lnsl for inet_pton() */
    2702                 :             : #elif defined(__has_include)
    2703                 :             : #if __has_include(<sys/socket.h>)
    2704                 :             : #include <sys/socket.h>
    2705                 :             : #endif
    2706                 :             : #if __has_include(<arpa/inet.h>)
    2707                 :             : #include <arpa/inet.h>
    2708                 :             : #endif
    2709                 :             : #endif
    2710                 :             : 
    2711                 :             : /* Use whether or not AF_INET6 is defined to indicate whether or not to use
    2712                 :             :  * the platform inet_pton() or a local implementation (below).  The local
    2713                 :             :  * implementation may be used even in cases where the platform provides
    2714                 :             :  * inet_pton(), e.g. when there are different includes required and/or the
    2715                 :             :  * platform implementation requires dependencies on additional libraries.
    2716                 :             :  * Specifically, Windows requires custom includes and additional link
    2717                 :             :  * dependencies, and Solaris requires additional link dependencies.
    2718                 :             :  * Also, as a coarse heuristic, use the local implementation if the compiler
    2719                 :             :  * does not support __has_include(), or if the definition of AF_INET6 is not
    2720                 :             :  * provided by headers included (or not) via __has_include() above.
    2721                 :             :  * MBEDTLS_TEST_SW_INET_PTON is a bypass define to force testing of this code //no-check-names
    2722                 :             :  * despite having a platform that has inet_pton. */
    2723                 :             : #if !defined(AF_INET6) || defined(MBEDTLS_TEST_SW_INET_PTON) //no-check-names
    2724                 :             : /* Definition located further below to possibly reduce compiler inlining */
    2725                 :             : static int x509_inet_pton_ipv4(const char *src, void *dst);
    2726                 :             : 
    2727                 :             : #define li_cton(c, n) \
    2728                 :             :     (((n) = (c) - '0') <= 9 || (((n) = ((c)&0xdf) - 'A') <= 5 ? ((n) += 10) : 0))
    2729                 :             : 
    2730                 :             : static int x509_inet_pton_ipv6(const char *src, void *dst)
    2731                 :             : {
    2732                 :             :     const unsigned char *p = (const unsigned char *) src;
    2733                 :             :     int nonzero_groups = 0, num_digits, zero_group_start = -1;
    2734                 :             :     uint16_t addr[8];
    2735                 :             :     do {
    2736                 :             :         /* note: allows excess leading 0's, e.g. 1:0002:3:... */
    2737                 :             :         uint16_t group = num_digits = 0;
    2738                 :             :         for (uint8_t digit; num_digits < 4; num_digits++) {
    2739                 :             :             if (li_cton(*p, digit) == 0) {
    2740                 :             :                 break;
    2741                 :             :             }
    2742                 :             :             group = (group << 4) | digit;
    2743                 :             :             p++;
    2744                 :             :         }
    2745                 :             :         if (num_digits != 0) {
    2746                 :             :             MBEDTLS_PUT_UINT16_BE(group, addr, nonzero_groups);
    2747                 :             :             nonzero_groups++;
    2748                 :             :             if (*p == '\0') {
    2749                 :             :                 break;
    2750                 :             :             } else if (*p == '.') {
    2751                 :             :                 /* Don't accept IPv4 too early or late */
    2752                 :             :                 if ((nonzero_groups == 0 && zero_group_start == -1) ||
    2753                 :             :                     nonzero_groups >= 7) {
    2754                 :             :                     break;
    2755                 :             :                 }
    2756                 :             : 
    2757                 :             :                 /* Walk back to prior ':', then parse as IPv4-mapped */
    2758                 :             :                 int steps = 4;
    2759                 :             :                 do {
    2760                 :             :                     p--;
    2761                 :             :                     steps--;
    2762                 :             :                 } while (*p != ':' && steps > 0);
    2763                 :             : 
    2764                 :             :                 if (*p != ':') {
    2765                 :             :                     break;
    2766                 :             :                 }
    2767                 :             :                 p++;
    2768                 :             :                 nonzero_groups--;
    2769                 :             :                 if (x509_inet_pton_ipv4((const char *) p,
    2770                 :             :                                         addr + nonzero_groups) != 0) {
    2771                 :             :                     break;
    2772                 :             :                 }
    2773                 :             : 
    2774                 :             :                 nonzero_groups += 2;
    2775                 :             :                 p = (const unsigned char *) "";
    2776                 :             :                 break;
    2777                 :             :             } else if (*p != ':') {
    2778                 :             :                 return -1;
    2779                 :             :             }
    2780                 :             :         } else {
    2781                 :             :             /* Don't accept a second zero group or an invalid delimiter */
    2782                 :             :             if (zero_group_start != -1 || *p != ':') {
    2783                 :             :                 return -1;
    2784                 :             :             }
    2785                 :             :             zero_group_start = nonzero_groups;
    2786                 :             : 
    2787                 :             :             /* Accept a zero group at start, but it has to be a double colon */
    2788                 :             :             if (zero_group_start == 0 && *++p != ':') {
    2789                 :             :                 return -1;
    2790                 :             :             }
    2791                 :             : 
    2792                 :             :             if (p[1] == '\0') {
    2793                 :             :                 ++p;
    2794                 :             :                 break;
    2795                 :             :             }
    2796                 :             :         }
    2797                 :             :         ++p;
    2798                 :             :     } while (nonzero_groups < 8);
    2799                 :             : 
    2800                 :             :     if (*p != '\0') {
    2801                 :             :         return -1;
    2802                 :             :     }
    2803                 :             : 
    2804                 :             :     if (zero_group_start != -1) {
    2805                 :             :         if (nonzero_groups > 6) {
    2806                 :             :             return -1;
    2807                 :             :         }
    2808                 :             :         int zero_groups = 8 - nonzero_groups;
    2809                 :             :         int groups_after_zero = nonzero_groups - zero_group_start;
    2810                 :             : 
    2811                 :             :         /* Move the non-zero part to after the zeroes */
    2812                 :             :         if (groups_after_zero) {
    2813                 :             :             memmove(addr + zero_group_start + zero_groups,
    2814                 :             :                     addr + zero_group_start,
    2815                 :             :                     groups_after_zero * sizeof(*addr));
    2816                 :             :         }
    2817                 :             :         memset(addr + zero_group_start, 0, zero_groups * sizeof(*addr));
    2818                 :             :     } else {
    2819                 :             :         if (nonzero_groups != 8) {
    2820                 :             :             return -1;
    2821                 :             :         }
    2822                 :             :     }
    2823                 :             :     memcpy(dst, addr, sizeof(addr));
    2824                 :             :     return 0;
    2825                 :             : }
    2826                 :             : 
    2827                 :             : static int x509_inet_pton_ipv4(const char *src, void *dst)
    2828                 :             : {
    2829                 :             :     const unsigned char *p = (const unsigned char *) src;
    2830                 :             :     uint8_t *res = (uint8_t *) dst;
    2831                 :             :     uint8_t digit, num_digits = 0;
    2832                 :             :     uint8_t num_octets = 0;
    2833                 :             :     uint16_t octet;
    2834                 :             : 
    2835                 :             :     do {
    2836                 :             :         octet = num_digits = 0;
    2837                 :             :         do {
    2838                 :             :             digit = *p - '0';
    2839                 :             :             if (digit > 9) {
    2840                 :             :                 break;
    2841                 :             :             }
    2842                 :             : 
    2843                 :             :             /* Don't allow leading zeroes. These might mean octal format,
    2844                 :             :              * which this implementation does not support. */
    2845                 :             :             if (octet == 0 && num_digits > 0) {
    2846                 :             :                 return -1;
    2847                 :             :             }
    2848                 :             : 
    2849                 :             :             octet = octet * 10 + digit;
    2850                 :             :             num_digits++;
    2851                 :             :             p++;
    2852                 :             :         } while (num_digits < 3);
    2853                 :             : 
    2854                 :             :         if (octet >= 256 || num_digits > 3 || num_digits == 0) {
    2855                 :             :             return -1;
    2856                 :             :         }
    2857                 :             :         *res++ = (uint8_t) octet;
    2858                 :             :         num_octets++;
    2859                 :             :     } while (num_octets < 4 && *p++ == '.');
    2860                 :             :     return num_octets == 4 && *p == '\0' ? 0 : -1;
    2861                 :             : }
    2862                 :             : 
    2863                 :             : #else
    2864                 :             : 
    2865                 :           0 : static int x509_inet_pton_ipv6(const char *src, void *dst)
    2866                 :             : {
    2867         [ #  # ]:           0 :     return inet_pton(AF_INET6, src, dst) == 1 ? 0 : -1;
    2868                 :             : }
    2869                 :             : 
    2870                 :           0 : static int x509_inet_pton_ipv4(const char *src, void *dst)
    2871                 :             : {
    2872         [ #  # ]:           0 :     return inet_pton(AF_INET, src, dst) == 1 ? 0 : -1;
    2873                 :             : }
    2874                 :             : 
    2875                 :             : #endif /* !AF_INET6 || MBEDTLS_TEST_SW_INET_PTON */ //no-check-names
    2876                 :             : 
    2877                 :           0 : size_t mbedtls_x509_crt_parse_cn_inet_pton(const char *cn, void *dst)
    2878                 :             : {
    2879                 :           0 :     return strchr(cn, ':') == NULL
    2880                 :           0 :             ? x509_inet_pton_ipv4(cn, dst) == 0 ? 4 : 0
    2881   [ #  #  #  #  :           0 :             : x509_inet_pton_ipv6(cn, dst) == 0 ? 16 : 0;
                   #  # ]
    2882                 :             : }
    2883                 :             : 
    2884                 :             : /*
    2885                 :             :  * Check for CN match
    2886                 :             :  */
    2887                 :           0 : static int x509_crt_check_cn(const mbedtls_x509_buf *name,
    2888                 :             :                              const char *cn, size_t cn_len)
    2889                 :             : {
    2890                 :             :     /* try exact match */
    2891         [ #  # ]:           0 :     if (name->len == cn_len &&
    2892         [ #  # ]:           0 :         x509_memcasecmp(cn, name->p, cn_len) == 0) {
    2893                 :             :         return 0;
    2894                 :             :     }
    2895                 :             : 
    2896                 :             :     /* try wildcard match */
    2897         [ #  # ]:           0 :     if (x509_check_wildcard(cn, name) == 0) {
    2898                 :             :         return 0;
    2899                 :             :     }
    2900                 :             : 
    2901                 :             :     return -1;
    2902                 :             : }
    2903                 :             : 
    2904                 :           0 : static int x509_crt_check_san_ip(const mbedtls_x509_sequence *san,
    2905                 :             :                                  const char *cn, size_t cn_len)
    2906                 :             : {
    2907                 :           0 :     uint32_t ip[4];
    2908                 :           0 :     cn_len = mbedtls_x509_crt_parse_cn_inet_pton(cn, ip);
    2909         [ #  # ]:           0 :     if (cn_len == 0) {
    2910                 :             :         return -1;
    2911                 :             :     }
    2912                 :             : 
    2913         [ #  # ]:           0 :     for (const mbedtls_x509_sequence *cur = san; cur != NULL; cur = cur->next) {
    2914                 :           0 :         const unsigned char san_type = (unsigned char) cur->buf.tag &
    2915                 :             :                                        MBEDTLS_ASN1_TAG_VALUE_MASK;
    2916         [ #  # ]:           0 :         if (san_type == MBEDTLS_X509_SAN_IP_ADDRESS &&
    2917   [ #  #  #  # ]:           0 :             cur->buf.len == cn_len && memcmp(cur->buf.p, ip, cn_len) == 0) {
    2918                 :             :             return 0;
    2919                 :             :         }
    2920                 :             :     }
    2921                 :             : 
    2922                 :             :     return -1;
    2923                 :             : }
    2924                 :             : 
    2925                 :           0 : static int x509_crt_check_san_uri(const mbedtls_x509_sequence *san,
    2926                 :             :                                   const char *cn, size_t cn_len)
    2927                 :             : {
    2928         [ #  # ]:           0 :     for (const mbedtls_x509_sequence *cur = san; cur != NULL; cur = cur->next) {
    2929                 :           0 :         const unsigned char san_type = (unsigned char) cur->buf.tag &
    2930                 :             :                                        MBEDTLS_ASN1_TAG_VALUE_MASK;
    2931         [ #  # ]:           0 :         if (san_type == MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER &&
    2932   [ #  #  #  # ]:           0 :             cur->buf.len == cn_len && memcmp(cur->buf.p, cn, cn_len) == 0) {
    2933                 :             :             return 0;
    2934                 :             :         }
    2935                 :             :     }
    2936                 :             : 
    2937                 :             :     return -1;
    2938                 :             : }
    2939                 :             : 
    2940                 :             : /*
    2941                 :             :  * Check for SAN match, see RFC 5280 Section 4.2.1.6
    2942                 :             :  */
    2943                 :           0 : static int x509_crt_check_san(const mbedtls_x509_sequence *san,
    2944                 :             :                               const char *cn, size_t cn_len)
    2945                 :             : {
    2946                 :           0 :     int san_ip = 0;
    2947                 :           0 :     int san_uri = 0;
    2948                 :             :     /* Prioritize DNS name over other subtypes due to popularity */
    2949         [ #  # ]:           0 :     for (const mbedtls_x509_sequence *cur = san; cur != NULL; cur = cur->next) {
    2950   [ #  #  #  # ]:           0 :         switch ((unsigned char) cur->buf.tag & MBEDTLS_ASN1_TAG_VALUE_MASK) {
    2951                 :           0 :             case MBEDTLS_X509_SAN_DNS_NAME:
    2952         [ #  # ]:           0 :                 if (x509_crt_check_cn(&cur->buf, cn, cn_len) == 0) {
    2953                 :             :                     return 0;
    2954                 :             :                 }
    2955                 :             :                 break;
    2956                 :           0 :             case MBEDTLS_X509_SAN_IP_ADDRESS:
    2957                 :           0 :                 san_ip = 1;
    2958                 :           0 :                 break;
    2959                 :           0 :             case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER:
    2960                 :           0 :                 san_uri = 1;
    2961                 :           0 :                 break;
    2962                 :             :             /* (We may handle other types here later.) */
    2963                 :             :             default: /* Unrecognized type */
    2964                 :             :                 break;
    2965                 :             :         }
    2966                 :             :     }
    2967         [ #  # ]:           0 :     if (san_ip) {
    2968         [ #  # ]:           0 :         if (x509_crt_check_san_ip(san, cn, cn_len) == 0) {
    2969                 :             :             return 0;
    2970                 :             :         }
    2971                 :             :     }
    2972         [ #  # ]:           0 :     if (san_uri) {
    2973         [ #  # ]:           0 :         if (x509_crt_check_san_uri(san, cn, cn_len) == 0) {
    2974                 :             :             return 0;
    2975                 :             :         }
    2976                 :             :     }
    2977                 :             : 
    2978                 :             :     return -1;
    2979                 :             : }
    2980                 :             : 
    2981                 :             : /*
    2982                 :             :  * Verify the requested CN - only call this if cn is not NULL!
    2983                 :             :  */
    2984                 :           0 : static void x509_crt_verify_name(const mbedtls_x509_crt *crt,
    2985                 :             :                                  const char *cn,
    2986                 :             :                                  uint32_t *flags)
    2987                 :             : {
    2988                 :           0 :     const mbedtls_x509_name *name;
    2989                 :           0 :     size_t cn_len = strlen(cn);
    2990                 :             : 
    2991         [ #  # ]:           0 :     if (crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME) {
    2992         [ #  # ]:           0 :         if (x509_crt_check_san(&crt->subject_alt_names, cn, cn_len) == 0) {
    2993                 :             :             return;
    2994                 :             :         }
    2995                 :             :     } else {
    2996         [ #  # ]:           0 :         for (name = &crt->subject; name != NULL; name = name->next) {
    2997   [ #  #  #  # ]:           0 :             if (MBEDTLS_OID_CMP(MBEDTLS_OID_AT_CN, &name->oid) == 0 &&
    2998         [ #  # ]:           0 :                 x509_crt_check_cn(&name->val, cn, cn_len) == 0) {
    2999                 :             :                 return;
    3000                 :             :             }
    3001                 :             :         }
    3002                 :             : 
    3003                 :             :     }
    3004                 :             : 
    3005                 :           0 :     *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH;
    3006                 :             : }
    3007                 :             : 
    3008                 :             : /*
    3009                 :             :  * Merge the flags for all certs in the chain, after calling callback
    3010                 :             :  */
    3011                 :           0 : static int x509_crt_merge_flags_with_cb(
    3012                 :             :     uint32_t *flags,
    3013                 :             :     const mbedtls_x509_crt_verify_chain *ver_chain,
    3014                 :             :     int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
    3015                 :             :     void *p_vrfy)
    3016                 :             : {
    3017                 :           0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    3018                 :           0 :     unsigned i;
    3019                 :           0 :     uint32_t cur_flags;
    3020                 :           0 :     const mbedtls_x509_crt_verify_chain_item *cur;
    3021                 :             : 
    3022         [ #  # ]:           0 :     for (i = ver_chain->len; i != 0; --i) {
    3023                 :           0 :         cur = &ver_chain->items[i-1];
    3024                 :           0 :         cur_flags = cur->flags;
    3025                 :             : 
    3026         [ #  # ]:           0 :         if (NULL != f_vrfy) {
    3027         [ #  # ]:           0 :             if ((ret = f_vrfy(p_vrfy, cur->crt, (int) i-1, &cur_flags)) != 0) {
    3028                 :           0 :                 return ret;
    3029                 :             :             }
    3030                 :             :         }
    3031                 :             : 
    3032                 :           0 :         *flags |= cur_flags;
    3033                 :             :     }
    3034                 :             : 
    3035                 :             :     return 0;
    3036                 :             : }
    3037                 :             : 
    3038                 :             : /*
    3039                 :             :  * Verify the certificate validity, with profile, restartable version
    3040                 :             :  *
    3041                 :             :  * This function:
    3042                 :             :  *  - checks the requested CN (if any)
    3043                 :             :  *  - checks the type and size of the EE cert's key,
    3044                 :             :  *    as that isn't done as part of chain building/verification currently
    3045                 :             :  *  - builds and verifies the chain
    3046                 :             :  *  - then calls the callback and merges the flags
    3047                 :             :  *
    3048                 :             :  * The parameters pairs `trust_ca`, `ca_crl` and `f_ca_cb`, `p_ca_cb`
    3049                 :             :  * are mutually exclusive: If `f_ca_cb != NULL`, it will be used by the
    3050                 :             :  * verification routine to search for trusted signers, and CRLs will
    3051                 :             :  * be disabled. Otherwise, `trust_ca` will be used as the static list
    3052                 :             :  * of trusted signers, and `ca_crl` will be use as the static list
    3053                 :             :  * of CRLs.
    3054                 :             :  */
    3055                 :           0 : static int x509_crt_verify_restartable_ca_cb(mbedtls_x509_crt *crt,
    3056                 :             :                                              mbedtls_x509_crt *trust_ca,
    3057                 :             :                                              mbedtls_x509_crl *ca_crl,
    3058                 :             :                                              mbedtls_x509_crt_ca_cb_t f_ca_cb,
    3059                 :             :                                              void *p_ca_cb,
    3060                 :             :                                              const mbedtls_x509_crt_profile *profile,
    3061                 :             :                                              const char *cn, uint32_t *flags,
    3062                 :             :                                              int (*f_vrfy)(void *,
    3063                 :             :                                                            mbedtls_x509_crt *,
    3064                 :             :                                                            int,
    3065                 :             :                                                            uint32_t *),
    3066                 :             :                                              void *p_vrfy,
    3067                 :             :                                              mbedtls_x509_crt_restart_ctx *rs_ctx)
    3068                 :             : {
    3069                 :           0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    3070                 :           0 :     mbedtls_pk_type_t pk_type;
    3071                 :           0 :     mbedtls_x509_crt_verify_chain ver_chain;
    3072                 :           0 :     uint32_t ee_flags;
    3073                 :             : 
    3074                 :           0 :     *flags = 0;
    3075                 :           0 :     ee_flags = 0;
    3076                 :           0 :     x509_crt_verify_chain_reset(&ver_chain);
    3077                 :             : 
    3078         [ #  # ]:           0 :     if (profile == NULL) {
    3079                 :           0 :         ret = MBEDTLS_ERR_X509_BAD_INPUT_DATA;
    3080                 :           0 :         goto exit;
    3081                 :             :     }
    3082                 :             : 
    3083                 :             :     /* check name if requested */
    3084         [ #  # ]:           0 :     if (cn != NULL) {
    3085                 :           0 :         x509_crt_verify_name(crt, cn, &ee_flags);
    3086                 :             :     }
    3087                 :             : 
    3088                 :             :     /* Check the type and size of the key */
    3089                 :           0 :     pk_type = mbedtls_pk_get_type(&crt->pk);
    3090                 :             : 
    3091         [ #  # ]:           0 :     if (x509_profile_check_pk_alg(profile, pk_type) != 0) {
    3092                 :           0 :         ee_flags |= MBEDTLS_X509_BADCERT_BAD_PK;
    3093                 :             :     }
    3094                 :             : 
    3095         [ #  # ]:           0 :     if (x509_profile_check_key(profile, &crt->pk) != 0) {
    3096                 :           0 :         ee_flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
    3097                 :             :     }
    3098                 :             : 
    3099                 :             :     /* Check the chain */
    3100                 :           0 :     ret = x509_crt_verify_chain(crt, trust_ca, ca_crl,
    3101                 :             :                                 f_ca_cb, p_ca_cb, profile,
    3102                 :             :                                 &ver_chain, rs_ctx);
    3103                 :             : 
    3104         [ #  # ]:           0 :     if (ret != 0) {
    3105                 :           0 :         goto exit;
    3106                 :             :     }
    3107                 :             : 
    3108                 :             :     /* Merge end-entity flags */
    3109                 :           0 :     ver_chain.items[0].flags |= ee_flags;
    3110                 :             : 
    3111                 :             :     /* Build final flags, calling callback on the way if any */
    3112                 :           0 :     ret = x509_crt_merge_flags_with_cb(flags, &ver_chain, f_vrfy, p_vrfy);
    3113                 :             : 
    3114                 :           0 : exit:
    3115                 :             : 
    3116                 :             : #if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
    3117                 :             :     mbedtls_x509_crt_free(ver_chain.trust_ca_cb_result);
    3118                 :             :     mbedtls_free(ver_chain.trust_ca_cb_result);
    3119                 :             :     ver_chain.trust_ca_cb_result = NULL;
    3120                 :             : #endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
    3121                 :             : 
    3122                 :             : #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
    3123                 :             :     if (rs_ctx != NULL && ret != MBEDTLS_ERR_ECP_IN_PROGRESS) {
    3124                 :             :         mbedtls_x509_crt_restart_free(rs_ctx);
    3125                 :             :     }
    3126                 :             : #endif
    3127                 :             : 
    3128                 :             :     /* prevent misuse of the vrfy callback - VERIFY_FAILED would be ignored by
    3129                 :             :      * the SSL module for authmode optional, but non-zero return from the
    3130                 :             :      * callback means a fatal error so it shouldn't be ignored */
    3131         [ #  # ]:           0 :     if (ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) {
    3132                 :             :         ret = MBEDTLS_ERR_X509_FATAL_ERROR;
    3133                 :             :     }
    3134                 :             : 
    3135         [ #  # ]:           0 :     if (ret != 0) {
    3136                 :           0 :         *flags = (uint32_t) -1;
    3137                 :           0 :         return ret;
    3138                 :             :     }
    3139                 :             : 
    3140         [ #  # ]:           0 :     if (*flags != 0) {
    3141                 :           0 :         return MBEDTLS_ERR_X509_CERT_VERIFY_FAILED;
    3142                 :             :     }
    3143                 :             : 
    3144                 :             :     return 0;
    3145                 :             : }
    3146                 :             : 
    3147                 :             : 
    3148                 :             : /*
    3149                 :             :  * Verify the certificate validity (default profile, not restartable)
    3150                 :             :  */
    3151                 :           0 : int mbedtls_x509_crt_verify(mbedtls_x509_crt *crt,
    3152                 :             :                             mbedtls_x509_crt *trust_ca,
    3153                 :             :                             mbedtls_x509_crl *ca_crl,
    3154                 :             :                             const char *cn, uint32_t *flags,
    3155                 :             :                             int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
    3156                 :             :                             void *p_vrfy)
    3157                 :             : {
    3158                 :           0 :     return x509_crt_verify_restartable_ca_cb(crt, trust_ca, ca_crl,
    3159                 :             :                                              NULL, NULL,
    3160                 :             :                                              &mbedtls_x509_crt_profile_default,
    3161                 :             :                                              cn, flags,
    3162                 :             :                                              f_vrfy, p_vrfy, NULL);
    3163                 :             : }
    3164                 :             : 
    3165                 :             : /*
    3166                 :             :  * Verify the certificate validity (user-chosen profile, not restartable)
    3167                 :             :  */
    3168                 :           0 : int mbedtls_x509_crt_verify_with_profile(mbedtls_x509_crt *crt,
    3169                 :             :                                          mbedtls_x509_crt *trust_ca,
    3170                 :             :                                          mbedtls_x509_crl *ca_crl,
    3171                 :             :                                          const mbedtls_x509_crt_profile *profile,
    3172                 :             :                                          const char *cn, uint32_t *flags,
    3173                 :             :                                          int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
    3174                 :             :                                          void *p_vrfy)
    3175                 :             : {
    3176                 :           0 :     return x509_crt_verify_restartable_ca_cb(crt, trust_ca, ca_crl,
    3177                 :             :                                              NULL, NULL,
    3178                 :             :                                              profile, cn, flags,
    3179                 :             :                                              f_vrfy, p_vrfy, NULL);
    3180                 :             : }
    3181                 :             : 
    3182                 :             : #if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
    3183                 :             : /*
    3184                 :             :  * Verify the certificate validity (user-chosen profile, CA callback,
    3185                 :             :  *                                  not restartable).
    3186                 :             :  */
    3187                 :             : int mbedtls_x509_crt_verify_with_ca_cb(mbedtls_x509_crt *crt,
    3188                 :             :                                        mbedtls_x509_crt_ca_cb_t f_ca_cb,
    3189                 :             :                                        void *p_ca_cb,
    3190                 :             :                                        const mbedtls_x509_crt_profile *profile,
    3191                 :             :                                        const char *cn, uint32_t *flags,
    3192                 :             :                                        int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
    3193                 :             :                                        void *p_vrfy)
    3194                 :             : {
    3195                 :             :     return x509_crt_verify_restartable_ca_cb(crt, NULL, NULL,
    3196                 :             :                                              f_ca_cb, p_ca_cb,
    3197                 :             :                                              profile, cn, flags,
    3198                 :             :                                              f_vrfy, p_vrfy, NULL);
    3199                 :             : }
    3200                 :             : #endif /* MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK */
    3201                 :             : 
    3202                 :           0 : int mbedtls_x509_crt_verify_restartable(mbedtls_x509_crt *crt,
    3203                 :             :                                         mbedtls_x509_crt *trust_ca,
    3204                 :             :                                         mbedtls_x509_crl *ca_crl,
    3205                 :             :                                         const mbedtls_x509_crt_profile *profile,
    3206                 :             :                                         const char *cn, uint32_t *flags,
    3207                 :             :                                         int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
    3208                 :             :                                         void *p_vrfy,
    3209                 :             :                                         mbedtls_x509_crt_restart_ctx *rs_ctx)
    3210                 :             : {
    3211                 :           0 :     return x509_crt_verify_restartable_ca_cb(crt, trust_ca, ca_crl,
    3212                 :             :                                              NULL, NULL,
    3213                 :             :                                              profile, cn, flags,
    3214                 :             :                                              f_vrfy, p_vrfy, rs_ctx);
    3215                 :             : }
    3216                 :             : 
    3217                 :             : 
    3218                 :             : /*
    3219                 :             :  * Initialize a certificate chain
    3220                 :             :  */
    3221                 :           4 : void mbedtls_x509_crt_init(mbedtls_x509_crt *crt)
    3222                 :             : {
    3223                 :           4 :     memset(crt, 0, sizeof(mbedtls_x509_crt));
    3224                 :           4 : }
    3225                 :             : 
    3226                 :             : /*
    3227                 :             :  * Unallocate all certificate data
    3228                 :             :  */
    3229                 :           4 : void mbedtls_x509_crt_free(mbedtls_x509_crt *crt)
    3230                 :             : {
    3231                 :           4 :     mbedtls_x509_crt *cert_cur = crt;
    3232                 :           4 :     mbedtls_x509_crt *cert_prv;
    3233                 :             : 
    3234         [ +  + ]:           8 :     while (cert_cur != NULL) {
    3235                 :           4 :         mbedtls_pk_free(&cert_cur->pk);
    3236                 :             : 
    3237                 :             : #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
    3238                 :             :         mbedtls_free(cert_cur->sig_opts);
    3239                 :             : #endif
    3240                 :             : 
    3241                 :           4 :         mbedtls_asn1_free_named_data_list_shallow(cert_cur->issuer.next);
    3242                 :           4 :         mbedtls_asn1_free_named_data_list_shallow(cert_cur->subject.next);
    3243                 :           4 :         mbedtls_asn1_sequence_free(cert_cur->ext_key_usage.next);
    3244                 :           4 :         mbedtls_asn1_sequence_free(cert_cur->subject_alt_names.next);
    3245                 :           4 :         mbedtls_asn1_sequence_free(cert_cur->certificate_policies.next);
    3246                 :           4 :         mbedtls_asn1_sequence_free(cert_cur->authority_key_id.authorityCertIssuer.next);
    3247                 :             : 
    3248   [ +  -  -  + ]:           4 :         if (cert_cur->raw.p != NULL && cert_cur->own_buffer) {
    3249                 :           0 :             mbedtls_zeroize_and_free(cert_cur->raw.p, cert_cur->raw.len);
    3250                 :             :         }
    3251                 :             : 
    3252                 :           4 :         cert_prv = cert_cur;
    3253                 :           4 :         cert_cur = cert_cur->next;
    3254                 :             : 
    3255                 :           4 :         mbedtls_platform_zeroize(cert_prv, sizeof(mbedtls_x509_crt));
    3256         [ -  + ]:           4 :         if (cert_prv != crt) {
    3257                 :           0 :             mbedtls_free(cert_prv);
    3258                 :             :         }
    3259                 :             :     }
    3260                 :           4 : }
    3261                 :             : 
    3262                 :             : #if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
    3263                 :             : /*
    3264                 :             :  * Initialize a restart context
    3265                 :             :  */
    3266                 :             : void mbedtls_x509_crt_restart_init(mbedtls_x509_crt_restart_ctx *ctx)
    3267                 :             : {
    3268                 :             :     mbedtls_pk_restart_init(&ctx->pk);
    3269                 :             : 
    3270                 :             :     ctx->parent = NULL;
    3271                 :             :     ctx->fallback_parent = NULL;
    3272                 :             :     ctx->fallback_signature_is_good = 0;
    3273                 :             : 
    3274                 :             :     ctx->parent_is_trusted = -1;
    3275                 :             : 
    3276                 :             :     ctx->in_progress = x509_crt_rs_none;
    3277                 :             :     ctx->self_cnt = 0;
    3278                 :             :     x509_crt_verify_chain_reset(&ctx->ver_chain);
    3279                 :             : }
    3280                 :             : 
    3281                 :             : /*
    3282                 :             :  * Free the components of a restart context
    3283                 :             :  */
    3284                 :             : void mbedtls_x509_crt_restart_free(mbedtls_x509_crt_restart_ctx *ctx)
    3285                 :             : {
    3286                 :             :     if (ctx == NULL) {
    3287                 :             :         return;
    3288                 :             :     }
    3289                 :             : 
    3290                 :             :     mbedtls_pk_restart_free(&ctx->pk);
    3291                 :             :     mbedtls_x509_crt_restart_init(ctx);
    3292                 :             : }
    3293                 :             : #endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
    3294                 :             : 
    3295                 :           0 : int mbedtls_x509_crt_get_ca_istrue(const mbedtls_x509_crt *crt)
    3296                 :             : {
    3297         [ #  # ]:           0 :     if ((crt->ext_types & MBEDTLS_X509_EXT_BASIC_CONSTRAINTS) != 0) {
    3298                 :           0 :         return crt->MBEDTLS_PRIVATE(ca_istrue);
    3299                 :             :     }
    3300                 :             :     return MBEDTLS_ERR_X509_INVALID_EXTENSIONS;
    3301                 :             : }
    3302                 :             : 
    3303                 :             : #endif /* MBEDTLS_X509_CRT_PARSE_C */
        

Generated by: LCOV version 2.0-1