LCOV - code coverage report
Current view: top level - externals/mbedtls/library - x509_crt.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 123 967 12.7 %
Date: 2024-09-16 20:15:30 Functions: 9 51 17.6 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 56 787 7.1 %

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

Generated by: LCOV version 1.14