Jan Korycan / WNCInterface

Dependencies:   WncControllerK64F

Fork of WNCInterface by Jan Korycan

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