Rtos API example

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