mbed TLS library

Dependents:   HTTPClient-SSL WS_SERVER

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-2014, ARM Limited, All Rights Reserved
00005  *
00006  *  This file is part of mbed TLS (https://tls.mbed.org)
00007  *
00008  *  This program is free software; you can redistribute it and/or modify
00009  *  it under the terms of the GNU General Public License as published by
00010  *  the Free Software Foundation; either version 2 of the License, or
00011  *  (at your option) any later version.
00012  *
00013  *  This program is distributed in the hope that it will be useful,
00014  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  *  GNU General Public License for more details.
00017  *
00018  *  You should have received a copy of the GNU General Public License along
00019  *  with this program; if not, write to the Free Software Foundation, Inc.,
00020  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00021  */
00022 /*
00023  *  The ITU-T X.509 standard defines a certificate format for PKI.
00024  *
00025  *  http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
00026  *  http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
00027  *  http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
00028  *
00029  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
00030  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
00031  */
00032 
00033 #if !defined(POLARSSL_CONFIG_FILE)
00034 #include "polarssl/config.h"
00035 #else
00036 #include POLARSSL_CONFIG_FILE
00037 #endif
00038 
00039 #if defined(POLARSSL_X509_CRT_PARSE_C)
00040 
00041 #include "polarssl/x509_crt.h"
00042 #include "polarssl/oid.h"
00043 
00044 #include <stdio.h>
00045 #include <string.h>
00046 
00047 #if defined(POLARSSL_PEM_PARSE_C)
00048 #include "polarssl/pem.h"
00049 #endif
00050 
00051 #if defined(POLARSSL_PLATFORM_C)
00052 #include "polarssl/platform.h"
00053 #else
00054 #include <stdlib.h>
00055 #define polarssl_free       free
00056 #define polarssl_malloc     malloc
00057 #define polarssl_snprintf   snprintf
00058 #endif
00059 
00060 #if defined(POLARSSL_THREADING_C)
00061 #include "polarssl/threading.h"
00062 #endif
00063 
00064 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
00065 #include <windows.h>
00066 #else
00067 #include <time.h>
00068 #endif
00069 
00070 #if defined(POLARSSL_FS_IO)
00071 #include <stdio.h>
00072 #if !defined(_WIN32) || defined(EFIX64) || defined(EFI32)
00073 #include <sys/types.h>
00074 #include <sys/stat.h>
00075 #include <dirent.h>
00076 #endif /* !_WIN32 || EFIX64 || EFI32 */
00077 #endif
00078 
00079 /* Implementation that should never be optimized out by the compiler */
00080 static void polarssl_zeroize( void *v, size_t n ) {
00081     volatile unsigned char *p = v; while( n-- ) *p++ = 0;
00082 }
00083 
00084 /*
00085  *  Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
00086  */
00087 static int x509_get_version( unsigned char **p,
00088                              const unsigned char *end,
00089                              int *ver )
00090 {
00091     int ret;
00092     size_t len;
00093 
00094     if( ( ret = asn1_get_tag( p, end, &len,
00095             ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) != 0 )
00096     {
00097         if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
00098         {
00099             *ver = 0;
00100             return( 0 );
00101         }
00102 
00103         return( ret );
00104     }
00105 
00106     end = *p + len;
00107 
00108     if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
00109         return( POLARSSL_ERR_X509_INVALID_VERSION + ret );
00110 
00111     if( *p != end )
00112         return( POLARSSL_ERR_X509_INVALID_VERSION +
00113                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00114 
00115     return( 0 );
00116 }
00117 
00118 /*
00119  *  Validity ::= SEQUENCE {
00120  *       notBefore      Time,
00121  *       notAfter       Time }
00122  */
00123 static int x509_get_dates( unsigned char **p,
00124                            const unsigned char *end,
00125                            x509_time *from,
00126                            x509_time *to )
00127 {
00128     int ret;
00129     size_t len;
00130 
00131     if( ( ret = asn1_get_tag( p, end, &len,
00132             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00133         return( POLARSSL_ERR_X509_INVALID_DATE + ret );
00134 
00135     end = *p + len;
00136 
00137     if( ( ret = x509_get_time( p, end, from ) ) != 0 )
00138         return( ret );
00139 
00140     if( ( ret = x509_get_time( p, end, to ) ) != 0 )
00141         return( ret );
00142 
00143     if( *p != end )
00144         return( POLARSSL_ERR_X509_INVALID_DATE +
00145                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00146 
00147     return( 0 );
00148 }
00149 
00150 /*
00151  * X.509 v2/v3 unique identifier (not parsed)
00152  */
00153 static int x509_get_uid( unsigned char **p,
00154                          const unsigned char *end,
00155                          x509_buf *uid, int n )
00156 {
00157     int ret;
00158 
00159     if( *p == end )
00160         return( 0 );
00161 
00162     uid->tag = **p;
00163 
00164     if( ( ret = asn1_get_tag( p, end, &uid->len,
00165             ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 )
00166     {
00167         if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
00168             return( 0 );
00169 
00170         return( ret );
00171     }
00172 
00173     uid->p = *p;
00174     *p += uid->len;
00175 
00176     return( 0 );
00177 }
00178 
00179 static int x509_get_basic_constraints( unsigned char **p,
00180                                        const unsigned char *end,
00181                                        int *ca_istrue,
00182                                        int *max_pathlen )
00183 {
00184     int ret;
00185     size_t len;
00186 
00187     /*
00188      * BasicConstraints ::= SEQUENCE {
00189      *      cA                      BOOLEAN DEFAULT FALSE,
00190      *      pathLenConstraint       INTEGER (0..MAX) OPTIONAL }
00191      */
00192     *ca_istrue = 0; /* DEFAULT FALSE */
00193     *max_pathlen = 0; /* endless */
00194 
00195     if( ( ret = asn1_get_tag( p, end, &len,
00196             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00197         return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
00198 
00199     if( *p == end )
00200         return( 0 );
00201 
00202     if( ( ret = asn1_get_bool( p, end, ca_istrue ) ) != 0 )
00203     {
00204         if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
00205             ret = asn1_get_int( p, end, ca_istrue );
00206 
00207         if( ret != 0 )
00208             return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
00209 
00210         if( *ca_istrue != 0 )
00211             *ca_istrue = 1;
00212     }
00213 
00214     if( *p == end )
00215         return( 0 );
00216 
00217     if( ( ret = asn1_get_int( p, end, max_pathlen ) ) != 0 )
00218         return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
00219 
00220     if( *p != end )
00221         return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
00222                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00223 
00224     (*max_pathlen)++;
00225 
00226     return( 0 );
00227 }
00228 
00229 static int x509_get_ns_cert_type( unsigned char **p,
00230                                        const unsigned char *end,
00231                                        unsigned char *ns_cert_type)
00232 {
00233     int ret;
00234     x509_bitstring bs = { 0, 0, NULL };
00235 
00236     if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
00237         return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
00238 
00239     if( bs.len != 1 )
00240         return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
00241                 POLARSSL_ERR_ASN1_INVALID_LENGTH );
00242 
00243     /* Get actual bitstring */
00244     *ns_cert_type = *bs.p;
00245     return( 0 );
00246 }
00247 
00248 static int x509_get_key_usage( unsigned char **p,
00249                                const unsigned char *end,
00250                                unsigned char *key_usage)
00251 {
00252     int ret;
00253     x509_bitstring bs = { 0, 0, NULL };
00254 
00255     if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
00256         return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
00257 
00258     if( bs.len < 1 )
00259         return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
00260                 POLARSSL_ERR_ASN1_INVALID_LENGTH );
00261 
00262     /* Get actual bitstring */
00263     *key_usage = *bs.p;
00264     return( 0 );
00265 }
00266 
00267 /*
00268  * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
00269  *
00270  * KeyPurposeId ::= OBJECT IDENTIFIER
00271  */
00272 static int x509_get_ext_key_usage( unsigned char **p,
00273                                const unsigned char *end,
00274                                x509_sequence *ext_key_usage)
00275 {
00276     int ret;
00277 
00278     if( ( ret = asn1_get_sequence_of( p, end, ext_key_usage, ASN1_OID ) ) != 0 )
00279         return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
00280 
00281     /* Sequence length must be >= 1 */
00282     if( ext_key_usage->buf.p == NULL )
00283         return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
00284                 POLARSSL_ERR_ASN1_INVALID_LENGTH );
00285 
00286     return( 0 );
00287 }
00288 
00289 /*
00290  * SubjectAltName ::= GeneralNames
00291  *
00292  * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
00293  *
00294  * GeneralName ::= CHOICE {
00295  *      otherName                       [0]     OtherName,
00296  *      rfc822Name                      [1]     IA5String,
00297  *      dNSName                         [2]     IA5String,
00298  *      x400Address                     [3]     ORAddress,
00299  *      directoryName                   [4]     Name,
00300  *      ediPartyName                    [5]     EDIPartyName,
00301  *      uniformResourceIdentifier       [6]     IA5String,
00302  *      iPAddress                       [7]     OCTET STRING,
00303  *      registeredID                    [8]     OBJECT IDENTIFIER }
00304  *
00305  * OtherName ::= SEQUENCE {
00306  *      type-id    OBJECT IDENTIFIER,
00307  *      value      [0] EXPLICIT ANY DEFINED BY type-id }
00308  *
00309  * EDIPartyName ::= SEQUENCE {
00310  *      nameAssigner            [0]     DirectoryString OPTIONAL,
00311  *      partyName               [1]     DirectoryString }
00312  *
00313  * NOTE: we only parse and use dNSName at this point.
00314  */
00315 static int x509_get_subject_alt_name( unsigned char **p,
00316                                       const unsigned char *end,
00317                                       x509_sequence *subject_alt_name )
00318 {
00319     int ret;
00320     size_t len, tag_len;
00321     asn1_buf *buf;
00322     unsigned char tag;
00323     asn1_sequence *cur = subject_alt_name;
00324 
00325     /* Get main sequence tag */
00326     if( ( ret = asn1_get_tag( p, end, &len,
00327             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00328         return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
00329 
00330     if( *p + len != end )
00331         return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
00332                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00333 
00334     while( *p < end )
00335     {
00336         if( ( end - *p ) < 1 )
00337             return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
00338                     POLARSSL_ERR_ASN1_OUT_OF_DATA );
00339 
00340         tag = **p;
00341         (*p)++;
00342         if( ( ret = asn1_get_len( p, end, &tag_len ) ) != 0 )
00343             return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
00344 
00345         if( ( tag & ASN1_CONTEXT_SPECIFIC ) != ASN1_CONTEXT_SPECIFIC )
00346             return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
00347                     POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
00348 
00349         /* Skip everything but DNS name */
00350         if( tag != ( ASN1_CONTEXT_SPECIFIC | 2 ) )
00351         {
00352             *p += tag_len;
00353             continue;
00354         }
00355 
00356         /* Allocate and assign next pointer */
00357         if( cur->buf.p != NULL )
00358         {
00359             if( cur->next != NULL )
00360                 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS );
00361 
00362             cur->next = polarssl_malloc( sizeof( asn1_sequence ) );
00363 
00364             if( cur->next == NULL )
00365                 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
00366                         POLARSSL_ERR_ASN1_MALLOC_FAILED );
00367 
00368             memset( cur->next, 0, sizeof( asn1_sequence ) );
00369             cur = cur->next;
00370         }
00371 
00372         buf = &(cur->buf);
00373         buf->tag = tag;
00374         buf->p = *p;
00375         buf->len = tag_len;
00376         *p += buf->len;
00377     }
00378 
00379     /* Set final sequence entry's next pointer to NULL */
00380     cur->next = NULL;
00381 
00382     if( *p != end )
00383         return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
00384                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00385 
00386     return( 0 );
00387 }
00388 
00389 /*
00390  * X.509 v3 extensions
00391  *
00392  * TODO: Perform all of the basic constraints tests required by the RFC
00393  * TODO: Set values for undetected extensions to a sane default?
00394  *
00395  */
00396 static int x509_get_crt_ext( unsigned char **p,
00397                              const unsigned char *end,
00398                              x509_crt *crt )
00399 {
00400     int ret;
00401     size_t len;
00402     unsigned char *end_ext_data, *end_ext_octet;
00403 
00404     if( ( ret = x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 )
00405     {
00406         if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
00407             return( 0 );
00408 
00409         return( ret );
00410     }
00411 
00412     while( *p < end )
00413     {
00414         /*
00415          * Extension  ::=  SEQUENCE  {
00416          *      extnID      OBJECT IDENTIFIER,
00417          *      critical    BOOLEAN DEFAULT FALSE,
00418          *      extnValue   OCTET STRING  }
00419          */
00420         x509_buf extn_oid = {0, 0, NULL};
00421         int is_critical = 0; /* DEFAULT FALSE */
00422         int ext_type = 0;
00423 
00424         if( ( ret = asn1_get_tag( p, end, &len,
00425                 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00426             return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
00427 
00428         end_ext_data = *p + len;
00429 
00430         /* Get extension ID */
00431         extn_oid.tag = **p;
00432 
00433         if( ( ret = asn1_get_tag( p, end, &extn_oid.len, ASN1_OID ) ) != 0 )
00434             return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
00435 
00436         extn_oid.p = *p;
00437         *p += extn_oid.len;
00438 
00439         if( ( end - *p ) < 1 )
00440             return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
00441                     POLARSSL_ERR_ASN1_OUT_OF_DATA );
00442 
00443         /* Get optional critical */
00444         if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
00445             ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
00446             return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
00447 
00448         /* Data should be octet string type */
00449         if( ( ret = asn1_get_tag( p, end_ext_data, &len,
00450                 ASN1_OCTET_STRING ) ) != 0 )
00451             return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
00452 
00453         end_ext_octet = *p + len;
00454 
00455         if( end_ext_octet != end_ext_data )
00456             return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
00457                     POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00458 
00459         /*
00460          * Detect supported extensions
00461          */
00462         ret = oid_get_x509_ext_type( &extn_oid, &ext_type );
00463 
00464         if( ret != 0 )
00465         {
00466             /* No parser found, skip extension */
00467             *p = end_ext_octet;
00468 
00469 #if !defined(POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
00470             if( is_critical )
00471             {
00472                 /* Data is marked as critical: fail */
00473                 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
00474                         POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
00475             }
00476 #endif
00477             continue;
00478         }
00479 
00480         /* Forbid repeated extensions */
00481         if( ( crt->ext_types & ext_type ) != 0 )
00482             return( POLARSSL_ERR_X509_INVALID_EXTENSIONS );
00483 
00484         crt->ext_types |= ext_type;
00485 
00486         switch( ext_type )
00487         {
00488         case EXT_BASIC_CONSTRAINTS:
00489             /* Parse basic constraints */
00490             if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
00491                     &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
00492                 return( ret );
00493             break;
00494 
00495         case EXT_KEY_USAGE:
00496             /* Parse key usage */
00497             if( ( ret = x509_get_key_usage( p, end_ext_octet,
00498                     &crt->key_usage ) ) != 0 )
00499                 return( ret );
00500             break;
00501 
00502         case EXT_EXTENDED_KEY_USAGE:
00503             /* Parse extended key usage */
00504             if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
00505                     &crt->ext_key_usage ) ) != 0 )
00506                 return( ret );
00507             break;
00508 
00509         case EXT_SUBJECT_ALT_NAME:
00510             /* Parse subject alt name */
00511             if( ( ret = x509_get_subject_alt_name( p, end_ext_octet,
00512                     &crt->subject_alt_names ) ) != 0 )
00513                 return( ret );
00514             break;
00515 
00516         case EXT_NS_CERT_TYPE:
00517             /* Parse netscape certificate type */
00518             if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
00519                     &crt->ns_cert_type ) ) != 0 )
00520                 return( ret );
00521             break;
00522 
00523         default:
00524             return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
00525         }
00526     }
00527 
00528     if( *p != end )
00529         return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
00530                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00531 
00532     return( 0 );
00533 }
00534 
00535 /*
00536  * Parse and fill a single X.509 certificate in DER format
00537  */
00538 static int x509_crt_parse_der_core( x509_crt *crt, const unsigned char *buf,
00539                                     size_t buflen )
00540 {
00541     int ret;
00542     size_t len;
00543     unsigned char *p, *end, *crt_end;
00544     x509_buf sig_params1, sig_params2;
00545 
00546     memset( &sig_params1, 0, sizeof( x509_buf ) );
00547     memset( &sig_params2, 0, sizeof( x509_buf ) );
00548 
00549     /*
00550      * Check for valid input
00551      */
00552     if( crt == NULL || buf == NULL )
00553         return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
00554 
00555     p = polarssl_malloc( len = buflen );
00556 
00557     if( p == NULL )
00558         return( POLARSSL_ERR_X509_MALLOC_FAILED );
00559 
00560     memcpy( p, buf, buflen );
00561 
00562     crt->raw.p = p;
00563     crt->raw.len = len;
00564     end = p + len;
00565 
00566     /*
00567      * Certificate  ::=  SEQUENCE  {
00568      *      tbsCertificate       TBSCertificate,
00569      *      signatureAlgorithm   AlgorithmIdentifier,
00570      *      signatureValue       BIT STRING  }
00571      */
00572     if( ( ret = asn1_get_tag( &p, end, &len,
00573             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00574     {
00575         x509_crt_free( crt );
00576         return( POLARSSL_ERR_X509_INVALID_FORMAT );
00577     }
00578 
00579     if( len > (size_t) ( end - p ) )
00580     {
00581         x509_crt_free( crt );
00582         return( POLARSSL_ERR_X509_INVALID_FORMAT +
00583                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00584     }
00585     crt_end = p + len;
00586 
00587     /*
00588      * TBSCertificate  ::=  SEQUENCE  {
00589      */
00590     crt->tbs.p = p;
00591 
00592     if( ( ret = asn1_get_tag( &p, end, &len,
00593             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00594     {
00595         x509_crt_free( crt );
00596         return( POLARSSL_ERR_X509_INVALID_FORMAT + ret );
00597     }
00598 
00599     end = p + len;
00600     crt->tbs.len = end - crt->tbs.p;
00601 
00602     /*
00603      * Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
00604      *
00605      * CertificateSerialNumber  ::=  INTEGER
00606      *
00607      * signature            AlgorithmIdentifier
00608      */
00609     if( ( ret = x509_get_version(  &p, end, &crt->version  ) ) != 0 ||
00610         ( ret = x509_get_serial(   &p, end, &crt->serial   ) ) != 0 ||
00611         ( ret = x509_get_alg(      &p, end, &crt->sig_oid1,
00612                                             &sig_params1 ) ) != 0 )
00613     {
00614         x509_crt_free( crt );
00615         return( ret );
00616     }
00617 
00618     crt->version++;
00619 
00620     if( crt->version > 3 )
00621     {
00622         x509_crt_free( crt );
00623         return( POLARSSL_ERR_X509_UNKNOWN_VERSION );
00624     }
00625 
00626     if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &sig_params1,
00627                                   &crt->sig_md, &crt->sig_pk,
00628                                   &crt->sig_opts ) ) != 0 )
00629     {
00630         x509_crt_free( crt );
00631         return( ret );
00632     }
00633 
00634     /*
00635      * issuer               Name
00636      */
00637     crt->issuer_raw.p = p;
00638 
00639     if( ( ret = asn1_get_tag( &p, end, &len,
00640             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00641     {
00642         x509_crt_free( crt );
00643         return( POLARSSL_ERR_X509_INVALID_FORMAT + ret );
00644     }
00645 
00646     if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
00647     {
00648         x509_crt_free( crt );
00649         return( ret );
00650     }
00651 
00652     crt->issuer_raw.len = p - crt->issuer_raw.p;
00653 
00654     /*
00655      * Validity ::= SEQUENCE {
00656      *      notBefore      Time,
00657      *      notAfter       Time }
00658      *
00659      */
00660     if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
00661                                          &crt->valid_to ) ) != 0 )
00662     {
00663         x509_crt_free( crt );
00664         return( ret );
00665     }
00666 
00667     /*
00668      * subject              Name
00669      */
00670     crt->subject_raw.p = p;
00671 
00672     if( ( ret = asn1_get_tag( &p, end, &len,
00673             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00674     {
00675         x509_crt_free( crt );
00676         return( POLARSSL_ERR_X509_INVALID_FORMAT + ret );
00677     }
00678 
00679     if( len && ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
00680     {
00681         x509_crt_free( crt );
00682         return( ret );
00683     }
00684 
00685     crt->subject_raw.len = p - crt->subject_raw.p;
00686 
00687     /*
00688      * SubjectPublicKeyInfo
00689      */
00690     if( ( ret = pk_parse_subpubkey( &p, end, &crt->pk ) ) != 0 )
00691     {
00692         x509_crt_free( crt );
00693         return( ret );
00694     }
00695 
00696     /*
00697      *  issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
00698      *                       -- If present, version shall be v2 or v3
00699      *  subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
00700      *                       -- If present, version shall be v2 or v3
00701      *  extensions      [3]  EXPLICIT Extensions OPTIONAL
00702      *                       -- If present, version shall be v3
00703      */
00704     if( crt->version == 2 || crt->version == 3 )
00705     {
00706         ret = x509_get_uid( &p, end, &crt->issuer_id,  1 );
00707         if( ret != 0 )
00708         {
00709             x509_crt_free( crt );
00710             return( ret );
00711         }
00712     }
00713 
00714     if( crt->version == 2 || crt->version == 3 )
00715     {
00716         ret = x509_get_uid( &p, end, &crt->subject_id,  2 );
00717         if( ret != 0 )
00718         {
00719             x509_crt_free( crt );
00720             return( ret );
00721         }
00722     }
00723 
00724 #if !defined(POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3)
00725     if( crt->version == 3 )
00726     {
00727 #endif
00728         ret = x509_get_crt_ext( &p, end, crt );
00729         if( ret != 0 )
00730         {
00731             x509_crt_free( crt );
00732             return( ret );
00733         }
00734 #if !defined(POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3)
00735     }
00736 #endif
00737 
00738     if( p != end )
00739     {
00740         x509_crt_free( crt );
00741         return( POLARSSL_ERR_X509_INVALID_FORMAT +
00742                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00743     }
00744 
00745     end = crt_end;
00746 
00747     /*
00748      *  }
00749      *  -- end of TBSCertificate
00750      *
00751      *  signatureAlgorithm   AlgorithmIdentifier,
00752      *  signatureValue       BIT STRING
00753      */
00754     if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2, &sig_params2 ) ) != 0 )
00755     {
00756         x509_crt_free( crt );
00757         return( ret );
00758     }
00759 
00760     if( crt->sig_oid1.len != crt->sig_oid2.len ||
00761         memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 ||
00762         sig_params1.len != sig_params2.len ||
00763         ( sig_params1.len != 0 &&
00764           memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) )
00765     {
00766         x509_crt_free( crt );
00767         return( POLARSSL_ERR_X509_SIG_MISMATCH );
00768     }
00769 
00770     if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
00771     {
00772         x509_crt_free( crt );
00773         return( ret );
00774     }
00775 
00776     if( p != end )
00777     {
00778         x509_crt_free( crt );
00779         return( POLARSSL_ERR_X509_INVALID_FORMAT +
00780                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00781     }
00782 
00783     return( 0 );
00784 }
00785 
00786 /*
00787  * Parse one X.509 certificate in DER format from a buffer and add them to a
00788  * chained list
00789  */
00790 int x509_crt_parse_der( x509_crt *chain, const unsigned char *buf,
00791                         size_t buflen )
00792 {
00793     int ret;
00794     x509_crt *crt = chain, *prev = NULL;
00795 
00796     /*
00797      * Check for valid input
00798      */
00799     if( crt == NULL || buf == NULL )
00800         return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
00801 
00802     while( crt->version != 0 && crt->next != NULL )
00803     {
00804         prev = crt;
00805         crt = crt->next;
00806     }
00807 
00808     /*
00809      * Add new certificate on the end of the chain if needed.
00810      */
00811     if( crt->version != 0 && crt->next == NULL )
00812     {
00813         crt->next = polarssl_malloc( sizeof( x509_crt ) );
00814 
00815         if( crt->next == NULL )
00816             return( POLARSSL_ERR_X509_MALLOC_FAILED );
00817 
00818         prev = crt;
00819         x509_crt_init( crt->next );
00820         crt = crt->next;
00821     }
00822 
00823     if( ( ret = x509_crt_parse_der_core( crt, buf, buflen ) ) != 0 )
00824     {
00825         if( prev )
00826             prev->next = NULL;
00827 
00828         if( crt != chain )
00829             polarssl_free( crt );
00830 
00831         return( ret );
00832     }
00833 
00834     return( 0 );
00835 }
00836 
00837 /*
00838  * Parse one or more PEM certificates from a buffer and add them to the chained
00839  * list
00840  */
00841 int x509_crt_parse( x509_crt *chain, const unsigned char *buf, size_t buflen )
00842 {
00843     int success = 0, first_error = 0, total_failed = 0;
00844     int buf_format = X509_FORMAT_DER;
00845 
00846     /*
00847      * Check for valid input
00848      */
00849     if( chain == NULL || buf == NULL )
00850         return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
00851 
00852     /*
00853      * Determine buffer content. Buffer contains either one DER certificate or
00854      * one or more PEM certificates.
00855      */
00856 #if defined(POLARSSL_PEM_PARSE_C)
00857     if( strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL )
00858         buf_format = X509_FORMAT_PEM;
00859 #endif
00860 
00861     if( buf_format == X509_FORMAT_DER )
00862         return x509_crt_parse_der( chain, buf, buflen );
00863 
00864 #if defined(POLARSSL_PEM_PARSE_C)
00865     if( buf_format == X509_FORMAT_PEM )
00866     {
00867         int ret;
00868         pem_context pem;
00869 
00870         while( buflen > 0 )
00871         {
00872             size_t use_len;
00873             pem_init( &pem );
00874 
00875             ret = pem_read_buffer( &pem,
00876                            "-----BEGIN CERTIFICATE-----",
00877                            "-----END CERTIFICATE-----",
00878                            buf, NULL, 0, &use_len );
00879 
00880             if( ret == 0 )
00881             {
00882                 /*
00883                  * Was PEM encoded
00884                  */
00885                 buflen -= use_len;
00886                 buf += use_len;
00887             }
00888             else if( ret == POLARSSL_ERR_PEM_BAD_INPUT_DATA )
00889             {
00890                 return( ret );
00891             }
00892             else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
00893             {
00894                 pem_free( &pem );
00895 
00896                 /*
00897                  * PEM header and footer were found
00898                  */
00899                 buflen -= use_len;
00900                 buf += use_len;
00901 
00902                 if( first_error == 0 )
00903                     first_error = ret;
00904 
00905                 total_failed++;
00906                 continue;
00907             }
00908             else
00909                 break;
00910 
00911             ret = x509_crt_parse_der( chain, pem.buf , pem.buflen  );
00912 
00913             pem_free( &pem );
00914 
00915             if( ret != 0 )
00916             {
00917                 /*
00918                  * Quit parsing on a memory error
00919                  */
00920                 if( ret == POLARSSL_ERR_X509_MALLOC_FAILED )
00921                     return( ret );
00922 
00923                 if( first_error == 0 )
00924                     first_error = ret;
00925 
00926                 total_failed++;
00927                 continue;
00928             }
00929 
00930             success = 1;
00931         }
00932     }
00933 #endif /* POLARSSL_PEM_PARSE_C */
00934 
00935     if( success )
00936         return( total_failed );
00937     else if( first_error )
00938         return( first_error );
00939     else
00940         return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT );
00941 }
00942 
00943 #if defined(POLARSSL_FS_IO)
00944 /*
00945  * Load one or more certificates and add them to the chained list
00946  */
00947 int x509_crt_parse_file( x509_crt *chain, const char *path )
00948 {
00949     int ret;
00950     size_t n;
00951     unsigned char *buf;
00952 
00953     if( ( ret = pk_load_file( path, &buf, &n ) ) != 0 )
00954         return( ret );
00955 
00956     ret = x509_crt_parse( chain, buf, n );
00957 
00958     polarssl_zeroize( buf, n + 1 );
00959     polarssl_free( buf );
00960 
00961     return( ret );
00962 }
00963 
00964 #if defined(POLARSSL_THREADING_PTHREAD)
00965 static threading_mutex_t readdir_mutex = PTHREAD_MUTEX_INITIALIZER;
00966 #endif
00967 
00968 int x509_crt_parse_path( x509_crt *chain, const char *path )
00969 {
00970     int ret = 0;
00971 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
00972     int w_ret;
00973     WCHAR szDir[MAX_PATH];
00974     char filename[MAX_PATH];
00975     char *p;
00976     int len = (int) strlen( path );
00977 
00978     WIN32_FIND_DATAW file_data;
00979     HANDLE hFind;
00980 
00981     if( len > MAX_PATH - 3 )
00982         return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
00983 
00984     memset( szDir, 0, sizeof(szDir) );
00985     memset( filename, 0, MAX_PATH );
00986     memcpy( filename, path, len );
00987     filename[len++] = '\\';
00988     p = filename + len;
00989     filename[len++] = '*';
00990 
00991     w_ret = MultiByteToWideChar( CP_ACP, 0, filename, len, szDir,
00992                                  MAX_PATH - 3 );
00993     if( w_ret == 0 )
00994         return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
00995 
00996     hFind = FindFirstFileW( szDir, &file_data );
00997     if( hFind == INVALID_HANDLE_VALUE )
00998         return( POLARSSL_ERR_X509_FILE_IO_ERROR );
00999 
01000     len = MAX_PATH - len;
01001     do
01002     {
01003         memset( p, 0, len );
01004 
01005         if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
01006             continue;
01007 
01008         w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName,
01009                                      lstrlenW( file_data.cFileName ),
01010                                      p, len - 1,
01011                                      NULL, NULL );
01012         if( w_ret == 0 )
01013             return( POLARSSL_ERR_X509_FILE_IO_ERROR );
01014 
01015         w_ret = x509_crt_parse_file( chain, filename );
01016         if( w_ret < 0 )
01017             ret++;
01018         else
01019             ret += w_ret;
01020     }
01021     while( FindNextFileW( hFind, &file_data ) != 0 );
01022 
01023     if( GetLastError() != ERROR_NO_MORE_FILES )
01024         ret = POLARSSL_ERR_X509_FILE_IO_ERROR;
01025 
01026     FindClose( hFind );
01027 #else /* _WIN32 */
01028     int t_ret;
01029     struct stat sb;
01030     struct dirent *entry;
01031     char entry_name[255];
01032     DIR *dir = opendir( path );
01033 
01034     if( dir == NULL )
01035         return( POLARSSL_ERR_X509_FILE_IO_ERROR );
01036 
01037 #if defined(POLARSSL_THREADING_PTHREAD)
01038     if( ( ret = polarssl_mutex_lock( &readdir_mutex ) ) != 0 )
01039         return( ret );
01040 #endif
01041 
01042     while( ( entry = readdir( dir ) ) != NULL )
01043     {
01044         polarssl_snprintf( entry_name, sizeof entry_name, "%s/%s", path, entry->d_name );
01045 
01046         if( stat( entry_name, &sb ) == -1 )
01047         {
01048             closedir( dir );
01049             ret = POLARSSL_ERR_X509_FILE_IO_ERROR;
01050             goto cleanup;
01051         }
01052 
01053         if( !S_ISREG( sb.st_mode ) )
01054             continue;
01055 
01056         // Ignore parse errors
01057         //
01058         t_ret = x509_crt_parse_file( chain, entry_name );
01059         if( t_ret < 0 )
01060             ret++;
01061         else
01062             ret += t_ret;
01063     }
01064     closedir( dir );
01065 
01066 cleanup:
01067 #if defined(POLARSSL_THREADING_PTHREAD)
01068     if( polarssl_mutex_unlock( &readdir_mutex ) != 0 )
01069         ret = POLARSSL_ERR_THREADING_MUTEX_ERROR;
01070 #endif
01071 
01072 #endif /* _WIN32 */
01073 
01074     return( ret );
01075 }
01076 #endif /* POLARSSL_FS_IO */
01077 
01078 #if defined(_MSC_VER) && !defined snprintf && !defined(EFIX64) && \
01079     !defined(EFI32)
01080 #include <stdarg.h>
01081 
01082 #if !defined vsnprintf
01083 #define vsnprintf _vsnprintf
01084 #endif // vsnprintf
01085 
01086 /*
01087  * Windows _snprintf and _vsnprintf are not compatible to linux versions.
01088  * Result value is not size of buffer needed, but -1 if no fit is possible.
01089  *
01090  * This fuction tries to 'fix' this by at least suggesting enlarging the
01091  * size by 20.
01092  */
01093 static int compat_snprintf( char *str, size_t size, const char *format, ... )
01094 {
01095     va_list ap;
01096     int res = -1;
01097 
01098     va_start( ap, format );
01099 
01100     res = vsnprintf( str, size, format, ap );
01101 
01102     va_end( ap );
01103 
01104     // No quick fix possible
01105     if( res < 0 )
01106         return( (int) size + 20 );
01107 
01108     return( res );
01109 }
01110 
01111 #define snprintf compat_snprintf
01112 #endif /* _MSC_VER  && !snprintf && !EFIX64 && !EFI32 */
01113 
01114 #define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL    -2
01115 
01116 #define SAFE_SNPRINTF()                             \
01117 {                                                   \
01118     if( ret == -1 )                                 \
01119         return( -1 );                               \
01120                                                     \
01121     if( (unsigned int) ret > n ) {                  \
01122         p[n - 1] = '\0';                            \
01123         return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL ); \
01124     }                                               \
01125                                                     \
01126     n -= (unsigned int) ret;                        \
01127     p += (unsigned int) ret;                        \
01128 }
01129 
01130 static int x509_info_subject_alt_name( char **buf, size_t *size,
01131                                        const x509_sequence *subject_alt_name )
01132 {
01133     size_t i;
01134     size_t n = *size;
01135     char *p = *buf;
01136     const x509_sequence *cur = subject_alt_name;
01137     const char *sep = "";
01138     size_t sep_len = 0;
01139 
01140     while( cur != NULL )
01141     {
01142         if( cur->buf.len + sep_len >= n )
01143         {
01144             *p = '\0';
01145             return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL );
01146         }
01147 
01148         n -= cur->buf.len + sep_len;
01149         for( i = 0; i < sep_len; i++ )
01150             *p++ = sep[i];
01151         for( i = 0; i < cur->buf.len; i++ )
01152             *p++ = cur->buf.p[i];
01153 
01154         sep = ", ";
01155         sep_len = 2;
01156 
01157         cur = cur->next;
01158     }
01159 
01160     *p = '\0';
01161 
01162     *size = n;
01163     *buf = p;
01164 
01165     return( 0 );
01166 }
01167 
01168 #define PRINT_ITEM(i)                           \
01169     {                                           \
01170         ret = polarssl_snprintf( p, n, "%s" i, sep );    \
01171         SAFE_SNPRINTF();                        \
01172         sep = ", ";                             \
01173     }
01174 
01175 #define CERT_TYPE(type,name)                    \
01176     if( ns_cert_type & type )                   \
01177         PRINT_ITEM( name );
01178 
01179 static int x509_info_cert_type( char **buf, size_t *size,
01180                                 unsigned char ns_cert_type )
01181 {
01182     int ret;
01183     size_t n = *size;
01184     char *p = *buf;
01185     const char *sep = "";
01186 
01187     CERT_TYPE( NS_CERT_TYPE_SSL_CLIENT,         "SSL Client" );
01188     CERT_TYPE( NS_CERT_TYPE_SSL_SERVER,         "SSL Server" );
01189     CERT_TYPE( NS_CERT_TYPE_EMAIL,              "Email" );
01190     CERT_TYPE( NS_CERT_TYPE_OBJECT_SIGNING,     "Object Signing" );
01191     CERT_TYPE( NS_CERT_TYPE_RESERVED,           "Reserved" );
01192     CERT_TYPE( NS_CERT_TYPE_SSL_CA,             "SSL CA" );
01193     CERT_TYPE( NS_CERT_TYPE_EMAIL_CA,           "Email CA" );
01194     CERT_TYPE( NS_CERT_TYPE_OBJECT_SIGNING_CA,  "Object Signing CA" );
01195 
01196     *size = n;
01197     *buf = p;
01198 
01199     return( 0 );
01200 }
01201 
01202 #define KEY_USAGE(code,name)    \
01203     if( key_usage & code )      \
01204         PRINT_ITEM( name );
01205 
01206 static int x509_info_key_usage( char **buf, size_t *size,
01207                                 unsigned char key_usage )
01208 {
01209     int ret;
01210     size_t n = *size;
01211     char *p = *buf;
01212     const char *sep = "";
01213 
01214     KEY_USAGE( KU_DIGITAL_SIGNATURE,    "Digital Signature" );
01215     KEY_USAGE( KU_NON_REPUDIATION,      "Non Repudiation" );
01216     KEY_USAGE( KU_KEY_ENCIPHERMENT,     "Key Encipherment" );
01217     KEY_USAGE( KU_DATA_ENCIPHERMENT,    "Data Encipherment" );
01218     KEY_USAGE( KU_KEY_AGREEMENT,        "Key Agreement" );
01219     KEY_USAGE( KU_KEY_CERT_SIGN,        "Key Cert Sign" );
01220     KEY_USAGE( KU_CRL_SIGN,             "CRL Sign" );
01221 
01222     *size = n;
01223     *buf = p;
01224 
01225     return( 0 );
01226 }
01227 
01228 static int x509_info_ext_key_usage( char **buf, size_t *size,
01229                                     const x509_sequence *extended_key_usage )
01230 {
01231     int ret;
01232     const char *desc;
01233     size_t n = *size;
01234     char *p = *buf;
01235     const x509_sequence *cur = extended_key_usage;
01236     const char *sep = "";
01237 
01238     while( cur != NULL )
01239     {
01240         if( oid_get_extended_key_usage( &cur->buf, &desc ) != 0 )
01241             desc = "???";
01242 
01243         ret = polarssl_snprintf( p, n, "%s%s", sep, desc );
01244         SAFE_SNPRINTF();
01245 
01246         sep = ", ";
01247 
01248         cur = cur->next;
01249     }
01250 
01251     *size = n;
01252     *buf = p;
01253 
01254     return( 0 );
01255 }
01256 
01257 /*
01258  * Return an informational string about the certificate.
01259  */
01260 #define BEFORE_COLON    18
01261 #define BC              "18"
01262 int x509_crt_info( char *buf, size_t size, const char *prefix,
01263                    const x509_crt *crt )
01264 {
01265     int ret;
01266     size_t n;
01267     char *p;
01268     char key_size_str[BEFORE_COLON];
01269 
01270     p = buf;
01271     n = size;
01272 
01273     ret = polarssl_snprintf( p, n, "%scert. version     : %d\n",
01274                                prefix, crt->version );
01275     SAFE_SNPRINTF();
01276     ret = polarssl_snprintf( p, n, "%sserial number     : ",
01277                                prefix );
01278     SAFE_SNPRINTF();
01279 
01280     ret = x509_serial_gets( p, n, &crt->serial );
01281     SAFE_SNPRINTF();
01282 
01283     ret = polarssl_snprintf( p, n, "\n%sissuer name       : ", prefix );
01284     SAFE_SNPRINTF();
01285     ret = x509_dn_gets( p, n, &crt->issuer  );
01286     SAFE_SNPRINTF();
01287 
01288     ret = polarssl_snprintf( p, n, "\n%ssubject name      : ", prefix );
01289     SAFE_SNPRINTF();
01290     ret = x509_dn_gets( p, n, &crt->subject );
01291     SAFE_SNPRINTF();
01292 
01293     ret = polarssl_snprintf( p, n, "\n%sissued  on        : " \
01294                    "%04d-%02d-%02d %02d:%02d:%02d", prefix,
01295                    crt->valid_from.year, crt->valid_from.mon,
01296                    crt->valid_from.day,  crt->valid_from.hour,
01297                    crt->valid_from.min,  crt->valid_from.sec );
01298     SAFE_SNPRINTF();
01299 
01300     ret = polarssl_snprintf( p, n, "\n%sexpires on        : " \
01301                    "%04d-%02d-%02d %02d:%02d:%02d", prefix,
01302                    crt->valid_to.year, crt->valid_to.mon,
01303                    crt->valid_to.day,  crt->valid_to.hour,
01304                    crt->valid_to.min,  crt->valid_to.sec );
01305     SAFE_SNPRINTF();
01306 
01307     ret = polarssl_snprintf( p, n, "\n%ssigned using      : ", prefix );
01308     SAFE_SNPRINTF();
01309 
01310     ret = x509_sig_alg_gets( p, n, &crt->sig_oid1, crt->sig_pk,
01311                              crt->sig_md, crt->sig_opts );
01312     SAFE_SNPRINTF();
01313 
01314     /* Key size */
01315     if( ( ret = x509_key_size_helper( key_size_str, BEFORE_COLON,
01316                                       pk_get_name( &crt->pk ) ) ) != 0 )
01317     {
01318         return( ret );
01319     }
01320 
01321     ret = polarssl_snprintf( p, n, "\n%s%-" BC "s: %d bits", prefix, key_size_str,
01322                           (int) pk_get_size( &crt->pk ) );
01323     SAFE_SNPRINTF();
01324 
01325     /*
01326      * Optional extensions
01327      */
01328 
01329     if( crt->ext_types & EXT_BASIC_CONSTRAINTS )
01330     {
01331         ret = polarssl_snprintf( p, n, "\n%sbasic constraints : CA=%s", prefix,
01332                         crt->ca_istrue ? "true" : "false" );
01333         SAFE_SNPRINTF();
01334 
01335         if( crt->max_pathlen > 0 )
01336         {
01337             ret = polarssl_snprintf( p, n, ", max_pathlen=%d", crt->max_pathlen - 1 );
01338             SAFE_SNPRINTF();
01339         }
01340     }
01341 
01342     if( crt->ext_types & EXT_SUBJECT_ALT_NAME )
01343     {
01344         ret = polarssl_snprintf( p, n, "\n%ssubject alt name  : ", prefix );
01345         SAFE_SNPRINTF();
01346 
01347         if( ( ret = x509_info_subject_alt_name( &p, &n,
01348                                             &crt->subject_alt_names ) ) != 0 )
01349             return( ret );
01350     }
01351 
01352     if( crt->ext_types & EXT_NS_CERT_TYPE )
01353     {
01354         ret = polarssl_snprintf( p, n, "\n%scert. type        : ", prefix );
01355         SAFE_SNPRINTF();
01356 
01357         if( ( ret = x509_info_cert_type( &p, &n, crt->ns_cert_type ) ) != 0 )
01358             return( ret );
01359     }
01360 
01361     if( crt->ext_types & EXT_KEY_USAGE )
01362     {
01363         ret = polarssl_snprintf( p, n, "\n%skey usage         : ", prefix );
01364         SAFE_SNPRINTF();
01365 
01366         if( ( ret = x509_info_key_usage( &p, &n, crt->key_usage ) ) != 0 )
01367             return( ret );
01368     }
01369 
01370     if( crt->ext_types & EXT_EXTENDED_KEY_USAGE )
01371     {
01372         ret = polarssl_snprintf( p, n, "\n%sext key usage     : ", prefix );
01373         SAFE_SNPRINTF();
01374 
01375         if( ( ret = x509_info_ext_key_usage( &p, &n,
01376                                              &crt->ext_key_usage ) ) != 0 )
01377             return( ret );
01378     }
01379 
01380     ret = polarssl_snprintf( p, n, "\n" );
01381     SAFE_SNPRINTF();
01382 
01383     return( (int) ( size - n ) );
01384 }
01385 
01386 struct x509_crt_verify_string {
01387     int code;
01388     const char *string;
01389 };
01390 
01391 static const struct x509_crt_verify_string x509_crt_verify_strings[] = {
01392     { BADCERT_EXPIRED,       "The certificate validity has expired" },
01393     { BADCERT_REVOKED,       "The certificate has been revoked (is on a CRL)" },
01394     { BADCERT_CN_MISMATCH,   "The certificate Common Name (CN) does not match with the expected CN" },
01395     { BADCERT_NOT_TRUSTED,   "The certificate is not correctly signed by the trusted CA" },
01396     { BADCRL_NOT_TRUSTED,    "The CRL is not correctly signed by the trusted CA" },
01397     { BADCRL_EXPIRED,        "The CRL is expired" },
01398     { BADCERT_MISSING,       "Certificate was missing" },
01399     { BADCERT_SKIP_VERIFY,   "Certificate verification was skipped" },
01400     { BADCERT_OTHER,         "Other reason (can be used by verify callback)" },
01401     { BADCERT_FUTURE,        "The certificate validity starts in the future" },
01402     { BADCRL_FUTURE,         "The CRL is from the future" },
01403     { BADCERT_KEY_USAGE,     "Usage does not match the keyUsage extension" },
01404     { BADCERT_EXT_KEY_USAGE, "Usage does not match the extendedKeyUsage extension" },
01405     { BADCERT_NS_CERT_TYPE,  "Usage does not match the nsCertType extension" },
01406     { 0, NULL }
01407 };
01408 
01409 int x509_crt_verify_info( char *buf, size_t size, const char *prefix,
01410                           int flags )
01411 {
01412     int ret;
01413     const struct x509_crt_verify_string *cur;
01414     char *p = buf;
01415     size_t n = size;
01416 
01417     for( cur = x509_crt_verify_strings; cur->string != NULL ; cur++ )
01418     {
01419         if( ( flags & cur->code ) == 0 )
01420             continue;
01421 
01422         ret = polarssl_snprintf( p, n, "%s%s\n", prefix, cur->string );
01423         SAFE_SNPRINTF();
01424         flags ^= cur->code;
01425     }
01426 
01427     if( flags != 0 )
01428     {
01429         ret = polarssl_snprintf( p, n, "%sUnknown reason "
01430                                        "(this should not happen)\n", prefix );
01431         SAFE_SNPRINTF();
01432     }
01433 
01434     return( (int) ( size - n ) );
01435 }
01436 
01437 #if defined(POLARSSL_X509_CHECK_KEY_USAGE)
01438 int x509_crt_check_key_usage( const x509_crt *crt, int usage )
01439 {
01440     if( ( crt->ext_types & EXT_KEY_USAGE ) != 0 &&
01441         ( crt->key_usage & usage ) != usage )
01442         return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
01443 
01444     return( 0 );
01445 }
01446 #endif
01447 
01448 #if defined(POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE)
01449 int x509_crt_check_extended_key_usage( const x509_crt *crt,
01450                                        const char *usage_oid,
01451                                        size_t usage_len )
01452 {
01453     const x509_sequence *cur;
01454 
01455     /* Extension is not mandatory, absent means no restriction */
01456     if( ( crt->ext_types & EXT_EXTENDED_KEY_USAGE ) == 0 )
01457         return( 0 );
01458 
01459     /*
01460      * Look for the requested usage (or wildcard ANY) in our list
01461      */
01462     for( cur = &crt->ext_key_usage; cur != NULL; cur = cur->next )
01463     {
01464         const x509_buf *cur_oid = &cur->buf;
01465 
01466         if( cur_oid->len == usage_len &&
01467             memcmp( cur_oid->p, usage_oid, usage_len ) == 0 )
01468         {
01469             return( 0 );
01470         }
01471 
01472         if( OID_CMP( OID_ANY_EXTENDED_KEY_USAGE, cur_oid ) )
01473             return( 0 );
01474     }
01475 
01476     return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
01477 }
01478 #endif /* POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE */
01479 
01480 #if defined(POLARSSL_X509_CRL_PARSE_C)
01481 /*
01482  * Return 1 if the certificate is revoked, or 0 otherwise.
01483  */
01484 int x509_crt_revoked( const x509_crt *crt, const x509_crl *crl )
01485 {
01486     const x509_crl_entry *cur = &crl->entry;
01487 
01488     while( cur != NULL && cur->serial.len != 0 )
01489     {
01490         if( crt->serial.len == cur->serial.len &&
01491             memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
01492         {
01493             if( x509_time_expired( &cur->revocation_date ) )
01494                 return( 1 );
01495         }
01496 
01497         cur = cur->next;
01498     }
01499 
01500     return( 0 );
01501 }
01502 
01503 /*
01504  * Check that the given certificate is valid according to the CRL.
01505  */
01506 static int x509_crt_verifycrl( x509_crt *crt, x509_crt *ca,
01507                                x509_crl *crl_list)
01508 {
01509     int flags = 0;
01510     unsigned char hash[POLARSSL_MD_MAX_SIZE];
01511     const md_info_t *md_info;
01512 
01513     if( ca == NULL )
01514         return( flags );
01515 
01516     /*
01517      * TODO: What happens if no CRL is present?
01518      * Suggestion: Revocation state should be unknown if no CRL is present.
01519      * For backwards compatibility this is not yet implemented.
01520      */
01521 
01522     while( crl_list != NULL )
01523     {
01524         if( crl_list->version == 0 ||
01525             crl_list->issuer_raw.len != ca->subject_raw.len ||
01526             memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
01527                     crl_list->issuer_raw.len ) != 0 )
01528         {
01529             crl_list = crl_list->next;
01530             continue;
01531         }
01532 
01533         /*
01534          * Check if the CA is configured to sign CRLs
01535          */
01536 #if defined(POLARSSL_X509_CHECK_KEY_USAGE)
01537         if( x509_crt_check_key_usage( ca, KU_CRL_SIGN ) != 0 )
01538         {
01539             flags |= BADCRL_NOT_TRUSTED;
01540             break;
01541         }
01542 #endif
01543 
01544         /*
01545          * Check if CRL is correctly signed by the trusted CA
01546          */
01547         md_info = md_info_from_type( crl_list->sig_md );
01548         if( md_info == NULL )
01549         {
01550             /*
01551              * Cannot check 'unknown' hash
01552              */
01553             flags |= BADCRL_NOT_TRUSTED;
01554             break;
01555         }
01556 
01557         md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash );
01558 
01559         if( pk_verify_ext( crl_list->sig_pk, crl_list->sig_opts, &ca->pk,
01560                            crl_list->sig_md, hash, md_info->size,
01561                            crl_list->sig.p, crl_list->sig.len ) != 0 )
01562         {
01563             flags |= BADCRL_NOT_TRUSTED;
01564             break;
01565         }
01566 
01567         /*
01568          * Check for validity of CRL (Do not drop out)
01569          */
01570         if( x509_time_expired( &crl_list->next_update ) )
01571             flags |= BADCRL_EXPIRED;
01572 
01573         if( x509_time_future( &crl_list->this_update ) )
01574             flags |= BADCRL_FUTURE;
01575 
01576         /*
01577          * Check if certificate is revoked
01578          */
01579         if( x509_crt_revoked( crt, crl_list ) )
01580         {
01581             flags |= BADCERT_REVOKED;
01582             break;
01583         }
01584 
01585         crl_list = crl_list->next;
01586     }
01587     return( flags );
01588 }
01589 #endif /* POLARSSL_X509_CRL_PARSE_C */
01590 
01591 /*
01592  * Like memcmp, but case-insensitive and always returns -1 if different
01593  */
01594 static int x509_memcasecmp( const void *s1, const void *s2, size_t len )
01595 {
01596     size_t i;
01597     unsigned char diff;
01598     const unsigned char *n1 = s1, *n2 = s2;
01599 
01600     for( i = 0; i < len; i++ )
01601     {
01602         diff = n1[i] ^ n2[i];
01603 
01604         if( diff == 0 )
01605             continue;
01606 
01607         if( diff == 32 &&
01608             ( ( n1[i] >= 'a' && n1[i] <= 'z' ) ||
01609               ( n1[i] >= 'A' && n1[i] <= 'Z' ) ) )
01610         {
01611             continue;
01612         }
01613 
01614         return( -1 );
01615     }
01616 
01617     return( 0 );
01618 }
01619 
01620 /*
01621  * Return 1 if match, 0 if not
01622  * TODO: inverted return value!
01623  */
01624 static int x509_wildcard_verify( const char *cn, x509_buf *name )
01625 {
01626     size_t i;
01627     size_t cn_idx = 0, cn_len = strlen( cn );
01628 
01629     if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' )
01630         return( 0 );
01631 
01632     for( i = 0; i < cn_len; ++i )
01633     {
01634         if( cn[i] == '.' )
01635         {
01636             cn_idx = i;
01637             break;
01638         }
01639     }
01640 
01641     if( cn_idx == 0 )
01642         return( 0 );
01643 
01644     if( cn_len - cn_idx == name->len - 1 &&
01645         x509_memcasecmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
01646     {
01647         return( 1 );
01648     }
01649 
01650     return( 0 );
01651 }
01652 
01653 /*
01654  * Compare two X.509 strings, case-insensitive, and allowing for some encoding
01655  * variations (but not all).
01656  *
01657  * Return 0 if equal, -1 otherwise.
01658  */
01659 static int x509_string_cmp( const x509_buf *a, const x509_buf *b )
01660 {
01661     if( a->tag == b->tag &&
01662         a->len == b->len &&
01663         memcmp( a->p, b->p, b->len ) == 0 )
01664     {
01665         return( 0 );
01666     }
01667 
01668     if( ( a->tag == ASN1_UTF8_STRING || a->tag == ASN1_PRINTABLE_STRING ) &&
01669         ( b->tag == ASN1_UTF8_STRING || b->tag == ASN1_PRINTABLE_STRING ) &&
01670         a->len == b->len &&
01671         x509_memcasecmp( a->p, b->p, b->len ) == 0 )
01672     {
01673         return( 0 );
01674     }
01675 
01676     return( -1 );
01677 }
01678 
01679 /*
01680  * Compare two X.509 Names (aka rdnSequence).
01681  *
01682  * See RFC 5280 section 7.1, though we don't implement the whole algorithm:
01683  * we sometimes return unequal when the full algorithm would return equal,
01684  * but never the other way. (In particular, we don't do Unicode normalisation
01685  * or space folding.)
01686  *
01687  * Return 0 if equal, -1 otherwise.
01688  */
01689 static int x509_name_cmp( const x509_name *a, const x509_name *b )
01690 {
01691     /* Avoid recursion, it might not be optimised by the compiler */
01692     while( a != NULL || b != NULL )
01693     {
01694         if( a == NULL || b == NULL )
01695             return( -1 );
01696 
01697         /* type */
01698         if( a->oid.tag != b->oid.tag ||
01699             a->oid.len != b->oid.len ||
01700             memcmp( a->oid.p, b->oid.p, b->oid.len ) != 0 )
01701         {
01702             return( -1 );
01703         }
01704 
01705         /* value */
01706         if( x509_string_cmp( &a->val, &b->val ) != 0 )
01707             return( -1 );
01708 
01709         /* structure of the list of sets */
01710         if( a->next_merged != b->next_merged )
01711             return( -1 );
01712 
01713         a = a->next;
01714         b = b->next;
01715     }
01716 
01717     /* a == NULL == b */
01718     return( 0 );
01719 }
01720 
01721 /*
01722  * Check if 'parent' is a suitable parent (signing CA) for 'child'.
01723  * Return 0 if yes, -1 if not.
01724  *
01725  * top means parent is a locally-trusted certificate
01726  * bottom means child is the end entity cert
01727  */
01728 static int x509_crt_check_parent( const x509_crt *child,
01729                                   const x509_crt *parent,
01730                                   int top, int bottom )
01731 {
01732     int need_ca_bit;
01733 
01734     /* Parent must be the issuer */
01735     if( x509_name_cmp( &child->issuer, &parent->subject ) != 0 )
01736         return( -1 );
01737 
01738     /* Parent must have the basicConstraints CA bit set as a general rule */
01739     need_ca_bit = 1;
01740 
01741     /* Exception: v1/v2 certificates that are locally trusted. */
01742     if( top && parent->version < 3 )
01743         need_ca_bit = 0;
01744 
01745     /* Exception: self-signed end-entity certs that are locally trusted. */
01746     if( top && bottom &&
01747         child->raw.len == parent->raw.len &&
01748         memcmp( child->raw.p, parent->raw.p, child->raw.len ) == 0 )
01749     {
01750         need_ca_bit = 0;
01751     }
01752 
01753     if( need_ca_bit && ! parent->ca_istrue )
01754         return( -1 );
01755 
01756 #if defined(POLARSSL_X509_CHECK_KEY_USAGE)
01757     if( need_ca_bit &&
01758         x509_crt_check_key_usage( parent, KU_KEY_CERT_SIGN ) != 0 )
01759     {
01760         return( -1 );
01761     }
01762 #endif
01763 
01764     return( 0 );
01765 }
01766 
01767 static int x509_crt_verify_top(
01768                 x509_crt *child, x509_crt *trust_ca,
01769                 x509_crl *ca_crl, int path_cnt, int *flags,
01770                 int (*f_vrfy)(void *, x509_crt *, int, int *),
01771                 void *p_vrfy )
01772 {
01773     int ret;
01774     int ca_flags = 0, check_path_cnt;
01775     unsigned char hash[POLARSSL_MD_MAX_SIZE];
01776     const md_info_t *md_info;
01777 
01778     if( x509_time_expired( &child->valid_to ) )
01779         *flags |= BADCERT_EXPIRED;
01780 
01781     if( x509_time_future( &child->valid_from ) )
01782         *flags |= BADCERT_FUTURE;
01783 
01784     /*
01785      * Child is the top of the chain. Check against the trust_ca list.
01786      */
01787     *flags |= BADCERT_NOT_TRUSTED;
01788 
01789     md_info = md_info_from_type( child->sig_md );
01790     if( md_info == NULL )
01791     {
01792         /*
01793          * Cannot check 'unknown', no need to try any CA
01794          */
01795         trust_ca = NULL;
01796     }
01797     else
01798         md( md_info, child->tbs.p, child->tbs.len, hash );
01799 
01800     for( /* trust_ca */ ; trust_ca != NULL; trust_ca = trust_ca->next )
01801     {
01802         if( x509_crt_check_parent( child, trust_ca, 1, path_cnt == 0 ) != 0 )
01803             continue;
01804 
01805         check_path_cnt = path_cnt + 1;
01806 
01807         /*
01808          * Reduce check_path_cnt to check against if top of the chain is
01809          * the same as the trusted CA
01810          */
01811         if( child->subject_raw.len == trust_ca->subject_raw.len &&
01812             memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
01813                             child->issuer_raw.len ) == 0 )
01814         {
01815             check_path_cnt--;
01816         }
01817 
01818         if( trust_ca->max_pathlen > 0 &&
01819             trust_ca->max_pathlen < check_path_cnt )
01820         {
01821             continue;
01822         }
01823 
01824         if( pk_verify_ext( child->sig_pk, child->sig_opts, &trust_ca->pk,
01825                            child->sig_md, hash, md_info->size,
01826                            child->sig.p, child->sig.len ) != 0 )
01827         {
01828             continue;
01829         }
01830 
01831         /*
01832          * Top of chain is signed by a trusted CA
01833          */
01834         *flags &= ~BADCERT_NOT_TRUSTED;
01835         break;
01836     }
01837 
01838     /*
01839      * If top of chain is not the same as the trusted CA send a verify request
01840      * to the callback for any issues with validity and CRL presence for the
01841      * trusted CA certificate.
01842      */
01843     if( trust_ca != NULL &&
01844         ( child->subject_raw.len != trust_ca->subject_raw.len ||
01845           memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
01846                             child->issuer_raw.len ) != 0 ) )
01847     {
01848 #if defined(POLARSSL_X509_CRL_PARSE_C)
01849         /* Check trusted CA's CRL for the chain's top crt */
01850         *flags |= x509_crt_verifycrl( child, trust_ca, ca_crl );
01851 #else
01852         ((void) ca_crl);
01853 #endif
01854 
01855         if( x509_time_expired( &trust_ca->valid_to ) )
01856             ca_flags |= BADCERT_EXPIRED;
01857 
01858         if( x509_time_future( &trust_ca->valid_from ) )
01859             ca_flags |= BADCERT_FUTURE;
01860 
01861         if( NULL != f_vrfy )
01862         {
01863             if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1,
01864                                 &ca_flags ) ) != 0 )
01865             {
01866                 return( ret );
01867             }
01868         }
01869     }
01870 
01871     /* Call callback on top cert */
01872     if( NULL != f_vrfy )
01873     {
01874         if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
01875             return( ret );
01876     }
01877 
01878     *flags |= ca_flags;
01879 
01880     return( 0 );
01881 }
01882 
01883 static int x509_crt_verify_child(
01884                 x509_crt *child, x509_crt *parent, x509_crt *trust_ca,
01885                 x509_crl *ca_crl, int path_cnt, int *flags,
01886                 int (*f_vrfy)(void *, x509_crt *, int, int *),
01887                 void *p_vrfy )
01888 {
01889     int ret;
01890     int parent_flags = 0;
01891     unsigned char hash[POLARSSL_MD_MAX_SIZE];
01892     x509_crt *grandparent;
01893     const md_info_t *md_info;
01894 
01895     /* path_cnt is 0 for the first intermediate CA */
01896     if( 1 + path_cnt > POLARSSL_X509_MAX_INTERMEDIATE_CA )
01897     {
01898         *flags |= BADCERT_NOT_TRUSTED;
01899         return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
01900     }
01901 
01902     if( x509_time_expired( &child->valid_to ) )
01903         *flags |= BADCERT_EXPIRED;
01904 
01905     if( x509_time_future( &child->valid_from ) )
01906         *flags |= BADCERT_FUTURE;
01907 
01908     md_info = md_info_from_type( child->sig_md );
01909     if( md_info == NULL )
01910     {
01911         /*
01912          * Cannot check 'unknown' hash
01913          */
01914         *flags |= BADCERT_NOT_TRUSTED;
01915     }
01916     else
01917     {
01918         md( md_info, child->tbs.p, child->tbs.len, hash );
01919 
01920         if( pk_verify_ext( child->sig_pk, child->sig_opts, &parent->pk,
01921                            child->sig_md, hash, md_info->size,
01922                            child->sig.p, child->sig.len ) != 0 )
01923         {
01924             *flags |= BADCERT_NOT_TRUSTED;
01925         }
01926     }
01927 
01928 #if defined(POLARSSL_X509_CRL_PARSE_C)
01929     /* Check trusted CA's CRL for the given crt */
01930     *flags |= x509_crt_verifycrl(child, parent, ca_crl);
01931 #endif
01932 
01933     /* Look for a grandparent upwards the chain */
01934     for( grandparent = parent->next;
01935          grandparent != NULL;
01936          grandparent = grandparent->next )
01937     {
01938         if( x509_crt_check_parent( parent, grandparent,
01939                                    0, path_cnt == 0 ) == 0 )
01940             break;
01941     }
01942 
01943     /* Is our parent part of the chain or at the top? */
01944     if( grandparent != NULL )
01945     {
01946         ret = x509_crt_verify_child( parent, grandparent, trust_ca, ca_crl,
01947                                 path_cnt + 1, &parent_flags, f_vrfy, p_vrfy );
01948         if( ret != 0 )
01949             return( ret );
01950     }
01951     else
01952     {
01953         ret = x509_crt_verify_top( parent, trust_ca, ca_crl,
01954                                 path_cnt + 1, &parent_flags, f_vrfy, p_vrfy );
01955         if( ret != 0 )
01956             return( ret );
01957     }
01958 
01959     /* child is verified to be a child of the parent, call verify callback */
01960     if( NULL != f_vrfy )
01961         if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
01962             return( ret );
01963 
01964     *flags |= parent_flags;
01965 
01966     return( 0 );
01967 }
01968 
01969 /*
01970  * Verify the certificate validity
01971  */
01972 int x509_crt_verify( x509_crt *crt,
01973                      x509_crt *trust_ca,
01974                      x509_crl *ca_crl,
01975                      const char *cn, int *flags,
01976                      int (*f_vrfy)(void *, x509_crt *, int, int *),
01977                      void *p_vrfy )
01978 {
01979     size_t cn_len;
01980     int ret;
01981     int pathlen = 0;
01982     x509_crt *parent;
01983     x509_name *name;
01984     x509_sequence *cur = NULL;
01985 
01986     *flags = 0;
01987 
01988     if( cn != NULL )
01989     {
01990         name = &crt->subject;
01991         cn_len = strlen( cn );
01992 
01993         if( crt->ext_types & EXT_SUBJECT_ALT_NAME )
01994         {
01995             cur = &crt->subject_alt_names;
01996 
01997             while( cur != NULL )
01998             {
01999                 if( cur->buf.len == cn_len &&
02000                     x509_memcasecmp( cn, cur->buf.p, cn_len ) == 0 )
02001                     break;
02002 
02003                 if( cur->buf.len > 2 &&
02004                     memcmp( cur->buf.p, "*.", 2 ) == 0 &&
02005                             x509_wildcard_verify( cn, &cur->buf ) )
02006                     break;
02007 
02008                 cur = cur->next;
02009             }
02010 
02011             if( cur == NULL )
02012                 *flags |= BADCERT_CN_MISMATCH;
02013         }
02014         else
02015         {
02016             while( name != NULL )
02017             {
02018                 if( OID_CMP( OID_AT_CN, &name->oid ) )
02019                 {
02020                     if( name->val.len == cn_len &&
02021                         x509_memcasecmp( name->val.p, cn, cn_len ) == 0 )
02022                         break;
02023 
02024                     if( name->val.len > 2 &&
02025                         memcmp( name->val.p, "*.", 2 ) == 0 &&
02026                                 x509_wildcard_verify( cn, &name->val ) )
02027                         break;
02028                 }
02029 
02030                 name = name->next;
02031             }
02032 
02033             if( name == NULL )
02034                 *flags |= BADCERT_CN_MISMATCH;
02035         }
02036     }
02037 
02038     /* Look for a parent upwards the chain */
02039     for( parent = crt->next; parent != NULL; parent = parent->next )
02040     {
02041         if( x509_crt_check_parent( crt, parent, 0, pathlen == 0 ) == 0 )
02042             break;
02043     }
02044 
02045     /* Are we part of the chain or at the top? */
02046     if( parent != NULL )
02047     {
02048         ret = x509_crt_verify_child( crt, parent, trust_ca, ca_crl,
02049                                      pathlen, flags, f_vrfy, p_vrfy );
02050         if( ret != 0 )
02051             return( ret );
02052     }
02053     else
02054     {
02055         ret = x509_crt_verify_top( crt, trust_ca, ca_crl,
02056                                    pathlen, flags, f_vrfy, p_vrfy );
02057         if( ret != 0 )
02058             return( ret );
02059     }
02060 
02061     if( *flags != 0 )
02062         return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
02063 
02064     return( 0 );
02065 }
02066 
02067 /*
02068  * Initialize a certificate chain
02069  */
02070 void x509_crt_init( x509_crt *crt )
02071 {
02072     memset( crt, 0, sizeof(x509_crt) );
02073 }
02074 
02075 /*
02076  * Unallocate all certificate data
02077  */
02078 void x509_crt_free( x509_crt *crt )
02079 {
02080     x509_crt *cert_cur = crt;
02081     x509_crt *cert_prv;
02082     x509_name *name_cur;
02083     x509_name *name_prv;
02084     x509_sequence *seq_cur;
02085     x509_sequence *seq_prv;
02086 
02087     if( crt == NULL )
02088         return;
02089 
02090     do
02091     {
02092         pk_free( &cert_cur->pk );
02093 
02094 #if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT)
02095         polarssl_free( cert_cur->sig_opts );
02096 #endif
02097 
02098         name_cur = cert_cur->issuer.next;
02099         while( name_cur != NULL )
02100         {
02101             name_prv = name_cur;
02102             name_cur = name_cur->next;
02103             polarssl_zeroize( name_prv, sizeof( x509_name ) );
02104             polarssl_free( name_prv );
02105         }
02106 
02107         name_cur = cert_cur->subject.next;
02108         while( name_cur != NULL )
02109         {
02110             name_prv = name_cur;
02111             name_cur = name_cur->next;
02112             polarssl_zeroize( name_prv, sizeof( x509_name ) );
02113             polarssl_free( name_prv );
02114         }
02115 
02116         seq_cur = cert_cur->ext_key_usage.next;
02117         while( seq_cur != NULL )
02118         {
02119             seq_prv = seq_cur;
02120             seq_cur = seq_cur->next;
02121             polarssl_zeroize( seq_prv, sizeof( x509_sequence ) );
02122             polarssl_free( seq_prv );
02123         }
02124 
02125         seq_cur = cert_cur->subject_alt_names.next;
02126         while( seq_cur != NULL )
02127         {
02128             seq_prv = seq_cur;
02129             seq_cur = seq_cur->next;
02130             polarssl_zeroize( seq_prv, sizeof( x509_sequence ) );
02131             polarssl_free( seq_prv );
02132         }
02133 
02134         if( cert_cur->raw.p != NULL )
02135         {
02136             polarssl_zeroize( cert_cur->raw.p, cert_cur->raw.len );
02137             polarssl_free( cert_cur->raw.p );
02138         }
02139 
02140         cert_cur = cert_cur->next;
02141     }
02142     while( cert_cur != NULL );
02143 
02144     cert_cur = crt;
02145     do
02146     {
02147         cert_prv = cert_cur;
02148         cert_cur = cert_cur->next;
02149 
02150         polarssl_zeroize( cert_prv, sizeof( x509_crt ) );
02151         if( cert_prv != crt )
02152             polarssl_free( cert_prv );
02153     }
02154     while( cert_cur != NULL );
02155 }
02156 
02157 #endif /* POLARSSL_X509_CRT_PARSE_C */
02158