Example program to test AES-GCM functionality. Used for a workshop

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers x509_crt.c Source File

x509_crt.c

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