PolarSSL v1.1.4
x509parse.c
Go to the documentation of this file.
00001 /*
00002  *  X.509 certificate and private key decoding
00003  *
00004  *  Copyright (C) 2006-2011, 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 certificat format for PKI.
00027  *
00028  *  http://www.ietf.org/rfc/rfc2459.txt
00029  *  http://www.ietf.org/rfc/rfc3279.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 #include "polarssl/config.h"
00038 
00039 #if defined(POLARSSL_X509_PARSE_C)
00040 
00041 #include "polarssl/x509.h"
00042 #include "polarssl/asn1.h"
00043 #include "polarssl/pem.h"
00044 #include "polarssl/des.h"
00045 #include "polarssl/md2.h"
00046 #include "polarssl/md4.h"
00047 #include "polarssl/md5.h"
00048 #include "polarssl/sha1.h"
00049 #include "polarssl/sha2.h"
00050 #include "polarssl/sha4.h"
00051 #include "polarssl/dhm.h"
00052 
00053 #include <string.h>
00054 #include <stdlib.h>
00055 #if defined(_WIN32)
00056 #include <windows.h>
00057 #else
00058 #include <time.h>
00059 #endif
00060 
00061 #if defined(POLARSSL_FS_IO)
00062 #include <stdio.h>
00063 #endif
00064 
00065 /*
00066  *  Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
00067  */
00068 static int x509_get_version( unsigned char **p,
00069                              const unsigned char *end,
00070                              int *ver )
00071 {
00072     int ret;
00073     size_t len;
00074 
00075     if( ( ret = asn1_get_tag( p, end, &len,
00076             ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) != 0 )
00077     {
00078         if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
00079         {
00080             *ver = 0;
00081             return( 0 );
00082         }
00083 
00084         return( ret );
00085     }
00086 
00087     end = *p + len;
00088 
00089     if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
00090         return( POLARSSL_ERR_X509_CERT_INVALID_VERSION + ret );
00091 
00092     if( *p != end )
00093         return( POLARSSL_ERR_X509_CERT_INVALID_VERSION +
00094                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00095 
00096     return( 0 );
00097 }
00098 
00099 /*
00100  *  Version  ::=  INTEGER  {  v1(0), v2(1)  }
00101  */
00102 static int x509_crl_get_version( unsigned char **p,
00103                              const unsigned char *end,
00104                              int *ver )
00105 {
00106     int ret;
00107 
00108     if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
00109     {
00110         if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
00111         {
00112             *ver = 0;
00113             return( 0 );
00114         }
00115 
00116         return( POLARSSL_ERR_X509_CERT_INVALID_VERSION + ret );
00117     }
00118 
00119     return( 0 );
00120 }
00121 
00122 /*
00123  *  CertificateSerialNumber  ::=  INTEGER
00124  */
00125 static int x509_get_serial( unsigned char **p,
00126                             const unsigned char *end,
00127                             x509_buf *serial )
00128 {
00129     int ret;
00130 
00131     if( ( end - *p ) < 1 )
00132         return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL +
00133                 POLARSSL_ERR_ASN1_OUT_OF_DATA );
00134 
00135     if( **p != ( ASN1_CONTEXT_SPECIFIC | ASN1_PRIMITIVE | 2 ) &&
00136         **p !=   ASN1_INTEGER )
00137         return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL +
00138                 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
00139 
00140     serial->tag = *(*p)++;
00141 
00142     if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 )
00143         return( POLARSSL_ERR_X509_CERT_INVALID_SERIAL + ret );
00144 
00145     serial->p = *p;
00146     *p += serial->len;
00147 
00148     return( 0 );
00149 }
00150 
00151 /*
00152  *  AlgorithmIdentifier  ::=  SEQUENCE  {
00153  *       algorithm               OBJECT IDENTIFIER,
00154  *       parameters              ANY DEFINED BY algorithm OPTIONAL  }
00155  */
00156 static int x509_get_alg( unsigned char **p,
00157                          const unsigned char *end,
00158                          x509_buf *alg )
00159 {
00160     int ret;
00161     size_t len;
00162 
00163     if( ( ret = asn1_get_tag( p, end, &len,
00164             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00165         return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
00166 
00167     end = *p + len;
00168     alg->tag = **p;
00169 
00170     if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 0 )
00171         return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
00172 
00173     alg->p = *p;
00174     *p += alg->len;
00175 
00176     if( *p == end )
00177         return( 0 );
00178 
00179     /*
00180      * assume the algorithm parameters must be NULL
00181      */
00182     if( ( ret = asn1_get_tag( p, end, &len, ASN1_NULL ) ) != 0 )
00183         return( POLARSSL_ERR_X509_CERT_INVALID_ALG + ret );
00184 
00185     if( *p != end )
00186         return( POLARSSL_ERR_X509_CERT_INVALID_ALG +
00187                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00188 
00189     return( 0 );
00190 }
00191 
00192 /*
00193  *  AttributeTypeAndValue ::= SEQUENCE {
00194  *    type     AttributeType,
00195  *    value    AttributeValue }
00196  *
00197  *  AttributeType ::= OBJECT IDENTIFIER
00198  *
00199  *  AttributeValue ::= ANY DEFINED BY AttributeType
00200  */
00201 static int x509_get_attr_type_value( unsigned char **p,
00202                                      const unsigned char *end,
00203                                      x509_name *cur )
00204 {
00205     int ret;
00206     size_t len;
00207     x509_buf *oid;
00208     x509_buf *val;
00209 
00210     if( ( ret = asn1_get_tag( p, end, &len,
00211             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00212         return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
00213 
00214     oid = &cur->oid;
00215     oid->tag = **p;
00216 
00217     if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 )
00218         return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
00219 
00220     oid->p = *p;
00221     *p += oid->len;
00222 
00223     if( ( end - *p ) < 1 )
00224         return( POLARSSL_ERR_X509_CERT_INVALID_NAME +
00225                 POLARSSL_ERR_ASN1_OUT_OF_DATA );
00226 
00227     if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING      &&
00228         **p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING &&
00229         **p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING )
00230         return( POLARSSL_ERR_X509_CERT_INVALID_NAME +
00231                 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
00232 
00233     val = &cur->val;
00234     val->tag = *(*p)++;
00235 
00236     if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
00237         return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
00238 
00239     val->p = *p;
00240     *p += val->len;
00241 
00242     cur->next = NULL;
00243 
00244     return( 0 );
00245 }
00246 
00247 /*
00248  *  RelativeDistinguishedName ::=
00249  *    SET OF AttributeTypeAndValue
00250  *
00251  *  AttributeTypeAndValue ::= SEQUENCE {
00252  *    type     AttributeType,
00253  *    value    AttributeValue }
00254  *
00255  *  AttributeType ::= OBJECT IDENTIFIER
00256  *
00257  *  AttributeValue ::= ANY DEFINED BY AttributeType
00258  */
00259 static int x509_get_name( unsigned char **p,
00260                           const unsigned char *end,
00261                           x509_name *cur )
00262 {
00263     int ret;
00264     size_t len;
00265     const unsigned char *end2;
00266     x509_name *use; 
00267     
00268     if( ( ret = asn1_get_tag( p, end, &len,
00269             ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
00270         return( POLARSSL_ERR_X509_CERT_INVALID_NAME + ret );
00271 
00272     end2 = end;
00273     end  = *p + len;
00274     use = cur;
00275 
00276     do
00277     {
00278         if( ( ret = x509_get_attr_type_value( p, end, use ) ) != 0 )
00279             return( ret );
00280         
00281         if( *p != end )
00282         {
00283             use->next = (x509_name *) malloc(
00284                     sizeof( x509_name ) );
00285 
00286             if( use->next == NULL )
00287                 return( POLARSSL_ERR_X509_MALLOC_FAILED );
00288             
00289             memset( use->next, 0, sizeof( x509_name ) );
00290 
00291             use = use->next;
00292         }
00293     }
00294     while( *p != end );
00295 
00296     /*
00297      * recurse until end of SEQUENCE is reached
00298      */
00299     if( *p == end2 )
00300         return( 0 );
00301 
00302     cur->next = (x509_name *) malloc(
00303          sizeof( x509_name ) );
00304 
00305     if( cur->next == NULL )
00306         return( POLARSSL_ERR_X509_MALLOC_FAILED );
00307 
00308     memset( cur->next, 0, sizeof( x509_name ) );
00309 
00310     return( x509_get_name( p, end2, cur->next ) );
00311 }
00312 
00313 /*
00314  *  Time ::= CHOICE {
00315  *       utcTime        UTCTime,
00316  *       generalTime    GeneralizedTime }
00317  */
00318 static int x509_get_time( unsigned char **p,
00319                           const unsigned char *end,
00320                           x509_time *time )
00321 {
00322     int ret;
00323     size_t len;
00324     char date[64];
00325     unsigned char tag;
00326 
00327     if( ( end - *p ) < 1 )
00328         return( POLARSSL_ERR_X509_CERT_INVALID_DATE +
00329                 POLARSSL_ERR_ASN1_OUT_OF_DATA );
00330 
00331     tag = **p;
00332 
00333     if ( tag == ASN1_UTC_TIME )
00334     {
00335         (*p)++;
00336         ret = asn1_get_len( p, end, &len );
00337         
00338         if( ret != 0 )
00339             return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
00340 
00341         memset( date,  0, sizeof( date ) );
00342         memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
00343                 len : sizeof( date ) - 1 );
00344 
00345         if( sscanf( date, "%2d%2d%2d%2d%2d%2d",
00346                     &time->year, &time->mon, &time->day,
00347                     &time->hour, &time->min, &time->sec ) < 5 )
00348             return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
00349 
00350         time->year +=  100 * ( time->year < 50 );
00351         time->year += 1900;
00352 
00353         *p += len;
00354 
00355         return( 0 );
00356     }
00357     else if ( tag == ASN1_GENERALIZED_TIME )
00358     {
00359         (*p)++;
00360         ret = asn1_get_len( p, end, &len );
00361         
00362         if( ret != 0 )
00363             return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
00364 
00365         memset( date,  0, sizeof( date ) );
00366         memcpy( date, *p, ( len < sizeof( date ) - 1 ) ?
00367                 len : sizeof( date ) - 1 );
00368 
00369         if( sscanf( date, "%4d%2d%2d%2d%2d%2d",
00370                     &time->year, &time->mon, &time->day,
00371                     &time->hour, &time->min, &time->sec ) < 5 )
00372             return( POLARSSL_ERR_X509_CERT_INVALID_DATE );
00373 
00374         *p += len;
00375 
00376         return( 0 );
00377     }
00378     else
00379         return( POLARSSL_ERR_X509_CERT_INVALID_DATE + POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
00380 }
00381 
00382 
00383 /*
00384  *  Validity ::= SEQUENCE {
00385  *       notBefore      Time,
00386  *       notAfter       Time }
00387  */
00388 static int x509_get_dates( unsigned char **p,
00389                            const unsigned char *end,
00390                            x509_time *from,
00391                            x509_time *to )
00392 {
00393     int ret;
00394     size_t len;
00395 
00396     if( ( ret = asn1_get_tag( p, end, &len,
00397             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00398         return( POLARSSL_ERR_X509_CERT_INVALID_DATE + ret );
00399 
00400     end = *p + len;
00401 
00402     if( ( ret = x509_get_time( p, end, from ) ) != 0 )
00403         return( ret );
00404 
00405     if( ( ret = x509_get_time( p, end, to ) ) != 0 )
00406         return( ret );
00407 
00408     if( *p != end )
00409         return( POLARSSL_ERR_X509_CERT_INVALID_DATE +
00410                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00411 
00412     return( 0 );
00413 }
00414 
00415 /*
00416  *  SubjectPublicKeyInfo  ::=  SEQUENCE  {
00417  *       algorithm            AlgorithmIdentifier,
00418  *       subjectPublicKey     BIT STRING }
00419  */
00420 static int x509_get_pubkey( unsigned char **p,
00421                             const unsigned char *end,
00422                             x509_buf *pk_alg_oid,
00423                             mpi *N, mpi *E )
00424 {
00425     int ret, can_handle;
00426     size_t len;
00427     unsigned char *end2;
00428 
00429     if( ( ret = x509_get_alg( p, end, pk_alg_oid ) ) != 0 )
00430         return( ret );
00431 
00432     /*
00433      * only RSA public keys handled at this time
00434      */
00435     can_handle = 0;
00436 
00437     if( pk_alg_oid->len == 9 &&
00438         memcmp( pk_alg_oid->p, OID_PKCS1_RSA, 9 ) == 0 )
00439         can_handle = 1;
00440 
00441     if( pk_alg_oid->len == 9 &&
00442         memcmp( pk_alg_oid->p, OID_PKCS1, 8 ) == 0 )
00443     {
00444         if( pk_alg_oid->p[8] >= 2 && pk_alg_oid->p[8] <= 5 )
00445             can_handle = 1;
00446 
00447         if ( pk_alg_oid->p[8] >= 11 && pk_alg_oid->p[8] <= 14 )
00448             can_handle = 1;
00449     }
00450 
00451     if( pk_alg_oid->len == 5 &&
00452         memcmp( pk_alg_oid->p, OID_RSA_SHA_OBS, 5 ) == 0 )
00453         can_handle = 1;
00454 
00455     if( can_handle == 0 )
00456         return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
00457 
00458     if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
00459         return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
00460 
00461     if( ( end - *p ) < 1 )
00462         return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
00463                 POLARSSL_ERR_ASN1_OUT_OF_DATA );
00464 
00465     end2 = *p + len;
00466 
00467     if( *(*p)++ != 0 )
00468         return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY );
00469 
00470     /*
00471      *  RSAPublicKey ::= SEQUENCE {
00472      *      modulus           INTEGER,  -- n
00473      *      publicExponent    INTEGER   -- e
00474      *  }
00475      */
00476     if( ( ret = asn1_get_tag( p, end2, &len,
00477             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00478         return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
00479 
00480     if( *p + len != end2 )
00481         return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
00482                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00483 
00484     if( ( ret = asn1_get_mpi( p, end2, N ) ) != 0 ||
00485         ( ret = asn1_get_mpi( p, end2, E ) ) != 0 )
00486         return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY + ret );
00487 
00488     if( *p != end )
00489         return( POLARSSL_ERR_X509_CERT_INVALID_PUBKEY +
00490                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00491 
00492     return( 0 );
00493 }
00494 
00495 static int x509_get_sig( unsigned char **p,
00496                          const unsigned char *end,
00497                          x509_buf *sig )
00498 {
00499     int ret;
00500     size_t len;
00501 
00502     sig->tag = **p;
00503 
00504     if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
00505         return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE + ret );
00506 
00507 
00508     if( --len < 1 || *(*p)++ != 0 )
00509         return( POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE );
00510 
00511     sig->len = len;
00512     sig->p = *p;
00513 
00514     *p += len;
00515 
00516     return( 0 );
00517 }
00518 
00519 /*
00520  * X.509 v2/v3 unique identifier (not parsed)
00521  */
00522 static int x509_get_uid( unsigned char **p,
00523                          const unsigned char *end,
00524                          x509_buf *uid, int n )
00525 {
00526     int ret;
00527 
00528     if( *p == end )
00529         return( 0 );
00530 
00531     uid->tag = **p;
00532 
00533     if( ( ret = asn1_get_tag( p, end, &uid->len,
00534             ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 )
00535     {
00536         if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
00537             return( 0 );
00538 
00539         return( ret );
00540     }
00541 
00542     uid->p = *p;
00543     *p += uid->len;
00544 
00545     return( 0 );
00546 }
00547 
00548 /*
00549  * X.509 Extensions (No parsing of extensions, pointer should
00550  * be either manually updated or extensions should be parsed!
00551  */
00552 static int x509_get_ext( unsigned char **p,
00553                          const unsigned char *end,
00554                          x509_buf *ext, int tag )
00555 {
00556     int ret;
00557     size_t len;
00558 
00559     if( *p == end )
00560         return( 0 );
00561 
00562     ext->tag = **p;
00563 
00564     if( ( ret = asn1_get_tag( p, end, &ext->len,
00565             ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | tag ) ) != 0 )
00566         return( ret );
00567 
00568     ext->p = *p;
00569     end = *p + ext->len;
00570 
00571     /*
00572      * Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
00573      *
00574      * Extension  ::=  SEQUENCE  {
00575      *      extnID      OBJECT IDENTIFIER,
00576      *      critical    BOOLEAN DEFAULT FALSE,
00577      *      extnValue   OCTET STRING  }
00578      */
00579     if( ( ret = asn1_get_tag( p, end, &len,
00580             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00581         return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
00582 
00583     if( end != *p + len )
00584         return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
00585                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00586 
00587     return( 0 );
00588 }
00589 
00590 /*
00591  * X.509 CRL v2 extensions (no extensions parsed yet.)
00592  */
00593 static int x509_get_crl_ext( unsigned char **p,
00594                              const unsigned char *end,
00595                              x509_buf *ext )
00596 {
00597     int ret;
00598     size_t len = 0;
00599 
00600     /* Get explicit tag */
00601     if( ( ret = x509_get_ext( p, end, ext, 0) ) != 0 )
00602     {
00603         if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
00604             return( 0 );
00605 
00606         return( ret );
00607     }
00608 
00609     while( *p < end )
00610     {
00611         if( ( ret = asn1_get_tag( p, end, &len,
00612                 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00613             return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
00614 
00615         *p += len;
00616     }
00617 
00618     if( *p != end )
00619         return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
00620                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00621 
00622     return( 0 );
00623 }
00624 
00625 /*
00626  * X.509 CRL v2 entry extensions (no extensions parsed yet.)
00627  */
00628 static int x509_get_crl_entry_ext( unsigned char **p,
00629                              const unsigned char *end,
00630                              x509_buf *ext )
00631 {
00632     int ret;
00633     size_t len = 0;
00634 
00635     /* OPTIONAL */
00636     if (end <= *p)
00637         return( 0 );
00638 
00639     ext->tag = **p;
00640     ext->p = *p;
00641 
00642     /*
00643      * Get CRL-entry extension sequence header
00644      * crlEntryExtensions      Extensions OPTIONAL  -- if present, MUST be v2
00645      */
00646     if( ( ret = asn1_get_tag( p, end, &ext->len,
00647             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00648     {
00649         if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
00650         {
00651             ext->p = NULL;
00652             return( 0 );
00653         }
00654         return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
00655     }
00656 
00657         end = *p + ext->len;
00658 
00659     if( end != *p + ext->len )
00660         return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
00661                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00662 
00663     while( *p < end )
00664     {
00665         if( ( ret = asn1_get_tag( p, end, &len,
00666                 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00667             return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
00668 
00669         *p += len;
00670     }
00671 
00672     if( *p != end )
00673         return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
00674                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00675 
00676     return( 0 );
00677 }
00678 
00679 static int x509_get_basic_constraints( unsigned char **p,
00680                                        const unsigned char *end,
00681                                        int *ca_istrue,
00682                                        int *max_pathlen )
00683 {
00684     int ret;
00685     size_t len;
00686 
00687     /*
00688      * BasicConstraints ::= SEQUENCE {
00689      *      cA                      BOOLEAN DEFAULT FALSE,
00690      *      pathLenConstraint       INTEGER (0..MAX) OPTIONAL }
00691      */
00692     *ca_istrue = 0; /* DEFAULT FALSE */
00693     *max_pathlen = 0; /* endless */
00694 
00695     if( ( ret = asn1_get_tag( p, end, &len,
00696             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00697         return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
00698 
00699     if( *p == end )
00700         return 0;
00701 
00702     if( ( ret = asn1_get_bool( p, end, ca_istrue ) ) != 0 )
00703     {
00704         if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
00705             ret = asn1_get_int( p, end, ca_istrue );
00706 
00707         if( ret != 0 )
00708             return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
00709 
00710         if( *ca_istrue != 0 )
00711             *ca_istrue = 1;
00712     }
00713 
00714     if( *p == end )
00715         return 0;
00716 
00717     if( ( ret = asn1_get_int( p, end, max_pathlen ) ) != 0 )
00718         return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
00719 
00720     if( *p != end )
00721         return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
00722                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00723 
00724     (*max_pathlen)++;
00725 
00726     return 0;
00727 }
00728 
00729 static int x509_get_ns_cert_type( unsigned char **p,
00730                                        const unsigned char *end,
00731                                        unsigned char *ns_cert_type)
00732 {
00733     int ret;
00734     x509_bitstring bs = { 0, 0, NULL };
00735 
00736     if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
00737         return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
00738 
00739     if( bs.len != 1 )
00740         return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
00741                 POLARSSL_ERR_ASN1_INVALID_LENGTH );
00742 
00743     /* Get actual bitstring */
00744     *ns_cert_type = *bs.p;
00745     return 0;
00746 }
00747 
00748 static int x509_get_key_usage( unsigned char **p,
00749                                const unsigned char *end,
00750                                unsigned char *key_usage)
00751 {
00752     int ret;
00753     x509_bitstring bs = { 0, 0, NULL };
00754 
00755     if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
00756         return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
00757 
00758     if( bs.len > 1 )
00759         return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
00760                 POLARSSL_ERR_ASN1_INVALID_LENGTH );
00761 
00762     /* Get actual bitstring */
00763     *key_usage = *bs.p;
00764     return 0;
00765 }
00766 
00767 /*
00768  * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
00769  *
00770  * KeyPurposeId ::= OBJECT IDENTIFIER
00771  */
00772 static int x509_get_ext_key_usage( unsigned char **p,
00773                                const unsigned char *end,
00774                                x509_sequence *ext_key_usage)
00775 {
00776     int ret;
00777 
00778     if( ( ret = asn1_get_sequence_of( p, end, ext_key_usage, ASN1_OID ) ) != 0 )
00779         return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
00780 
00781     /* Sequence length must be >= 1 */
00782     if( ext_key_usage->buf.p == NULL )
00783         return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
00784                 POLARSSL_ERR_ASN1_INVALID_LENGTH );
00785 
00786     return 0;
00787 }
00788 
00789 /*
00790  * X.509 v3 extensions
00791  *
00792  * TODO: Perform all of the basic constraints tests required by the RFC
00793  * TODO: Set values for undetected extensions to a sane default?
00794  *
00795  */
00796 static int x509_get_crt_ext( unsigned char **p,
00797                              const unsigned char *end,
00798                              x509_cert *crt )
00799 {
00800     int ret;
00801     size_t len;
00802     unsigned char *end_ext_data, *end_ext_octet;
00803 
00804     if( ( ret = x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 )
00805     {
00806         if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
00807             return( 0 );
00808 
00809         return( ret );
00810     }
00811 
00812     while( *p < end )
00813     {
00814         /*
00815          * Extension  ::=  SEQUENCE  {
00816          *      extnID      OBJECT IDENTIFIER,
00817          *      critical    BOOLEAN DEFAULT FALSE,
00818          *      extnValue   OCTET STRING  }
00819          */
00820         x509_buf extn_oid = {0, 0, NULL};
00821         int is_critical = 0; /* DEFAULT FALSE */
00822 
00823         if( ( ret = asn1_get_tag( p, end, &len,
00824                 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00825             return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
00826 
00827         end_ext_data = *p + len;
00828 
00829         /* Get extension ID */
00830         extn_oid.tag = **p;
00831 
00832         if( ( ret = asn1_get_tag( p, end, &extn_oid.len, ASN1_OID ) ) != 0 )
00833             return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
00834 
00835         extn_oid.p = *p;
00836         *p += extn_oid.len;
00837 
00838         if( ( end - *p ) < 1 )
00839             return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
00840                     POLARSSL_ERR_ASN1_OUT_OF_DATA );
00841 
00842         /* Get optional critical */
00843         if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
00844             ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
00845             return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
00846 
00847         /* Data should be octet string type */
00848         if( ( ret = asn1_get_tag( p, end_ext_data, &len,
00849                 ASN1_OCTET_STRING ) ) != 0 )
00850             return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS + ret );
00851 
00852         end_ext_octet = *p + len;
00853 
00854         if( end_ext_octet != end_ext_data )
00855             return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
00856                     POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00857 
00858         /*
00859          * Detect supported extensions
00860          */
00861         if( ( OID_SIZE( OID_BASIC_CONSTRAINTS ) == extn_oid.len ) &&
00862                 memcmp( extn_oid.p, OID_BASIC_CONSTRAINTS, extn_oid.len ) == 0 )
00863         {
00864             /* Parse basic constraints */
00865             if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
00866                     &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
00867                 return ( ret );
00868             crt->ext_types |= EXT_BASIC_CONSTRAINTS;
00869         }
00870         else if( ( OID_SIZE( OID_NS_CERT_TYPE ) == extn_oid.len ) &&
00871                 memcmp( extn_oid.p, OID_NS_CERT_TYPE, extn_oid.len ) == 0 )
00872         {
00873             /* Parse netscape certificate type */
00874             if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
00875                     &crt->ns_cert_type ) ) != 0 )
00876                 return ( ret );
00877             crt->ext_types |= EXT_NS_CERT_TYPE;
00878         }
00879         else if( ( OID_SIZE( OID_KEY_USAGE ) == extn_oid.len ) &&
00880                 memcmp( extn_oid.p, OID_KEY_USAGE, extn_oid.len ) == 0 )
00881         {
00882             /* Parse key usage */
00883             if( ( ret = x509_get_key_usage( p, end_ext_octet,
00884                     &crt->key_usage ) ) != 0 )
00885                 return ( ret );
00886             crt->ext_types |= EXT_KEY_USAGE;
00887         }
00888         else if( ( OID_SIZE( OID_EXTENDED_KEY_USAGE ) == extn_oid.len ) &&
00889                 memcmp( extn_oid.p, OID_EXTENDED_KEY_USAGE, extn_oid.len ) == 0 )
00890         {
00891             /* Parse extended key usage */
00892             if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
00893                     &crt->ext_key_usage ) ) != 0 )
00894                 return ( ret );
00895             crt->ext_types |= EXT_EXTENDED_KEY_USAGE;
00896         }
00897         else
00898         {
00899             /* No parser found, skip extension */
00900             *p = end_ext_octet;
00901 
00902 #if !defined(POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
00903             if( is_critical )
00904             {
00905                 /* Data is marked as critical: fail */
00906                 return ( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
00907                         POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
00908             }
00909 #endif
00910         }
00911     }
00912 
00913     if( *p != end )
00914         return( POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS +
00915                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00916 
00917     return( 0 );
00918 }
00919 
00920 /*
00921  * X.509 CRL Entries
00922  */
00923 static int x509_get_entries( unsigned char **p,
00924                              const unsigned char *end,
00925                              x509_crl_entry *entry )
00926 {
00927     int ret;
00928     size_t entry_len;
00929     x509_crl_entry *cur_entry = entry;
00930 
00931     if( *p == end )
00932         return( 0 );
00933 
00934     if( ( ret = asn1_get_tag( p, end, &entry_len,
00935             ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
00936     {
00937         if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
00938             return( 0 );
00939 
00940         return( ret );
00941     }
00942 
00943     end = *p + entry_len;
00944 
00945     while( *p < end )
00946     {
00947         size_t len2;
00948         const unsigned char *end2;
00949 
00950         if( ( ret = asn1_get_tag( p, end, &len2,
00951                 ASN1_SEQUENCE | ASN1_CONSTRUCTED ) ) != 0 )
00952         {
00953             return( ret );
00954         }
00955 
00956         cur_entry->raw.tag = **p;
00957         cur_entry->raw.p = *p;
00958         cur_entry->raw.len = len2;
00959         end2 = *p + len2;
00960 
00961         if( ( ret = x509_get_serial( p, end2, &cur_entry->serial ) ) != 0 )
00962             return( ret );
00963 
00964         if( ( ret = x509_get_time( p, end2, &cur_entry->revocation_date ) ) != 0 )
00965             return( ret );
00966 
00967         if( ( ret = x509_get_crl_entry_ext( p, end2, &cur_entry->entry_ext ) ) != 0 )
00968             return( ret );
00969 
00970         if ( *p < end )
00971         {
00972             cur_entry->next = malloc( sizeof( x509_crl_entry ) );
00973 
00974             if( cur_entry->next == NULL )
00975                 return( POLARSSL_ERR_X509_MALLOC_FAILED );
00976 
00977             cur_entry = cur_entry->next;
00978             memset( cur_entry, 0, sizeof( x509_crl_entry ) );
00979         }
00980     }
00981 
00982     return( 0 );
00983 }
00984 
00985 static int x509_get_sig_alg( const x509_buf *sig_oid, int *sig_alg )
00986 {
00987     if( sig_oid->len == 9 &&
00988         memcmp( sig_oid->p, OID_PKCS1, 8 ) == 0 )
00989     {
00990         if( sig_oid->p[8] >= 2 && sig_oid->p[8] <= 5 )
00991         {
00992             *sig_alg = sig_oid->p[8];
00993             return( 0 );
00994         }
00995 
00996         if ( sig_oid->p[8] >= 11 && sig_oid->p[8] <= 14 )
00997         {
00998             *sig_alg = sig_oid->p[8];
00999             return( 0 );
01000         }
01001 
01002         return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
01003     }
01004     if( sig_oid->len == 5 &&
01005         memcmp( sig_oid->p, OID_RSA_SHA_OBS, 5 ) == 0 )
01006     {
01007         *sig_alg = SIG_RSA_SHA1;
01008         return( 0 );
01009     }
01010 
01011     return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
01012 }
01013 
01014 /*
01015  * Parse and fill a single X.509 certificate in DER format
01016  */
01017 int x509parse_crt_der( x509_cert *crt, const unsigned char *buf, size_t buflen )
01018 {
01019     int ret;
01020     size_t len;
01021     unsigned char *p, *end;
01022 
01023     /*
01024      * Check for valid input
01025      */
01026     if( crt == NULL || buf == NULL )
01027         return( POLARSSL_ERR_X509_INVALID_INPUT );
01028 
01029     p = (unsigned char *) malloc( len = buflen );
01030 
01031     if( p == NULL )
01032         return( POLARSSL_ERR_X509_MALLOC_FAILED );
01033 
01034     memcpy( p, buf, buflen );
01035 
01036     buflen = 0;
01037 
01038     crt->raw.p = p;
01039     crt->raw.len = len;
01040     end = p + len;
01041 
01042     /*
01043      * Certificate  ::=  SEQUENCE  {
01044      *      tbsCertificate       TBSCertificate,
01045      *      signatureAlgorithm   AlgorithmIdentifier,
01046      *      signatureValue       BIT STRING  }
01047      */
01048     if( ( ret = asn1_get_tag( &p, end, &len,
01049             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
01050     {
01051         x509_free( crt );
01052         return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
01053     }
01054 
01055     if( len != (size_t) ( end - p ) )
01056     {
01057         x509_free( crt );
01058         return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
01059                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
01060     }
01061 
01062     /*
01063      * TBSCertificate  ::=  SEQUENCE  {
01064      */
01065     crt->tbs.p = p;
01066 
01067     if( ( ret = asn1_get_tag( &p, end, &len,
01068             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
01069     {
01070         x509_free( crt );
01071         return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
01072     }
01073 
01074     end = p + len;
01075     crt->tbs.len = end - crt->tbs.p;
01076 
01077     /*
01078      * Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
01079      *
01080      * CertificateSerialNumber  ::=  INTEGER
01081      *
01082      * signature            AlgorithmIdentifier
01083      */
01084     if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
01085         ( ret = x509_get_serial(  &p, end, &crt->serial  ) ) != 0 ||
01086         ( ret = x509_get_alg(  &p, end, &crt->sig_oid1   ) ) != 0 )
01087     {
01088         x509_free( crt );
01089         return( ret );
01090     }
01091 
01092     crt->version++;
01093 
01094     if( crt->version > 3 )
01095     {
01096         x509_free( crt );
01097         return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
01098     }
01099 
01100     if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &crt->sig_alg ) ) != 0 )
01101     {
01102         x509_free( crt );
01103         return( ret );
01104     }
01105 
01106     /*
01107      * issuer               Name
01108      */
01109     crt->issuer_raw.p = p;
01110 
01111     if( ( ret = asn1_get_tag( &p, end, &len,
01112             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
01113     {
01114         x509_free( crt );
01115         return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
01116     }
01117 
01118     if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
01119     {
01120         x509_free( crt );
01121         return( ret );
01122     }
01123 
01124     crt->issuer_raw.len = p - crt->issuer_raw.p;
01125 
01126     /*
01127      * Validity ::= SEQUENCE {
01128      *      notBefore      Time,
01129      *      notAfter       Time }
01130      *
01131      */
01132     if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
01133                                          &crt->valid_to ) ) != 0 )
01134     {
01135         x509_free( crt );
01136         return( ret );
01137     }
01138 
01139     /*
01140      * subject              Name
01141      */
01142     crt->subject_raw.p = p;
01143 
01144     if( ( ret = asn1_get_tag( &p, end, &len,
01145             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
01146     {
01147         x509_free( crt );
01148         return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
01149     }
01150 
01151     if( ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
01152     {
01153         x509_free( crt );
01154         return( ret );
01155     }
01156 
01157     crt->subject_raw.len = p - crt->subject_raw.p;
01158 
01159     /*
01160      * SubjectPublicKeyInfo  ::=  SEQUENCE
01161      *      algorithm            AlgorithmIdentifier,
01162      *      subjectPublicKey     BIT STRING  }
01163      */
01164     if( ( ret = asn1_get_tag( &p, end, &len,
01165             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
01166     {
01167         x509_free( crt );
01168         return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
01169     }
01170 
01171     if( ( ret = x509_get_pubkey( &p, p + len, &crt->pk_oid,
01172                                  &crt->rsa.N, &crt->rsa.E ) ) != 0 )
01173     {
01174         x509_free( crt );
01175         return( ret );
01176     }
01177 
01178     if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 )
01179     {
01180         x509_free( crt );
01181         return( ret );
01182     }
01183 
01184     crt->rsa.len = mpi_size( &crt->rsa.N );
01185 
01186     /*
01187      *  issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
01188      *                       -- If present, version shall be v2 or v3
01189      *  subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
01190      *                       -- If present, version shall be v2 or v3
01191      *  extensions      [3]  EXPLICIT Extensions OPTIONAL
01192      *                       -- If present, version shall be v3
01193      */
01194     if( crt->version == 2 || crt->version == 3 )
01195     {
01196         ret = x509_get_uid( &p, end, &crt->issuer_id,  1 );
01197         if( ret != 0 )
01198         {
01199             x509_free( crt );
01200             return( ret );
01201         }
01202     }
01203 
01204     if( crt->version == 2 || crt->version == 3 )
01205     {
01206         ret = x509_get_uid( &p, end, &crt->subject_id,  2 );
01207         if( ret != 0 )
01208         {
01209             x509_free( crt );
01210             return( ret );
01211         }
01212     }
01213 
01214     if( crt->version == 3 )
01215     {
01216         ret = x509_get_crt_ext( &p, end, crt);
01217         if( ret != 0 )
01218         {
01219             x509_free( crt );
01220             return( ret );
01221         }
01222     }
01223 
01224     if( p != end )
01225     {
01226         x509_free( crt );
01227         return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
01228                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
01229     }
01230 
01231     end = crt->raw.p + crt->raw.len;
01232 
01233     /*
01234      *  signatureAlgorithm   AlgorithmIdentifier,
01235      *  signatureValue       BIT STRING
01236      */
01237     if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2 ) ) != 0 )
01238     {
01239         x509_free( crt );
01240         return( ret );
01241     }
01242 
01243     if( memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
01244     {
01245         x509_free( crt );
01246         return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
01247     }
01248 
01249     if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
01250     {
01251         x509_free( crt );
01252         return( ret );
01253     }
01254 
01255     if( p != end )
01256     {
01257         x509_free( crt );
01258         return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
01259                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
01260     }
01261 
01262     return( 0 );
01263 }
01264 
01265 /*
01266  * Parse one or more PEM certificates from a buffer and add them to the chained list
01267  */
01268 int x509parse_crt( x509_cert *chain, const unsigned char *buf, size_t buflen )
01269 {
01270     int ret, success = 0, first_error = 0, total_failed = 0;
01271     x509_cert *crt, *prev = NULL;
01272     int buf_format = X509_FORMAT_DER;
01273 
01274     crt = chain;
01275 
01276     /*
01277      * Check for valid input
01278      */
01279     if( crt == NULL || buf == NULL )
01280         return( POLARSSL_ERR_X509_INVALID_INPUT );
01281 
01282     while( crt->version != 0 && crt->next != NULL )
01283     {
01284         prev = crt;
01285         crt = crt->next;
01286     }
01287 
01288     /*
01289      * Add new certificate on the end of the chain if needed.
01290      */
01291     if ( crt->version != 0 && crt->next == NULL)
01292     {
01293         crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
01294 
01295         if( crt->next == NULL )
01296             return( POLARSSL_ERR_X509_MALLOC_FAILED );
01297 
01298         prev = crt;
01299         crt = crt->next;
01300         memset( crt, 0, sizeof( x509_cert ) );
01301     }
01302 
01303     /*
01304      * Determine buffer content. Buffer contains either one DER certificate or
01305      * one or more PEM certificates.
01306      */
01307 #if defined(POLARSSL_PEM_C)
01308     if( strstr( (char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL )
01309         buf_format = X509_FORMAT_PEM;
01310 #endif
01311 
01312     if( buf_format == X509_FORMAT_DER )
01313         return x509parse_crt_der( crt, buf, buflen );
01314     
01315 #if defined(POLARSSL_PEM_C)
01316     if( buf_format == X509_FORMAT_PEM )
01317     {
01318         pem_context pem;
01319 
01320         while( buflen > 0 )
01321         {
01322             size_t use_len;
01323             pem_init( &pem );
01324 
01325             ret = pem_read_buffer( &pem,
01326                            "-----BEGIN CERTIFICATE-----",
01327                            "-----END CERTIFICATE-----",
01328                            buf, NULL, 0, &use_len );
01329 
01330             if( ret == 0 )
01331             {
01332                 /*
01333                  * Was PEM encoded
01334                  */
01335                 buflen -= use_len;
01336                 buf += use_len;
01337             }
01338             else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
01339             {
01340                 pem_free( &pem );
01341 
01342                 if( first_error == 0 )
01343                     first_error = ret;
01344 
01345                 continue;
01346             }
01347             else
01348                 break;
01349 
01350             ret = x509parse_crt_der( crt, pem.buf, pem.buflen );
01351 
01352             pem_free( &pem );
01353 
01354             if( ret != 0 )
01355             {
01356                 /*
01357                  * quit parsing on a memory error
01358                  */
01359                 if( ret == POLARSSL_ERR_X509_MALLOC_FAILED )
01360                 {
01361                     if( prev )
01362                         prev->next = NULL;
01363 
01364                     if( crt != chain )
01365                         free( crt );
01366 
01367                     return( ret );
01368                 }
01369 
01370                 if( first_error == 0 )
01371                     first_error = ret;
01372                 
01373                 total_failed++;
01374 
01375                 memset( crt, 0, sizeof( x509_cert ) );
01376                 continue;
01377             }
01378 
01379             success = 1;
01380 
01381             /*
01382              * Add new certificate to the list
01383              */
01384             crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
01385 
01386             if( crt->next == NULL )
01387                 return( POLARSSL_ERR_X509_MALLOC_FAILED );
01388 
01389             prev = crt;
01390             crt = crt->next;
01391             memset( crt, 0, sizeof( x509_cert ) );
01392         }
01393     }
01394 #endif
01395 
01396     if( crt->version == 0 )
01397     {
01398         if( prev )
01399             prev->next = NULL;
01400 
01401         if( crt != chain )
01402             free( crt );
01403     }
01404 
01405     if( success )
01406         return( total_failed );
01407     else if( first_error )
01408         return( first_error );
01409     else
01410         return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT );
01411 }
01412 
01413 /*
01414  * Parse one or more CRLs and add them to the chained list
01415  */
01416 int x509parse_crl( x509_crl *chain, const unsigned char *buf, size_t buflen )
01417 {
01418     int ret;
01419     size_t len;
01420     unsigned char *p, *end;
01421     x509_crl *crl;
01422 #if defined(POLARSSL_PEM_C)
01423     size_t use_len;
01424     pem_context pem;
01425 #endif
01426 
01427     crl = chain;
01428 
01429     /*
01430      * Check for valid input
01431      */
01432     if( crl == NULL || buf == NULL )
01433         return( POLARSSL_ERR_X509_INVALID_INPUT );
01434 
01435     while( crl->version != 0 && crl->next != NULL )
01436         crl = crl->next;
01437 
01438     /*
01439      * Add new CRL on the end of the chain if needed.
01440      */
01441     if ( crl->version != 0 && crl->next == NULL)
01442     {
01443         crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
01444 
01445         if( crl->next == NULL )
01446         {
01447             x509_crl_free( crl );
01448             return( POLARSSL_ERR_X509_MALLOC_FAILED );
01449         }
01450 
01451         crl = crl->next;
01452         memset( crl, 0, sizeof( x509_crl ) );
01453     }
01454 
01455 #if defined(POLARSSL_PEM_C)
01456     pem_init( &pem );
01457     ret = pem_read_buffer( &pem,
01458                            "-----BEGIN X509 CRL-----",
01459                            "-----END X509 CRL-----",
01460                            buf, NULL, 0, &use_len );
01461 
01462     if( ret == 0 )
01463     {
01464         /*
01465          * Was PEM encoded
01466          */
01467         buflen -= use_len;
01468         buf += use_len;
01469 
01470         /*
01471          * Steal PEM buffer
01472          */
01473         p = pem.buf;
01474         pem.buf = NULL;
01475         len = pem.buflen;
01476         pem_free( &pem );
01477     }
01478     else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
01479     {
01480         pem_free( &pem );
01481         return( ret );
01482     }
01483     else
01484     {
01485         /*
01486          * nope, copy the raw DER data
01487          */
01488         p = (unsigned char *) malloc( len = buflen );
01489 
01490         if( p == NULL )
01491             return( POLARSSL_ERR_X509_MALLOC_FAILED );
01492 
01493         memcpy( p, buf, buflen );
01494 
01495         buflen = 0;
01496     }
01497 #else
01498     p = (unsigned char *) malloc( len = buflen );
01499 
01500     if( p == NULL )
01501         return( POLARSSL_ERR_X509_MALLOC_FAILED );
01502 
01503     memcpy( p, buf, buflen );
01504 
01505     buflen = 0;
01506 #endif
01507 
01508     crl->raw.p = p;
01509     crl->raw.len = len;
01510     end = p + len;
01511 
01512     /*
01513      * CertificateList  ::=  SEQUENCE  {
01514      *      tbsCertList          TBSCertList,
01515      *      signatureAlgorithm   AlgorithmIdentifier,
01516      *      signatureValue       BIT STRING  }
01517      */
01518     if( ( ret = asn1_get_tag( &p, end, &len,
01519             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
01520     {
01521         x509_crl_free( crl );
01522         return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT );
01523     }
01524 
01525     if( len != (size_t) ( end - p ) )
01526     {
01527         x509_crl_free( crl );
01528         return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
01529                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
01530     }
01531 
01532     /*
01533      * TBSCertList  ::=  SEQUENCE  {
01534      */
01535     crl->tbs.p = p;
01536 
01537     if( ( ret = asn1_get_tag( &p, end, &len,
01538             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
01539     {
01540         x509_crl_free( crl );
01541         return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
01542     }
01543 
01544     end = p + len;
01545     crl->tbs.len = end - crl->tbs.p;
01546 
01547     /*
01548      * Version  ::=  INTEGER  OPTIONAL {  v1(0), v2(1)  }
01549      *               -- if present, MUST be v2
01550      *
01551      * signature            AlgorithmIdentifier
01552      */
01553     if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 ||
01554         ( ret = x509_get_alg(  &p, end, &crl->sig_oid1   ) ) != 0 )
01555     {
01556         x509_crl_free( crl );
01557         return( ret );
01558     }
01559 
01560     crl->version++;
01561 
01562     if( crl->version > 2 )
01563     {
01564         x509_crl_free( crl );
01565         return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
01566     }
01567 
01568     if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_alg ) ) != 0 )
01569     {
01570         x509_crl_free( crl );
01571         return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
01572     }
01573 
01574     /*
01575      * issuer               Name
01576      */
01577     crl->issuer_raw.p = p;
01578 
01579     if( ( ret = asn1_get_tag( &p, end, &len,
01580             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
01581     {
01582         x509_crl_free( crl );
01583         return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
01584     }
01585 
01586     if( ( ret = x509_get_name( &p, p + len, &crl->issuer ) ) != 0 )
01587     {
01588         x509_crl_free( crl );
01589         return( ret );
01590     }
01591 
01592     crl->issuer_raw.len = p - crl->issuer_raw.p;
01593 
01594     /*
01595      * thisUpdate          Time
01596      * nextUpdate          Time OPTIONAL
01597      */
01598     if( ( ret = x509_get_time( &p, end, &crl->this_update ) ) != 0 )
01599     {
01600         x509_crl_free( crl );
01601         return( ret );
01602     }
01603 
01604     if( ( ret = x509_get_time( &p, end, &crl->next_update ) ) != 0 )
01605     {
01606         if ( ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
01607                         POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) &&
01608              ret != ( POLARSSL_ERR_X509_CERT_INVALID_DATE +
01609                         POLARSSL_ERR_ASN1_OUT_OF_DATA ) )
01610         {
01611             x509_crl_free( crl );
01612             return( ret );
01613         }
01614     }
01615 
01616     /*
01617      * revokedCertificates    SEQUENCE OF SEQUENCE   {
01618      *      userCertificate        CertificateSerialNumber,
01619      *      revocationDate         Time,
01620      *      crlEntryExtensions     Extensions OPTIONAL
01621      *                                   -- if present, MUST be v2
01622      *                        } OPTIONAL
01623      */
01624     if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 )
01625     {
01626         x509_crl_free( crl );
01627         return( ret );
01628     }
01629 
01630     /*
01631      * crlExtensions          EXPLICIT Extensions OPTIONAL
01632      *                              -- if present, MUST be v2
01633      */
01634     if( crl->version == 2 )
01635     {
01636         ret = x509_get_crl_ext( &p, end, &crl->crl_ext );
01637                             
01638         if( ret != 0 )
01639         {
01640             x509_crl_free( crl );
01641             return( ret );
01642         }
01643     }
01644 
01645     if( p != end )
01646     {
01647         x509_crl_free( crl );
01648         return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
01649                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
01650     }
01651 
01652     end = crl->raw.p + crl->raw.len;
01653 
01654     /*
01655      *  signatureAlgorithm   AlgorithmIdentifier,
01656      *  signatureValue       BIT STRING
01657      */
01658     if( ( ret = x509_get_alg( &p, end, &crl->sig_oid2 ) ) != 0 )
01659     {
01660         x509_crl_free( crl );
01661         return( ret );
01662     }
01663 
01664     if( memcmp( crl->sig_oid1.p, crl->sig_oid2.p, crl->sig_oid1.len ) != 0 )
01665     {
01666         x509_crl_free( crl );
01667         return( POLARSSL_ERR_X509_CERT_SIG_MISMATCH );
01668     }
01669 
01670     if( ( ret = x509_get_sig( &p, end, &crl->sig ) ) != 0 )
01671     {
01672         x509_crl_free( crl );
01673         return( ret );
01674     }
01675 
01676     if( p != end )
01677     {
01678         x509_crl_free( crl );
01679         return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
01680                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
01681     }
01682 
01683     if( buflen > 0 )
01684     {
01685         crl->next = (x509_crl *) malloc( sizeof( x509_crl ) );
01686 
01687         if( crl->next == NULL )
01688         {
01689             x509_crl_free( crl );
01690             return( POLARSSL_ERR_X509_MALLOC_FAILED );
01691         }
01692 
01693         crl = crl->next;
01694         memset( crl, 0, sizeof( x509_crl ) );
01695 
01696         return( x509parse_crl( crl, buf, buflen ) );
01697     }
01698 
01699     return( 0 );
01700 }
01701 
01702 #if defined(POLARSSL_FS_IO)
01703 /*
01704  * Load all data from a file into a given buffer.
01705  */
01706 int load_file( const char *path, unsigned char **buf, size_t *n )
01707 {
01708     FILE *f;
01709 
01710     if( ( f = fopen( path, "rb" ) ) == NULL )
01711         return( POLARSSL_ERR_X509_FILE_IO_ERROR );
01712 
01713     fseek( f, 0, SEEK_END );
01714     *n = (size_t) ftell( f );
01715     fseek( f, 0, SEEK_SET );
01716 
01717     if( ( *buf = (unsigned char *) malloc( *n + 1 ) ) == NULL )
01718         return( POLARSSL_ERR_X509_MALLOC_FAILED );
01719 
01720     if( fread( *buf, 1, *n, f ) != *n )
01721     {
01722         fclose( f );
01723         free( *buf );
01724         return( POLARSSL_ERR_X509_FILE_IO_ERROR );
01725     }
01726 
01727     fclose( f );
01728 
01729     (*buf)[*n] = '\0';
01730 
01731     return( 0 );
01732 }
01733 
01734 /*
01735  * Load one or more certificates and add them to the chained list
01736  */
01737 int x509parse_crtfile( x509_cert *chain, const char *path )
01738 {
01739     int ret;
01740     size_t n;
01741     unsigned char *buf;
01742 
01743     if ( (ret = load_file( path, &buf, &n ) ) != 0 )
01744         return( ret );
01745 
01746     ret = x509parse_crt( chain, buf, n );
01747 
01748     memset( buf, 0, n + 1 );
01749     free( buf );
01750 
01751     return( ret );
01752 }
01753 
01754 /*
01755  * Load one or more CRLs and add them to the chained list
01756  */
01757 int x509parse_crlfile( x509_crl *chain, const char *path )
01758 {
01759     int ret;
01760     size_t n;
01761     unsigned char *buf;
01762 
01763     if ( (ret = load_file( path, &buf, &n ) ) != 0 )
01764         return( ret );
01765 
01766     ret = x509parse_crl( chain, buf, n );
01767 
01768     memset( buf, 0, n + 1 );
01769     free( buf );
01770 
01771     return( ret );
01772 }
01773 
01774 /*
01775  * Load and parse a private RSA key
01776  */
01777 int x509parse_keyfile( rsa_context *rsa, const char *path, const char *pwd )
01778 {
01779     int ret;
01780     size_t n;
01781     unsigned char *buf;
01782 
01783     if ( (ret = load_file( path, &buf, &n ) ) != 0 )
01784         return( ret );
01785 
01786     if( pwd == NULL )
01787         ret = x509parse_key( rsa, buf, n, NULL, 0 );
01788     else
01789         ret = x509parse_key( rsa, buf, n,
01790                 (unsigned char *) pwd, strlen( pwd ) );
01791 
01792     memset( buf, 0, n + 1 );
01793     free( buf );
01794 
01795     return( ret );
01796 }
01797 
01798 /*
01799  * Load and parse a public RSA key
01800  */
01801 int x509parse_public_keyfile( rsa_context *rsa, const char *path )
01802 {
01803     int ret;
01804     size_t n;
01805     unsigned char *buf;
01806 
01807     if ( (ret = load_file( path, &buf, &n ) ) != 0 )
01808         return( ret );
01809 
01810     ret = x509parse_public_key( rsa, buf, n );
01811 
01812     memset( buf, 0, n + 1 );
01813     free( buf );
01814 
01815     return( ret );
01816 }
01817 #endif /* POLARSSL_FS_IO */
01818 
01819 /*
01820  * Parse a private RSA key
01821  */
01822 int x509parse_key( rsa_context *rsa, const unsigned char *key, size_t keylen,
01823                                      const unsigned char *pwd, size_t pwdlen )
01824 {
01825     int ret;
01826     size_t len;
01827     unsigned char *p, *end;
01828     unsigned char *p_alt;
01829     x509_buf pk_alg_oid;
01830 
01831 #if defined(POLARSSL_PEM_C)
01832     pem_context pem;
01833 
01834     pem_init( &pem );
01835     ret = pem_read_buffer( &pem,
01836                            "-----BEGIN RSA PRIVATE KEY-----",
01837                            "-----END RSA PRIVATE KEY-----",
01838                            key, pwd, pwdlen, &len );
01839 
01840     if( ret == POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
01841     {
01842         ret = pem_read_buffer( &pem,
01843                            "-----BEGIN PRIVATE KEY-----",
01844                            "-----END PRIVATE KEY-----",
01845                            key, pwd, pwdlen, &len );
01846     }
01847 
01848     if( ret == 0 )
01849     {
01850         /*
01851          * Was PEM encoded
01852          */
01853         keylen = pem.buflen;
01854     }
01855     else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
01856     {
01857         pem_free( &pem );
01858         return( ret );
01859     }
01860 
01861     p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
01862 #else
01863     ((void) pwd);
01864     ((void) pwdlen);
01865     p = (unsigned char *) key;
01866 #endif
01867     end = p + keylen;
01868 
01869     /*
01870      * Note: Depending on the type of private key file one can expect either a
01871      * PrivatKeyInfo object (PKCS#8) or a RSAPrivateKey (PKCS#1) directly.
01872      *
01873      *  PrivateKeyInfo ::= SEQUENCE {
01874      *    version           Version,
01875      *    algorithm       AlgorithmIdentifier,
01876      *    PrivateKey      BIT STRING
01877      *  }
01878      *
01879      *  AlgorithmIdentifier ::= SEQUENCE {
01880      *    algorithm       OBJECT IDENTIFIER,
01881      *    parameters      ANY DEFINED BY algorithm OPTIONAL
01882      *  }
01883      *
01884      *  RSAPrivateKey ::= SEQUENCE {
01885      *      version           Version,
01886      *      modulus           INTEGER,  -- n
01887      *      publicExponent    INTEGER,  -- e
01888      *      privateExponent   INTEGER,  -- d
01889      *      prime1            INTEGER,  -- p
01890      *      prime2            INTEGER,  -- q
01891      *      exponent1         INTEGER,  -- d mod (p-1)
01892      *      exponent2         INTEGER,  -- d mod (q-1)
01893      *      coefficient       INTEGER,  -- (inverse of q) mod p
01894      *      otherPrimeInfos   OtherPrimeInfos OPTIONAL
01895      *  }
01896      */
01897     if( ( ret = asn1_get_tag( &p, end, &len,
01898             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
01899     {
01900 #if defined(POLARSSL_PEM_C)
01901         pem_free( &pem );
01902 #endif
01903         rsa_free( rsa );
01904         return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
01905     }
01906 
01907     end = p + len;
01908 
01909     if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
01910     {
01911 #if defined(POLARSSL_PEM_C)
01912         pem_free( &pem );
01913 #endif
01914         rsa_free( rsa );
01915         return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
01916     }
01917 
01918     if( rsa->ver != 0 )
01919     {
01920 #if defined(POLARSSL_PEM_C)
01921         pem_free( &pem );
01922 #endif
01923         rsa_free( rsa );
01924         return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
01925     }
01926 
01927     p_alt = p;
01928 
01929     if( ( ret = x509_get_alg( &p_alt, end, &pk_alg_oid ) ) != 0 )
01930     {
01931         // Assume that we have the PKCS#1 format if wrong
01932         // tag was encountered
01933         //
01934         if( ret != POLARSSL_ERR_X509_CERT_INVALID_ALG +
01935                     POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
01936         {
01937 #if defined(POLARSSL_PEM_C)
01938             pem_free( &pem );
01939 #endif
01940             rsa_free( rsa );
01941             return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT );
01942         } 
01943     }
01944     else
01945     {
01946         int can_handle;
01947 
01948         /*
01949          * only RSA keys handled at this time
01950          */
01951         can_handle = 0;
01952 
01953         if( pk_alg_oid.len == 9 &&
01954                 memcmp( pk_alg_oid.p, OID_PKCS1_RSA, 9 ) == 0 )
01955             can_handle = 1;
01956 
01957         if( pk_alg_oid.len == 9 &&
01958                 memcmp( pk_alg_oid.p, OID_PKCS1, 8 ) == 0 )
01959         {
01960             if( pk_alg_oid.p[8] >= 2 && pk_alg_oid.p[8] <= 5 )
01961                 can_handle = 1;
01962 
01963             if ( pk_alg_oid.p[8] >= 11 && pk_alg_oid.p[8] <= 14 )
01964                 can_handle = 1;
01965         }
01966 
01967         if( pk_alg_oid.len == 5 &&
01968                 memcmp( pk_alg_oid.p, OID_RSA_SHA_OBS, 5 ) == 0 )
01969             can_handle = 1;
01970 
01971         if( can_handle == 0 )
01972             return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
01973 
01974         /*
01975          * Parse the PKCS#8 format
01976          */
01977         
01978         p = p_alt;
01979         if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
01980         {
01981 #if defined(POLARSSL_PEM_C)
01982             pem_free( &pem );
01983 #endif
01984             rsa_free( rsa );
01985             return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
01986         }
01987 
01988         if( ( end - p ) < 1 )
01989         {
01990 #if defined(POLARSSL_PEM_C)
01991             pem_free( &pem );
01992 #endif
01993             rsa_free( rsa );
01994             return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
01995                     POLARSSL_ERR_ASN1_OUT_OF_DATA );
01996         }
01997 
01998         end = p + len;
01999 
02000         if( ( ret = asn1_get_tag( &p, end, &len,
02001                         ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
02002         {
02003 #if defined(POLARSSL_PEM_C)
02004             pem_free( &pem );
02005 #endif
02006             rsa_free( rsa );
02007             return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
02008         }
02009 
02010         end = p + len;
02011 
02012         if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
02013         {
02014 #if defined(POLARSSL_PEM_C)
02015             pem_free( &pem );
02016 #endif
02017             rsa_free( rsa );
02018             return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
02019         }
02020 
02021         if( rsa->ver != 0 )
02022         {
02023 #if defined(POLARSSL_PEM_C)
02024             pem_free( &pem );
02025 #endif
02026             rsa_free( rsa );
02027             return( POLARSSL_ERR_X509_KEY_INVALID_VERSION + ret );
02028         }
02029     }
02030 
02031     if( ( ret = asn1_get_mpi( &p, end, &rsa->N  ) ) != 0 ||
02032         ( ret = asn1_get_mpi( &p, end, &rsa->E  ) ) != 0 ||
02033         ( ret = asn1_get_mpi( &p, end, &rsa->D  ) ) != 0 ||
02034         ( ret = asn1_get_mpi( &p, end, &rsa->P  ) ) != 0 ||
02035         ( ret = asn1_get_mpi( &p, end, &rsa->Q  ) ) != 0 ||
02036         ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
02037         ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
02038         ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
02039     {
02040 #if defined(POLARSSL_PEM_C)
02041         pem_free( &pem );
02042 #endif
02043         rsa_free( rsa );
02044         return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
02045     }
02046 
02047     rsa->len = mpi_size( &rsa->N );
02048 
02049     if( p != end )
02050     {
02051 #if defined(POLARSSL_PEM_C)
02052         pem_free( &pem );
02053 #endif
02054         rsa_free( rsa );
02055         return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
02056                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
02057     }
02058 
02059     if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
02060     {
02061 #if defined(POLARSSL_PEM_C)
02062         pem_free( &pem );
02063 #endif
02064         rsa_free( rsa );
02065         return( ret );
02066     }
02067 
02068 #if defined(POLARSSL_PEM_C)
02069     pem_free( &pem );
02070 #endif
02071 
02072     return( 0 );
02073 }
02074 
02075 /*
02076  * Parse a public RSA key
02077  */
02078 int x509parse_public_key( rsa_context *rsa, const unsigned char *key, size_t keylen )
02079 {
02080     int ret;
02081     size_t len;
02082     unsigned char *p, *end;
02083     x509_buf alg_oid;
02084 #if defined(POLARSSL_PEM_C)
02085     pem_context pem;
02086 
02087     pem_init( &pem );
02088     ret = pem_read_buffer( &pem,
02089             "-----BEGIN PUBLIC KEY-----",
02090             "-----END PUBLIC KEY-----",
02091             key, NULL, 0, &len );
02092 
02093     if( ret == 0 )
02094     {
02095         /*
02096          * Was PEM encoded
02097          */
02098         keylen = pem.buflen;
02099     }
02100     else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
02101     {
02102         pem_free( &pem );
02103         return( ret );
02104     }
02105 
02106     p = ( ret == 0 ) ? pem.buf : (unsigned char *) key;
02107 #else
02108     p = (unsigned char *) key;
02109 #endif
02110     end = p + keylen;
02111 
02112     /*
02113      *  PublicKeyInfo ::= SEQUENCE {
02114      *    algorithm       AlgorithmIdentifier,
02115      *    PublicKey       BIT STRING
02116      *  }
02117      *
02118      *  AlgorithmIdentifier ::= SEQUENCE {
02119      *    algorithm       OBJECT IDENTIFIER,
02120      *    parameters      ANY DEFINED BY algorithm OPTIONAL
02121      *  }
02122      *
02123      *  RSAPublicKey ::= SEQUENCE {
02124      *      modulus           INTEGER,  -- n
02125      *      publicExponent    INTEGER   -- e
02126      *  }
02127      */
02128 
02129     if( ( ret = asn1_get_tag( &p, end, &len,
02130                     ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
02131     {
02132 #if defined(POLARSSL_PEM_C)
02133         pem_free( &pem );
02134 #endif
02135         rsa_free( rsa );
02136         return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
02137     }
02138 
02139     if( ( ret = x509_get_pubkey( &p, end, &alg_oid, &rsa->N, &rsa->E ) ) != 0 )
02140     {
02141 #if defined(POLARSSL_PEM_C)
02142         pem_free( &pem );
02143 #endif
02144         rsa_free( rsa );
02145         return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
02146     }
02147 
02148     if( ( ret = rsa_check_pubkey( rsa ) ) != 0 )
02149     {
02150 #if defined(POLARSSL_PEM_C)
02151         pem_free( &pem );
02152 #endif
02153         rsa_free( rsa );
02154         return( ret );
02155     }
02156 
02157     rsa->len = mpi_size( &rsa->N );
02158 
02159 #if defined(POLARSSL_PEM_C)
02160     pem_free( &pem );
02161 #endif
02162 
02163     return( 0 );
02164 }
02165 
02166 #if defined(POLARSSL_DHM_C)
02167 /*
02168  * Parse DHM parameters
02169  */
02170 int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, size_t dhminlen )
02171 {
02172     int ret;
02173     size_t len;
02174     unsigned char *p, *end;
02175 #if defined(POLARSSL_PEM_C)
02176     pem_context pem;
02177 
02178     pem_init( &pem );
02179 
02180     ret = pem_read_buffer( &pem, 
02181                            "-----BEGIN DH PARAMETERS-----",
02182                            "-----END DH PARAMETERS-----",
02183                            dhmin, NULL, 0, &dhminlen );
02184 
02185     if( ret == 0 )
02186     {
02187         /*
02188          * Was PEM encoded
02189          */
02190         dhminlen = pem.buflen;
02191     }
02192     else if( ret != POLARSSL_ERR_PEM_NO_HEADER_PRESENT )
02193     {
02194         pem_free( &pem );
02195         return( ret );
02196     }
02197 
02198     p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
02199 #else
02200     p = (unsigned char *) dhmin;
02201 #endif
02202     end = p + dhminlen;
02203 
02204     memset( dhm, 0, sizeof( dhm_context ) );
02205 
02206     /*
02207      *  DHParams ::= SEQUENCE {
02208      *      prime            INTEGER,  -- P
02209      *      generator        INTEGER,  -- g
02210      *  }
02211      */
02212     if( ( ret = asn1_get_tag( &p, end, &len,
02213             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
02214     {
02215 #if defined(POLARSSL_PEM_C)
02216         pem_free( &pem );
02217 #endif
02218         return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
02219     }
02220 
02221     end = p + len;
02222 
02223     if( ( ret = asn1_get_mpi( &p, end, &dhm->P  ) ) != 0 ||
02224         ( ret = asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
02225     {
02226 #if defined(POLARSSL_PEM_C)
02227         pem_free( &pem );
02228 #endif
02229         dhm_free( dhm );
02230         return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT + ret );
02231     }
02232 
02233     if( p != end )
02234     {
02235 #if defined(POLARSSL_PEM_C)
02236         pem_free( &pem );
02237 #endif
02238         dhm_free( dhm );
02239         return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT +
02240                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
02241     }
02242 
02243 #if defined(POLARSSL_PEM_C)
02244     pem_free( &pem );
02245 #endif
02246 
02247     return( 0 );
02248 }
02249 
02250 #if defined(POLARSSL_FS_IO)
02251 /*
02252  * Load and parse a private RSA key
02253  */
02254 int x509parse_dhmfile( dhm_context *dhm, const char *path )
02255 {
02256     int ret;
02257     size_t n;
02258     unsigned char *buf;
02259 
02260     if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
02261         return( ret );
02262 
02263     ret = x509parse_dhm( dhm, buf, n );
02264 
02265     memset( buf, 0, n + 1 );
02266     free( buf );
02267 
02268     return( ret );
02269 }
02270 #endif /* POLARSSL_FS_IO */
02271 #endif /* POLARSSL_DHM_C */
02272 
02273 #if defined _MSC_VER && !defined snprintf
02274 #include <stdarg.h>
02275 
02276 #if !defined vsnprintf
02277 #define vsnprintf _vsnprintf
02278 #endif // vsnprintf
02279 
02280 /*
02281  * Windows _snprintf and _vsnprintf are not compatible to linux versions.
02282  * Result value is not size of buffer needed, but -1 if no fit is possible.
02283  *
02284  * This fuction tries to 'fix' this by at least suggesting enlarging the
02285  * size by 20.
02286  */
02287 int compat_snprintf(char *str, size_t size, const char *format, ...)
02288 {
02289     va_list ap;
02290     int res = -1;
02291 
02292     va_start( ap, format );
02293 
02294     res = vsnprintf( str, size, format, ap );
02295 
02296     va_end( ap );
02297 
02298     // No quick fix possible
02299     if ( res < 0 )
02300         return( (int) size + 20 );
02301     
02302     return res;
02303 }
02304 
02305 #define snprintf compat_snprintf
02306 #endif
02307 
02308 #define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL    -2
02309 
02310 #define SAFE_SNPRINTF()                         \
02311 {                                               \
02312     if( ret == -1 )                             \
02313         return( -1 );                           \
02314                                                 \
02315     if ( (unsigned int) ret > n ) {             \
02316         p[n - 1] = '\0';                        \
02317         return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
02318     }                                           \
02319                                                 \
02320     n -= (unsigned int) ret;                    \
02321     p += (unsigned int) ret;                    \
02322 }
02323 
02324 /*
02325  * Store the name in printable form into buf; no more
02326  * than size characters will be written
02327  */
02328 int x509parse_dn_gets( char *buf, size_t size, const x509_name *dn )
02329 {
02330     int ret;
02331     size_t i, n;
02332     unsigned char c;
02333     const x509_name *name;
02334     char s[128], *p;
02335 
02336     memset( s, 0, sizeof( s ) );
02337 
02338     name = dn;
02339     p = buf;
02340     n = size;
02341 
02342     while( name != NULL )
02343     {
02344         if( name != dn )
02345         {
02346             ret = snprintf( p, n, ", " );
02347             SAFE_SNPRINTF();
02348         }
02349 
02350         if( memcmp( name->oid.p, OID_X520, 2 ) == 0 )
02351         {
02352             switch( name->oid.p[2] )
02353             {
02354             case X520_COMMON_NAME:
02355                 ret = snprintf( p, n, "CN=" ); break;
02356 
02357             case X520_COUNTRY:
02358                 ret = snprintf( p, n, "C="  ); break;
02359 
02360             case X520_LOCALITY:
02361                 ret = snprintf( p, n, "L="  ); break;
02362 
02363             case X520_STATE:
02364                 ret = snprintf( p, n, "ST=" ); break;
02365 
02366             case X520_ORGANIZATION:
02367                 ret = snprintf( p, n, "O="  ); break;
02368 
02369             case X520_ORG_UNIT:
02370                 ret = snprintf( p, n, "OU=" ); break;
02371 
02372             default:
02373                 ret = snprintf( p, n, "0x%02X=",
02374                                name->oid.p[2] );
02375                 break;
02376             }
02377         SAFE_SNPRINTF();
02378         }
02379         else if( memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
02380         {
02381             switch( name->oid.p[8] )
02382             {
02383             case PKCS9_EMAIL:
02384                 ret = snprintf( p, n, "emailAddress=" ); break;
02385 
02386             default:
02387                 ret = snprintf( p, n, "0x%02X=",
02388                                name->oid.p[8] );
02389                 break;
02390             }
02391         SAFE_SNPRINTF();
02392         }
02393         else
02394         {
02395             ret = snprintf( p, n, "\?\?=" );
02396             SAFE_SNPRINTF();
02397         }
02398 
02399         for( i = 0; i < name->val.len; i++ )
02400         {
02401             if( i >= sizeof( s ) - 1 )
02402                 break;
02403 
02404             c = name->val.p[i];
02405             if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
02406                  s[i] = '?';
02407             else s[i] = c;
02408         }
02409         s[i] = '\0';
02410         ret = snprintf( p, n, "%s", s );
02411     SAFE_SNPRINTF();
02412         name = name->next;
02413     }
02414 
02415     return( (int) ( size - n ) );
02416 }
02417 
02418 /*
02419  * Store the serial in printable form into buf; no more
02420  * than size characters will be written
02421  */
02422 int x509parse_serial_gets( char *buf, size_t size, const x509_buf *serial )
02423 {
02424     int ret;
02425     size_t i, n, nr;
02426     char *p;
02427 
02428     p = buf;
02429     n = size;
02430 
02431     nr = ( serial->len <= 32 )
02432         ? serial->len  : 28;
02433 
02434     for( i = 0; i < nr; i++ )
02435     {
02436         if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
02437             continue;
02438 
02439         ret = snprintf( p, n, "%02X%s",
02440                 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
02441         SAFE_SNPRINTF();
02442     }
02443 
02444     if( nr != serial->len )
02445     {
02446         ret = snprintf( p, n, "...." );
02447         SAFE_SNPRINTF();
02448     }
02449 
02450     return( (int) ( size - n ) );
02451 }
02452 
02453 /*
02454  * Return an informational string about the certificate.
02455  */
02456 int x509parse_cert_info( char *buf, size_t size, const char *prefix,
02457                          const x509_cert *crt )
02458 {
02459     int ret;
02460     size_t n;
02461     char *p;
02462 
02463     p = buf;
02464     n = size;
02465 
02466     ret = snprintf( p, n, "%scert. version : %d\n",
02467                                prefix, crt->version );
02468     SAFE_SNPRINTF();
02469     ret = snprintf( p, n, "%sserial number : ",
02470                                prefix );
02471     SAFE_SNPRINTF();
02472 
02473     ret = x509parse_serial_gets( p, n, &crt->serial);
02474     SAFE_SNPRINTF();
02475 
02476     ret = snprintf( p, n, "\n%sissuer name   : ", prefix );
02477     SAFE_SNPRINTF();
02478     ret = x509parse_dn_gets( p, n, &crt->issuer  );
02479     SAFE_SNPRINTF();
02480 
02481     ret = snprintf( p, n, "\n%ssubject name  : ", prefix );
02482     SAFE_SNPRINTF();
02483     ret = x509parse_dn_gets( p, n, &crt->subject );
02484     SAFE_SNPRINTF();
02485 
02486     ret = snprintf( p, n, "\n%sissued  on    : " \
02487                    "%04d-%02d-%02d %02d:%02d:%02d", prefix,
02488                    crt->valid_from.year, crt->valid_from.mon,
02489                    crt->valid_from.day,  crt->valid_from.hour,
02490                    crt->valid_from.min,  crt->valid_from.sec );
02491     SAFE_SNPRINTF();
02492 
02493     ret = snprintf( p, n, "\n%sexpires on    : " \
02494                    "%04d-%02d-%02d %02d:%02d:%02d", prefix,
02495                    crt->valid_to.year, crt->valid_to.mon,
02496                    crt->valid_to.day,  crt->valid_to.hour,
02497                    crt->valid_to.min,  crt->valid_to.sec );
02498     SAFE_SNPRINTF();
02499 
02500     ret = snprintf( p, n, "\n%ssigned using  : RSA+", prefix );
02501     SAFE_SNPRINTF();
02502 
02503     switch( crt->sig_alg )
02504     {
02505         case SIG_RSA_MD2    : ret = snprintf( p, n, "MD2"    ); break;
02506         case SIG_RSA_MD4    : ret = snprintf( p, n, "MD4"    ); break;
02507         case SIG_RSA_MD5    : ret = snprintf( p, n, "MD5"    ); break;
02508         case SIG_RSA_SHA1   : ret = snprintf( p, n, "SHA1"   ); break;
02509         case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
02510         case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
02511         case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
02512         case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
02513         default: ret = snprintf( p, n, "???"  ); break;
02514     }
02515     SAFE_SNPRINTF();
02516 
02517     ret = snprintf( p, n, "\n%sRSA key size  : %d bits\n", prefix,
02518                    (int) crt->rsa.N.n * (int) sizeof( unsigned long ) * 8 );
02519     SAFE_SNPRINTF();
02520 
02521     return( (int) ( size - n ) );
02522 }
02523 
02524 /* Compare a given OID string with an OID x509_buf * */
02525 #define OID_CMP(oid_str, oid_buf) \
02526         ( ( OID_SIZE(oid_str) == (oid_buf)->len ) && \
02527                 memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) == 0)
02528 
02529 /*
02530  * Return an informational string describing the given OID
02531  */
02532 const char *x509_oid_get_description( x509_buf *oid )
02533 {
02534     if ( oid == NULL )
02535         return ( NULL );
02536     
02537     else if( OID_CMP( OID_SERVER_AUTH, oid ) )
02538         return( STRING_SERVER_AUTH );
02539     
02540     else if( OID_CMP( OID_CLIENT_AUTH, oid ) )
02541         return( STRING_CLIENT_AUTH );
02542     
02543     else if( OID_CMP( OID_CODE_SIGNING, oid ) )
02544         return( STRING_CODE_SIGNING );
02545     
02546     else if( OID_CMP( OID_EMAIL_PROTECTION, oid ) )
02547         return( STRING_EMAIL_PROTECTION );
02548     
02549     else if( OID_CMP( OID_TIME_STAMPING, oid ) )
02550         return( STRING_TIME_STAMPING );
02551 
02552     else if( OID_CMP( OID_OCSP_SIGNING, oid ) )
02553         return( STRING_OCSP_SIGNING );
02554 
02555     return( NULL );
02556 }
02557 
02558 /* Return the x.y.z.... style numeric string for the given OID */
02559 int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
02560 {
02561     int ret;
02562     size_t i, n;
02563     unsigned int value;
02564     char *p;
02565 
02566     p = buf;
02567     n = size;
02568 
02569     /* First byte contains first two dots */
02570     if( oid->len > 0 )
02571     {
02572         ret = snprintf( p, n, "%d.%d", oid->p[0]/40, oid->p[0]%40 );
02573         SAFE_SNPRINTF();
02574     }
02575 
02576     /* TODO: value can overflow in value. */
02577     value = 0;
02578     for( i = 1; i < oid->len; i++ )
02579     {
02580         value <<= 7;
02581         value += oid->p[i] & 0x7F;
02582 
02583         if( !( oid->p[i] & 0x80 ) )
02584         {
02585             /* Last byte */
02586             ret = snprintf( p, n, ".%d", value );
02587             SAFE_SNPRINTF();
02588             value = 0;
02589         }
02590     }
02591 
02592     return( (int) ( size - n ) );
02593 }
02594 
02595 /*
02596  * Return an informational string about the CRL.
02597  */
02598 int x509parse_crl_info( char *buf, size_t size, const char *prefix,
02599                         const x509_crl *crl )
02600 {
02601     int ret;
02602     size_t n;
02603     char *p;
02604     const x509_crl_entry *entry;
02605 
02606     p = buf;
02607     n = size;
02608 
02609     ret = snprintf( p, n, "%sCRL version   : %d",
02610                                prefix, crl->version );
02611     SAFE_SNPRINTF();
02612 
02613     ret = snprintf( p, n, "\n%sissuer name   : ", prefix );
02614     SAFE_SNPRINTF();
02615     ret = x509parse_dn_gets( p, n, &crl->issuer );
02616     SAFE_SNPRINTF();
02617 
02618     ret = snprintf( p, n, "\n%sthis update   : " \
02619                    "%04d-%02d-%02d %02d:%02d:%02d", prefix,
02620                    crl->this_update.year, crl->this_update.mon,
02621                    crl->this_update.day,  crl->this_update.hour,
02622                    crl->this_update.min,  crl->this_update.sec );
02623     SAFE_SNPRINTF();
02624 
02625     ret = snprintf( p, n, "\n%snext update   : " \
02626                    "%04d-%02d-%02d %02d:%02d:%02d", prefix,
02627                    crl->next_update.year, crl->next_update.mon,
02628                    crl->next_update.day,  crl->next_update.hour,
02629                    crl->next_update.min,  crl->next_update.sec );
02630     SAFE_SNPRINTF();
02631 
02632     entry = &crl->entry;
02633 
02634     ret = snprintf( p, n, "\n%sRevoked certificates:",
02635                                prefix );
02636     SAFE_SNPRINTF();
02637 
02638     while( entry != NULL && entry->raw.len != 0 )
02639     {
02640         ret = snprintf( p, n, "\n%sserial number: ",
02641                                prefix );
02642         SAFE_SNPRINTF();
02643 
02644         ret = x509parse_serial_gets( p, n, &entry->serial);
02645         SAFE_SNPRINTF();
02646 
02647         ret = snprintf( p, n, " revocation date: " \
02648                    "%04d-%02d-%02d %02d:%02d:%02d",
02649                    entry->revocation_date.year, entry->revocation_date.mon,
02650                    entry->revocation_date.day,  entry->revocation_date.hour,
02651                    entry->revocation_date.min,  entry->revocation_date.sec );
02652         SAFE_SNPRINTF();
02653 
02654         entry = entry->next;
02655     }
02656 
02657     ret = snprintf( p, n, "\n%ssigned using  : RSA+", prefix );
02658     SAFE_SNPRINTF();
02659 
02660     switch( crl->sig_alg )
02661     {
02662         case SIG_RSA_MD2    : ret = snprintf( p, n, "MD2"    ); break;
02663         case SIG_RSA_MD4    : ret = snprintf( p, n, "MD4"    ); break;
02664         case SIG_RSA_MD5    : ret = snprintf( p, n, "MD5"    ); break;
02665         case SIG_RSA_SHA1   : ret = snprintf( p, n, "SHA1"   ); break;
02666         case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
02667         case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
02668         case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
02669         case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
02670         default: ret = snprintf( p, n, "???"  ); break;
02671     }
02672     SAFE_SNPRINTF();
02673 
02674     ret = snprintf( p, n, "\n" );
02675     SAFE_SNPRINTF();
02676 
02677     return( (int) ( size - n ) );
02678 }
02679 
02680 /*
02681  * Return 0 if the x509_time is still valid, or 1 otherwise.
02682  */
02683 int x509parse_time_expired( const x509_time *to )
02684 {
02685     int year, mon, day;
02686     int hour, min, sec;
02687 
02688 #if defined(_WIN32)
02689     SYSTEMTIME st;
02690 
02691     GetLocalTime(&st);
02692 
02693     year = st.wYear;
02694     mon = st.wMonth;
02695     day = st.wDay;
02696     hour = st.wHour;
02697     min = st.wMinute;
02698     sec = st.wSecond;
02699 #else
02700     struct tm *lt;
02701     time_t tt;
02702 
02703     tt = time( NULL );
02704     lt = localtime( &tt );
02705 
02706     year = lt->tm_year + 1900;
02707     mon = lt->tm_mon + 1;
02708     day = lt->tm_mday;
02709     hour = lt->tm_hour;
02710     min = lt->tm_min;
02711     sec = lt->tm_sec;
02712 #endif
02713 
02714     if( year  > to->year )
02715         return( 1 );
02716 
02717     if( year == to->year &&
02718         mon   > to->mon )
02719         return( 1 );
02720 
02721     if( year == to->year &&
02722         mon  == to->mon  &&
02723         day   > to->day )
02724         return( 1 );
02725 
02726     if( year == to->year &&
02727         mon  == to->mon  &&
02728         day  == to->day  &&
02729         hour  > to->hour )
02730         return( 1 );
02731 
02732     if( year == to->year &&
02733         mon  == to->mon  &&
02734         day  == to->day  &&
02735         hour == to->hour &&
02736         min   > to->min  )
02737         return( 1 );
02738 
02739     if( year == to->year &&
02740         mon  == to->mon  &&
02741         day  == to->day  &&
02742         hour == to->hour &&
02743         min  == to->min  &&
02744         sec   > to->sec  )
02745         return( 1 );
02746 
02747     return( 0 );
02748 }
02749 
02750 /*
02751  * Return 1 if the certificate is revoked, or 0 otherwise.
02752  */
02753 int x509parse_revoked( const x509_cert *crt, const x509_crl *crl )
02754 {
02755     const x509_crl_entry *cur = &crl->entry;
02756 
02757     while( cur != NULL && cur->serial.len != 0 )
02758     {
02759         if( crt->serial.len == cur->serial.len &&
02760             memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
02761         {
02762             if( x509parse_time_expired( &cur->revocation_date ) )
02763                 return( 1 );
02764         }
02765 
02766         cur = cur->next;
02767     }
02768 
02769     return( 0 );
02770 }
02771 
02772 /*
02773  * Wrapper for x509 hashes.
02774  *
02775  * \param out   Buffer to receive the hash (Should be at least 64 bytes)
02776  */
02777 static void x509_hash( const unsigned char *in, size_t len, int alg,
02778                        unsigned char *out )
02779 {
02780     switch( alg )
02781     {
02782 #if defined(POLARSSL_MD2_C)
02783         case SIG_RSA_MD2    :  md2( in, len, out ); break;
02784 #endif
02785 #if defined(POLARSSL_MD4_C)
02786         case SIG_RSA_MD4    :  md4( in, len, out ); break;
02787 #endif
02788 #if defined(POLARSSL_MD5_C)
02789         case SIG_RSA_MD5    :  md5( in, len, out ); break;
02790 #endif
02791 #if defined(POLARSSL_SHA1_C)
02792         case SIG_RSA_SHA1   : sha1( in, len, out ); break;
02793 #endif
02794 #if defined(POLARSSL_SHA2_C)
02795         case SIG_RSA_SHA224 : sha2( in, len, out, 1 ); break;
02796         case SIG_RSA_SHA256 : sha2( in, len, out, 0 ); break;
02797 #endif
02798 #if defined(POLARSSL_SHA4_C)
02799         case SIG_RSA_SHA384 : sha4( in, len, out, 1 ); break;
02800         case SIG_RSA_SHA512 : sha4( in, len, out, 0 ); break;
02801 #endif
02802         default:
02803             memset( out, '\xFF', 64 );
02804             break;
02805     }
02806 }
02807 
02808 /*
02809  * Check that the given certificate is valid accoring to the CRL.
02810  */
02811 static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca,
02812         x509_crl *crl_list)
02813 {
02814     int flags = 0;
02815     int hash_id;
02816     unsigned char hash[64];
02817 
02818     /*
02819      * TODO: What happens if no CRL is present?
02820      * Suggestion: Revocation state should be unknown if no CRL is present.
02821      * For backwards compatibility this is not yet implemented.
02822      */
02823 
02824     while( ca != NULL && crl_list != NULL && crl_list->version != 0 )
02825     {
02826         if( crl_list->issuer_raw.len != ca->subject_raw.len ||
02827             memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
02828                     crl_list->issuer_raw.len ) != 0 )
02829         {
02830             crl_list = crl_list->next;
02831             continue;
02832         }
02833 
02834         /*
02835          * Check if CRL is correctly signed by the trusted CA
02836          */
02837         hash_id = crl_list->sig_alg;
02838 
02839         x509_hash( crl_list->tbs.p, crl_list->tbs.len, hash_id, hash );
02840 
02841         if( !rsa_pkcs1_verify( &ca->rsa, RSA_PUBLIC, hash_id,
02842                               0, hash, crl_list->sig.p ) == 0 )
02843         {
02844             /*
02845              * CRL is not trusted
02846              */
02847             flags |= BADCRL_NOT_TRUSTED;
02848             break;
02849         }
02850 
02851         /*
02852          * Check for validity of CRL (Do not drop out)
02853          */
02854         if( x509parse_time_expired( &crl_list->next_update ) )
02855             flags |= BADCRL_EXPIRED;
02856 
02857         /*
02858          * Check if certificate is revoked
02859          */
02860         if( x509parse_revoked(crt, crl_list) )
02861         {
02862             flags |= BADCERT_REVOKED;
02863             break;
02864         }
02865 
02866         crl_list = crl_list->next;
02867     }
02868     return flags;
02869 }
02870 
02871 /*
02872  * Verify the certificate validity
02873  */
02874 int x509parse_verify( x509_cert *crt,
02875                       x509_cert *trust_ca,
02876                       x509_crl *ca_crl,
02877                       const char *cn, int *flags,
02878                       int (*f_vrfy)(void *, x509_cert *, int, int),
02879                       void *p_vrfy )
02880 {
02881     size_t cn_len;
02882     int hash_id;
02883     int pathlen;
02884     x509_cert *parent;
02885     x509_name *name;
02886     unsigned char hash[64];
02887 
02888     *flags = 0;
02889 
02890     if( x509parse_time_expired( &crt->valid_to ) )
02891         *flags = BADCERT_EXPIRED;
02892 
02893     if( cn != NULL )
02894     {
02895         name = &crt->subject;
02896         cn_len = strlen( cn );
02897 
02898         while( name != NULL )
02899         {
02900             if( memcmp( name->oid.p, OID_CN,  3 ) == 0 &&
02901                 memcmp( name->val.p, cn, cn_len ) == 0 &&
02902                 name->val.len == cn_len )
02903                 break;
02904 
02905             name = name->next;
02906         }
02907 
02908         if( name == NULL )
02909             *flags |= BADCERT_CN_MISMATCH;
02910     }
02911 
02912     /*
02913      * Iterate upwards in the given cert chain,
02914      * ignoring any upper cert with CA != TRUE.
02915      */
02916     parent = crt->next;
02917 
02918     pathlen = 1;
02919 
02920     while( parent != NULL && parent->version != 0 )
02921     {
02922         if( parent->ca_istrue == 0 ||
02923             crt->issuer_raw.len != parent->subject_raw.len ||
02924             memcmp( crt->issuer_raw.p, parent->subject_raw.p,
02925                     crt->issuer_raw.len ) != 0 )
02926         {
02927             parent = parent->next;
02928             continue;
02929         }
02930 
02931         hash_id = crt->sig_alg;
02932 
02933         x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
02934 
02935         if( rsa_pkcs1_verify( &parent->rsa, RSA_PUBLIC, hash_id, 0, hash,
02936                     crt->sig.p ) != 0 )
02937             *flags |= BADCERT_NOT_TRUSTED;
02938         
02939         /* Check trusted CA's CRL for the given crt */
02940         *flags |= x509parse_verifycrl(crt, parent, ca_crl);
02941 
02942         /* crt is verified to be a child of the parent cur, call verify callback */
02943         if( NULL != f_vrfy )
02944         {
02945             if( f_vrfy( p_vrfy, crt, pathlen - 1, ( *flags == 0 ) ) != 0 )
02946                 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
02947             else
02948                 *flags = 0;
02949         }
02950         else if( *flags != 0 )
02951             return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
02952 
02953         pathlen++;
02954 
02955         crt = parent;
02956         parent = crt->next;
02957     }
02958 
02959     /*
02960      * Attempt to validate topmost cert with our CA chain.
02961      */
02962     *flags |= BADCERT_NOT_TRUSTED;
02963 
02964     while( trust_ca != NULL && trust_ca->version != 0 )
02965     {
02966         if( crt->issuer_raw.len != trust_ca->subject_raw.len ||
02967             memcmp( crt->issuer_raw.p, trust_ca->subject_raw.p,
02968                     crt->issuer_raw.len ) != 0 )
02969         {
02970             trust_ca = trust_ca->next;
02971             continue;
02972         }
02973 
02974         if( trust_ca->max_pathlen > 0 &&
02975             trust_ca->max_pathlen < pathlen )
02976             break;
02977 
02978         hash_id = crt->sig_alg;
02979 
02980         x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
02981 
02982         if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
02983                               0, hash, crt->sig.p ) == 0 )
02984         {
02985             /*
02986              * cert. is signed by a trusted CA
02987              */
02988             *flags &= ~BADCERT_NOT_TRUSTED;
02989             break;
02990         }
02991 
02992         trust_ca = trust_ca->next;
02993     }
02994 
02995     /* Check trusted CA's CRL for the given crt */
02996     *flags |= x509parse_verifycrl( crt, trust_ca, ca_crl );
02997 
02998     /* Verification succeeded, call callback on top cert */
02999     if( NULL != f_vrfy )
03000     {
03001         if( f_vrfy(p_vrfy, crt, pathlen-1, ( *flags == 0 ) ) != 0 ) 
03002             return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
03003         else
03004             *flags = 0;
03005     }
03006     else if( *flags != 0 )
03007         return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
03008 
03009     return( 0 );
03010 }
03011 
03012 /*
03013  * Unallocate all certificate data
03014  */
03015 void x509_free( x509_cert *crt )
03016 {
03017     x509_cert *cert_cur = crt;
03018     x509_cert *cert_prv;
03019     x509_name *name_cur;
03020     x509_name *name_prv;
03021     x509_sequence *seq_cur;
03022     x509_sequence *seq_prv;
03023 
03024     if( crt == NULL )
03025         return;
03026 
03027     do
03028     {
03029         rsa_free( &cert_cur->rsa );
03030 
03031         name_cur = cert_cur->issuer.next;
03032         while( name_cur != NULL )
03033         {
03034             name_prv = name_cur;
03035             name_cur = name_cur->next;
03036             memset( name_prv, 0, sizeof( x509_name ) );
03037             free( name_prv );
03038         }
03039 
03040         name_cur = cert_cur->subject.next;
03041         while( name_cur != NULL )
03042         {
03043             name_prv = name_cur;
03044             name_cur = name_cur->next;
03045             memset( name_prv, 0, sizeof( x509_name ) );
03046             free( name_prv );
03047         }
03048 
03049         seq_cur = cert_cur->ext_key_usage.next;
03050         while( seq_cur != NULL )
03051         {
03052             seq_prv = seq_cur;
03053             seq_cur = seq_cur->next;
03054             memset( seq_prv, 0, sizeof( x509_sequence ) );
03055             free( seq_prv );
03056         }
03057 
03058         if( cert_cur->raw.p != NULL )
03059         {
03060             memset( cert_cur->raw.p, 0, cert_cur->raw.len );
03061             free( cert_cur->raw.p );
03062         }
03063 
03064         cert_cur = cert_cur->next;
03065     }
03066     while( cert_cur != NULL );
03067 
03068     cert_cur = crt;
03069     do
03070     {
03071         cert_prv = cert_cur;
03072         cert_cur = cert_cur->next;
03073 
03074         memset( cert_prv, 0, sizeof( x509_cert ) );
03075         if( cert_prv != crt )
03076             free( cert_prv );
03077     }
03078     while( cert_cur != NULL );
03079 }
03080 
03081 /*
03082  * Unallocate all CRL data
03083  */
03084 void x509_crl_free( x509_crl *crl )
03085 {
03086     x509_crl *crl_cur = crl;
03087     x509_crl *crl_prv;
03088     x509_name *name_cur;
03089     x509_name *name_prv;
03090     x509_crl_entry *entry_cur;
03091     x509_crl_entry *entry_prv;
03092 
03093     if( crl == NULL )
03094         return;
03095 
03096     do
03097     {
03098         name_cur = crl_cur->issuer.next;
03099         while( name_cur != NULL )
03100         {
03101             name_prv = name_cur;
03102             name_cur = name_cur->next;
03103             memset( name_prv, 0, sizeof( x509_name ) );
03104             free( name_prv );
03105         }
03106 
03107         entry_cur = crl_cur->entry.next;
03108         while( entry_cur != NULL )
03109         {
03110             entry_prv = entry_cur;
03111             entry_cur = entry_cur->next;
03112             memset( entry_prv, 0, sizeof( x509_crl_entry ) );
03113             free( entry_prv );
03114         }
03115 
03116         if( crl_cur->raw.p != NULL )
03117         {
03118             memset( crl_cur->raw.p, 0, crl_cur->raw.len );
03119             free( crl_cur->raw.p );
03120         }
03121 
03122         crl_cur = crl_cur->next;
03123     }
03124     while( crl_cur != NULL );
03125 
03126     crl_cur = crl;
03127     do
03128     {
03129         crl_prv = crl_cur;
03130         crl_cur = crl_cur->next;
03131 
03132         memset( crl_prv, 0, sizeof( x509_crl ) );
03133         if( crl_prv != crl )
03134             free( crl_prv );
03135     }
03136     while( crl_cur != NULL );
03137 }
03138 
03139 #if defined(POLARSSL_SELF_TEST)
03140 
03141 #include "polarssl/certs.h"
03142 
03143 /*
03144  * Checkup routine
03145  */
03146 int x509_self_test( int verbose )
03147 {
03148 #if defined(POLARSSL_CERTS_C) && defined(POLARSSL_MD5_C)
03149     int ret;
03150     int flags;
03151     size_t i, j;
03152     x509_cert cacert;
03153     x509_cert clicert;
03154     rsa_context rsa;
03155 #if defined(POLARSSL_DHM_C)
03156     dhm_context dhm;
03157 #endif
03158 
03159     if( verbose != 0 )
03160         printf( "  X.509 certificate load: " );
03161 
03162     memset( &clicert, 0, sizeof( x509_cert ) );
03163 
03164     ret = x509parse_crt( &clicert, (unsigned char *) test_cli_crt,
03165                          strlen( test_cli_crt ) );
03166     if( ret != 0 )
03167     {
03168         if( verbose != 0 )
03169             printf( "failed\n" );
03170 
03171         return( ret );
03172     }
03173 
03174     memset( &cacert, 0, sizeof( x509_cert ) );
03175 
03176     ret = x509parse_crt( &cacert, (unsigned char *) test_ca_crt,
03177                          strlen( test_ca_crt ) );
03178     if( ret != 0 )
03179     {
03180         if( verbose != 0 )
03181             printf( "failed\n" );
03182 
03183         return( ret );
03184     }
03185 
03186     if( verbose != 0 )
03187         printf( "passed\n  X.509 private key load: " );
03188 
03189     i = strlen( test_ca_key );
03190     j = strlen( test_ca_pwd );
03191 
03192     rsa_init( &rsa, RSA_PKCS_V15, 0 );
03193 
03194     if( ( ret = x509parse_key( &rsa,
03195                     (unsigned char *) test_ca_key, i,
03196                     (unsigned char *) test_ca_pwd, j ) ) != 0 )
03197     {
03198         if( verbose != 0 )
03199             printf( "failed\n" );
03200 
03201         return( ret );
03202     }
03203 
03204     if( verbose != 0 )
03205         printf( "passed\n  X.509 signature verify: ");
03206 
03207     ret = x509parse_verify( &clicert, &cacert, NULL, "PolarSSL Client 2", &flags, NULL, NULL );
03208     if( ret != 0 )
03209     {
03210         printf("%02x", flags);
03211         if( verbose != 0 )
03212             printf( "failed\n" );
03213 
03214         return( ret );
03215     }
03216 
03217 #if defined(POLARSSL_DHM_C)
03218     if( verbose != 0 )
03219         printf( "passed\n  X.509 DHM parameter load: " );
03220 
03221     i = strlen( test_dhm_params );
03222     j = strlen( test_ca_pwd );
03223 
03224     if( ( ret = x509parse_dhm( &dhm, (unsigned char *) test_dhm_params, i ) ) != 0 )
03225     {
03226         if( verbose != 0 )
03227             printf( "failed\n" );
03228 
03229         return( ret );
03230     }
03231 
03232     if( verbose != 0 )
03233         printf( "passed\n\n" );
03234 #endif
03235 
03236     x509_free( &cacert  );
03237     x509_free( &clicert );
03238     rsa_free( &rsa );
03239 #if defined(POLARSSL_DHM_C)
03240     dhm_free( &dhm );
03241 #endif
03242 
03243     return( 0 );
03244 #else
03245     ((void) verbose);
03246     return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
03247 #endif
03248 }
03249 
03250 #endif
03251 
03252 #endif