Nicolas Borla / Mbed OS BBR_1Ebene
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers x509_crt.c Source File

x509_crt.c

00001 /*
00002  *  X.509 certificate parsing and verification
00003  *
00004  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
00005  *  SPDX-License-Identifier: Apache-2.0
00006  *
00007  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
00008  *  not use this file except in compliance with the License.
00009  *  You may obtain a copy of the License at
00010  *
00011  *  http://www.apache.org/licenses/LICENSE-2.0
00012  *
00013  *  Unless required by applicable law or agreed to in writing, software
00014  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00015  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00016  *  See the License for the specific language governing permissions and
00017  *  limitations under the License.
00018  *
00019  *  This file is part of mbed TLS (https://tls.mbed.org)
00020  */
00021 /*
00022  *  The ITU-T X.509 standard defines a certificate format for PKI.
00023  *
00024  *  http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
00025  *  http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
00026  *  http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
00027  *
00028  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
00029  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
00030  */
00031 
00032 #if !defined(MBEDTLS_CONFIG_FILE)
00033 #include "mbedtls/config.h"
00034 #else
00035 #include MBEDTLS_CONFIG_FILE
00036 #endif
00037 
00038 #if defined(MBEDTLS_X509_CRT_PARSE_C)
00039 
00040 #include "mbedtls/x509_crt.h"
00041 #include "mbedtls/oid.h"
00042 
00043 #include <stdio.h>
00044 #include <string.h>
00045 
00046 #if defined(MBEDTLS_PEM_PARSE_C)
00047 #include "mbedtls/pem.h"
00048 #endif
00049 
00050 #if defined(MBEDTLS_PLATFORM_C)
00051 #include "mbedtls/platform.h"
00052 #else
00053 #include <stdlib.h>
00054 #define mbedtls_free       free
00055 #define mbedtls_calloc    calloc
00056 #define mbedtls_snprintf   snprintf
00057 #endif
00058 
00059 #if defined(MBEDTLS_THREADING_C)
00060 #include "mbedtls/threading.h"
00061 #endif
00062 
00063 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
00064 #include <windows.h>
00065 #else
00066 #include <time.h>
00067 #endif
00068 
00069 #if defined(MBEDTLS_FS_IO)
00070 #include <stdio.h>
00071 #if !defined(_WIN32) || defined(EFIX64) || defined(EFI32)
00072 #include <sys/types.h>
00073 #include <sys/stat.h>
00074 #include <dirent.h>
00075 #endif /* !_WIN32 || EFIX64 || EFI32 */
00076 #endif
00077 
00078 /* Implementation that should never be optimized out by the compiler */
00079 static void mbedtls_zeroize( void *v, size_t n ) {
00080     volatile unsigned char *p = v; while( n-- ) *p++ = 0;
00081 }
00082 
00083 /*
00084  * Default profile
00085  */
00086 const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default =
00087 {
00088 #if defined(MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES)
00089     /* Allow SHA-1 (weak, but still safe in controlled environments) */
00090     MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 ) |
00091 #endif
00092     /* Only SHA-2 hashes */
00093     MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224 ) |
00094     MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
00095     MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) |
00096     MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ),
00097     0xFFFFFFF, /* Any PK alg    */
00098     0xFFFFFFF, /* Any curve     */
00099     2048,
00100 };
00101 
00102 /*
00103  * Next-default profile
00104  */
00105 const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_next =
00106 {
00107     /* Hashes from SHA-256 and above */
00108     MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
00109     MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) |
00110     MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ),
00111     0xFFFFFFF, /* Any PK alg    */
00112 #if defined(MBEDTLS_ECP_C)
00113     /* Curves at or above 128-bit security level */
00114     MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) |
00115     MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ) |
00116     MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP521R1 ) |
00117     MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP256R1 ) |
00118     MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP384R1 ) |
00119     MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP512R1 ) |
00120     MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256K1 ),
00121 #else
00122     0,
00123 #endif
00124     2048,
00125 };
00126 
00127 /*
00128  * NSA Suite B Profile
00129  */
00130 const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb =
00131 {
00132     /* Only SHA-256 and 384 */
00133     MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
00134     MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ),
00135     /* Only ECDSA */
00136     MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECDSA ) |
00137     MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECKEY ),
00138 #if defined(MBEDTLS_ECP_C)
00139     /* Only NIST P-256 and P-384 */
00140     MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) |
00141     MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ),
00142 #else
00143     0,
00144 #endif
00145     0,
00146 };
00147 
00148 /*
00149  * Check md_alg against profile
00150  * Return 0 if md_alg acceptable for this profile, -1 otherwise
00151  */
00152 static int x509_profile_check_md_alg( const mbedtls_x509_crt_profile *profile,
00153                                       mbedtls_md_type_t md_alg )
00154 {
00155     if( ( profile->allowed_mds & MBEDTLS_X509_ID_FLAG( md_alg ) ) != 0 )
00156         return( 0 );
00157 
00158     return( -1 );
00159 }
00160 
00161 /*
00162  * Check pk_alg against profile
00163  * Return 0 if pk_alg acceptable for this profile, -1 otherwise
00164  */
00165 static int x509_profile_check_pk_alg( const mbedtls_x509_crt_profile *profile,
00166                                       mbedtls_pk_type_t pk_alg )
00167 {
00168     if( ( profile->allowed_pks & MBEDTLS_X509_ID_FLAG( pk_alg ) ) != 0 )
00169         return( 0 );
00170 
00171     return( -1 );
00172 }
00173 
00174 /*
00175  * Check key against profile
00176  * Return 0 if pk_alg acceptable for this profile, -1 otherwise
00177  */
00178 static int x509_profile_check_key( const mbedtls_x509_crt_profile *profile,
00179                                    mbedtls_pk_type_t pk_alg,
00180                                    const mbedtls_pk_context *pk )
00181 {
00182 #if defined(MBEDTLS_RSA_C)
00183     if( pk_alg == MBEDTLS_PK_RSA || pk_alg == MBEDTLS_PK_RSASSA_PSS )
00184     {
00185         if( mbedtls_pk_get_bitlen( pk ) >= profile->rsa_min_bitlen )
00186             return( 0 );
00187 
00188         return( -1 );
00189     }
00190 #endif
00191 
00192 #if defined(MBEDTLS_ECP_C)
00193     if( pk_alg == MBEDTLS_PK_ECDSA ||
00194         pk_alg == MBEDTLS_PK_ECKEY ||
00195         pk_alg == MBEDTLS_PK_ECKEY_DH )
00196     {
00197         mbedtls_ecp_group_id gid = mbedtls_pk_ec( *pk )->grp .id ;
00198 
00199         if( ( profile->allowed_curves & MBEDTLS_X509_ID_FLAG( gid ) ) != 0 )
00200             return( 0 );
00201 
00202         return( -1 );
00203     }
00204 #endif
00205 
00206     return( -1 );
00207 }
00208 
00209 /*
00210  *  Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
00211  */
00212 static int x509_get_version( unsigned char **p,
00213                              const unsigned char *end,
00214                              int *ver )
00215 {
00216     int ret;
00217     size_t len;
00218 
00219     if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
00220             MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) != 0 )
00221     {
00222         if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
00223         {
00224             *ver = 0;
00225             return( 0 );
00226         }
00227 
00228         return( ret );
00229     }
00230 
00231     end = *p + len;
00232 
00233     if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 )
00234         return( MBEDTLS_ERR_X509_INVALID_VERSION + ret );
00235 
00236     if( *p != end )
00237         return( MBEDTLS_ERR_X509_INVALID_VERSION +
00238                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
00239 
00240     return( 0 );
00241 }
00242 
00243 /*
00244  *  Validity ::= SEQUENCE {
00245  *       notBefore      Time,
00246  *       notAfter       Time }
00247  */
00248 static int x509_get_dates( unsigned char **p,
00249                            const unsigned char *end,
00250                            mbedtls_x509_time *from,
00251                            mbedtls_x509_time *to )
00252 {
00253     int ret;
00254     size_t len;
00255 
00256     if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
00257             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
00258         return( MBEDTLS_ERR_X509_INVALID_DATE + ret );
00259 
00260     end = *p + len;
00261 
00262     if( ( ret = mbedtls_x509_get_time( p, end, from ) ) != 0 )
00263         return( ret );
00264 
00265     if( ( ret = mbedtls_x509_get_time( p, end, to ) ) != 0 )
00266         return( ret );
00267 
00268     if( *p != end )
00269         return( MBEDTLS_ERR_X509_INVALID_DATE +
00270                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
00271 
00272     return( 0 );
00273 }
00274 
00275 /*
00276  * X.509 v2/v3 unique identifier (not parsed)
00277  */
00278 static int x509_get_uid( unsigned char **p,
00279                          const unsigned char *end,
00280                          mbedtls_x509_buf *uid, int n )
00281 {
00282     int ret;
00283 
00284     if( *p == end )
00285         return( 0 );
00286 
00287     uid->tag = **p;
00288 
00289     if( ( ret = mbedtls_asn1_get_tag( p, end, &uid->len,
00290             MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | n ) ) != 0 )
00291     {
00292         if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
00293             return( 0 );
00294 
00295         return( ret );
00296     }
00297 
00298     uid->p = *p;
00299     *p += uid->len;
00300 
00301     return( 0 );
00302 }
00303 
00304 static int x509_get_basic_constraints( unsigned char **p,
00305                                        const unsigned char *end,
00306                                        int *ca_istrue,
00307                                        int *max_pathlen )
00308 {
00309     int ret;
00310     size_t len;
00311 
00312     /*
00313      * BasicConstraints ::= SEQUENCE {
00314      *      cA                      BOOLEAN DEFAULT FALSE,
00315      *      pathLenConstraint       INTEGER (0..MAX) OPTIONAL }
00316      */
00317     *ca_istrue = 0; /* DEFAULT FALSE */
00318     *max_pathlen = 0; /* endless */
00319 
00320     if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
00321             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
00322         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
00323 
00324     if( *p == end )
00325         return( 0 );
00326 
00327     if( ( ret = mbedtls_asn1_get_bool( p, end, ca_istrue ) ) != 0 )
00328     {
00329         if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
00330             ret = mbedtls_asn1_get_int( p, end, ca_istrue );
00331 
00332         if( ret != 0 )
00333             return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
00334 
00335         if( *ca_istrue != 0 )
00336             *ca_istrue = 1;
00337     }
00338 
00339     if( *p == end )
00340         return( 0 );
00341 
00342     if( ( ret = mbedtls_asn1_get_int( p, end, max_pathlen ) ) != 0 )
00343         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
00344 
00345     if( *p != end )
00346         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
00347                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
00348 
00349     (*max_pathlen)++;
00350 
00351     return( 0 );
00352 }
00353 
00354 static int x509_get_ns_cert_type( unsigned char **p,
00355                                        const unsigned char *end,
00356                                        unsigned char *ns_cert_type)
00357 {
00358     int ret;
00359     mbedtls_x509_bitstring bs = { 0, 0, NULL };
00360 
00361     if( ( ret = mbedtls_asn1_get_bitstring( p, end, &bs ) ) != 0 )
00362         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
00363 
00364     if( bs.len != 1 )
00365         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
00366                 MBEDTLS_ERR_ASN1_INVALID_LENGTH );
00367 
00368     /* Get actual bitstring */
00369     *ns_cert_type = *bs.p;
00370     return( 0 );
00371 }
00372 
00373 static int x509_get_key_usage( unsigned char **p,
00374                                const unsigned char *end,
00375                                unsigned int *key_usage)
00376 {
00377     int ret;
00378     size_t i;
00379     mbedtls_x509_bitstring bs = { 0, 0, NULL };
00380 
00381     if( ( ret = mbedtls_asn1_get_bitstring( p, end, &bs ) ) != 0 )
00382         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
00383 
00384     if( bs.len < 1 )
00385         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
00386                 MBEDTLS_ERR_ASN1_INVALID_LENGTH );
00387 
00388     /* Get actual bitstring */
00389     *key_usage = 0;
00390     for( i = 0; i < bs.len && i < sizeof( unsigned int ); i++ )
00391     {
00392         *key_usage |= (unsigned int) bs.p[i] << (8*i);
00393     }
00394 
00395     return( 0 );
00396 }
00397 
00398 /*
00399  * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
00400  *
00401  * KeyPurposeId ::= OBJECT IDENTIFIER
00402  */
00403 static int x509_get_ext_key_usage( unsigned char **p,
00404                                const unsigned char *end,
00405                                mbedtls_x509_sequence *ext_key_usage)
00406 {
00407     int ret;
00408 
00409     if( ( ret = mbedtls_asn1_get_sequence_of( p, end, ext_key_usage, MBEDTLS_ASN1_OID ) ) != 0 )
00410         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
00411 
00412     /* Sequence length must be >= 1 */
00413     if( ext_key_usage->buf.p == NULL )
00414         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
00415                 MBEDTLS_ERR_ASN1_INVALID_LENGTH );
00416 
00417     return( 0 );
00418 }
00419 
00420 /*
00421  * SubjectAltName ::= GeneralNames
00422  *
00423  * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
00424  *
00425  * GeneralName ::= CHOICE {
00426  *      otherName                       [0]     OtherName,
00427  *      rfc822Name                      [1]     IA5String,
00428  *      dNSName                         [2]     IA5String,
00429  *      x400Address                     [3]     ORAddress,
00430  *      directoryName                   [4]     Name,
00431  *      ediPartyName                    [5]     EDIPartyName,
00432  *      uniformResourceIdentifier       [6]     IA5String,
00433  *      iPAddress                       [7]     OCTET STRING,
00434  *      registeredID                    [8]     OBJECT IDENTIFIER }
00435  *
00436  * OtherName ::= SEQUENCE {
00437  *      type-id    OBJECT IDENTIFIER,
00438  *      value      [0] EXPLICIT ANY DEFINED BY type-id }
00439  *
00440  * EDIPartyName ::= SEQUENCE {
00441  *      nameAssigner            [0]     DirectoryString OPTIONAL,
00442  *      partyName               [1]     DirectoryString }
00443  *
00444  * NOTE: we only parse and use dNSName at this point.
00445  */
00446 static int x509_get_subject_alt_name( unsigned char **p,
00447                                       const unsigned char *end,
00448                                       mbedtls_x509_sequence *subject_alt_name )
00449 {
00450     int ret;
00451     size_t len, tag_len;
00452     mbedtls_asn1_buf *buf;
00453     unsigned char tag;
00454     mbedtls_asn1_sequence *cur = subject_alt_name;
00455 
00456     /* Get main sequence tag */
00457     if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
00458             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
00459         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
00460 
00461     if( *p + len != end )
00462         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
00463                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
00464 
00465     while( *p < end )
00466     {
00467         if( ( end - *p ) < 1 )
00468             return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
00469                     MBEDTLS_ERR_ASN1_OUT_OF_DATA );
00470 
00471         tag = **p;
00472         (*p)++;
00473         if( ( ret = mbedtls_asn1_get_len( p, end, &tag_len ) ) != 0 )
00474             return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
00475 
00476         if( ( tag & MBEDTLS_ASN1_CONTEXT_SPECIFIC ) != MBEDTLS_ASN1_CONTEXT_SPECIFIC )
00477             return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
00478                     MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
00479 
00480         /* Skip everything but DNS name */
00481         if( tag != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | 2 ) )
00482         {
00483             *p += tag_len;
00484             continue;
00485         }
00486 
00487         /* Allocate and assign next pointer */
00488         if( cur->buf.p != NULL )
00489         {
00490             if( cur->next != NULL )
00491                 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS );
00492 
00493             cur->next = mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence ) );
00494 
00495             if( cur->next == NULL )
00496                 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
00497                         MBEDTLS_ERR_ASN1_ALLOC_FAILED );
00498 
00499             cur = cur->next;
00500         }
00501 
00502         buf = &(cur->buf);
00503         buf->tag = tag;
00504         buf->p = *p;
00505         buf->len = tag_len;
00506         *p += buf->len;
00507     }
00508 
00509     /* Set final sequence entry's next pointer to NULL */
00510     cur->next = NULL;
00511 
00512     if( *p != end )
00513         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
00514                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
00515 
00516     return( 0 );
00517 }
00518 
00519 /*
00520  * X.509 v3 extensions
00521  *
00522  */
00523 static int x509_get_crt_ext( unsigned char **p,
00524                              const unsigned char *end,
00525                              mbedtls_x509_crt *crt )
00526 {
00527     int ret;
00528     size_t len;
00529     unsigned char *end_ext_data, *end_ext_octet;
00530 
00531     if( ( ret = mbedtls_x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 )
00532     {
00533         if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
00534             return( 0 );
00535 
00536         return( ret );
00537     }
00538 
00539     while( *p < end )
00540     {
00541         /*
00542          * Extension  ::=  SEQUENCE  {
00543          *      extnID      OBJECT IDENTIFIER,
00544          *      critical    BOOLEAN DEFAULT FALSE,
00545          *      extnValue   OCTET STRING  }
00546          */
00547         mbedtls_x509_buf extn_oid = {0, 0, NULL};
00548         int is_critical = 0; /* DEFAULT FALSE */
00549         int ext_type = 0;
00550 
00551         if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
00552                 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
00553             return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
00554 
00555         end_ext_data = *p + len;
00556 
00557         /* Get extension ID */
00558         extn_oid.tag = **p;
00559 
00560         if( ( ret = mbedtls_asn1_get_tag( p, end, &extn_oid.len, MBEDTLS_ASN1_OID ) ) != 0 )
00561             return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
00562 
00563         extn_oid.p = *p;
00564         *p += extn_oid.len;
00565 
00566         if( ( end - *p ) < 1 )
00567             return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
00568                     MBEDTLS_ERR_ASN1_OUT_OF_DATA );
00569 
00570         /* Get optional critical */
00571         if( ( ret = mbedtls_asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
00572             ( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) )
00573             return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
00574 
00575         /* Data should be octet string type */
00576         if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &len,
00577                 MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
00578             return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
00579 
00580         end_ext_octet = *p + len;
00581 
00582         if( end_ext_octet != end_ext_data )
00583             return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
00584                     MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
00585 
00586         /*
00587          * Detect supported extensions
00588          */
00589         ret = mbedtls_oid_get_x509_ext_type( &extn_oid, &ext_type );
00590 
00591         if( ret != 0 )
00592         {
00593             /* No parser found, skip extension */
00594             *p = end_ext_octet;
00595 
00596 #if !defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
00597             if( is_critical )
00598             {
00599                 /* Data is marked as critical: fail */
00600                 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
00601                         MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
00602             }
00603 #endif
00604             continue;
00605         }
00606 
00607         /* Forbid repeated extensions */
00608         if( ( crt->ext_types & ext_type ) != 0 )
00609             return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS );
00610 
00611         crt->ext_types |= ext_type;
00612 
00613         switch( ext_type )
00614         {
00615         case MBEDTLS_X509_EXT_BASIC_CONSTRAINTS:
00616             /* Parse basic constraints */
00617             if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
00618                     &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
00619                 return( ret );
00620             break;
00621 
00622         case MBEDTLS_X509_EXT_KEY_USAGE:
00623             /* Parse key usage */
00624             if( ( ret = x509_get_key_usage( p, end_ext_octet,
00625                     &crt->key_usage ) ) != 0 )
00626                 return( ret );
00627             break;
00628 
00629         case MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE:
00630             /* Parse extended key usage */
00631             if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
00632                     &crt->ext_key_usage ) ) != 0 )
00633                 return( ret );
00634             break;
00635 
00636         case MBEDTLS_X509_EXT_SUBJECT_ALT_NAME:
00637             /* Parse subject alt name */
00638             if( ( ret = x509_get_subject_alt_name( p, end_ext_octet,
00639                     &crt->subject_alt_names ) ) != 0 )
00640                 return( ret );
00641             break;
00642 
00643         case MBEDTLS_X509_EXT_NS_CERT_TYPE:
00644             /* Parse netscape certificate type */
00645             if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
00646                     &crt->ns_cert_type ) ) != 0 )
00647                 return( ret );
00648             break;
00649 
00650         default:
00651             return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE );
00652         }
00653     }
00654 
00655     if( *p != end )
00656         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
00657                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
00658 
00659     return( 0 );
00660 }
00661 
00662 /*
00663  * Parse and fill a single X.509 certificate in DER format
00664  */
00665 static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *buf,
00666                                     size_t buflen )
00667 {
00668     int ret;
00669     size_t len;
00670     unsigned char *p, *end, *crt_end;
00671     mbedtls_x509_buf sig_params1, sig_params2, sig_oid2;
00672 
00673     memset( &sig_params1, 0, sizeof( mbedtls_x509_buf ) );
00674     memset( &sig_params2, 0, sizeof( mbedtls_x509_buf ) );
00675     memset( &sig_oid2, 0, sizeof( mbedtls_x509_buf ) );
00676 
00677     /*
00678      * Check for valid input
00679      */
00680     if( crt == NULL || buf == NULL )
00681         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
00682 
00683     // Use the original buffer until we figure out actual length
00684     p = (unsigned char*) buf;
00685     len = buflen;
00686     end = p + len;
00687 
00688     /*
00689      * Certificate  ::=  SEQUENCE  {
00690      *      tbsCertificate       TBSCertificate,
00691      *      signatureAlgorithm   AlgorithmIdentifier,
00692      *      signatureValue       BIT STRING  }
00693      */
00694     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
00695             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
00696     {
00697         mbedtls_x509_crt_free( crt );
00698         return( MBEDTLS_ERR_X509_INVALID_FORMAT );
00699     }
00700 
00701     if( len > (size_t) ( end - p ) )
00702     {
00703         mbedtls_x509_crt_free( crt );
00704         return( MBEDTLS_ERR_X509_INVALID_FORMAT +
00705                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
00706     }
00707     crt_end = p + len;
00708 
00709     // Create and populate a new buffer for the raw field
00710     crt->raw.len = crt_end - buf;
00711     crt->raw.p = p = mbedtls_calloc( 1, crt->raw.len );
00712     if( p == NULL )
00713         return( MBEDTLS_ERR_X509_ALLOC_FAILED );
00714 
00715     memcpy( p, buf, crt->raw.len );
00716 
00717     // Direct pointers to the new buffer 
00718     p += crt->raw.len - len;
00719     end = crt_end = p + len;
00720 
00721     /*
00722      * TBSCertificate  ::=  SEQUENCE  {
00723      */
00724     crt->tbs.p = p;
00725 
00726     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
00727             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
00728     {
00729         mbedtls_x509_crt_free( crt );
00730         return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
00731     }
00732 
00733     end = p + len;
00734     crt->tbs.len = end - crt->tbs.p;
00735 
00736     /*
00737      * Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
00738      *
00739      * CertificateSerialNumber  ::=  INTEGER
00740      *
00741      * signature            AlgorithmIdentifier
00742      */
00743     if( ( ret = x509_get_version(  &p, end, &crt->version  ) ) != 0 ||
00744         ( ret = mbedtls_x509_get_serial(   &p, end, &crt->serial   ) ) != 0 ||
00745         ( ret = mbedtls_x509_get_alg(      &p, end, &crt->sig_oid,
00746                                             &sig_params1 ) ) != 0 )
00747     {
00748         mbedtls_x509_crt_free( crt );
00749         return( ret );
00750     }
00751 
00752     if( crt->version < 0 || crt->version > 2 )
00753     {
00754         mbedtls_x509_crt_free( crt );
00755         return( MBEDTLS_ERR_X509_UNKNOWN_VERSION );
00756     }
00757 
00758     crt->version++;
00759 
00760     if( ( ret = mbedtls_x509_get_sig_alg( &crt->sig_oid, &sig_params1,
00761                                   &crt->sig_md, &crt->sig_pk,
00762                                   &crt->sig_opts ) ) != 0 )
00763     {
00764         mbedtls_x509_crt_free( crt );
00765         return( ret );
00766     }
00767 
00768     /*
00769      * issuer               Name
00770      */
00771     crt->issuer_raw.p = p;
00772 
00773     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
00774             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
00775     {
00776         mbedtls_x509_crt_free( crt );
00777         return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
00778     }
00779 
00780     if( ( ret = mbedtls_x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
00781     {
00782         mbedtls_x509_crt_free( crt );
00783         return( ret );
00784     }
00785 
00786     crt->issuer_raw.len = p - crt->issuer_raw.p;
00787 
00788     /*
00789      * Validity ::= SEQUENCE {
00790      *      notBefore      Time,
00791      *      notAfter       Time }
00792      *
00793      */
00794     if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
00795                                          &crt->valid_to ) ) != 0 )
00796     {
00797         mbedtls_x509_crt_free( crt );
00798         return( ret );
00799     }
00800 
00801     /*
00802      * subject              Name
00803      */
00804     crt->subject_raw.p = p;
00805 
00806     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
00807             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
00808     {
00809         mbedtls_x509_crt_free( crt );
00810         return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
00811     }
00812 
00813     if( len && ( ret = mbedtls_x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
00814     {
00815         mbedtls_x509_crt_free( crt );
00816         return( ret );
00817     }
00818 
00819     crt->subject_raw.len = p - crt->subject_raw.p;
00820 
00821     /*
00822      * SubjectPublicKeyInfo
00823      */
00824     if( ( ret = mbedtls_pk_parse_subpubkey( &p, end, &crt->pk ) ) != 0 )
00825     {
00826         mbedtls_x509_crt_free( crt );
00827         return( ret );
00828     }
00829 
00830     /*
00831      *  issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
00832      *                       -- If present, version shall be v2 or v3
00833      *  subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
00834      *                       -- If present, version shall be v2 or v3
00835      *  extensions      [3]  EXPLICIT Extensions OPTIONAL
00836      *                       -- If present, version shall be v3
00837      */
00838     if( crt->version == 2 || crt->version == 3 )
00839     {
00840         ret = x509_get_uid( &p, end, &crt->issuer_id,  1 );
00841         if( ret != 0 )
00842         {
00843             mbedtls_x509_crt_free( crt );
00844             return( ret );
00845         }
00846     }
00847 
00848     if( crt->version == 2 || crt->version == 3 )
00849     {
00850         ret = x509_get_uid( &p, end, &crt->subject_id,  2 );
00851         if( ret != 0 )
00852         {
00853             mbedtls_x509_crt_free( crt );
00854             return( ret );
00855         }
00856     }
00857 
00858 #if !defined(MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3)
00859     if( crt->version == 3 )
00860 #endif
00861     {
00862         ret = x509_get_crt_ext( &p, end, crt );
00863         if( ret != 0 )
00864         {
00865             mbedtls_x509_crt_free( crt );
00866             return( ret );
00867         }
00868     }
00869 
00870     if( p != end )
00871     {
00872         mbedtls_x509_crt_free( crt );
00873         return( MBEDTLS_ERR_X509_INVALID_FORMAT +
00874                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
00875     }
00876 
00877     end = crt_end;
00878 
00879     /*
00880      *  }
00881      *  -- end of TBSCertificate
00882      *
00883      *  signatureAlgorithm   AlgorithmIdentifier,
00884      *  signatureValue       BIT STRING
00885      */
00886     if( ( ret = mbedtls_x509_get_alg( &p, end, &sig_oid2, &sig_params2 ) ) != 0 )
00887     {
00888         mbedtls_x509_crt_free( crt );
00889         return( ret );
00890     }
00891 
00892     if( crt->sig_oid.len != sig_oid2.len ||
00893         memcmp( crt->sig_oid.p, sig_oid2.p, crt->sig_oid.len ) != 0 ||
00894         sig_params1.len != sig_params2.len ||
00895         ( sig_params1.len != 0 &&
00896           memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) )
00897     {
00898         mbedtls_x509_crt_free( crt );
00899         return( MBEDTLS_ERR_X509_SIG_MISMATCH );
00900     }
00901 
00902     if( ( ret = mbedtls_x509_get_sig( &p, end, &crt->sig ) ) != 0 )
00903     {
00904         mbedtls_x509_crt_free( crt );
00905         return( ret );
00906     }
00907 
00908     if( p != end )
00909     {
00910         mbedtls_x509_crt_free( crt );
00911         return( MBEDTLS_ERR_X509_INVALID_FORMAT +
00912                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
00913     }
00914 
00915     return( 0 );
00916 }
00917 
00918 /*
00919  * Parse one X.509 certificate in DER format from a buffer and add them to a
00920  * chained list
00921  */
00922 int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, const unsigned char *buf,
00923                         size_t buflen )
00924 {
00925     int ret;
00926     mbedtls_x509_crt *crt = chain, *prev = NULL;
00927 
00928     /*
00929      * Check for valid input
00930      */
00931     if( crt == NULL || buf == NULL )
00932         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
00933 
00934     while( crt->version != 0 && crt->next != NULL )
00935     {
00936         prev = crt;
00937         crt = crt->next;
00938     }
00939 
00940     /*
00941      * Add new certificate on the end of the chain if needed.
00942      */
00943     if( crt->version != 0 && crt->next == NULL )
00944     {
00945         crt->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) );
00946 
00947         if( crt->next == NULL )
00948             return( MBEDTLS_ERR_X509_ALLOC_FAILED );
00949 
00950         prev = crt;
00951         mbedtls_x509_crt_init( crt->next );
00952         crt = crt->next;
00953     }
00954 
00955     if( ( ret = x509_crt_parse_der_core( crt, buf, buflen ) ) != 0 )
00956     {
00957         if( prev )
00958             prev->next = NULL;
00959 
00960         if( crt != chain )
00961             mbedtls_free( crt );
00962 
00963         return( ret );
00964     }
00965 
00966     return( 0 );
00967 }
00968 
00969 /*
00970  * Parse one or more PEM certificates from a buffer and add them to the chained
00971  * list
00972  */
00973 int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, size_t buflen )
00974 {
00975 #if defined(MBEDTLS_PEM_PARSE_C)
00976     int success = 0, first_error = 0, total_failed = 0;
00977     int buf_format = MBEDTLS_X509_FORMAT_DER;
00978 #endif
00979 
00980     /*
00981      * Check for valid input
00982      */
00983     if( chain == NULL || buf == NULL )
00984         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
00985 
00986     /*
00987      * Determine buffer content. Buffer contains either one DER certificate or
00988      * one or more PEM certificates.
00989      */
00990 #if defined(MBEDTLS_PEM_PARSE_C)
00991     if( buflen != 0 && buf[buflen - 1] == '\0' &&
00992         strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL )
00993     {
00994         buf_format = MBEDTLS_X509_FORMAT_PEM;
00995     }
00996 
00997     if( buf_format == MBEDTLS_X509_FORMAT_DER )
00998         return mbedtls_x509_crt_parse_der( chain, buf, buflen );
00999 #else
01000     return mbedtls_x509_crt_parse_der( chain, buf, buflen );
01001 #endif
01002 
01003 #if defined(MBEDTLS_PEM_PARSE_C)
01004     if( buf_format == MBEDTLS_X509_FORMAT_PEM )
01005     {
01006         int ret;
01007         mbedtls_pem_context pem;
01008 
01009         /* 1 rather than 0 since the terminating NULL byte is counted in */
01010         while( buflen > 1 )
01011         {
01012             size_t use_len;
01013             mbedtls_pem_init( &pem );
01014 
01015             /* If we get there, we know the string is null-terminated */
01016             ret = mbedtls_pem_read_buffer( &pem,
01017                            "-----BEGIN CERTIFICATE-----",
01018                            "-----END CERTIFICATE-----",
01019                            buf, NULL, 0, &use_len );
01020 
01021             if( ret == 0 )
01022             {
01023                 /*
01024                  * Was PEM encoded
01025                  */
01026                 buflen -= use_len;
01027                 buf += use_len;
01028             }
01029             else if( ret == MBEDTLS_ERR_PEM_BAD_INPUT_DATA )
01030             {
01031                 return( ret );
01032             }
01033             else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
01034             {
01035                 mbedtls_pem_free( &pem );
01036 
01037                 /*
01038                  * PEM header and footer were found
01039                  */
01040                 buflen -= use_len;
01041                 buf += use_len;
01042 
01043                 if( first_error == 0 )
01044                     first_error = ret;
01045 
01046                 total_failed++;
01047                 continue;
01048             }
01049             else
01050                 break;
01051 
01052             ret = mbedtls_x509_crt_parse_der( chain, pem.buf , pem.buflen  );
01053 
01054             mbedtls_pem_free( &pem );
01055 
01056             if( ret != 0 )
01057             {
01058                 /*
01059                  * Quit parsing on a memory error
01060                  */
01061                 if( ret == MBEDTLS_ERR_X509_ALLOC_FAILED )
01062                     return( ret );
01063 
01064                 if( first_error == 0 )
01065                     first_error = ret;
01066 
01067                 total_failed++;
01068                 continue;
01069             }
01070 
01071             success = 1;
01072         }
01073     }
01074 
01075     if( success )
01076         return( total_failed );
01077     else if( first_error )
01078         return( first_error );
01079     else
01080         return( MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT );
01081 #endif /* MBEDTLS_PEM_PARSE_C */
01082 }
01083 
01084 #if defined(MBEDTLS_FS_IO)
01085 /*
01086  * Load one or more certificates and add them to the chained list
01087  */
01088 int mbedtls_x509_crt_parse_file( mbedtls_x509_crt *chain, const char *path )
01089 {
01090     int ret;
01091     size_t n;
01092     unsigned char *buf;
01093 
01094     if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
01095         return( ret );
01096 
01097     ret = mbedtls_x509_crt_parse( chain, buf, n );
01098 
01099     mbedtls_zeroize( buf, n );
01100     mbedtls_free( buf );
01101 
01102     return( ret );
01103 }
01104 
01105 int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path )
01106 {
01107     int ret = 0;
01108 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
01109     int w_ret;
01110     WCHAR szDir[MAX_PATH];
01111     char filename[MAX_PATH];
01112     char *p;
01113     size_t len = strlen( path );
01114 
01115     WIN32_FIND_DATAW file_data;
01116     HANDLE hFind;
01117 
01118     if( len > MAX_PATH - 3 )
01119         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
01120 
01121     memset( szDir, 0, sizeof(szDir) );
01122     memset( filename, 0, MAX_PATH );
01123     memcpy( filename, path, len );
01124     filename[len++] = '\\';
01125     p = filename + len;
01126     filename[len++] = '*';
01127 
01128     w_ret = MultiByteToWideChar( CP_ACP, 0, filename, (int)len, szDir,
01129                                  MAX_PATH - 3 );
01130     if( w_ret == 0 )
01131         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
01132 
01133     hFind = FindFirstFileW( szDir, &file_data );
01134     if( hFind == INVALID_HANDLE_VALUE )
01135         return( MBEDTLS_ERR_X509_FILE_IO_ERROR );
01136 
01137     len = MAX_PATH - len;
01138     do
01139     {
01140         memset( p, 0, len );
01141 
01142         if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
01143             continue;
01144 
01145         w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName,
01146                                      lstrlenW( file_data.cFileName ),
01147                                      p, (int) len - 1,
01148                                      NULL, NULL );
01149         if( w_ret == 0 )
01150         {
01151             ret = MBEDTLS_ERR_X509_FILE_IO_ERROR;
01152             goto cleanup;
01153         }
01154 
01155         w_ret = mbedtls_x509_crt_parse_file( chain, filename );
01156         if( w_ret < 0 )
01157             ret++;
01158         else
01159             ret += w_ret;
01160     }
01161     while( FindNextFileW( hFind, &file_data ) != 0 );
01162 
01163     if( GetLastError() != ERROR_NO_MORE_FILES )
01164         ret = MBEDTLS_ERR_X509_FILE_IO_ERROR;
01165 
01166 cleanup:
01167     FindClose( hFind );
01168 #else /* _WIN32 */
01169     int t_ret;
01170     int snp_ret;
01171     struct stat sb;
01172     struct dirent *entry;
01173     char entry_name[MBEDTLS_X509_MAX_FILE_PATH_LEN];
01174     DIR *dir = opendir( path );
01175 
01176     if( dir == NULL )
01177         return( MBEDTLS_ERR_X509_FILE_IO_ERROR );
01178 
01179 #if defined(MBEDTLS_THREADING_C)
01180     if( ( ret = mbedtls_mutex_lock( &mbedtls_threading_readdir_mutex ) ) != 0 )
01181     {
01182         closedir( dir );
01183         return( ret );
01184     }
01185 #endif /* MBEDTLS_THREADING_C */
01186 
01187     while( ( entry = readdir( dir ) ) != NULL )
01188     {
01189         snp_ret = mbedtls_snprintf( entry_name, sizeof entry_name,
01190                                     "%s/%s", path, entry->d_name );
01191 
01192         if( snp_ret < 0 || (size_t)snp_ret >= sizeof entry_name )
01193         {
01194             ret = MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
01195             goto cleanup;
01196         }
01197         else if( stat( entry_name, &sb ) == -1 )
01198         {
01199             ret = MBEDTLS_ERR_X509_FILE_IO_ERROR;
01200             goto cleanup;
01201         }
01202 
01203         if( !S_ISREG( sb.st_mode ) )
01204             continue;
01205 
01206         // Ignore parse errors
01207         //
01208         t_ret = mbedtls_x509_crt_parse_file( chain, entry_name );
01209         if( t_ret < 0 )
01210             ret++;
01211         else
01212             ret += t_ret;
01213     }
01214 
01215 cleanup:
01216     closedir( dir );
01217 
01218 #if defined(MBEDTLS_THREADING_C)
01219     if( mbedtls_mutex_unlock( &mbedtls_threading_readdir_mutex ) != 0 )
01220         ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
01221 #endif /* MBEDTLS_THREADING_C */
01222 
01223 #endif /* _WIN32 */
01224 
01225     return( ret );
01226 }
01227 #endif /* MBEDTLS_FS_IO */
01228 
01229 static int x509_info_subject_alt_name( char **buf, size_t *size,
01230                                        const mbedtls_x509_sequence *subject_alt_name )
01231 {
01232     size_t i;
01233     size_t n = *size;
01234     char *p = *buf;
01235     const mbedtls_x509_sequence *cur = subject_alt_name;
01236     const char *sep = "";
01237     size_t sep_len = 0;
01238 
01239     while( cur != NULL )
01240     {
01241         if( cur->buf.len + sep_len >= n )
01242         {
01243             *p = '\0';
01244             return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL );
01245         }
01246 
01247         n -= cur->buf.len + sep_len;
01248         for( i = 0; i < sep_len; i++ )
01249             *p++ = sep[i];
01250         for( i = 0; i < cur->buf.len; i++ )
01251             *p++ = cur->buf.p[i];
01252 
01253         sep = ", ";
01254         sep_len = 2;
01255 
01256         cur = cur->next;
01257     }
01258 
01259     *p = '\0';
01260 
01261     *size = n;
01262     *buf = p;
01263 
01264     return( 0 );
01265 }
01266 
01267 #define PRINT_ITEM(i)                           \
01268     {                                           \
01269         ret = mbedtls_snprintf( p, n, "%s" i, sep );    \
01270         MBEDTLS_X509_SAFE_SNPRINTF;                        \
01271         sep = ", ";                             \
01272     }
01273 
01274 #define CERT_TYPE(type,name)                    \
01275     if( ns_cert_type & type )                   \
01276         PRINT_ITEM( name );
01277 
01278 static int x509_info_cert_type( char **buf, size_t *size,
01279                                 unsigned char ns_cert_type )
01280 {
01281     int ret;
01282     size_t n = *size;
01283     char *p = *buf;
01284     const char *sep = "";
01285 
01286     CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT,         "SSL Client" );
01287     CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER,         "SSL Server" );
01288     CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_EMAIL,              "Email" );
01289     CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING,     "Object Signing" );
01290     CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_RESERVED,           "Reserved" );
01291     CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_CA,             "SSL CA" );
01292     CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA,           "Email CA" );
01293     CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA,  "Object Signing CA" );
01294 
01295     *size = n;
01296     *buf = p;
01297 
01298     return( 0 );
01299 }
01300 
01301 #define KEY_USAGE(code,name)    \
01302     if( key_usage & code )      \
01303         PRINT_ITEM( name );
01304 
01305 static int x509_info_key_usage( char **buf, size_t *size,
01306                                 unsigned int key_usage )
01307 {
01308     int ret;
01309     size_t n = *size;
01310     char *p = *buf;
01311     const char *sep = "";
01312 
01313     KEY_USAGE( MBEDTLS_X509_KU_DIGITAL_SIGNATURE,    "Digital Signature" );
01314     KEY_USAGE( MBEDTLS_X509_KU_NON_REPUDIATION,      "Non Repudiation" );
01315     KEY_USAGE( MBEDTLS_X509_KU_KEY_ENCIPHERMENT,     "Key Encipherment" );
01316     KEY_USAGE( MBEDTLS_X509_KU_DATA_ENCIPHERMENT,    "Data Encipherment" );
01317     KEY_USAGE( MBEDTLS_X509_KU_KEY_AGREEMENT,        "Key Agreement" );
01318     KEY_USAGE( MBEDTLS_X509_KU_KEY_CERT_SIGN,        "Key Cert Sign" );
01319     KEY_USAGE( MBEDTLS_X509_KU_CRL_SIGN,             "CRL Sign" );
01320     KEY_USAGE( MBEDTLS_X509_KU_ENCIPHER_ONLY,        "Encipher Only" );
01321     KEY_USAGE( MBEDTLS_X509_KU_DECIPHER_ONLY,        "Decipher Only" );
01322 
01323     *size = n;
01324     *buf = p;
01325 
01326     return( 0 );
01327 }
01328 
01329 static int x509_info_ext_key_usage( char **buf, size_t *size,
01330                                     const mbedtls_x509_sequence *extended_key_usage )
01331 {
01332     int ret;
01333     const char *desc;
01334     size_t n = *size;
01335     char *p = *buf;
01336     const mbedtls_x509_sequence *cur = extended_key_usage;
01337     const char *sep = "";
01338 
01339     while( cur != NULL )
01340     {
01341         if( mbedtls_oid_get_extended_key_usage( &cur->buf, &desc ) != 0 )
01342             desc = "???";
01343 
01344         ret = mbedtls_snprintf( p, n, "%s%s", sep, desc );
01345         MBEDTLS_X509_SAFE_SNPRINTF;
01346 
01347         sep = ", ";
01348 
01349         cur = cur->next;
01350     }
01351 
01352     *size = n;
01353     *buf = p;
01354 
01355     return( 0 );
01356 }
01357 
01358 /*
01359  * Return an informational string about the certificate.
01360  */
01361 #define BEFORE_COLON    18
01362 #define BC              "18"
01363 int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix,
01364                    const mbedtls_x509_crt *crt )
01365 {
01366     int ret;
01367     size_t n;
01368     char *p;
01369     char key_size_str[BEFORE_COLON];
01370 
01371     p = buf;
01372     n = size;
01373 
01374     if( NULL == crt )
01375     {
01376         ret = mbedtls_snprintf( p, n, "\nCertificate is uninitialised!\n" );
01377         MBEDTLS_X509_SAFE_SNPRINTF;
01378 
01379         return( (int) ( size - n ) );
01380     }
01381 
01382     ret = mbedtls_snprintf( p, n, "%scert. version     : %d\n",
01383                                prefix, crt->version );
01384     MBEDTLS_X509_SAFE_SNPRINTF;
01385     ret = mbedtls_snprintf( p, n, "%sserial number     : ",
01386                                prefix );
01387     MBEDTLS_X509_SAFE_SNPRINTF;
01388 
01389     ret = mbedtls_x509_serial_gets( p, n, &crt->serial );
01390     MBEDTLS_X509_SAFE_SNPRINTF;
01391 
01392     ret = mbedtls_snprintf( p, n, "\n%sissuer name       : ", prefix );
01393     MBEDTLS_X509_SAFE_SNPRINTF;
01394     ret = mbedtls_x509_dn_gets( p, n, &crt->issuer  );
01395     MBEDTLS_X509_SAFE_SNPRINTF;
01396 
01397     ret = mbedtls_snprintf( p, n, "\n%ssubject name      : ", prefix );
01398     MBEDTLS_X509_SAFE_SNPRINTF;
01399     ret = mbedtls_x509_dn_gets( p, n, &crt->subject );
01400     MBEDTLS_X509_SAFE_SNPRINTF;
01401 
01402     ret = mbedtls_snprintf( p, n, "\n%sissued  on        : " \
01403                    "%04d-%02d-%02d %02d:%02d:%02d", prefix,
01404                    crt->valid_from.year, crt->valid_from.mon,
01405                    crt->valid_from.day,  crt->valid_from.hour,
01406                    crt->valid_from.min,  crt->valid_from.sec );
01407     MBEDTLS_X509_SAFE_SNPRINTF;
01408 
01409     ret = mbedtls_snprintf( p, n, "\n%sexpires on        : " \
01410                    "%04d-%02d-%02d %02d:%02d:%02d", prefix,
01411                    crt->valid_to.year, crt->valid_to.mon,
01412                    crt->valid_to.day,  crt->valid_to.hour,
01413                    crt->valid_to.min,  crt->valid_to.sec );
01414     MBEDTLS_X509_SAFE_SNPRINTF;
01415 
01416     ret = mbedtls_snprintf( p, n, "\n%ssigned using      : ", prefix );
01417     MBEDTLS_X509_SAFE_SNPRINTF;
01418 
01419     ret = mbedtls_x509_sig_alg_gets( p, n, &crt->sig_oid, crt->sig_pk,
01420                              crt->sig_md, crt->sig_opts );
01421     MBEDTLS_X509_SAFE_SNPRINTF;
01422 
01423     /* Key size */
01424     if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON,
01425                                       mbedtls_pk_get_name( &crt->pk ) ) ) != 0 )
01426     {
01427         return( ret );
01428     }
01429 
01430     ret = mbedtls_snprintf( p, n, "\n%s%-" BC "s: %d bits", prefix, key_size_str,
01431                           (int) mbedtls_pk_get_bitlen( &crt->pk ) );
01432     MBEDTLS_X509_SAFE_SNPRINTF;
01433 
01434     /*
01435      * Optional extensions
01436      */
01437 
01438     if( crt->ext_types & MBEDTLS_X509_EXT_BASIC_CONSTRAINTS )
01439     {
01440         ret = mbedtls_snprintf( p, n, "\n%sbasic constraints : CA=%s", prefix,
01441                         crt->ca_istrue ? "true" : "false" );
01442         MBEDTLS_X509_SAFE_SNPRINTF;
01443 
01444         if( crt->max_pathlen > 0 )
01445         {
01446             ret = mbedtls_snprintf( p, n, ", max_pathlen=%d", crt->max_pathlen - 1 );
01447             MBEDTLS_X509_SAFE_SNPRINTF;
01448         }
01449     }
01450 
01451     if( crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME )
01452     {
01453         ret = mbedtls_snprintf( p, n, "\n%ssubject alt name  : ", prefix );
01454         MBEDTLS_X509_SAFE_SNPRINTF;
01455 
01456         if( ( ret = x509_info_subject_alt_name( &p, &n,
01457                                             &crt->subject_alt_names ) ) != 0 )
01458             return( ret );
01459     }
01460 
01461     if( crt->ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE )
01462     {
01463         ret = mbedtls_snprintf( p, n, "\n%scert. type        : ", prefix );
01464         MBEDTLS_X509_SAFE_SNPRINTF;
01465 
01466         if( ( ret = x509_info_cert_type( &p, &n, crt->ns_cert_type ) ) != 0 )
01467             return( ret );
01468     }
01469 
01470     if( crt->ext_types & MBEDTLS_X509_EXT_KEY_USAGE )
01471     {
01472         ret = mbedtls_snprintf( p, n, "\n%skey usage         : ", prefix );
01473         MBEDTLS_X509_SAFE_SNPRINTF;
01474 
01475         if( ( ret = x509_info_key_usage( &p, &n, crt->key_usage ) ) != 0 )
01476             return( ret );
01477     }
01478 
01479     if( crt->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE )
01480     {
01481         ret = mbedtls_snprintf( p, n, "\n%sext key usage     : ", prefix );
01482         MBEDTLS_X509_SAFE_SNPRINTF;
01483 
01484         if( ( ret = x509_info_ext_key_usage( &p, &n,
01485                                              &crt->ext_key_usage ) ) != 0 )
01486             return( ret );
01487     }
01488 
01489     ret = mbedtls_snprintf( p, n, "\n" );
01490     MBEDTLS_X509_SAFE_SNPRINTF;
01491 
01492     return( (int) ( size - n ) );
01493 }
01494 
01495 struct x509_crt_verify_string {
01496     int code;
01497     const char *string;
01498 };
01499 
01500 static const struct x509_crt_verify_string x509_crt_verify_strings[] = {
01501     { MBEDTLS_X509_BADCERT_EXPIRED,       "The certificate validity has expired" },
01502     { MBEDTLS_X509_BADCERT_REVOKED,       "The certificate has been revoked (is on a CRL)" },
01503     { MBEDTLS_X509_BADCERT_CN_MISMATCH,   "The certificate Common Name (CN) does not match with the expected CN" },
01504     { MBEDTLS_X509_BADCERT_NOT_TRUSTED,   "The certificate is not correctly signed by the trusted CA" },
01505     { MBEDTLS_X509_BADCRL_NOT_TRUSTED,    "The CRL is not correctly signed by the trusted CA" },
01506     { MBEDTLS_X509_BADCRL_EXPIRED,        "The CRL is expired" },
01507     { MBEDTLS_X509_BADCERT_MISSING,       "Certificate was missing" },
01508     { MBEDTLS_X509_BADCERT_SKIP_VERIFY,   "Certificate verification was skipped" },
01509     { MBEDTLS_X509_BADCERT_OTHER,         "Other reason (can be used by verify callback)" },
01510     { MBEDTLS_X509_BADCERT_FUTURE,        "The certificate validity starts in the future" },
01511     { MBEDTLS_X509_BADCRL_FUTURE,         "The CRL is from the future" },
01512     { MBEDTLS_X509_BADCERT_KEY_USAGE,     "Usage does not match the keyUsage extension" },
01513     { MBEDTLS_X509_BADCERT_EXT_KEY_USAGE, "Usage does not match the extendedKeyUsage extension" },
01514     { MBEDTLS_X509_BADCERT_NS_CERT_TYPE,  "Usage does not match the nsCertType extension" },
01515     { MBEDTLS_X509_BADCERT_BAD_MD,        "The certificate is signed with an unacceptable hash." },
01516     { MBEDTLS_X509_BADCERT_BAD_PK,        "The certificate is signed with an unacceptable PK alg (eg RSA vs ECDSA)." },
01517     { MBEDTLS_X509_BADCERT_BAD_KEY,       "The certificate is signed with an unacceptable key (eg bad curve, RSA too short)." },
01518     { MBEDTLS_X509_BADCRL_BAD_MD,         "The CRL is signed with an unacceptable hash." },
01519     { MBEDTLS_X509_BADCRL_BAD_PK,         "The CRL is signed with an unacceptable PK alg (eg RSA vs ECDSA)." },
01520     { MBEDTLS_X509_BADCRL_BAD_KEY,        "The CRL is signed with an unacceptable key (eg bad curve, RSA too short)." },
01521     { 0, NULL }
01522 };
01523 
01524 int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix,
01525                           uint32_t flags )
01526 {
01527     int ret;
01528     const struct x509_crt_verify_string *cur;
01529     char *p = buf;
01530     size_t n = size;
01531 
01532     for( cur = x509_crt_verify_strings; cur->string != NULL ; cur++ )
01533     {
01534         if( ( flags & cur->code ) == 0 )
01535             continue;
01536 
01537         ret = mbedtls_snprintf( p, n, "%s%s\n", prefix, cur->string );
01538         MBEDTLS_X509_SAFE_SNPRINTF;
01539         flags ^= cur->code;
01540     }
01541 
01542     if( flags != 0 )
01543     {
01544         ret = mbedtls_snprintf( p, n, "%sUnknown reason "
01545                                        "(this should not happen)\n", prefix );
01546         MBEDTLS_X509_SAFE_SNPRINTF;
01547     }
01548 
01549     return( (int) ( size - n ) );
01550 }
01551 
01552 #if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
01553 int mbedtls_x509_crt_check_key_usage( const mbedtls_x509_crt *crt,
01554                                       unsigned int usage )
01555 {
01556     unsigned int usage_must, usage_may;
01557     unsigned int may_mask = MBEDTLS_X509_KU_ENCIPHER_ONLY
01558                           | MBEDTLS_X509_KU_DECIPHER_ONLY;
01559 
01560     if( ( crt->ext_types & MBEDTLS_X509_EXT_KEY_USAGE ) == 0 )
01561         return( 0 );
01562 
01563     usage_must = usage & ~may_mask;
01564 
01565     if( ( ( crt->key_usage & ~may_mask ) & usage_must ) != usage_must )
01566         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
01567 
01568     usage_may = usage & may_mask;
01569 
01570     if( ( ( crt->key_usage & may_mask ) | usage_may ) != usage_may )
01571         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
01572 
01573     return( 0 );
01574 }
01575 #endif
01576 
01577 #if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
01578 int mbedtls_x509_crt_check_extended_key_usage( const mbedtls_x509_crt *crt,
01579                                        const char *usage_oid,
01580                                        size_t usage_len )
01581 {
01582     const mbedtls_x509_sequence *cur;
01583 
01584     /* Extension is not mandatory, absent means no restriction */
01585     if( ( crt->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE ) == 0 )
01586         return( 0 );
01587 
01588     /*
01589      * Look for the requested usage (or wildcard ANY) in our list
01590      */
01591     for( cur = &crt->ext_key_usage; cur != NULL; cur = cur->next )
01592     {
01593         const mbedtls_x509_buf *cur_oid = &cur->buf;
01594 
01595         if( cur_oid->len == usage_len &&
01596             memcmp( cur_oid->p, usage_oid, usage_len ) == 0 )
01597         {
01598             return( 0 );
01599         }
01600 
01601         if( MBEDTLS_OID_CMP( MBEDTLS_OID_ANY_EXTENDED_KEY_USAGE, cur_oid ) == 0 )
01602             return( 0 );
01603     }
01604 
01605     return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
01606 }
01607 #endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */
01608 
01609 #if defined(MBEDTLS_X509_CRL_PARSE_C)
01610 /*
01611  * Return 1 if the certificate is revoked, or 0 otherwise.
01612  */
01613 int mbedtls_x509_crt_is_revoked( const mbedtls_x509_crt *crt, const mbedtls_x509_crl *crl )
01614 {
01615     const mbedtls_x509_crl_entry *cur = &crl->entry;
01616 
01617     while( cur != NULL && cur->serial.len != 0 )
01618     {
01619         if( crt->serial.len == cur->serial.len &&
01620             memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
01621         {
01622             if( mbedtls_x509_time_is_past( &cur->revocation_date ) )
01623                 return( 1 );
01624         }
01625 
01626         cur = cur->next;
01627     }
01628 
01629     return( 0 );
01630 }
01631 
01632 /*
01633  * Check that the given certificate is not revoked according to the CRL.
01634  * Skip validation is no CRL for the given CA is present.
01635  */
01636 static int x509_crt_verifycrl( mbedtls_x509_crt *crt, mbedtls_x509_crt *ca,
01637                                mbedtls_x509_crl *crl_list,
01638                                const mbedtls_x509_crt_profile *profile )
01639 {
01640     int flags = 0;
01641     unsigned char hash[MBEDTLS_MD_MAX_SIZE];
01642     const mbedtls_md_info_t *md_info;
01643 
01644     if( ca == NULL )
01645         return( flags );
01646 
01647     while( crl_list != NULL )
01648     {
01649         if( crl_list->version == 0 ||
01650             crl_list->issuer_raw.len != ca->subject_raw.len ||
01651             memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
01652                     crl_list->issuer_raw.len ) != 0 )
01653         {
01654             crl_list = crl_list->next;
01655             continue;
01656         }
01657 
01658         /*
01659          * Check if the CA is configured to sign CRLs
01660          */
01661 #if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
01662         if( mbedtls_x509_crt_check_key_usage( ca, MBEDTLS_X509_KU_CRL_SIGN ) != 0 )
01663         {
01664             flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
01665             break;
01666         }
01667 #endif
01668 
01669         /*
01670          * Check if CRL is correctly signed by the trusted CA
01671          */
01672         if( x509_profile_check_md_alg( profile, crl_list->sig_md ) != 0 )
01673             flags |= MBEDTLS_X509_BADCRL_BAD_MD;
01674 
01675         if( x509_profile_check_pk_alg( profile, crl_list->sig_pk ) != 0 )
01676             flags |= MBEDTLS_X509_BADCRL_BAD_PK;
01677 
01678         md_info = mbedtls_md_info_from_type( crl_list->sig_md );
01679         if( md_info == NULL )
01680         {
01681             /*
01682              * Cannot check 'unknown' hash
01683              */
01684             flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
01685             break;
01686         }
01687 
01688         mbedtls_md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash );
01689 
01690         if( x509_profile_check_key( profile, crl_list->sig_pk, &ca->pk ) != 0 )
01691             flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
01692 
01693         if( mbedtls_pk_verify_ext( crl_list->sig_pk, crl_list->sig_opts, &ca->pk,
01694                            crl_list->sig_md, hash, mbedtls_md_get_size( md_info ),
01695                            crl_list->sig.p, crl_list->sig.len ) != 0 )
01696         {
01697             flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
01698             break;
01699         }
01700 
01701         /*
01702          * Check for validity of CRL (Do not drop out)
01703          */
01704         if( mbedtls_x509_time_is_past( &crl_list->next_update ) )
01705             flags |= MBEDTLS_X509_BADCRL_EXPIRED;
01706 
01707         if( mbedtls_x509_time_is_future( &crl_list->this_update ) )
01708             flags |= MBEDTLS_X509_BADCRL_FUTURE;
01709 
01710         /*
01711          * Check if certificate is revoked
01712          */
01713         if( mbedtls_x509_crt_is_revoked( crt, crl_list ) )
01714         {
01715             flags |= MBEDTLS_X509_BADCERT_REVOKED;
01716             break;
01717         }
01718 
01719         crl_list = crl_list->next;
01720     }
01721 
01722     return( flags );
01723 }
01724 #endif /* MBEDTLS_X509_CRL_PARSE_C */
01725 
01726 /*
01727  * Like memcmp, but case-insensitive and always returns -1 if different
01728  */
01729 static int x509_memcasecmp( const void *s1, const void *s2, size_t len )
01730 {
01731     size_t i;
01732     unsigned char diff;
01733     const unsigned char *n1 = s1, *n2 = s2;
01734 
01735     for( i = 0; i < len; i++ )
01736     {
01737         diff = n1[i] ^ n2[i];
01738 
01739         if( diff == 0 )
01740             continue;
01741 
01742         if( diff == 32 &&
01743             ( ( n1[i] >= 'a' && n1[i] <= 'z' ) ||
01744               ( n1[i] >= 'A' && n1[i] <= 'Z' ) ) )
01745         {
01746             continue;
01747         }
01748 
01749         return( -1 );
01750     }
01751 
01752     return( 0 );
01753 }
01754 
01755 /*
01756  * Return 0 if name matches wildcard, -1 otherwise
01757  */
01758 static int x509_check_wildcard( const char *cn, mbedtls_x509_buf *name )
01759 {
01760     size_t i;
01761     size_t cn_idx = 0, cn_len = strlen( cn );
01762 
01763     if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' )
01764         return( 0 );
01765 
01766     for( i = 0; i < cn_len; ++i )
01767     {
01768         if( cn[i] == '.' )
01769         {
01770             cn_idx = i;
01771             break;
01772         }
01773     }
01774 
01775     if( cn_idx == 0 )
01776         return( -1 );
01777 
01778     if( cn_len - cn_idx == name->len - 1 &&
01779         x509_memcasecmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
01780     {
01781         return( 0 );
01782     }
01783 
01784     return( -1 );
01785 }
01786 
01787 /*
01788  * Compare two X.509 strings, case-insensitive, and allowing for some encoding
01789  * variations (but not all).
01790  *
01791  * Return 0 if equal, -1 otherwise.
01792  */
01793 static int x509_string_cmp( const mbedtls_x509_buf *a, const mbedtls_x509_buf *b )
01794 {
01795     if( a->tag == b->tag &&
01796         a->len == b->len &&
01797         memcmp( a->p, b->p, b->len ) == 0 )
01798     {
01799         return( 0 );
01800     }
01801 
01802     if( ( a->tag == MBEDTLS_ASN1_UTF8_STRING || a->tag == MBEDTLS_ASN1_PRINTABLE_STRING ) &&
01803         ( b->tag == MBEDTLS_ASN1_UTF8_STRING || b->tag == MBEDTLS_ASN1_PRINTABLE_STRING ) &&
01804         a->len == b->len &&
01805         x509_memcasecmp( a->p, b->p, b->len ) == 0 )
01806     {
01807         return( 0 );
01808     }
01809 
01810     return( -1 );
01811 }
01812 
01813 /*
01814  * Compare two X.509 Names (aka rdnSequence).
01815  *
01816  * See RFC 5280 section 7.1, though we don't implement the whole algorithm:
01817  * we sometimes return unequal when the full algorithm would return equal,
01818  * but never the other way. (In particular, we don't do Unicode normalisation
01819  * or space folding.)
01820  *
01821  * Return 0 if equal, -1 otherwise.
01822  */
01823 static int x509_name_cmp( const mbedtls_x509_name *a, const mbedtls_x509_name *b )
01824 {
01825     /* Avoid recursion, it might not be optimised by the compiler */
01826     while( a != NULL || b != NULL )
01827     {
01828         if( a == NULL || b == NULL )
01829             return( -1 );
01830 
01831         /* type */
01832         if( a->oid.tag != b->oid.tag ||
01833             a->oid.len != b->oid.len ||
01834             memcmp( a->oid.p, b->oid.p, b->oid.len ) != 0 )
01835         {
01836             return( -1 );
01837         }
01838 
01839         /* value */
01840         if( x509_string_cmp( &a->val, &b->val ) != 0 )
01841             return( -1 );
01842 
01843         /* structure of the list of sets */
01844         if( a->next_merged != b->next_merged )
01845             return( -1 );
01846 
01847         a = a->next;
01848         b = b->next;
01849     }
01850 
01851     /* a == NULL == b */
01852     return( 0 );
01853 }
01854 
01855 /*
01856  * Check if 'parent' is a suitable parent (signing CA) for 'child'.
01857  * Return 0 if yes, -1 if not.
01858  *
01859  * top means parent is a locally-trusted certificate
01860  * bottom means child is the end entity cert
01861  */
01862 static int x509_crt_check_parent( const mbedtls_x509_crt *child,
01863                                   const mbedtls_x509_crt *parent,
01864                                   int top, int bottom )
01865 {
01866     int need_ca_bit;
01867 
01868     /* Parent must be the issuer */
01869     if( x509_name_cmp( &child->issuer, &parent->subject ) != 0 )
01870         return( -1 );
01871 
01872     /* Parent must have the basicConstraints CA bit set as a general rule */
01873     need_ca_bit = 1;
01874 
01875     /* Exception: v1/v2 certificates that are locally trusted. */
01876     if( top && parent->version < 3 )
01877         need_ca_bit = 0;
01878 
01879     /* Exception: self-signed end-entity certs that are locally trusted. */
01880     if( top && bottom &&
01881         child->raw.len == parent->raw.len &&
01882         memcmp( child->raw.p, parent->raw.p, child->raw.len ) == 0 )
01883     {
01884         need_ca_bit = 0;
01885     }
01886 
01887     if( need_ca_bit && ! parent->ca_istrue )
01888         return( -1 );
01889 
01890 #if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
01891     if( need_ca_bit &&
01892         mbedtls_x509_crt_check_key_usage( parent, MBEDTLS_X509_KU_KEY_CERT_SIGN ) != 0 )
01893     {
01894         return( -1 );
01895     }
01896 #endif
01897 
01898     return( 0 );
01899 }
01900 
01901 static int x509_crt_verify_top(
01902                 mbedtls_x509_crt *child, mbedtls_x509_crt *trust_ca,
01903                 mbedtls_x509_crl *ca_crl,
01904                 const mbedtls_x509_crt_profile *profile,
01905                 int path_cnt, int self_cnt, uint32_t *flags,
01906                 int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
01907                 void *p_vrfy )
01908 {
01909     int ret;
01910     uint32_t ca_flags = 0;
01911     int check_path_cnt;
01912     unsigned char hash[MBEDTLS_MD_MAX_SIZE];
01913     const mbedtls_md_info_t *md_info;
01914     mbedtls_x509_crt *future_past_ca = NULL;
01915 
01916     if( mbedtls_x509_time_is_past( &child->valid_to ) )
01917         *flags |= MBEDTLS_X509_BADCERT_EXPIRED;
01918 
01919     if( mbedtls_x509_time_is_future( &child->valid_from ) )
01920         *flags |= MBEDTLS_X509_BADCERT_FUTURE;
01921 
01922     if( x509_profile_check_md_alg( profile, child->sig_md ) != 0 )
01923         *flags |= MBEDTLS_X509_BADCERT_BAD_MD;
01924 
01925     if( x509_profile_check_pk_alg( profile, child->sig_pk ) != 0 )
01926         *flags |= MBEDTLS_X509_BADCERT_BAD_PK;
01927 
01928     /*
01929      * Child is the top of the chain. Check against the trust_ca list.
01930      */
01931     *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
01932 
01933     md_info = mbedtls_md_info_from_type( child->sig_md );
01934     if( md_info == NULL )
01935     {
01936         /*
01937          * Cannot check 'unknown', no need to try any CA
01938          */
01939         trust_ca = NULL;
01940     }
01941     else
01942         mbedtls_md( md_info, child->tbs.p, child->tbs.len, hash );
01943 
01944     for( /* trust_ca */ ; trust_ca != NULL; trust_ca = trust_ca->next )
01945     {
01946         if( x509_crt_check_parent( child, trust_ca, 1, path_cnt == 0 ) != 0 )
01947             continue;
01948 
01949         check_path_cnt = path_cnt + 1;
01950 
01951         /*
01952          * Reduce check_path_cnt to check against if top of the chain is
01953          * the same as the trusted CA
01954          */
01955         if( child->subject_raw.len == trust_ca->subject_raw.len &&
01956             memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
01957                             child->issuer_raw.len ) == 0 )
01958         {
01959             check_path_cnt--;
01960         }
01961 
01962         /* Self signed certificates do not count towards the limit */
01963         if( trust_ca->max_pathlen > 0 &&
01964             trust_ca->max_pathlen < check_path_cnt - self_cnt )
01965         {
01966             continue;
01967         }
01968 
01969         if( mbedtls_pk_verify_ext( child->sig_pk, child->sig_opts, &trust_ca->pk,
01970                            child->sig_md, hash, mbedtls_md_get_size( md_info ),
01971                            child->sig.p, child->sig.len ) != 0 )
01972         {
01973             continue;
01974         }
01975 
01976         if( mbedtls_x509_time_is_past( &trust_ca->valid_to ) ||
01977             mbedtls_x509_time_is_future( &trust_ca->valid_from ) )
01978         {
01979             if ( future_past_ca == NULL )
01980                 future_past_ca = trust_ca;
01981 
01982             continue;
01983         }
01984 
01985         break;
01986     }
01987 
01988     if( trust_ca != NULL || ( trust_ca = future_past_ca ) != NULL )
01989     {
01990         /*
01991          * Top of chain is signed by a trusted CA
01992          */
01993         *flags &= ~MBEDTLS_X509_BADCERT_NOT_TRUSTED;
01994 
01995         if( x509_profile_check_key( profile, child->sig_pk, &trust_ca->pk ) != 0 )
01996             *flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
01997     }
01998 
01999     /*
02000      * If top of chain is not the same as the trusted CA send a verify request
02001      * to the callback for any issues with validity and CRL presence for the
02002      * trusted CA certificate.
02003      */
02004     if( trust_ca != NULL &&
02005         ( child->subject_raw.len != trust_ca->subject_raw.len ||
02006           memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
02007                             child->issuer_raw.len ) != 0 ) )
02008     {
02009 #if defined(MBEDTLS_X509_CRL_PARSE_C)
02010         /* Check trusted CA's CRL for the chain's top crt */
02011         *flags |= x509_crt_verifycrl( child, trust_ca, ca_crl, profile );
02012 #else
02013         ((void) ca_crl);
02014 #endif
02015 
02016         if( mbedtls_x509_time_is_past( &trust_ca->valid_to ) )
02017             ca_flags |= MBEDTLS_X509_BADCERT_EXPIRED;
02018 
02019         if( mbedtls_x509_time_is_future( &trust_ca->valid_from ) )
02020             ca_flags |= MBEDTLS_X509_BADCERT_FUTURE;
02021 
02022         if( NULL != f_vrfy )
02023         {
02024             if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1,
02025                                 &ca_flags ) ) != 0 )
02026             {
02027                 return( ret );
02028             }
02029         }
02030     }
02031 
02032     /* Call callback on top cert */
02033     if( NULL != f_vrfy )
02034     {
02035         if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
02036             return( ret );
02037     }
02038 
02039     *flags |= ca_flags;
02040 
02041     return( 0 );
02042 }
02043 
02044 static int x509_crt_verify_child(
02045                 mbedtls_x509_crt *child, mbedtls_x509_crt *parent,
02046                 mbedtls_x509_crt *trust_ca, mbedtls_x509_crl *ca_crl,
02047                 const mbedtls_x509_crt_profile *profile,
02048                 int path_cnt, int self_cnt, uint32_t *flags,
02049                 int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
02050                 void *p_vrfy )
02051 {
02052     int ret;
02053     uint32_t parent_flags = 0;
02054     unsigned char hash[MBEDTLS_MD_MAX_SIZE];
02055     mbedtls_x509_crt *grandparent;
02056     const mbedtls_md_info_t *md_info;
02057 
02058     /* Counting intermediate self signed certificates */
02059     if( ( path_cnt != 0 ) && x509_name_cmp( &child->issuer, &child->subject ) == 0 )
02060         self_cnt++;
02061 
02062     /* path_cnt is 0 for the first intermediate CA */
02063     if( 1 + path_cnt > MBEDTLS_X509_MAX_INTERMEDIATE_CA )
02064     {
02065         /* return immediately as the goal is to avoid unbounded recursion */
02066         return( MBEDTLS_ERR_X509_FATAL_ERROR );
02067     }
02068 
02069     if( mbedtls_x509_time_is_past( &child->valid_to ) )
02070         *flags |= MBEDTLS_X509_BADCERT_EXPIRED;
02071 
02072     if( mbedtls_x509_time_is_future( &child->valid_from ) )
02073         *flags |= MBEDTLS_X509_BADCERT_FUTURE;
02074 
02075     if( x509_profile_check_md_alg( profile, child->sig_md ) != 0 )
02076         *flags |= MBEDTLS_X509_BADCERT_BAD_MD;
02077 
02078     if( x509_profile_check_pk_alg( profile, child->sig_pk ) != 0 )
02079         *flags |= MBEDTLS_X509_BADCERT_BAD_PK;
02080 
02081     md_info = mbedtls_md_info_from_type( child->sig_md );
02082     if( md_info == NULL )
02083     {
02084         /*
02085          * Cannot check 'unknown' hash
02086          */
02087         *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
02088     }
02089     else
02090     {
02091         mbedtls_md( md_info, child->tbs.p, child->tbs.len, hash );
02092 
02093         if( x509_profile_check_key( profile, child->sig_pk, &parent->pk ) != 0 )
02094             *flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
02095 
02096         if( mbedtls_pk_verify_ext( child->sig_pk, child->sig_opts, &parent->pk,
02097                            child->sig_md, hash, mbedtls_md_get_size( md_info ),
02098                            child->sig.p, child->sig.len ) != 0 )
02099         {
02100             *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
02101         }
02102     }
02103 
02104 #if defined(MBEDTLS_X509_CRL_PARSE_C)
02105     /* Check trusted CA's CRL for the given crt */
02106     *flags |= x509_crt_verifycrl(child, parent, ca_crl, profile );
02107 #endif
02108 
02109     /* Look for a grandparent in trusted CAs */
02110     for( grandparent = trust_ca;
02111          grandparent != NULL;
02112          grandparent = grandparent->next )
02113     {
02114         if( x509_crt_check_parent( parent, grandparent,
02115                                    0, path_cnt == 0 ) == 0 )
02116             break;
02117     }
02118 
02119     if( grandparent != NULL )
02120     {
02121         ret = x509_crt_verify_top( parent, grandparent, ca_crl, profile,
02122                                 path_cnt + 1, self_cnt, &parent_flags, f_vrfy, p_vrfy );
02123         if( ret != 0 )
02124             return( ret );
02125     }
02126     else
02127     {
02128         /* Look for a grandparent upwards the chain */
02129         for( grandparent = parent->next;
02130              grandparent != NULL;
02131              grandparent = grandparent->next )
02132         {
02133             /* +2 because the current step is not yet accounted for
02134              * and because max_pathlen is one higher than it should be.
02135              * Also self signed certificates do not count to the limit. */
02136             if( grandparent->max_pathlen > 0 &&
02137                 grandparent->max_pathlen < 2 + path_cnt - self_cnt )
02138             {
02139                 continue;
02140             }
02141 
02142             if( x509_crt_check_parent( parent, grandparent,
02143                                        0, path_cnt == 0 ) == 0 )
02144                 break;
02145         }
02146 
02147         /* Is our parent part of the chain or at the top? */
02148         if( grandparent != NULL )
02149         {
02150             ret = x509_crt_verify_child( parent, grandparent, trust_ca, ca_crl,
02151                                          profile, path_cnt + 1, self_cnt, &parent_flags,
02152                                          f_vrfy, p_vrfy );
02153             if( ret != 0 )
02154                 return( ret );
02155         }
02156         else
02157         {
02158             ret = x509_crt_verify_top( parent, trust_ca, ca_crl, profile,
02159                                        path_cnt + 1, self_cnt, &parent_flags,
02160                                        f_vrfy, p_vrfy );
02161             if( ret != 0 )
02162                 return( ret );
02163         }
02164     }
02165 
02166     /* child is verified to be a child of the parent, call verify callback */
02167     if( NULL != f_vrfy )
02168         if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
02169             return( ret );
02170 
02171     *flags |= parent_flags;
02172 
02173     return( 0 );
02174 }
02175 
02176 /*
02177  * Verify the certificate validity
02178  */
02179 int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt,
02180                      mbedtls_x509_crt *trust_ca,
02181                      mbedtls_x509_crl *ca_crl,
02182                      const char *cn, uint32_t *flags,
02183                      int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
02184                      void *p_vrfy )
02185 {
02186     return( mbedtls_x509_crt_verify_with_profile( crt, trust_ca, ca_crl,
02187                 &mbedtls_x509_crt_profile_default, cn, flags, f_vrfy, p_vrfy ) );
02188 }
02189 
02190 
02191 /*
02192  * Verify the certificate validity, with profile
02193  */
02194 int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt,
02195                      mbedtls_x509_crt *trust_ca,
02196                      mbedtls_x509_crl *ca_crl,
02197                      const mbedtls_x509_crt_profile *profile,
02198                      const char *cn, uint32_t *flags,
02199                      int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
02200                      void *p_vrfy )
02201 {
02202     size_t cn_len;
02203     int ret;
02204     int pathlen = 0, selfsigned = 0;
02205     mbedtls_x509_crt *parent;
02206     mbedtls_x509_name *name;
02207     mbedtls_x509_sequence *cur = NULL;
02208     mbedtls_pk_type_t pk_type;
02209 
02210     *flags = 0;
02211 
02212     if( profile == NULL )
02213     {
02214         ret = MBEDTLS_ERR_X509_BAD_INPUT_DATA;
02215         goto exit;
02216     }
02217 
02218     if( cn != NULL )
02219     {
02220         name = &crt->subject;
02221         cn_len = strlen( cn );
02222 
02223         if( crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME )
02224         {
02225             cur = &crt->subject_alt_names;
02226 
02227             while( cur != NULL )
02228             {
02229                 if( cur->buf.len == cn_len &&
02230                     x509_memcasecmp( cn, cur->buf.p, cn_len ) == 0 )
02231                     break;
02232 
02233                 if( cur->buf.len > 2 &&
02234                     memcmp( cur->buf.p, "*.", 2 ) == 0 &&
02235                     x509_check_wildcard( cn, &cur->buf ) == 0 )
02236                 {
02237                     break;
02238                 }
02239 
02240                 cur = cur->next;
02241             }
02242 
02243             if( cur == NULL )
02244                 *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH;
02245         }
02246         else
02247         {
02248             while( name != NULL )
02249             {
02250                 if( MBEDTLS_OID_CMP( MBEDTLS_OID_AT_CN, &name->oid ) == 0 )
02251                 {
02252                     if( name->val.len == cn_len &&
02253                         x509_memcasecmp( name->val.p, cn, cn_len ) == 0 )
02254                         break;
02255 
02256                     if( name->val.len > 2 &&
02257                         memcmp( name->val.p, "*.", 2 ) == 0 &&
02258                         x509_check_wildcard( cn, &name->val ) == 0 )
02259                         break;
02260                 }
02261 
02262                 name = name->next;
02263             }
02264 
02265             if( name == NULL )
02266                 *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH;
02267         }
02268     }
02269 
02270     /* Check the type and size of the key */
02271     pk_type = mbedtls_pk_get_type( &crt->pk );
02272 
02273     if( x509_profile_check_pk_alg( profile, pk_type ) != 0 )
02274         *flags |= MBEDTLS_X509_BADCERT_BAD_PK;
02275 
02276     if( x509_profile_check_key( profile, pk_type, &crt->pk ) != 0 )
02277         *flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
02278 
02279     /* Look for a parent in trusted CAs */
02280     for( parent = trust_ca; parent != NULL; parent = parent->next )
02281     {
02282         if( x509_crt_check_parent( crt, parent, 0, pathlen == 0 ) == 0 )
02283             break;
02284     }
02285 
02286     if( parent != NULL )
02287     {
02288         ret = x509_crt_verify_top( crt, parent, ca_crl, profile,
02289                                    pathlen, selfsigned, flags, f_vrfy, p_vrfy );
02290         if( ret != 0 )
02291             goto exit;
02292     }
02293     else
02294     {
02295         /* Look for a parent upwards the chain */
02296         for( parent = crt->next; parent != NULL; parent = parent->next )
02297             if( x509_crt_check_parent( crt, parent, 0, pathlen == 0 ) == 0 )
02298                 break;
02299 
02300         /* Are we part of the chain or at the top? */
02301         if( parent != NULL )
02302         {
02303             ret = x509_crt_verify_child( crt, parent, trust_ca, ca_crl, profile,
02304                                          pathlen, selfsigned, flags, f_vrfy, p_vrfy );
02305             if( ret != 0 )
02306                 goto exit;
02307         }
02308         else
02309         {
02310             ret = x509_crt_verify_top( crt, trust_ca, ca_crl, profile,
02311                                        pathlen, selfsigned, flags, f_vrfy, p_vrfy );
02312             if( ret != 0 )
02313                 goto exit;
02314         }
02315     }
02316 
02317 exit:
02318     /* prevent misuse of the vrfy callback - VERIFY_FAILED would be ignored by
02319      * the SSL module for authmode optional, but non-zero return from the
02320      * callback means a fatal error so it shouldn't be ignored */
02321     if( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED )
02322         ret = MBEDTLS_ERR_X509_FATAL_ERROR;
02323 
02324     if( ret != 0 )
02325     {
02326         *flags = (uint32_t) -1;
02327         return( ret );
02328     }
02329 
02330     if( *flags != 0 )
02331         return( MBEDTLS_ERR_X509_CERT_VERIFY_FAILED );
02332 
02333     return( 0 );
02334 }
02335 
02336 /*
02337  * Initialize a certificate chain
02338  */
02339 void mbedtls_x509_crt_init( mbedtls_x509_crt *crt )
02340 {
02341     memset( crt, 0, sizeof(mbedtls_x509_crt) );
02342 }
02343 
02344 /*
02345  * Unallocate all certificate data
02346  */
02347 void mbedtls_x509_crt_free( mbedtls_x509_crt *crt )
02348 {
02349     mbedtls_x509_crt *cert_cur = crt;
02350     mbedtls_x509_crt *cert_prv;
02351     mbedtls_x509_name *name_cur;
02352     mbedtls_x509_name *name_prv;
02353     mbedtls_x509_sequence *seq_cur;
02354     mbedtls_x509_sequence *seq_prv;
02355 
02356     if( crt == NULL )
02357         return;
02358 
02359     do
02360     {
02361         mbedtls_pk_free( &cert_cur->pk );
02362 
02363 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
02364         mbedtls_free( cert_cur->sig_opts );
02365 #endif
02366 
02367         name_cur = cert_cur->issuer.next;
02368         while( name_cur != NULL )
02369         {
02370             name_prv = name_cur;
02371             name_cur = name_cur->next;
02372             mbedtls_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
02373             mbedtls_free( name_prv );
02374         }
02375 
02376         name_cur = cert_cur->subject.next;
02377         while( name_cur != NULL )
02378         {
02379             name_prv = name_cur;
02380             name_cur = name_cur->next;
02381             mbedtls_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
02382             mbedtls_free( name_prv );
02383         }
02384 
02385         seq_cur = cert_cur->ext_key_usage.next;
02386         while( seq_cur != NULL )
02387         {
02388             seq_prv = seq_cur;
02389             seq_cur = seq_cur->next;
02390             mbedtls_zeroize( seq_prv, sizeof( mbedtls_x509_sequence ) );
02391             mbedtls_free( seq_prv );
02392         }
02393 
02394         seq_cur = cert_cur->subject_alt_names.next;
02395         while( seq_cur != NULL )
02396         {
02397             seq_prv = seq_cur;
02398             seq_cur = seq_cur->next;
02399             mbedtls_zeroize( seq_prv, sizeof( mbedtls_x509_sequence ) );
02400             mbedtls_free( seq_prv );
02401         }
02402 
02403         if( cert_cur->raw.p != NULL )
02404         {
02405             mbedtls_zeroize( cert_cur->raw.p, cert_cur->raw.len );
02406             mbedtls_free( cert_cur->raw.p );
02407         }
02408 
02409         cert_cur = cert_cur->next;
02410     }
02411     while( cert_cur != NULL );
02412 
02413     cert_cur = crt;
02414     do
02415     {
02416         cert_prv = cert_cur;
02417         cert_cur = cert_cur->next;
02418 
02419         mbedtls_zeroize( cert_prv, sizeof( mbedtls_x509_crt ) );
02420         if( cert_prv != crt )
02421             mbedtls_free( cert_prv );
02422     }
02423     while( cert_cur != NULL );
02424 }
02425 
02426 #endif /* MBEDTLS_X509_CRT_PARSE_C */