Mark Radbourne / mbedtls

Dependents:   Encrypt_Decrypt1 mbed_blink_tls encrypt encrypt

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, (int)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     int snp_ret;
01164     struct stat sb;
01165     struct dirent *entry;
01166     char entry_name[MBEDTLS_X509_MAX_FILE_PATH_LEN];
01167     DIR *dir = opendir( path );
01168 
01169     if( dir == NULL )
01170         return( MBEDTLS_ERR_X509_FILE_IO_ERROR );
01171 
01172 #if defined(MBEDTLS_THREADING_PTHREAD)
01173     if( ( ret = mbedtls_mutex_lock( &mbedtls_threading_readdir_mutex ) ) != 0 )
01174     {
01175         closedir( dir );
01176         return( ret );
01177     }
01178 #endif
01179 
01180     while( ( entry = readdir( dir ) ) != NULL )
01181     {
01182         snp_ret = mbedtls_snprintf( entry_name, sizeof entry_name,
01183                                     "%s/%s", path, entry->d_name );
01184 
01185         if( snp_ret < 0 || (size_t)snp_ret >= sizeof entry_name )
01186         {
01187             ret = MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
01188             goto cleanup;
01189         }
01190         else if( stat( entry_name, &sb ) == -1 )
01191         {
01192             ret = MBEDTLS_ERR_X509_FILE_IO_ERROR;
01193             goto cleanup;
01194         }
01195 
01196         if( !S_ISREG( sb.st_mode ) )
01197             continue;
01198 
01199         // Ignore parse errors
01200         //
01201         t_ret = mbedtls_x509_crt_parse_file( chain, entry_name );
01202         if( t_ret < 0 )
01203             ret++;
01204         else
01205             ret += t_ret;
01206     }
01207 
01208 cleanup:
01209     closedir( dir );
01210 
01211 #if defined(MBEDTLS_THREADING_PTHREAD)
01212     if( mbedtls_mutex_unlock( &mbedtls_threading_readdir_mutex ) != 0 )
01213         ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
01214 #endif
01215 
01216 #endif /* _WIN32 */
01217 
01218     return( ret );
01219 }
01220 #endif /* MBEDTLS_FS_IO */
01221 
01222 static int x509_info_subject_alt_name( char **buf, size_t *size,
01223                                        const mbedtls_x509_sequence *subject_alt_name )
01224 {
01225     size_t i;
01226     size_t n = *size;
01227     char *p = *buf;
01228     const mbedtls_x509_sequence *cur = subject_alt_name;
01229     const char *sep = "";
01230     size_t sep_len = 0;
01231 
01232     while( cur != NULL )
01233     {
01234         if( cur->buf.len + sep_len >= n )
01235         {
01236             *p = '\0';
01237             return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL );
01238         }
01239 
01240         n -= cur->buf.len + sep_len;
01241         for( i = 0; i < sep_len; i++ )
01242             *p++ = sep[i];
01243         for( i = 0; i < cur->buf.len; i++ )
01244             *p++ = cur->buf.p[i];
01245 
01246         sep = ", ";
01247         sep_len = 2;
01248 
01249         cur = cur->next;
01250     }
01251 
01252     *p = '\0';
01253 
01254     *size = n;
01255     *buf = p;
01256 
01257     return( 0 );
01258 }
01259 
01260 #define PRINT_ITEM(i)                           \
01261     {                                           \
01262         ret = mbedtls_snprintf( p, n, "%s" i, sep );    \
01263         MBEDTLS_X509_SAFE_SNPRINTF;                        \
01264         sep = ", ";                             \
01265     }
01266 
01267 #define CERT_TYPE(type,name)                    \
01268     if( ns_cert_type & type )                   \
01269         PRINT_ITEM( name );
01270 
01271 static int x509_info_cert_type( char **buf, size_t *size,
01272                                 unsigned char ns_cert_type )
01273 {
01274     int ret;
01275     size_t n = *size;
01276     char *p = *buf;
01277     const char *sep = "";
01278 
01279     CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT,         "SSL Client" );
01280     CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER,         "SSL Server" );
01281     CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_EMAIL,              "Email" );
01282     CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING,     "Object Signing" );
01283     CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_RESERVED,           "Reserved" );
01284     CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_CA,             "SSL CA" );
01285     CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA,           "Email CA" );
01286     CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA,  "Object Signing CA" );
01287 
01288     *size = n;
01289     *buf = p;
01290 
01291     return( 0 );
01292 }
01293 
01294 #define KEY_USAGE(code,name)    \
01295     if( key_usage & code )      \
01296         PRINT_ITEM( name );
01297 
01298 static int x509_info_key_usage( char **buf, size_t *size,
01299                                 unsigned int key_usage )
01300 {
01301     int ret;
01302     size_t n = *size;
01303     char *p = *buf;
01304     const char *sep = "";
01305 
01306     KEY_USAGE( MBEDTLS_X509_KU_DIGITAL_SIGNATURE,    "Digital Signature" );
01307     KEY_USAGE( MBEDTLS_X509_KU_NON_REPUDIATION,      "Non Repudiation" );
01308     KEY_USAGE( MBEDTLS_X509_KU_KEY_ENCIPHERMENT,     "Key Encipherment" );
01309     KEY_USAGE( MBEDTLS_X509_KU_DATA_ENCIPHERMENT,    "Data Encipherment" );
01310     KEY_USAGE( MBEDTLS_X509_KU_KEY_AGREEMENT,        "Key Agreement" );
01311     KEY_USAGE( MBEDTLS_X509_KU_KEY_CERT_SIGN,        "Key Cert Sign" );
01312     KEY_USAGE( MBEDTLS_X509_KU_CRL_SIGN,             "CRL Sign" );
01313     KEY_USAGE( MBEDTLS_X509_KU_ENCIPHER_ONLY,        "Encipher Only" );
01314     KEY_USAGE( MBEDTLS_X509_KU_DECIPHER_ONLY,        "Decipher Only" );
01315 
01316     *size = n;
01317     *buf = p;
01318 
01319     return( 0 );
01320 }
01321 
01322 static int x509_info_ext_key_usage( char **buf, size_t *size,
01323                                     const mbedtls_x509_sequence *extended_key_usage )
01324 {
01325     int ret;
01326     const char *desc;
01327     size_t n = *size;
01328     char *p = *buf;
01329     const mbedtls_x509_sequence *cur = extended_key_usage;
01330     const char *sep = "";
01331 
01332     while( cur != NULL )
01333     {
01334         if( mbedtls_oid_get_extended_key_usage( &cur->buf, &desc ) != 0 )
01335             desc = "???";
01336 
01337         ret = mbedtls_snprintf( p, n, "%s%s", sep, desc );
01338         MBEDTLS_X509_SAFE_SNPRINTF;
01339 
01340         sep = ", ";
01341 
01342         cur = cur->next;
01343     }
01344 
01345     *size = n;
01346     *buf = p;
01347 
01348     return( 0 );
01349 }
01350 
01351 /*
01352  * Return an informational string about the certificate.
01353  */
01354 #define BEFORE_COLON    18
01355 #define BC              "18"
01356 int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix,
01357                    const mbedtls_x509_crt *crt )
01358 {
01359     int ret;
01360     size_t n;
01361     char *p;
01362     char key_size_str[BEFORE_COLON];
01363 
01364     p = buf;
01365     n = size;
01366 
01367     if( NULL == crt )
01368     {
01369         ret = mbedtls_snprintf( p, n, "\nCertificate is uninitialised!\n" );
01370         MBEDTLS_X509_SAFE_SNPRINTF;
01371 
01372         return( (int) ( size - n ) );
01373     }
01374 
01375     ret = mbedtls_snprintf( p, n, "%scert. version     : %d\n",
01376                                prefix, crt->version );
01377     MBEDTLS_X509_SAFE_SNPRINTF;
01378     ret = mbedtls_snprintf( p, n, "%sserial number     : ",
01379                                prefix );
01380     MBEDTLS_X509_SAFE_SNPRINTF;
01381 
01382     ret = mbedtls_x509_serial_gets( p, n, &crt->serial );
01383     MBEDTLS_X509_SAFE_SNPRINTF;
01384 
01385     ret = mbedtls_snprintf( p, n, "\n%sissuer name       : ", prefix );
01386     MBEDTLS_X509_SAFE_SNPRINTF;
01387     ret = mbedtls_x509_dn_gets( p, n, &crt->issuer  );
01388     MBEDTLS_X509_SAFE_SNPRINTF;
01389 
01390     ret = mbedtls_snprintf( p, n, "\n%ssubject name      : ", prefix );
01391     MBEDTLS_X509_SAFE_SNPRINTF;
01392     ret = mbedtls_x509_dn_gets( p, n, &crt->subject );
01393     MBEDTLS_X509_SAFE_SNPRINTF;
01394 
01395     ret = mbedtls_snprintf( p, n, "\n%sissued  on        : " \
01396                    "%04d-%02d-%02d %02d:%02d:%02d", prefix,
01397                    crt->valid_from.year, crt->valid_from.mon,
01398                    crt->valid_from.day,  crt->valid_from.hour,
01399                    crt->valid_from.min,  crt->valid_from.sec );
01400     MBEDTLS_X509_SAFE_SNPRINTF;
01401 
01402     ret = mbedtls_snprintf( p, n, "\n%sexpires on        : " \
01403                    "%04d-%02d-%02d %02d:%02d:%02d", prefix,
01404                    crt->valid_to.year, crt->valid_to.mon,
01405                    crt->valid_to.day,  crt->valid_to.hour,
01406                    crt->valid_to.min,  crt->valid_to.sec );
01407     MBEDTLS_X509_SAFE_SNPRINTF;
01408 
01409     ret = mbedtls_snprintf( p, n, "\n%ssigned using      : ", prefix );
01410     MBEDTLS_X509_SAFE_SNPRINTF;
01411 
01412     ret = mbedtls_x509_sig_alg_gets( p, n, &crt->sig_oid, crt->sig_pk,
01413                              crt->sig_md, crt->sig_opts );
01414     MBEDTLS_X509_SAFE_SNPRINTF;
01415 
01416     /* Key size */
01417     if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON,
01418                                       mbedtls_pk_get_name( &crt->pk ) ) ) != 0 )
01419     {
01420         return( ret );
01421     }
01422 
01423     ret = mbedtls_snprintf( p, n, "\n%s%-" BC "s: %d bits", prefix, key_size_str,
01424                           (int) mbedtls_pk_get_bitlen( &crt->pk ) );
01425     MBEDTLS_X509_SAFE_SNPRINTF;
01426 
01427     /*
01428      * Optional extensions
01429      */
01430 
01431     if( crt->ext_types & MBEDTLS_X509_EXT_BASIC_CONSTRAINTS )
01432     {
01433         ret = mbedtls_snprintf( p, n, "\n%sbasic constraints : CA=%s", prefix,
01434                         crt->ca_istrue ? "true" : "false" );
01435         MBEDTLS_X509_SAFE_SNPRINTF;
01436 
01437         if( crt->max_pathlen > 0 )
01438         {
01439             ret = mbedtls_snprintf( p, n, ", max_pathlen=%d", crt->max_pathlen - 1 );
01440             MBEDTLS_X509_SAFE_SNPRINTF;
01441         }
01442     }
01443 
01444     if( crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME )
01445     {
01446         ret = mbedtls_snprintf( p, n, "\n%ssubject alt name  : ", prefix );
01447         MBEDTLS_X509_SAFE_SNPRINTF;
01448 
01449         if( ( ret = x509_info_subject_alt_name( &p, &n,
01450                                             &crt->subject_alt_names ) ) != 0 )
01451             return( ret );
01452     }
01453 
01454     if( crt->ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE )
01455     {
01456         ret = mbedtls_snprintf( p, n, "\n%scert. type        : ", prefix );
01457         MBEDTLS_X509_SAFE_SNPRINTF;
01458 
01459         if( ( ret = x509_info_cert_type( &p, &n, crt->ns_cert_type ) ) != 0 )
01460             return( ret );
01461     }
01462 
01463     if( crt->ext_types & MBEDTLS_X509_EXT_KEY_USAGE )
01464     {
01465         ret = mbedtls_snprintf( p, n, "\n%skey usage         : ", prefix );
01466         MBEDTLS_X509_SAFE_SNPRINTF;
01467 
01468         if( ( ret = x509_info_key_usage( &p, &n, crt->key_usage ) ) != 0 )
01469             return( ret );
01470     }
01471 
01472     if( crt->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE )
01473     {
01474         ret = mbedtls_snprintf( p, n, "\n%sext key usage     : ", prefix );
01475         MBEDTLS_X509_SAFE_SNPRINTF;
01476 
01477         if( ( ret = x509_info_ext_key_usage( &p, &n,
01478                                              &crt->ext_key_usage ) ) != 0 )
01479             return( ret );
01480     }
01481 
01482     ret = mbedtls_snprintf( p, n, "\n" );
01483     MBEDTLS_X509_SAFE_SNPRINTF;
01484 
01485     return( (int) ( size - n ) );
01486 }
01487 
01488 struct x509_crt_verify_string {
01489     int code;
01490     const char *string;
01491 };
01492 
01493 static const struct x509_crt_verify_string x509_crt_verify_strings[] = {
01494     { MBEDTLS_X509_BADCERT_EXPIRED,       "The certificate validity has expired" },
01495     { MBEDTLS_X509_BADCERT_REVOKED,       "The certificate has been revoked (is on a CRL)" },
01496     { MBEDTLS_X509_BADCERT_CN_MISMATCH,   "The certificate Common Name (CN) does not match with the expected CN" },
01497     { MBEDTLS_X509_BADCERT_NOT_TRUSTED,   "The certificate is not correctly signed by the trusted CA" },
01498     { MBEDTLS_X509_BADCRL_NOT_TRUSTED,    "The CRL is not correctly signed by the trusted CA" },
01499     { MBEDTLS_X509_BADCRL_EXPIRED,        "The CRL is expired" },
01500     { MBEDTLS_X509_BADCERT_MISSING,       "Certificate was missing" },
01501     { MBEDTLS_X509_BADCERT_SKIP_VERIFY,   "Certificate verification was skipped" },
01502     { MBEDTLS_X509_BADCERT_OTHER,         "Other reason (can be used by verify callback)" },
01503     { MBEDTLS_X509_BADCERT_FUTURE,        "The certificate validity starts in the future" },
01504     { MBEDTLS_X509_BADCRL_FUTURE,         "The CRL is from the future" },
01505     { MBEDTLS_X509_BADCERT_KEY_USAGE,     "Usage does not match the keyUsage extension" },
01506     { MBEDTLS_X509_BADCERT_EXT_KEY_USAGE, "Usage does not match the extendedKeyUsage extension" },
01507     { MBEDTLS_X509_BADCERT_NS_CERT_TYPE,  "Usage does not match the nsCertType extension" },
01508     { MBEDTLS_X509_BADCERT_BAD_MD,        "The certificate is signed with an unacceptable hash." },
01509     { MBEDTLS_X509_BADCERT_BAD_PK,        "The certificate is signed with an unacceptable PK alg (eg RSA vs ECDSA)." },
01510     { MBEDTLS_X509_BADCERT_BAD_KEY,       "The certificate is signed with an unacceptable key (eg bad curve, RSA too short)." },
01511     { MBEDTLS_X509_BADCRL_BAD_MD,         "The CRL is signed with an unacceptable hash." },
01512     { MBEDTLS_X509_BADCRL_BAD_PK,         "The CRL is signed with an unacceptable PK alg (eg RSA vs ECDSA)." },
01513     { MBEDTLS_X509_BADCRL_BAD_KEY,        "The CRL is signed with an unacceptable key (eg bad curve, RSA too short)." },
01514     { 0, NULL }
01515 };
01516 
01517 int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix,
01518                           uint32_t flags )
01519 {
01520     int ret;
01521     const struct x509_crt_verify_string *cur;
01522     char *p = buf;
01523     size_t n = size;
01524 
01525     for( cur = x509_crt_verify_strings; cur->string != NULL ; cur++ )
01526     {
01527         if( ( flags & cur->code ) == 0 )
01528             continue;
01529 
01530         ret = mbedtls_snprintf( p, n, "%s%s\n", prefix, cur->string );
01531         MBEDTLS_X509_SAFE_SNPRINTF;
01532         flags ^= cur->code;
01533     }
01534 
01535     if( flags != 0 )
01536     {
01537         ret = mbedtls_snprintf( p, n, "%sUnknown reason "
01538                                        "(this should not happen)\n", prefix );
01539         MBEDTLS_X509_SAFE_SNPRINTF;
01540     }
01541 
01542     return( (int) ( size - n ) );
01543 }
01544 
01545 #if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
01546 int mbedtls_x509_crt_check_key_usage( const mbedtls_x509_crt *crt,
01547                                       unsigned int usage )
01548 {
01549     unsigned int usage_must, usage_may;
01550     unsigned int may_mask = MBEDTLS_X509_KU_ENCIPHER_ONLY
01551                           | MBEDTLS_X509_KU_DECIPHER_ONLY;
01552 
01553     if( ( crt->ext_types & MBEDTLS_X509_EXT_KEY_USAGE ) == 0 )
01554         return( 0 );
01555 
01556     usage_must = usage & ~may_mask;
01557 
01558     if( ( ( crt->key_usage & ~may_mask ) & usage_must ) != usage_must )
01559         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
01560 
01561     usage_may = usage & may_mask;
01562 
01563     if( ( ( crt->key_usage & may_mask ) | usage_may ) != usage_may )
01564         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
01565 
01566     return( 0 );
01567 }
01568 #endif
01569 
01570 #if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
01571 int mbedtls_x509_crt_check_extended_key_usage( const mbedtls_x509_crt *crt,
01572                                        const char *usage_oid,
01573                                        size_t usage_len )
01574 {
01575     const mbedtls_x509_sequence *cur;
01576 
01577     /* Extension is not mandatory, absent means no restriction */
01578     if( ( crt->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE ) == 0 )
01579         return( 0 );
01580 
01581     /*
01582      * Look for the requested usage (or wildcard ANY) in our list
01583      */
01584     for( cur = &crt->ext_key_usage; cur != NULL; cur = cur->next )
01585     {
01586         const mbedtls_x509_buf *cur_oid = &cur->buf;
01587 
01588         if( cur_oid->len == usage_len &&
01589             memcmp( cur_oid->p, usage_oid, usage_len ) == 0 )
01590         {
01591             return( 0 );
01592         }
01593 
01594         if( MBEDTLS_OID_CMP( MBEDTLS_OID_ANY_EXTENDED_KEY_USAGE, cur_oid ) == 0 )
01595             return( 0 );
01596     }
01597 
01598     return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
01599 }
01600 #endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */
01601 
01602 #if defined(MBEDTLS_X509_CRL_PARSE_C)
01603 /*
01604  * Return 1 if the certificate is revoked, or 0 otherwise.
01605  */
01606 int mbedtls_x509_crt_is_revoked( const mbedtls_x509_crt *crt, const mbedtls_x509_crl *crl )
01607 {
01608     const mbedtls_x509_crl_entry *cur = &crl->entry;
01609 
01610     while( cur != NULL && cur->serial.len != 0 )
01611     {
01612         if( crt->serial.len == cur->serial.len &&
01613             memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
01614         {
01615             if( mbedtls_x509_time_is_past( &cur->revocation_date ) )
01616                 return( 1 );
01617         }
01618 
01619         cur = cur->next;
01620     }
01621 
01622     return( 0 );
01623 }
01624 
01625 /*
01626  * Check that the given certificate is not revoked according to the CRL.
01627  * Skip validation is no CRL for the given CA is present.
01628  */
01629 static int x509_crt_verifycrl( mbedtls_x509_crt *crt, mbedtls_x509_crt *ca,
01630                                mbedtls_x509_crl *crl_list,
01631                                const mbedtls_x509_crt_profile *profile )
01632 {
01633     int flags = 0;
01634     unsigned char hash[MBEDTLS_MD_MAX_SIZE];
01635     const mbedtls_md_info_t *md_info;
01636 
01637     if( ca == NULL )
01638         return( flags );
01639 
01640     while( crl_list != NULL )
01641     {
01642         if( crl_list->version == 0 ||
01643             crl_list->issuer_raw.len != ca->subject_raw.len ||
01644             memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
01645                     crl_list->issuer_raw.len ) != 0 )
01646         {
01647             crl_list = crl_list->next;
01648             continue;
01649         }
01650 
01651         /*
01652          * Check if the CA is configured to sign CRLs
01653          */
01654 #if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
01655         if( mbedtls_x509_crt_check_key_usage( ca, MBEDTLS_X509_KU_CRL_SIGN ) != 0 )
01656         {
01657             flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
01658             break;
01659         }
01660 #endif
01661 
01662         /*
01663          * Check if CRL is correctly signed by the trusted CA
01664          */
01665         if( x509_profile_check_md_alg( profile, crl_list->sig_md ) != 0 )
01666             flags |= MBEDTLS_X509_BADCRL_BAD_MD;
01667 
01668         if( x509_profile_check_pk_alg( profile, crl_list->sig_pk ) != 0 )
01669             flags |= MBEDTLS_X509_BADCRL_BAD_PK;
01670 
01671         md_info = mbedtls_md_info_from_type( crl_list->sig_md );
01672         if( md_info == NULL )
01673         {
01674             /*
01675              * Cannot check 'unknown' hash
01676              */
01677             flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
01678             break;
01679         }
01680 
01681         mbedtls_md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash );
01682 
01683         if( x509_profile_check_key( profile, crl_list->sig_pk, &ca->pk ) != 0 )
01684             flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
01685 
01686         if( mbedtls_pk_verify_ext( crl_list->sig_pk, crl_list->sig_opts, &ca->pk,
01687                            crl_list->sig_md, hash, mbedtls_md_get_size( md_info ),
01688                            crl_list->sig.p, crl_list->sig.len ) != 0 )
01689         {
01690             flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
01691             break;
01692         }
01693 
01694         /*
01695          * Check for validity of CRL (Do not drop out)
01696          */
01697         if( mbedtls_x509_time_is_past( &crl_list->next_update ) )
01698             flags |= MBEDTLS_X509_BADCRL_EXPIRED;
01699 
01700         if( mbedtls_x509_time_is_future( &crl_list->this_update ) )
01701             flags |= MBEDTLS_X509_BADCRL_FUTURE;
01702 
01703         /*
01704          * Check if certificate is revoked
01705          */
01706         if( mbedtls_x509_crt_is_revoked( crt, crl_list ) )
01707         {
01708             flags |= MBEDTLS_X509_BADCERT_REVOKED;
01709             break;
01710         }
01711 
01712         crl_list = crl_list->next;
01713     }
01714 
01715     return( flags );
01716 }
01717 #endif /* MBEDTLS_X509_CRL_PARSE_C */
01718 
01719 /*
01720  * Like memcmp, but case-insensitive and always returns -1 if different
01721  */
01722 static int x509_memcasecmp( const void *s1, const void *s2, size_t len )
01723 {
01724     size_t i;
01725     unsigned char diff;
01726     const unsigned char *n1 = s1, *n2 = s2;
01727 
01728     for( i = 0; i < len; i++ )
01729     {
01730         diff = n1[i] ^ n2[i];
01731 
01732         if( diff == 0 )
01733             continue;
01734 
01735         if( diff == 32 &&
01736             ( ( n1[i] >= 'a' && n1[i] <= 'z' ) ||
01737               ( n1[i] >= 'A' && n1[i] <= 'Z' ) ) )
01738         {
01739             continue;
01740         }
01741 
01742         return( -1 );
01743     }
01744 
01745     return( 0 );
01746 }
01747 
01748 /*
01749  * Return 0 if name matches wildcard, -1 otherwise
01750  */
01751 static int x509_check_wildcard( const char *cn, mbedtls_x509_buf *name )
01752 {
01753     size_t i;
01754     size_t cn_idx = 0, cn_len = strlen( cn );
01755 
01756     if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' )
01757         return( 0 );
01758 
01759     for( i = 0; i < cn_len; ++i )
01760     {
01761         if( cn[i] == '.' )
01762         {
01763             cn_idx = i;
01764             break;
01765         }
01766     }
01767 
01768     if( cn_idx == 0 )
01769         return( -1 );
01770 
01771     if( cn_len - cn_idx == name->len - 1 &&
01772         x509_memcasecmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
01773     {
01774         return( 0 );
01775     }
01776 
01777     return( -1 );
01778 }
01779 
01780 /*
01781  * Compare two X.509 strings, case-insensitive, and allowing for some encoding
01782  * variations (but not all).
01783  *
01784  * Return 0 if equal, -1 otherwise.
01785  */
01786 static int x509_string_cmp( const mbedtls_x509_buf *a, const mbedtls_x509_buf *b )
01787 {
01788     if( a->tag == b->tag &&
01789         a->len == b->len &&
01790         memcmp( a->p, b->p, b->len ) == 0 )
01791     {
01792         return( 0 );
01793     }
01794 
01795     if( ( a->tag == MBEDTLS_ASN1_UTF8_STRING || a->tag == MBEDTLS_ASN1_PRINTABLE_STRING ) &&
01796         ( b->tag == MBEDTLS_ASN1_UTF8_STRING || b->tag == MBEDTLS_ASN1_PRINTABLE_STRING ) &&
01797         a->len == b->len &&
01798         x509_memcasecmp( a->p, b->p, b->len ) == 0 )
01799     {
01800         return( 0 );
01801     }
01802 
01803     return( -1 );
01804 }
01805 
01806 /*
01807  * Compare two X.509 Names (aka rdnSequence).
01808  *
01809  * See RFC 5280 section 7.1, though we don't implement the whole algorithm:
01810  * we sometimes return unequal when the full algorithm would return equal,
01811  * but never the other way. (In particular, we don't do Unicode normalisation
01812  * or space folding.)
01813  *
01814  * Return 0 if equal, -1 otherwise.
01815  */
01816 static int x509_name_cmp( const mbedtls_x509_name *a, const mbedtls_x509_name *b )
01817 {
01818     /* Avoid recursion, it might not be optimised by the compiler */
01819     while( a != NULL || b != NULL )
01820     {
01821         if( a == NULL || b == NULL )
01822             return( -1 );
01823 
01824         /* type */
01825         if( a->oid.tag != b->oid.tag ||
01826             a->oid.len != b->oid.len ||
01827             memcmp( a->oid.p, b->oid.p, b->oid.len ) != 0 )
01828         {
01829             return( -1 );
01830         }
01831 
01832         /* value */
01833         if( x509_string_cmp( &a->val, &b->val ) != 0 )
01834             return( -1 );
01835 
01836         /* structure of the list of sets */
01837         if( a->next_merged != b->next_merged )
01838             return( -1 );
01839 
01840         a = a->next;
01841         b = b->next;
01842     }
01843 
01844     /* a == NULL == b */
01845     return( 0 );
01846 }
01847 
01848 /*
01849  * Check if 'parent' is a suitable parent (signing CA) for 'child'.
01850  * Return 0 if yes, -1 if not.
01851  *
01852  * top means parent is a locally-trusted certificate
01853  * bottom means child is the end entity cert
01854  */
01855 static int x509_crt_check_parent( const mbedtls_x509_crt *child,
01856                                   const mbedtls_x509_crt *parent,
01857                                   int top, int bottom )
01858 {
01859     int need_ca_bit;
01860 
01861     /* Parent must be the issuer */
01862     if( x509_name_cmp( &child->issuer, &parent->subject ) != 0 )
01863         return( -1 );
01864 
01865     /* Parent must have the basicConstraints CA bit set as a general rule */
01866     need_ca_bit = 1;
01867 
01868     /* Exception: v1/v2 certificates that are locally trusted. */
01869     if( top && parent->version < 3 )
01870         need_ca_bit = 0;
01871 
01872     /* Exception: self-signed end-entity certs that are locally trusted. */
01873     if( top && bottom &&
01874         child->raw.len == parent->raw.len &&
01875         memcmp( child->raw.p, parent->raw.p, child->raw.len ) == 0 )
01876     {
01877         need_ca_bit = 0;
01878     }
01879 
01880     if( need_ca_bit && ! parent->ca_istrue )
01881         return( -1 );
01882 
01883 #if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
01884     if( need_ca_bit &&
01885         mbedtls_x509_crt_check_key_usage( parent, MBEDTLS_X509_KU_KEY_CERT_SIGN ) != 0 )
01886     {
01887         return( -1 );
01888     }
01889 #endif
01890 
01891     return( 0 );
01892 }
01893 
01894 static int x509_crt_verify_top(
01895                 mbedtls_x509_crt *child, mbedtls_x509_crt *trust_ca,
01896                 mbedtls_x509_crl *ca_crl,
01897                 const mbedtls_x509_crt_profile *profile,
01898                 int path_cnt, int self_cnt, uint32_t *flags,
01899                 int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
01900                 void *p_vrfy )
01901 {
01902     int ret;
01903     uint32_t ca_flags = 0;
01904     int check_path_cnt;
01905     unsigned char hash[MBEDTLS_MD_MAX_SIZE];
01906     const mbedtls_md_info_t *md_info;
01907 
01908     if( mbedtls_x509_time_is_past( &child->valid_to ) )
01909         *flags |= MBEDTLS_X509_BADCERT_EXPIRED;
01910 
01911     if( mbedtls_x509_time_is_future( &child->valid_from ) )
01912         *flags |= MBEDTLS_X509_BADCERT_FUTURE;
01913 
01914     if( x509_profile_check_md_alg( profile, child->sig_md ) != 0 )
01915         *flags |= MBEDTLS_X509_BADCERT_BAD_MD;
01916 
01917     if( x509_profile_check_pk_alg( profile, child->sig_pk ) != 0 )
01918         *flags |= MBEDTLS_X509_BADCERT_BAD_PK;
01919 
01920     /*
01921      * Child is the top of the chain. Check against the trust_ca list.
01922      */
01923     *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
01924 
01925     md_info = mbedtls_md_info_from_type( child->sig_md );
01926     if( md_info == NULL )
01927     {
01928         /*
01929          * Cannot check 'unknown', no need to try any CA
01930          */
01931         trust_ca = NULL;
01932     }
01933     else
01934         mbedtls_md( md_info, child->tbs.p, child->tbs.len, hash );
01935 
01936     for( /* trust_ca */ ; trust_ca != NULL; trust_ca = trust_ca->next )
01937     {
01938         if( x509_crt_check_parent( child, trust_ca, 1, path_cnt == 0 ) != 0 )
01939             continue;
01940 
01941         check_path_cnt = path_cnt + 1;
01942 
01943         /*
01944          * Reduce check_path_cnt to check against if top of the chain is
01945          * the same as the trusted CA
01946          */
01947         if( child->subject_raw.len == trust_ca->subject_raw.len &&
01948             memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
01949                             child->issuer_raw.len ) == 0 )
01950         {
01951             check_path_cnt--;
01952         }
01953 
01954         /* Self signed certificates do not count towards the limit */
01955         if( trust_ca->max_pathlen > 0 &&
01956             trust_ca->max_pathlen < check_path_cnt - self_cnt )
01957         {
01958             continue;
01959         }
01960 
01961         if( mbedtls_x509_time_is_past( &trust_ca->valid_to ) )
01962         {
01963             continue;
01964         }
01965 
01966         if( mbedtls_x509_time_is_future( &trust_ca->valid_from ) )
01967         {
01968             continue;
01969         }
01970 
01971         if( mbedtls_pk_verify_ext( child->sig_pk, child->sig_opts, &trust_ca->pk,
01972                            child->sig_md, hash, mbedtls_md_get_size( md_info ),
01973                            child->sig.p, child->sig.len ) != 0 )
01974         {
01975             continue;
01976         }
01977 
01978         /*
01979          * Top of chain is signed by a trusted CA
01980          */
01981         *flags &= ~MBEDTLS_X509_BADCERT_NOT_TRUSTED;
01982 
01983         if( x509_profile_check_key( profile, child->sig_pk, &trust_ca->pk ) != 0 )
01984             *flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
01985 
01986         break;
01987     }
01988 
01989     /*
01990      * If top of chain is not the same as the trusted CA send a verify request
01991      * to the callback for any issues with validity and CRL presence for the
01992      * trusted CA certificate.
01993      */
01994     if( trust_ca != NULL &&
01995         ( child->subject_raw.len != trust_ca->subject_raw.len ||
01996           memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
01997                             child->issuer_raw.len ) != 0 ) )
01998     {
01999 #if defined(MBEDTLS_X509_CRL_PARSE_C)
02000         /* Check trusted CA's CRL for the chain's top crt */
02001         *flags |= x509_crt_verifycrl( child, trust_ca, ca_crl, profile );
02002 #else
02003         ((void) ca_crl);
02004 #endif
02005 
02006         if( NULL != f_vrfy )
02007         {
02008             if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1,
02009                                 &ca_flags ) ) != 0 )
02010             {
02011                 return( ret );
02012             }
02013         }
02014     }
02015 
02016     /* Call callback on top cert */
02017     if( NULL != f_vrfy )
02018     {
02019         if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
02020             return( ret );
02021     }
02022 
02023     *flags |= ca_flags;
02024 
02025     return( 0 );
02026 }
02027 
02028 static int x509_crt_verify_child(
02029                 mbedtls_x509_crt *child, mbedtls_x509_crt *parent,
02030                 mbedtls_x509_crt *trust_ca, mbedtls_x509_crl *ca_crl,
02031                 const mbedtls_x509_crt_profile *profile,
02032                 int path_cnt, int self_cnt, uint32_t *flags,
02033                 int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
02034                 void *p_vrfy )
02035 {
02036     int ret;
02037     uint32_t parent_flags = 0;
02038     unsigned char hash[MBEDTLS_MD_MAX_SIZE];
02039     mbedtls_x509_crt *grandparent;
02040     const mbedtls_md_info_t *md_info;
02041 
02042     /* Counting intermediate self signed certificates */
02043     if( ( path_cnt != 0 ) && x509_name_cmp( &child->issuer, &child->subject ) == 0 )
02044         self_cnt++;
02045 
02046     /* path_cnt is 0 for the first intermediate CA */
02047     if( 1 + path_cnt > MBEDTLS_X509_MAX_INTERMEDIATE_CA )
02048     {
02049         *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
02050         return( MBEDTLS_ERR_X509_CERT_VERIFY_FAILED );
02051     }
02052 
02053     if( mbedtls_x509_time_is_past( &child->valid_to ) )
02054         *flags |= MBEDTLS_X509_BADCERT_EXPIRED;
02055 
02056     if( mbedtls_x509_time_is_future( &child->valid_from ) )
02057         *flags |= MBEDTLS_X509_BADCERT_FUTURE;
02058 
02059     if( x509_profile_check_md_alg( profile, child->sig_md ) != 0 )
02060         *flags |= MBEDTLS_X509_BADCERT_BAD_MD;
02061 
02062     if( x509_profile_check_pk_alg( profile, child->sig_pk ) != 0 )
02063         *flags |= MBEDTLS_X509_BADCERT_BAD_PK;
02064 
02065     md_info = mbedtls_md_info_from_type( child->sig_md );
02066     if( md_info == NULL )
02067     {
02068         /*
02069          * Cannot check 'unknown' hash
02070          */
02071         *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
02072     }
02073     else
02074     {
02075         mbedtls_md( md_info, child->tbs.p, child->tbs.len, hash );
02076 
02077         if( x509_profile_check_key( profile, child->sig_pk, &parent->pk ) != 0 )
02078             *flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
02079 
02080         if( mbedtls_pk_verify_ext( child->sig_pk, child->sig_opts, &parent->pk,
02081                            child->sig_md, hash, mbedtls_md_get_size( md_info ),
02082                            child->sig.p, child->sig.len ) != 0 )
02083         {
02084             *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
02085         }
02086     }
02087 
02088 #if defined(MBEDTLS_X509_CRL_PARSE_C)
02089     /* Check trusted CA's CRL for the given crt */
02090     *flags |= x509_crt_verifycrl(child, parent, ca_crl, profile );
02091 #endif
02092 
02093     /* Look for a grandparent in trusted CAs */
02094     for( grandparent = trust_ca;
02095          grandparent != NULL;
02096          grandparent = grandparent->next )
02097     {
02098         if( x509_crt_check_parent( parent, grandparent,
02099                                    0, path_cnt == 0 ) == 0 )
02100             break;
02101     }
02102 
02103     if( grandparent != NULL )
02104     {
02105         ret = x509_crt_verify_top( parent, grandparent, ca_crl, profile,
02106                                 path_cnt + 1, self_cnt, &parent_flags, f_vrfy, p_vrfy );
02107         if( ret != 0 )
02108             return( ret );
02109     }
02110     else
02111     {
02112         /* Look for a grandparent upwards the chain */
02113         for( grandparent = parent->next;
02114              grandparent != NULL;
02115              grandparent = grandparent->next )
02116         {
02117             /* +2 because the current step is not yet accounted for
02118              * and because max_pathlen is one higher than it should be.
02119              * Also self signed certificates do not count to the limit. */
02120             if( grandparent->max_pathlen > 0 &&
02121                 grandparent->max_pathlen < 2 + path_cnt - self_cnt )
02122             {
02123                 continue;
02124             }
02125 
02126             if( x509_crt_check_parent( parent, grandparent,
02127                                        0, path_cnt == 0 ) == 0 )
02128                 break;
02129         }
02130 
02131         /* Is our parent part of the chain or at the top? */
02132         if( grandparent != NULL )
02133         {
02134             ret = x509_crt_verify_child( parent, grandparent, trust_ca, ca_crl,
02135                                          profile, path_cnt + 1, self_cnt, &parent_flags,
02136                                          f_vrfy, p_vrfy );
02137             if( ret != 0 )
02138                 return( ret );
02139         }
02140         else
02141         {
02142             ret = x509_crt_verify_top( parent, trust_ca, ca_crl, profile,
02143                                        path_cnt + 1, self_cnt, &parent_flags,
02144                                        f_vrfy, p_vrfy );
02145             if( ret != 0 )
02146                 return( ret );
02147         }
02148     }
02149 
02150     /* child is verified to be a child of the parent, call verify callback */
02151     if( NULL != f_vrfy )
02152         if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
02153             return( ret );
02154 
02155     *flags |= parent_flags;
02156 
02157     return( 0 );
02158 }
02159 
02160 /*
02161  * Verify the certificate validity
02162  */
02163 int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt,
02164                      mbedtls_x509_crt *trust_ca,
02165                      mbedtls_x509_crl *ca_crl,
02166                      const char *cn, uint32_t *flags,
02167                      int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
02168                      void *p_vrfy )
02169 {
02170     return( mbedtls_x509_crt_verify_with_profile( crt, trust_ca, ca_crl,
02171                 &mbedtls_x509_crt_profile_default, cn, flags, f_vrfy, p_vrfy ) );
02172 }
02173 
02174 
02175 /*
02176  * Verify the certificate validity, with profile
02177  */
02178 int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt,
02179                      mbedtls_x509_crt *trust_ca,
02180                      mbedtls_x509_crl *ca_crl,
02181                      const mbedtls_x509_crt_profile *profile,
02182                      const char *cn, uint32_t *flags,
02183                      int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
02184                      void *p_vrfy )
02185 {
02186     size_t cn_len;
02187     int ret;
02188     int pathlen = 0, selfsigned = 0;
02189     mbedtls_x509_crt *parent;
02190     mbedtls_x509_name *name;
02191     mbedtls_x509_sequence *cur = NULL;
02192     mbedtls_pk_type_t pk_type;
02193 
02194     if( profile == NULL )
02195         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
02196 
02197     *flags = 0;
02198 
02199     if( cn != NULL )
02200     {
02201         name = &crt->subject;
02202         cn_len = strlen( cn );
02203 
02204         if( crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME )
02205         {
02206             cur = &crt->subject_alt_names;
02207 
02208             while( cur != NULL )
02209             {
02210                 if( cur->buf.len == cn_len &&
02211                     x509_memcasecmp( cn, cur->buf.p, cn_len ) == 0 )
02212                     break;
02213 
02214                 if( cur->buf.len > 2 &&
02215                     memcmp( cur->buf.p, "*.", 2 ) == 0 &&
02216                     x509_check_wildcard( cn, &cur->buf ) == 0 )
02217                 {
02218                     break;
02219                 }
02220 
02221                 cur = cur->next;
02222             }
02223 
02224             if( cur == NULL )
02225                 *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH;
02226         }
02227         else
02228         {
02229             while( name != NULL )
02230             {
02231                 if( MBEDTLS_OID_CMP( MBEDTLS_OID_AT_CN, &name->oid ) == 0 )
02232                 {
02233                     if( name->val.len == cn_len &&
02234                         x509_memcasecmp( name->val.p, cn, cn_len ) == 0 )
02235                         break;
02236 
02237                     if( name->val.len > 2 &&
02238                         memcmp( name->val.p, "*.", 2 ) == 0 &&
02239                         x509_check_wildcard( cn, &name->val ) == 0 )
02240                         break;
02241                 }
02242 
02243                 name = name->next;
02244             }
02245 
02246             if( name == NULL )
02247                 *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH;
02248         }
02249     }
02250 
02251     /* Check the type and size of the key */
02252     pk_type = mbedtls_pk_get_type( &crt->pk );
02253 
02254     if( x509_profile_check_pk_alg( profile, pk_type ) != 0 )
02255         *flags |= MBEDTLS_X509_BADCERT_BAD_PK;
02256 
02257     if( x509_profile_check_key( profile, pk_type, &crt->pk ) != 0 )
02258         *flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
02259 
02260     /* Look for a parent in trusted CAs */
02261     for( parent = trust_ca; parent != NULL; parent = parent->next )
02262     {
02263         if( x509_crt_check_parent( crt, parent, 0, pathlen == 0 ) == 0 )
02264             break;
02265     }
02266 
02267     if( parent != NULL )
02268     {
02269         ret = x509_crt_verify_top( crt, parent, ca_crl, profile,
02270                                    pathlen, selfsigned, flags, f_vrfy, p_vrfy );
02271         if( ret != 0 )
02272             return( ret );
02273     }
02274     else
02275     {
02276         /* Look for a parent upwards the chain */
02277         for( parent = crt->next; parent != NULL; parent = parent->next )
02278             if( x509_crt_check_parent( crt, parent, 0, pathlen == 0 ) == 0 )
02279                 break;
02280 
02281         /* Are we part of the chain or at the top? */
02282         if( parent != NULL )
02283         {
02284             ret = x509_crt_verify_child( crt, parent, trust_ca, ca_crl, profile,
02285                                          pathlen, selfsigned, flags, f_vrfy, p_vrfy );
02286             if( ret != 0 )
02287                 return( ret );
02288         }
02289         else
02290         {
02291             ret = x509_crt_verify_top( crt, trust_ca, ca_crl, profile,
02292                                        pathlen, selfsigned, flags, f_vrfy, p_vrfy );
02293             if( ret != 0 )
02294                 return( ret );
02295         }
02296     }
02297 
02298     if( *flags != 0 )
02299         return( MBEDTLS_ERR_X509_CERT_VERIFY_FAILED );
02300 
02301     return( 0 );
02302 }
02303 
02304 /*
02305  * Initialize a certificate chain
02306  */
02307 void mbedtls_x509_crt_init( mbedtls_x509_crt *crt )
02308 {
02309     memset( crt, 0, sizeof(mbedtls_x509_crt) );
02310 }
02311 
02312 /*
02313  * Unallocate all certificate data
02314  */
02315 void mbedtls_x509_crt_free( mbedtls_x509_crt *crt )
02316 {
02317     mbedtls_x509_crt *cert_cur = crt;
02318     mbedtls_x509_crt *cert_prv;
02319     mbedtls_x509_name *name_cur;
02320     mbedtls_x509_name *name_prv;
02321     mbedtls_x509_sequence *seq_cur;
02322     mbedtls_x509_sequence *seq_prv;
02323 
02324     if( crt == NULL )
02325         return;
02326 
02327     do
02328     {
02329         mbedtls_pk_free( &cert_cur->pk );
02330 
02331 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
02332         mbedtls_free( cert_cur->sig_opts );
02333 #endif
02334 
02335         name_cur = cert_cur->issuer.next;
02336         while( name_cur != NULL )
02337         {
02338             name_prv = name_cur;
02339             name_cur = name_cur->next;
02340             mbedtls_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
02341             mbedtls_free( name_prv );
02342         }
02343 
02344         name_cur = cert_cur->subject.next;
02345         while( name_cur != NULL )
02346         {
02347             name_prv = name_cur;
02348             name_cur = name_cur->next;
02349             mbedtls_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
02350             mbedtls_free( name_prv );
02351         }
02352 
02353         seq_cur = cert_cur->ext_key_usage.next;
02354         while( seq_cur != NULL )
02355         {
02356             seq_prv = seq_cur;
02357             seq_cur = seq_cur->next;
02358             mbedtls_zeroize( seq_prv, sizeof( mbedtls_x509_sequence ) );
02359             mbedtls_free( seq_prv );
02360         }
02361 
02362         seq_cur = cert_cur->subject_alt_names.next;
02363         while( seq_cur != NULL )
02364         {
02365             seq_prv = seq_cur;
02366             seq_cur = seq_cur->next;
02367             mbedtls_zeroize( seq_prv, sizeof( mbedtls_x509_sequence ) );
02368             mbedtls_free( seq_prv );
02369         }
02370 
02371         if( cert_cur->raw.p != NULL )
02372         {
02373             mbedtls_zeroize( cert_cur->raw.p, cert_cur->raw.len );
02374             mbedtls_free( cert_cur->raw.p );
02375         }
02376 
02377         cert_cur = cert_cur->next;
02378     }
02379     while( cert_cur != NULL );
02380 
02381     cert_cur = crt;
02382     do
02383     {
02384         cert_prv = cert_cur;
02385         cert_cur = cert_cur->next;
02386 
02387         mbedtls_zeroize( cert_prv, sizeof( mbedtls_x509_crt ) );
02388         if( cert_prv != crt )
02389             mbedtls_free( cert_prv );
02390     }
02391     while( cert_cur != NULL );
02392 }
02393 
02394 #endif /* MBEDTLS_X509_CRT_PARSE_C */