mbed client lightswitch demo

Dependencies:   mbed Socket lwip-eth lwip-sys lwip

Fork of mbed-client-classic-example-lwip by Austin Blackstone

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