/home/dko/projects/mobilec/tags/MobileC-v1.10.2/MobileC-v1.10.2/src/security/xyssl-0.9/library/x509parse.c

Go to the documentation of this file.
00001 /*
00002  *  X.509 certificate and private key decoding
00003  *
00004  *  Copyright (C) 2006-2007  Christophe Devine
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License along
00017  *  with this program; if not, write to the Free Software Foundation, Inc.,
00018  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00019  */
00020 /*
00021  *  The ITU-T X.509 standard defines a certificat format for PKI.
00022  *
00023  *  http://www.ietf.org/rfc/rfc2459.txt
00024  *  http://www.ietf.org/rfc/rfc3279.txt
00025  *
00026  *  ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc
00027  *
00028  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
00029  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
00030  */
00031 
00032 #include "xyssl/config.h"
00033 
00034 #if defined(XYSSL_X509_PARSE_C)
00035 
00036 #include "xyssl/x509.h"
00037 #include "xyssl/base64.h"
00038 #include "xyssl/des.h"
00039 #include "xyssl/md2.h"
00040 #include "xyssl/md4.h"
00041 #include "xyssl/md5.h"
00042 #include "xyssl/sha1.h"
00043 
00044 #include <string.h>
00045 #include <stdlib.h>
00046 #include <stdio.h>
00047 #include <time.h>
00048 
00049 /*
00050  * ASN.1 DER decoding routines
00051  */
00052 static int asn1_get_len( unsigned char **p,
00053                          unsigned char *end,
00054                          int *len )
00055 {
00056     if( ( end - *p ) < 1 )
00057         return( XYSSL_ERR_ASN1_OUT_OF_DATA );
00058 
00059     if( ( **p & 0x80 ) == 0 )
00060         *len = *(*p)++;
00061     else
00062     {
00063         switch( **p & 0x7F )
00064         {
00065         case 1:
00066             if( ( end - *p ) < 2 )
00067                 return( XYSSL_ERR_ASN1_OUT_OF_DATA );
00068 
00069             *len = (*p)[1];
00070             (*p) += 2;
00071             break;
00072 
00073         case 2:
00074             if( ( end - *p ) < 3 )
00075                 return( XYSSL_ERR_ASN1_OUT_OF_DATA );
00076 
00077             *len = ( (*p)[1] << 8 ) | (*p)[2];
00078             (*p) += 3;
00079             break;
00080 
00081         default:
00082             return( XYSSL_ERR_ASN1_INVALID_LENGTH );
00083             break;
00084         }
00085     }
00086 
00087     if( *len > (int) ( end - *p ) )
00088         return( XYSSL_ERR_ASN1_OUT_OF_DATA );
00089 
00090     return( 0 );
00091 }
00092 
00093 static int asn1_get_tag( unsigned char **p,
00094                          unsigned char *end,
00095                          int *len, int tag )
00096 {
00097     if( ( end - *p ) < 1 )
00098         return( XYSSL_ERR_ASN1_OUT_OF_DATA );
00099 
00100     if( **p != tag )
00101         return( XYSSL_ERR_ASN1_UNEXPECTED_TAG );
00102 
00103     (*p)++;
00104 
00105     return( asn1_get_len( p, end, len ) );
00106 }
00107 
00108 static int asn1_get_bool( unsigned char **p,
00109                           unsigned char *end,
00110                           int *val )
00111 {
00112     int ret, len;
00113 
00114     if( ( ret = asn1_get_tag( p, end, &len, ASN1_BOOLEAN ) ) != 0 )
00115         return( ret );
00116 
00117     if( len != 1 )
00118         return( XYSSL_ERR_ASN1_INVALID_LENGTH );
00119 
00120     *val = ( **p != 0 ) ? 1 : 0;
00121     (*p)++;
00122 
00123     return( 0 );
00124 }
00125 
00126 static int asn1_get_int( unsigned char **p,
00127                          unsigned char *end,
00128                          int *val )
00129 {
00130     int ret, len;
00131 
00132     if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
00133         return( ret );
00134 
00135     if( len > (int) sizeof( int ) || ( **p & 0x80 ) != 0 )
00136         return( XYSSL_ERR_ASN1_INVALID_LENGTH );
00137 
00138     *val = 0;
00139 
00140     while( len-- > 0 )
00141     {
00142         *val = ( *val << 8 ) | **p;
00143         (*p)++;
00144     }
00145 
00146     return( 0 );
00147 }
00148 
00149 static int asn1_get_mpi( unsigned char **p,
00150                          unsigned char *end,
00151                          mpi *X )
00152 {
00153     int ret, len;
00154 
00155     if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 )
00156         return( ret );
00157 
00158     ret = mpi_read_binary( X, *p, len );
00159 
00160     *p += len;
00161 
00162     return( ret );
00163 }
00164 
00165 /*
00166  *  Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
00167  */
00168 static int x509_get_version( unsigned char **p,
00169                              unsigned char *end,
00170                              int *ver )
00171 {
00172     int ret, len;
00173 
00174     if( ( ret = asn1_get_tag( p, end, &len,
00175             ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) != 0 )
00176     {
00177         if( ret == XYSSL_ERR_ASN1_UNEXPECTED_TAG )
00178             return( *ver = 0 );
00179 
00180         return( ret );
00181     }
00182 
00183     end = *p + len;
00184 
00185     if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
00186         return( XYSSL_ERR_X509_CERT_INVALID_VERSION | ret );
00187 
00188     if( *p != end )
00189         return( XYSSL_ERR_X509_CERT_INVALID_VERSION |
00190                 XYSSL_ERR_ASN1_LENGTH_MISMATCH );
00191 
00192     return( 0 );
00193 }
00194 
00195 /*
00196  *  CertificateSerialNumber  ::=  INTEGER
00197  */
00198 static int x509_get_serial( unsigned char **p,
00199                             unsigned char *end,
00200                             x509_buf *serial )
00201 {
00202     int ret;
00203 
00204     if( ( end - *p ) < 1 )
00205         return( XYSSL_ERR_X509_CERT_INVALID_SERIAL |
00206                 XYSSL_ERR_ASN1_OUT_OF_DATA );
00207 
00208     if( **p != ( ASN1_CONTEXT_SPECIFIC | ASN1_PRIMITIVE | 2 ) &&
00209         **p !=   ASN1_INTEGER )
00210         return( XYSSL_ERR_X509_CERT_INVALID_SERIAL |
00211                 XYSSL_ERR_ASN1_UNEXPECTED_TAG );
00212 
00213     serial->tag = *(*p)++;
00214 
00215     if( ( ret = asn1_get_len( p, end, &serial->len ) ) != 0 )
00216         return( XYSSL_ERR_X509_CERT_INVALID_SERIAL | ret );
00217 
00218     serial->p = *p;
00219     *p += serial->len;
00220 
00221     return( 0 );
00222 }
00223 
00224 /*
00225  *  AlgorithmIdentifier  ::=  SEQUENCE  {
00226  *       algorithm               OBJECT IDENTIFIER,
00227  *       parameters              ANY DEFINED BY algorithm OPTIONAL  }
00228  */
00229 static int x509_get_alg( unsigned char **p,
00230                          unsigned char *end,
00231                          x509_buf *alg )
00232 {
00233     int ret, len;
00234 
00235     if( ( ret = asn1_get_tag( p, end, &len,
00236             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00237         return( XYSSL_ERR_X509_CERT_INVALID_ALG | ret );
00238 
00239     end = *p + len;
00240     alg->tag = **p;
00241 
00242     if( ( ret = asn1_get_tag( p, end, &alg->len, ASN1_OID ) ) != 0 )
00243         return( XYSSL_ERR_X509_CERT_INVALID_ALG | ret );
00244 
00245     alg->p = *p;
00246     *p += alg->len;
00247 
00248     if( *p == end )
00249         return( 0 );
00250 
00251     /*
00252      * assume the algorithm parameters must be NULL
00253      */
00254     if( ( ret = asn1_get_tag( p, end, &len, ASN1_NULL ) ) != 0 )
00255         return( XYSSL_ERR_X509_CERT_INVALID_ALG | ret );
00256 
00257     if( *p != end )
00258         return( XYSSL_ERR_X509_CERT_INVALID_ALG |
00259                 XYSSL_ERR_ASN1_LENGTH_MISMATCH );
00260 
00261     return( 0 );
00262 }
00263 
00264 /*
00265  *  RelativeDistinguishedName ::=
00266  *    SET OF AttributeTypeAndValue
00267  *
00268  *  AttributeTypeAndValue ::= SEQUENCE {
00269  *    type     AttributeType,
00270  *    value    AttributeValue }
00271  *
00272  *  AttributeType ::= OBJECT IDENTIFIER
00273  *
00274  *  AttributeValue ::= ANY DEFINED BY AttributeType
00275  */
00276 static int x509_get_name( unsigned char **p,
00277                           unsigned char *end,
00278                           x509_name *cur )
00279 {
00280     int ret, len;
00281     unsigned char *end2;
00282     x509_buf *oid;
00283     x509_buf *val;
00284 
00285     if( ( ret = asn1_get_tag( p, end, &len,
00286             ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 )
00287         return( XYSSL_ERR_X509_CERT_INVALID_NAME | ret );
00288 
00289     end2 = end;
00290     end  = *p + len;
00291 
00292     if( ( ret = asn1_get_tag( p, end, &len,
00293             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00294         return( XYSSL_ERR_X509_CERT_INVALID_NAME | ret );
00295 
00296     if( *p + len != end )
00297         return( XYSSL_ERR_X509_CERT_INVALID_NAME |
00298                 XYSSL_ERR_ASN1_LENGTH_MISMATCH );
00299 
00300     oid = &cur->oid;
00301     oid->tag = **p;
00302 
00303     if( ( ret = asn1_get_tag( p, end, &oid->len, ASN1_OID ) ) != 0 )
00304         return( XYSSL_ERR_X509_CERT_INVALID_NAME | ret );
00305 
00306     oid->p = *p;
00307     *p += oid->len;
00308 
00309     if( ( end - *p ) < 1 )
00310         return( XYSSL_ERR_X509_CERT_INVALID_NAME |
00311                 XYSSL_ERR_ASN1_OUT_OF_DATA );
00312 
00313     if( **p != ASN1_BMP_STRING && **p != ASN1_UTF8_STRING      &&
00314         **p != ASN1_T61_STRING && **p != ASN1_PRINTABLE_STRING &&
00315         **p != ASN1_IA5_STRING && **p != ASN1_UNIVERSAL_STRING )
00316         return( XYSSL_ERR_X509_CERT_INVALID_NAME |
00317                 XYSSL_ERR_ASN1_UNEXPECTED_TAG );
00318 
00319     val = &cur->val;
00320     val->tag = *(*p)++;
00321 
00322     if( ( ret = asn1_get_len( p, end, &val->len ) ) != 0 )
00323         return( XYSSL_ERR_X509_CERT_INVALID_NAME | ret );
00324 
00325     val->p = *p;
00326     *p += val->len;
00327 
00328     cur->next = NULL;
00329 
00330     if( *p != end )
00331         return( XYSSL_ERR_X509_CERT_INVALID_NAME |
00332                 XYSSL_ERR_ASN1_LENGTH_MISMATCH );
00333 
00334     /*
00335      * recurse until end of SEQUENCE is reached
00336      */
00337     if( *p == end2 )
00338         return( 0 );
00339 
00340     cur->next = (x509_name *) malloc(
00341          sizeof( x509_name ) );
00342 
00343     if( cur->next == NULL )
00344         return( 1 );
00345 
00346     return( x509_get_name( p, end2, cur->next ) );
00347 }
00348 
00349 /*
00350  *  Validity ::= SEQUENCE {
00351  *       notBefore      Time,
00352  *       notAfter       Time }
00353  *
00354  *  Time ::= CHOICE {
00355  *       utcTime        UTCTime,
00356  *       generalTime    GeneralizedTime }
00357  */
00358 static int x509_get_dates( unsigned char **p,
00359                            unsigned char *end,
00360                            x509_time *from,
00361                            x509_time *to )
00362 {
00363     int ret, len;
00364     char date[64];
00365 
00366     if( ( ret = asn1_get_tag( p, end, &len,
00367             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00368         return( XYSSL_ERR_X509_CERT_INVALID_DATE | ret );
00369 
00370     end = *p + len;
00371 
00372     /*
00373      * TODO: also handle GeneralizedTime
00374      */
00375     if( ( ret = asn1_get_tag( p, end, &len, ASN1_UTC_TIME ) ) != 0 )
00376         return( XYSSL_ERR_X509_CERT_INVALID_DATE | ret );
00377 
00378     memset( date,  0, sizeof( date ) );
00379     memcpy( date, *p, ( len < (int) sizeof( date ) - 1 ) ?
00380                         len : (int) sizeof( date ) - 1 );
00381 
00382     if( sscanf( date, "%2d%2d%2d%2d%2d%2d",
00383                 &from->year, &from->mon, &from->day,
00384                 &from->hour, &from->min, &from->sec ) < 5 )
00385         return( XYSSL_ERR_X509_CERT_INVALID_DATE );
00386 
00387     from->year +=  100 * ( from->year < 90 );
00388     from->year += 1900;
00389 
00390     *p += len;
00391 
00392     if( ( ret = asn1_get_tag( p, end, &len, ASN1_UTC_TIME ) ) != 0 )
00393         return( XYSSL_ERR_X509_CERT_INVALID_DATE | ret );
00394 
00395     memset( date,  0, sizeof( date ) );
00396     memcpy( date, *p, ( len < (int) sizeof( date ) - 1 ) ?
00397                         len : (int) sizeof( date ) - 1 );
00398 
00399     if( sscanf( date, "%2d%2d%2d%2d%2d%2d",
00400                 &to->year, &to->mon, &to->day,
00401                 &to->hour, &to->min, &to->sec ) < 5 ) 
00402         return( XYSSL_ERR_X509_CERT_INVALID_DATE );
00403 
00404     to->year +=  100 * ( to->year < 90 );
00405     to->year += 1900;
00406 
00407     *p += len;
00408 
00409     if( *p != end )
00410         return( XYSSL_ERR_X509_CERT_INVALID_DATE |
00411                 XYSSL_ERR_ASN1_LENGTH_MISMATCH );
00412 
00413     return( 0 );
00414 }
00415 
00416 /*
00417  *  SubjectPublicKeyInfo  ::=  SEQUENCE  {
00418  *       algorithm            AlgorithmIdentifier,
00419  *       subjectPublicKey     BIT STRING }
00420  */
00421 static int x509_get_pubkey( unsigned char **p,
00422                             unsigned char *end,
00423                             x509_buf *pk_alg_oid,
00424                             mpi *N, mpi *E )
00425 {
00426     int ret, 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     if( pk_alg_oid->len != 9 ||
00436         memcmp( pk_alg_oid->p, OID_PKCS1_RSA, 9 ) != 0 )
00437         return( XYSSL_ERR_X509_CERT_UNKNOWN_PK_ALG );
00438 
00439     if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
00440         return( XYSSL_ERR_X509_CERT_INVALID_PUBKEY | ret );
00441 
00442     if( ( end - *p ) < 1 )
00443         return( XYSSL_ERR_X509_CERT_INVALID_PUBKEY |
00444                 XYSSL_ERR_ASN1_OUT_OF_DATA );
00445 
00446     end2 = *p + len;
00447 
00448     if( *(*p)++ != 0 )
00449         return( XYSSL_ERR_X509_CERT_INVALID_PUBKEY );
00450 
00451     /*
00452      *  RSAPublicKey ::= SEQUENCE {
00453      *      modulus           INTEGER,  -- n
00454      *      publicExponent    INTEGER   -- e
00455      *  }
00456      */
00457     if( ( ret = asn1_get_tag( p, end2, &len,
00458             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00459         return( XYSSL_ERR_X509_CERT_INVALID_PUBKEY | ret );
00460 
00461     if( *p + len != end2 )
00462         return( XYSSL_ERR_X509_CERT_INVALID_PUBKEY |
00463                 XYSSL_ERR_ASN1_LENGTH_MISMATCH );
00464 
00465     if( ( ret = asn1_get_mpi( p, end2, N ) ) != 0 ||
00466         ( ret = asn1_get_mpi( p, end2, E ) ) != 0 )
00467         return( XYSSL_ERR_X509_CERT_INVALID_PUBKEY | ret );
00468 
00469     if( *p != end )
00470         return( XYSSL_ERR_X509_CERT_INVALID_PUBKEY |
00471                 XYSSL_ERR_ASN1_LENGTH_MISMATCH );
00472 
00473     return( 0 );
00474 }
00475 
00476 static int x509_get_sig( unsigned char **p,
00477                          unsigned char *end,
00478                          x509_buf *sig )
00479 {
00480     int ret, len;
00481 
00482     sig->tag = **p;
00483 
00484     if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
00485         return( XYSSL_ERR_X509_CERT_INVALID_SIGNATURE | ret );
00486 
00487     if( --len < 1 || *(*p)++ != 0 )
00488         return( XYSSL_ERR_X509_CERT_INVALID_SIGNATURE );
00489 
00490     sig->len = len;
00491     sig->p = *p;
00492 
00493     *p += len;
00494 
00495     return( 0 );
00496 }
00497 
00498 /*
00499  * X.509 v2/v3 unique identifier (not parsed)
00500  */
00501 static int x509_get_uid( unsigned char **p,
00502                          unsigned char *end,
00503                          x509_buf *uid, int n )
00504 {
00505     int ret;
00506 
00507     if( *p == end )
00508         return( 0 );
00509 
00510     uid->tag = **p;
00511 
00512     if( ( ret = asn1_get_tag( p, end, &uid->len,
00513             ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 )
00514     {
00515         if( ret == XYSSL_ERR_ASN1_UNEXPECTED_TAG )
00516             return( 0 );
00517 
00518         return( ret );
00519     }
00520 
00521     uid->p = *p;
00522     *p += uid->len;
00523 
00524     return( 0 );
00525 }
00526 
00527 /*
00528  * X.509 v3 extensions (only BasicConstraints are parsed)
00529  */
00530 static int x509_get_ext( unsigned char **p,
00531                          unsigned char *end,
00532                          x509_buf *ext,
00533                          int *ca_istrue,
00534                          int *max_pathlen )
00535 {
00536     int ret, len;
00537     int is_critical = 1;
00538     int is_cacert   = 0;
00539     unsigned char *end2;
00540 
00541     if( *p == end )
00542         return( 0 );
00543 
00544     ext->tag = **p;
00545 
00546     if( ( ret = asn1_get_tag( p, end, &ext->len,
00547             ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 3 ) ) != 0 )
00548     {
00549         if( ret == XYSSL_ERR_ASN1_UNEXPECTED_TAG )
00550             return( 0 );
00551 
00552         return( ret );
00553     }
00554 
00555     ext->p = *p;
00556     end = *p + ext->len;
00557 
00558     /*
00559      * Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
00560      *
00561      * Extension  ::=  SEQUENCE  {
00562      *      extnID      OBJECT IDENTIFIER,
00563      *      critical    BOOLEAN DEFAULT FALSE,
00564      *      extnValue   OCTET STRING  }
00565      */
00566     if( ( ret = asn1_get_tag( p, end, &len,
00567             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00568         return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
00569 
00570     if( end != *p + len )
00571         return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
00572                 XYSSL_ERR_ASN1_LENGTH_MISMATCH );
00573 
00574     while( *p < end )
00575     {
00576         if( ( ret = asn1_get_tag( p, end, &len,
00577                 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00578             return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
00579 
00580         if( memcmp( *p, "\x06\x03\x55\x1D\x13", 5 ) != 0 )
00581         {
00582             *p += len;
00583             continue;
00584         }
00585 
00586         *p += 5;
00587 
00588         if( ( ret = asn1_get_bool( p, end, &is_critical ) ) != 0 &&
00589             ( ret != XYSSL_ERR_ASN1_UNEXPECTED_TAG ) )
00590             return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
00591 
00592         if( ( ret = asn1_get_tag( p, end, &len,
00593                 ASN1_OCTET_STRING ) ) != 0 )
00594             return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
00595 
00596         /*
00597          * BasicConstraints ::= SEQUENCE {
00598          *      cA                      BOOLEAN DEFAULT FALSE,
00599          *      pathLenConstraint       INTEGER (0..MAX) OPTIONAL }
00600          */
00601         end2 = *p + len;
00602 
00603         if( ( ret = asn1_get_tag( p, end2, &len,
00604                 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00605             return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
00606 
00607         if( *p == end2 )
00608             continue;
00609 
00610         if( ( ret = asn1_get_bool( p, end2, &is_cacert ) ) != 0 )
00611         {
00612             if( ret == XYSSL_ERR_ASN1_UNEXPECTED_TAG )
00613                 ret = asn1_get_int( p, end2, &is_cacert );
00614 
00615             if( ret != 0 )
00616                 return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
00617 
00618             if( is_cacert != 0 )
00619                 is_cacert  = 1;
00620         }
00621 
00622         if( *p == end2 )
00623             continue;
00624 
00625         if( ( ret = asn1_get_int( p, end2, max_pathlen ) ) != 0 )
00626             return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS | ret );
00627 
00628         if( *p != end2 )
00629             return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
00630                     XYSSL_ERR_ASN1_LENGTH_MISMATCH );
00631 
00632         max_pathlen++;
00633     }
00634 
00635     if( *p != end )
00636         return( XYSSL_ERR_X509_CERT_INVALID_EXTENSIONS |
00637                 XYSSL_ERR_ASN1_LENGTH_MISMATCH );
00638 
00639     *ca_istrue = is_critical & is_cacert;
00640 
00641     return( 0 );
00642 }
00643 
00644 /*
00645  * Parse one or more certificates and add them to the chained list
00646  */
00647 int x509parse_crt( x509_cert *chain, unsigned char *buf, int buflen )
00648 {
00649     int ret, len;
00650     unsigned char *s1, *s2;
00651     unsigned char *p, *end;
00652     x509_cert *crt;
00653 
00654     crt = chain;
00655 
00656     while( crt->version != 0 )
00657         crt = crt->next;
00658 
00659     /*
00660      * check if the certificate is encoded in base64
00661      */
00662     s1 = (unsigned char *) strstr( (char *) buf,
00663         "-----BEGIN CERTIFICATE-----" );
00664 
00665     if( s1 != NULL )
00666     {
00667         s2 = (unsigned char *) strstr( (char *) buf,
00668             "-----END CERTIFICATE-----" );
00669 
00670         if( s2 == NULL || s2 <= s1 )
00671             return( XYSSL_ERR_X509_CERT_INVALID_PEM );
00672 
00673         s1 += 27;
00674         if( *s1 == '\r' ) s1++;
00675         if( *s1 == '\n' ) s1++;
00676             else return( XYSSL_ERR_X509_CERT_INVALID_PEM );
00677 
00678         /*
00679          * get the DER data length and decode the buffer
00680          */
00681         len = 0;
00682         ret = base64_decode( NULL, &len, s1, s2 - s1 );
00683 
00684         if( ret == XYSSL_ERR_BASE64_INVALID_CHARACTER )
00685             return( XYSSL_ERR_X509_CERT_INVALID_PEM | ret );
00686 
00687         if( ( p = (unsigned char *) malloc( len ) ) == NULL )
00688             return( 1 );
00689             
00690         if( ( ret = base64_decode( p, &len, s1, s2 - s1 ) ) != 0 )
00691         {
00692             free( p );
00693             return( XYSSL_ERR_X509_CERT_INVALID_PEM | ret );
00694         }
00695 
00696         /*
00697          * update the buffer size and offset
00698          */
00699         s2 += 25;
00700         if( *s2 == '\r' ) s2++;
00701         if( *s2 == '\n' ) s2++;
00702         else
00703         {
00704             free( p );
00705             return( XYSSL_ERR_X509_CERT_INVALID_PEM );
00706         }
00707 
00708         buflen -= s2 - buf;
00709         buf = s2;
00710     }
00711     else
00712     {
00713         /*
00714          * nope, copy the raw DER data
00715          */
00716         p = (unsigned char *) malloc( len = buflen );
00717 
00718         if( p == NULL )
00719             return( 1 );
00720 
00721         memcpy( p, buf, buflen );
00722 
00723         buflen = 0;
00724     }
00725 
00726     crt->raw.p = p;
00727     crt->raw.len = len;
00728     end = p + len;
00729 
00730     /*
00731      * Certificate  ::=  SEQUENCE  {
00732      *      tbsCertificate       TBSCertificate,
00733      *      signatureAlgorithm   AlgorithmIdentifier,
00734      *      signatureValue       BIT STRING  }
00735      */
00736     if( ( ret = asn1_get_tag( &p, end, &len,
00737             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00738     {
00739           x509_free( crt );
00740         return( XYSSL_ERR_X509_CERT_INVALID_FORMAT );
00741     }
00742 
00743     if( len != (int) ( end - p ) )
00744     {
00745           x509_free( crt );
00746         return( XYSSL_ERR_X509_CERT_INVALID_FORMAT |
00747                 XYSSL_ERR_ASN1_LENGTH_MISMATCH );
00748     }
00749 
00750     /*
00751      * TBSCertificate  ::=  SEQUENCE  {
00752      */
00753     crt->tbs.p = p;
00754 
00755     if( ( ret = asn1_get_tag( &p, end, &len,
00756             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00757     {
00758           x509_free( crt );
00759         return( XYSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
00760     }
00761 
00762     end = p + len;
00763     crt->tbs.len = end - crt->tbs.p;
00764 
00765     /*
00766      * Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
00767      *
00768      * CertificateSerialNumber  ::=  INTEGER
00769      *
00770      * signature            AlgorithmIdentifier
00771      */
00772     if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
00773         ( ret = x509_get_serial(  &p, end, &crt->serial  ) ) != 0 ||
00774         ( ret = x509_get_alg(  &p, end, &crt->sig_oid1   ) ) != 0 )
00775     {
00776           x509_free( crt );
00777         return( ret );
00778     }
00779 
00780     crt->version++;
00781 
00782     if( crt->version > 3 )
00783     {
00784           x509_free( crt );
00785         return( XYSSL_ERR_X509_CERT_UNKNOWN_VERSION );
00786     }
00787 
00788     if( crt->sig_oid1.len != 9 ||
00789         memcmp( crt->sig_oid1.p, OID_PKCS1, 8 ) != 0 )
00790     {
00791           x509_free( crt );
00792         return( XYSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
00793     }
00794 
00795     if( crt->sig_oid1.p[8] < 2 ||
00796         crt->sig_oid1.p[8] > 5 )
00797     {
00798           x509_free( crt );
00799         return( XYSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
00800     }
00801 
00802     /*
00803      * issuer               Name
00804      */
00805     crt->issuer_raw.p = p;
00806 
00807     if( ( ret = asn1_get_tag( &p, end, &len,
00808             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00809     {
00810           x509_free( crt );
00811         return( XYSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
00812     }
00813 
00814     if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
00815     {
00816           x509_free( crt );
00817         return( ret );
00818     }
00819 
00820     crt->issuer_raw.len = p - crt->issuer_raw.p;
00821 
00822     /*
00823      * Validity ::= SEQUENCE {
00824      *      notBefore      Time,
00825      *      notAfter       Time }
00826      *
00827      */
00828     if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
00829                                          &crt->valid_to ) ) != 0 )
00830     {
00831           x509_free( crt );
00832         return( ret );
00833     }
00834 
00835     /*
00836      * subject              Name
00837      */
00838     crt->subject_raw.p = p;
00839 
00840     if( ( ret = asn1_get_tag( &p, end, &len,
00841             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00842     {
00843           x509_free( crt );
00844         return( XYSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
00845     }
00846 
00847     if( ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
00848     {
00849           x509_free( crt );
00850         return( ret );
00851     }
00852 
00853     crt->subject_raw.len = p - crt->subject_raw.p;
00854 
00855     /*
00856      * SubjectPublicKeyInfo  ::=  SEQUENCE
00857      *      algorithm            AlgorithmIdentifier,
00858      *      subjectPublicKey     BIT STRING  }
00859      */
00860     if( ( ret = asn1_get_tag( &p, end, &len,
00861             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00862     {
00863           x509_free( crt );
00864         return( XYSSL_ERR_X509_CERT_INVALID_FORMAT | ret );
00865     }
00866 
00867     if( ( ret = x509_get_pubkey( &p, p + len, &crt->pk_oid,
00868                                  &crt->rsa.N, &crt->rsa.E ) ) != 0 )
00869     {
00870           x509_free( crt );
00871         return( ret );
00872     }
00873 
00874     if( ( ret = rsa_check_pubkey( &crt->rsa ) ) != 0 )
00875     {
00876           x509_free( crt );
00877         return( ret );
00878     }
00879 
00880     crt->rsa.len = mpi_size( &crt->rsa.N );
00881 
00882     /*
00883      *  issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
00884      *                       -- If present, version shall be v2 or v3
00885      *  subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
00886      *                       -- If present, version shall be v2 or v3
00887      *  extensions      [3]  EXPLICIT Extensions OPTIONAL
00888      *                       -- If present, version shall be v3
00889      */
00890     if( crt->version == 2 || crt->version == 3 )
00891     {
00892         ret = x509_get_uid( &p, end, &crt->issuer_id,  1 );
00893         if( ret != 0 )
00894         {
00895               x509_free( crt );
00896             return( ret );
00897         }
00898     }
00899 
00900     if( crt->version == 2 || crt->version == 3 )
00901     {
00902         ret = x509_get_uid( &p, end, &crt->subject_id,  2 );
00903         if( ret != 0 )
00904         {
00905               x509_free( crt );
00906             return( ret );
00907         }
00908     }
00909 
00910     if( crt->version == 3 )
00911     {
00912         ret = x509_get_ext( &p, end, &crt->v3_ext,
00913                             &crt->ca_istrue, &crt->max_pathlen );
00914         if( ret != 0 )
00915         {
00916               x509_free( crt );
00917             return( ret );
00918         }
00919     }
00920 
00921     if( p != end )
00922     {
00923           x509_free( crt );
00924         return( XYSSL_ERR_X509_CERT_INVALID_FORMAT |
00925                 XYSSL_ERR_ASN1_LENGTH_MISMATCH );
00926     }
00927 
00928     end = crt->raw.p + crt->raw.len;
00929 
00930     /*
00931      *  signatureAlgorithm   AlgorithmIdentifier,
00932      *  signatureValue       BIT STRING
00933      */
00934     if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2 ) ) != 0 )
00935     {
00936           x509_free( crt );
00937         return( ret );
00938     }
00939 
00940     if( memcmp( crt->sig_oid1.p, crt->sig_oid2.p, 9 ) != 0 )
00941     {
00942           x509_free( crt );
00943         return( XYSSL_ERR_X509_CERT_SIG_MISMATCH );
00944     }
00945 
00946     if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
00947     {
00948           x509_free( crt );
00949         return( ret );
00950     }
00951 
00952     if( p != end )
00953     {
00954           x509_free( crt );
00955         return( XYSSL_ERR_X509_CERT_INVALID_FORMAT |
00956                 XYSSL_ERR_ASN1_LENGTH_MISMATCH );
00957     }
00958 
00959     crt->next = (x509_cert *) malloc( sizeof( x509_cert ) );
00960 
00961     if( crt->next == NULL )
00962     {
00963           x509_free( crt );
00964         return( 1 );
00965     }
00966 
00967     crt = crt->next;
00968     memset( crt, 0, sizeof( x509_cert ) );
00969 
00970     if( buflen > 0 )
00971         return( x509parse_crt( crt, buf, buflen ) );
00972 
00973     return( 0 );
00974 }
00975 
00976 /*
00977  * Load one or more certificates and add them to the chained list
00978  */
00979 int x509parse_crtfile( x509_cert *chain, char *path )
00980 {
00981     int ret;
00982     FILE *f;
00983     size_t n;
00984     unsigned char *buf;
00985 
00986     if( ( f = fopen( path, "rb" ) ) == NULL )
00987         return( 1 );
00988 
00989     fseek( f, 0, SEEK_END );
00990     n = (size_t) ftell( f );
00991     fseek( f, 0, SEEK_SET );
00992 
00993     if( ( buf = (unsigned char *) malloc( n + 1 ) ) == NULL )
00994         return( 1 );
00995 
00996     if( fread( buf, 1, n, f ) != n )
00997     {
00998         fclose( f );
00999         free( buf );
01000         return( 1 );
01001     }
01002 
01003     buf[n] = '\0';
01004 
01005     ret = x509parse_crt( chain, buf, (int) n );
01006 
01007     memset( buf, 0, n + 1 );
01008     free( buf );
01009     fclose( f );
01010 
01011     return( ret );
01012 }
01013 
01014 #if defined(XYSSL_DES_C)
01015 /*
01016  * Read a 16-byte hex string and convert it to binary
01017  */
01018 static int x509_get_iv( unsigned char *s, unsigned char iv[8] )
01019 {
01020     int i, j, k;
01021 
01022     memset( iv, 0, 8 );
01023 
01024     for( i = 0; i < 16; i++, s++ )
01025     {
01026         if( *s >= '0' && *s <= '9' ) j = *s - '0'; else
01027         if( *s >= 'A' && *s <= 'F' ) j = *s - '7'; else
01028         if( *s >= 'a' && *s <= 'f' ) j = *s - 'W'; else
01029             return( XYSSL_ERR_X509_KEY_INVALID_ENC_IV );
01030 
01031         k = ( ( i & 1 ) != 0 ) ? j : j << 4;
01032 
01033         iv[i >> 1] = (unsigned char)( iv[i >> 1] | k );
01034     }
01035 
01036     return( 0 );
01037 }
01038 
01039 /*
01040  * Decrypt with 3DES-CBC, using PBKDF1 for key derivation
01041  */
01042 static void x509_des3_decrypt( unsigned char des3_iv[8],
01043                                unsigned char *buf, int buflen,
01044                                unsigned char *pwd, int pwdlen )
01045 {
01046     md5_context md5_ctx;
01047     des3_context des3_ctx;
01048     unsigned char md5sum[16];
01049     unsigned char des3_key[24];
01050 
01051     /*
01052      * 3DES key[ 0..15] = MD5(pwd || IV)
01053      *      key[16..23] = MD5(pwd || IV || 3DES key[ 0..15])
01054      */
01055     md5_starts( &md5_ctx );
01056     md5_update( &md5_ctx, pwd, pwdlen );
01057     md5_update( &md5_ctx, des3_iv,  8 );
01058     md5_finish( &md5_ctx, md5sum );
01059     memcpy( des3_key, md5sum, 16 );
01060 
01061     md5_starts( &md5_ctx );
01062     md5_update( &md5_ctx, md5sum,  16 );
01063     md5_update( &md5_ctx, pwd, pwdlen );
01064     md5_update( &md5_ctx, des3_iv,  8 );
01065     md5_finish( &md5_ctx, md5sum );
01066     memcpy( des3_key + 16, md5sum, 8 );
01067 
01068     des3_set3key_dec( &des3_ctx, des3_key );
01069     des3_crypt_cbc( &des3_ctx, DES_DECRYPT, buflen,
01070                      des3_iv, buf, buf );
01071 
01072     memset(  &md5_ctx, 0, sizeof(  md5_ctx ) );
01073     memset( &des3_ctx, 0, sizeof( des3_ctx ) );
01074     memset( md5sum, 0, 16 );
01075     memset( des3_key, 0, 24 );
01076 }
01077 #endif
01078 
01079 /*
01080  * Parse a private RSA key
01081  */
01082 int x509parse_key( rsa_context *rsa, unsigned char *buf, int buflen,
01083                                      unsigned char *pwd, int pwdlen )
01084 {
01085     int ret, len, enc;
01086     unsigned char *s1, *s2;
01087     unsigned char *p, *end;
01088     unsigned char des3_iv[8];
01089 
01090     s1 = (unsigned char *) strstr( (char *) buf,
01091         "-----BEGIN RSA PRIVATE KEY-----" );
01092 
01093     if( s1 != NULL )
01094     {
01095         s2 = (unsigned char *) strstr( (char *) buf,
01096             "-----END RSA PRIVATE KEY-----" );
01097 
01098         if( s2 == NULL || s2 <= s1 )
01099             return( XYSSL_ERR_X509_KEY_INVALID_PEM );
01100 
01101         s1 += 31;
01102         if( *s1 == '\r' ) s1++;
01103         if( *s1 == '\n' ) s1++;
01104             else return( XYSSL_ERR_X509_KEY_INVALID_PEM );
01105 
01106         enc = 0;
01107 
01108         if( memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 )
01109         {
01110 #if defined(XYSSL_DES_C)
01111             enc++;
01112 
01113             s1 += 22;
01114             if( *s1 == '\r' ) s1++;
01115             if( *s1 == '\n' ) s1++;
01116                 else return( XYSSL_ERR_X509_KEY_INVALID_PEM );
01117 
01118             if( memcmp( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) != 0 )
01119                 return( XYSSL_ERR_X509_KEY_UNKNOWN_ENC_ALG );
01120 
01121             s1 += 23;
01122             if( x509_get_iv( s1, des3_iv ) != 0 )
01123                 return( XYSSL_ERR_X509_KEY_INVALID_ENC_IV );
01124 
01125             s1 += 16;
01126             if( *s1 == '\r' ) s1++;
01127             if( *s1 == '\n' ) s1++;
01128                 else return( XYSSL_ERR_X509_KEY_INVALID_PEM );
01129 #else
01130             return( XYSSL_ERR_X509_FEATURE_UNAVAILABLE );
01131 #endif
01132         }
01133 
01134         len = 0;
01135         ret = base64_decode( NULL, &len, s1, s2 - s1 );
01136 
01137         if( ret == XYSSL_ERR_BASE64_INVALID_CHARACTER )
01138             return( ret | XYSSL_ERR_X509_KEY_INVALID_PEM );
01139 
01140         if( ( buf = (unsigned char *) malloc( len ) ) == NULL )
01141             return( 1 );
01142 
01143         if( ( ret = base64_decode( buf, &len, s1, s2 - s1 ) ) != 0 )
01144         {
01145             free( buf );
01146             return( ret | XYSSL_ERR_X509_KEY_INVALID_PEM );
01147         }
01148 
01149         buflen = len;
01150 
01151         if( enc != 0 )
01152         {
01153 #if defined(XYSSL_DES_C)
01154             if( pwd == NULL )
01155             {
01156                 free( buf );
01157                 return( XYSSL_ERR_X509_KEY_PASSWORD_REQUIRED );
01158             }
01159 
01160             x509_des3_decrypt( des3_iv, buf, buflen, pwd, pwdlen );
01161 
01162             if( buf[0] != 0x30 || buf[1] != 0x82 ||
01163                 buf[4] != 0x02 || buf[5] != 0x01 )
01164             {
01165                 free( buf );
01166                 return( XYSSL_ERR_X509_KEY_PASSWORD_MISMATCH );
01167             }
01168 #else
01169             return( XYSSL_ERR_X509_FEATURE_UNAVAILABLE );
01170 #endif
01171         }
01172     }
01173 
01174     memset( rsa, 0, sizeof( rsa_context ) );
01175 
01176     p = buf;
01177     end = buf + buflen;
01178 
01179     /*
01180      *  RSAPrivateKey ::= SEQUENCE {
01181      *      version           Version,
01182      *      modulus           INTEGER,  -- n
01183      *      publicExponent    INTEGER,  -- e
01184      *      privateExponent   INTEGER,  -- d
01185      *      prime1            INTEGER,  -- p
01186      *      prime2            INTEGER,  -- q
01187      *      exponent1         INTEGER,  -- d mod (p-1)
01188      *      exponent2         INTEGER,  -- d mod (q-1)
01189      *      coefficient       INTEGER,  -- (inverse of q) mod p
01190      *      otherPrimeInfos   OtherPrimeInfos OPTIONAL
01191      *  }
01192      */
01193     if( ( ret = asn1_get_tag( &p, end, &len,
01194             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
01195     {
01196         if( s1 != NULL )
01197             free( buf );
01198 
01199         rsa_free( rsa );
01200         return( XYSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
01201     }
01202 
01203     end = p + len;
01204 
01205     if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
01206     {
01207         if( s1 != NULL )
01208             free( buf );
01209 
01210         rsa_free( rsa );
01211         return( XYSSL_ERR_X509_KEY_INVALID_FORMAT | ret );
01212     }
01213 
01214     if( rsa->ver != 0 )
01215     {
01216         if( s1 != NULL )
01217             free( buf );
01218 
01219         rsa_free( rsa );
01220         return( ret | XYSSL_ERR_X509_KEY_INVALID_VERSION );
01221     }
01222 
01223     if( ( ret = asn1_get_mpi( &p, end, &rsa->N  ) ) != 0 ||
01224         ( ret = asn1_get_mpi( &p, end, &rsa->E  ) ) != 0 ||
01225         ( ret = asn1_get_mpi( &p, end, &rsa->D  ) ) != 0 ||
01226         ( ret = asn1_get_mpi( &p, end, &rsa->P  ) ) != 0 ||
01227         ( ret = asn1_get_mpi( &p, end, &rsa->Q  ) ) != 0 ||
01228         ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
01229         ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
01230         ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
01231     {
01232         if( s1 != NULL )
01233             free( buf );
01234 
01235         rsa_free( rsa );
01236         return( ret | XYSSL_ERR_X509_KEY_INVALID_FORMAT );
01237     }
01238 
01239     rsa->len = mpi_size( &rsa->N );
01240 
01241     if( p != end )
01242     {
01243         if( s1 != NULL )
01244             free( buf );
01245 
01246         rsa_free( rsa );
01247         return( XYSSL_ERR_X509_KEY_INVALID_FORMAT |
01248                 XYSSL_ERR_ASN1_LENGTH_MISMATCH );
01249     }
01250 
01251     if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
01252     {
01253         if( s1 != NULL )
01254             free( buf );
01255 
01256         rsa_free( rsa );
01257         return( ret );
01258     }
01259 
01260     if( s1 != NULL )
01261         free( buf );
01262 
01263     return( 0 );
01264 }
01265 
01266 /*
01267  * Load and parse a private RSA key
01268  */
01269 int x509parse_keyfile( rsa_context *rsa, char *path, char *pwd )
01270 {
01271     int ret;
01272     FILE *f;
01273     size_t n;
01274     unsigned char *buf;
01275 
01276     if( ( f = fopen( path, "rb" ) ) == NULL )
01277         return( 1 );
01278 
01279     fseek( f, 0, SEEK_END );
01280     n = (size_t) ftell( f );
01281     fseek( f, 0, SEEK_SET );
01282 
01283     if( ( buf = (unsigned char *) malloc( n + 1 ) ) == NULL )
01284         return( 1 );
01285 
01286     if( fread( buf, 1, n, f ) != n )
01287     {
01288         fclose( f );
01289         free( buf );
01290         return( 1 );
01291     }
01292 
01293     buf[n] = '\0';
01294 
01295     if( pwd == NULL )
01296         ret = x509parse_key( rsa, buf, (int) n, NULL, 0 );
01297     else
01298         ret = x509parse_key( rsa, buf, (int) n,
01299                 (unsigned char *) pwd, strlen( pwd ) );
01300 
01301     memset( buf, 0, n + 1 );
01302     free( buf );
01303     fclose( f );
01304 
01305     return( ret );
01306 }
01307 
01308 #if defined _MSC_VER && !defined snprintf
01309 #define snprintf _snprintf
01310 #endif
01311 
01312 /*
01313  * Store the name in printable form into buf; no more
01314  * than (end - buf) characters will be written
01315  */
01316 int x509parse_dn_gets( char *buf, char *end, x509_name *dn )
01317 {
01318     int i;
01319     unsigned char c;
01320     x509_name *name;
01321     char s[128], *p;
01322 
01323     memset( s, 0, sizeof( s ) );
01324 
01325     name = dn;
01326     p = buf;
01327 
01328     while( name != NULL )
01329     {
01330         if( name != dn )
01331             p += snprintf( p, end - p, ", " );
01332 
01333         if( memcmp( name->oid.p, OID_X520, 2 ) == 0 )
01334         {
01335             switch( name->oid.p[2] )
01336             {
01337             case X520_COMMON_NAME:
01338                 p += snprintf( p, end - p, "CN=" ); break;
01339 
01340             case X520_COUNTRY:
01341                 p += snprintf( p, end - p, "C="  ); break;
01342 
01343             case X520_LOCALITY:
01344                 p += snprintf( p, end - p, "L="  ); break;
01345 
01346             case X520_STATE:
01347                 p += snprintf( p, end - p, "ST=" ); break;
01348 
01349             case X520_ORGANIZATION:
01350                 p += snprintf( p, end - p, "O="  ); break;
01351 
01352             case X520_ORG_UNIT:
01353                 p += snprintf( p, end - p, "OU=" ); break;
01354 
01355             default:
01356                 p += snprintf( p, end - p, "0x%02X=",
01357                                name->oid.p[2] );
01358                 break;
01359             }
01360         }
01361         else if( memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
01362         {
01363             switch( name->oid.p[8] )
01364             {
01365             case PKCS9_EMAIL:
01366                 p += snprintf( p, end - p, "emailAddress=" ); break;
01367 
01368             default:
01369                 p += snprintf( p, end - p, "0x%02X=",
01370                                name->oid.p[8] );
01371                 break;
01372             }
01373         }
01374         else
01375             p += snprintf( p, end - p, "\?\?=" );
01376 
01377         for( i = 0; i < name->val.len; i++ )
01378         {
01379             if( i >= (int) sizeof( s ) - 1 )
01380                 break;
01381 
01382             c = name->val.p[i];
01383             if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
01384                  s[i] = '?';
01385             else s[i] = c;
01386         }
01387         s[i] = '\0';
01388         p += snprintf( p, end - p, "%s", s );
01389         name = name->next;
01390     }
01391 
01392     return( p - buf );
01393 }
01394 
01395 /*
01396  * Return an informational string about the
01397  * certificate, or NULL if memory allocation failed
01398  */
01399 char *x509parse_cert_info( char *prefix, x509_cert *crt )
01400 {
01401     int i, n;
01402     char *p, *end;
01403     static char buf[512];
01404 
01405     p = buf;
01406     end = buf + sizeof( buf ) - 1;
01407 
01408     p += snprintf( p, end - p, "%scert. version : %d\n",
01409                                prefix, crt->version );
01410     p += snprintf( p, end - p, "%sserial number : ",
01411                                prefix );
01412 
01413     n = ( crt->serial.len <= 32 )
01414         ? crt->serial.len  : 32;
01415 
01416     for( i = 0; i < n; i++ )
01417         p += snprintf( p, end - p, "%02X%s",
01418                 crt->serial.p[i], ( i < n - 1 ) ? ":" : "" );
01419 
01420     p += snprintf( p, end - p, "\n%sissuer  name  : ", prefix );
01421     p += x509parse_dn_gets( p, end, &crt->issuer  );
01422 
01423     p += snprintf( p, end - p, "\n%ssubject name  : ", prefix );
01424     p += x509parse_dn_gets( p, end, &crt->subject );
01425 
01426     p += snprintf( p, end - p, "\n%sissued  on    : " \
01427                    "%04d-%02d-%02d %02d:%02d:%02d", prefix,
01428                    crt->valid_from.year, crt->valid_from.mon,
01429                    crt->valid_from.day,  crt->valid_from.hour,
01430                    crt->valid_from.min,  crt->valid_from.sec );
01431 
01432     p += snprintf( p, end - p, "\n%sexpires on    : " \
01433                    "%04d-%02d-%02d %02d:%02d:%02d", prefix,
01434                    crt->valid_to.year, crt->valid_to.mon,
01435                    crt->valid_to.day,  crt->valid_to.hour,
01436                    crt->valid_to.min,  crt->valid_to.sec );
01437 
01438     p += snprintf( p, end - p, "\n%ssigned using  : RSA+", prefix );
01439 
01440     switch( crt->sig_oid1.p[8] )
01441     {
01442         case RSA_MD2 : p += snprintf( p, end - p, "MD2"  ); break;
01443         case RSA_MD4 : p += snprintf( p, end - p, "MD4"  ); break;
01444         case RSA_MD5 : p += snprintf( p, end - p, "MD5"  ); break;
01445         case RSA_SHA1: p += snprintf( p, end - p, "SHA1" ); break;
01446         default: p += snprintf( p, end - p, "???"  ); break;
01447     }
01448 
01449     p += snprintf( p, end - p, "\n%sRSA key size  : %d bits\n", prefix,
01450                    crt->rsa.N.n * (int) sizeof( unsigned long ) * 8 );
01451 
01452     return( buf );
01453 }
01454 
01455 /*
01456  * Return 0 if the certificate is still valid, or BADCERT_EXPIRED
01457  */
01458 int x509parse_expired( x509_cert *crt )
01459 {
01460     struct tm *lt;
01461     time_t tt;
01462 
01463     tt = time( NULL );
01464     lt = localtime( &tt );
01465 
01466     if( lt->tm_year  > crt->valid_to.year - 1900 )
01467         return( BADCERT_EXPIRED );
01468 
01469     if( lt->tm_year == crt->valid_to.year - 1900 &&
01470         lt->tm_mon   > crt->valid_to.mon  - 1 )
01471         return( BADCERT_EXPIRED );
01472 
01473     if( lt->tm_year == crt->valid_to.year - 1900 &&
01474         lt->tm_mon  == crt->valid_to.mon  - 1    &&
01475         lt->tm_mday  > crt->valid_to.day )
01476         return( BADCERT_EXPIRED );
01477 
01478     return( 0 );
01479 }
01480 
01481 static void x509_hash( unsigned char *in, int len, int alg,
01482                        unsigned char *out )
01483 {
01484     switch( alg )
01485     {
01486 #if defined(XYSSL_MD2_C)
01487         case RSA_MD2  :  md2( in, len, out ); break;
01488 #endif
01489 #if defined(XYSSL_MD4_C)
01490         case RSA_MD4  :  md4( in, len, out ); break;
01491 #endif
01492         case RSA_MD5  :  md5( in, len, out ); break;
01493         case RSA_SHA1 : sha1( in, len, out ); break;
01494         default:
01495             memset( out, '\xFF', len );
01496             break;
01497     }
01498 }
01499 
01500 /*
01501  * Verify the certificate validity
01502  */
01503 int x509parse_verify( x509_cert *crt,
01504                       x509_cert *trust_ca,
01505                       char *cn, int *flags )
01506 {
01507     int cn_len;
01508     int hash_id;
01509     int pathlen;
01510     x509_cert *cur;
01511     x509_name *name;
01512     unsigned char hash[20];
01513 
01514     *flags = x509parse_expired( crt );
01515 
01516     if( cn != NULL )
01517     {
01518         name = &crt->subject;
01519         cn_len = strlen( cn );
01520 
01521         while( name != NULL )
01522         {
01523             if( memcmp( name->oid.p, OID_CN,  3 ) == 0 &&
01524                 memcmp( name->val.p, cn, cn_len ) == 0 &&
01525                 name->val.len == cn_len )
01526                 break;
01527 
01528             name = name->next;
01529         }
01530 
01531         if( name == NULL )
01532             *flags |= BADCERT_CN_MISMATCH;
01533     }
01534 
01535     *flags |= BADCERT_NOT_TRUSTED;
01536 
01537     /*
01538      * Iterate upwards in the given cert chain,
01539      * ignoring any upper cert with CA != TRUE.
01540      */
01541     cur = crt->next;
01542 
01543     pathlen = 1;
01544 
01545     while( cur->version != 0 )
01546     {
01547         if( cur->ca_istrue == 0 ||
01548             crt->issuer_raw.len != cur->subject_raw.len ||
01549             memcmp( crt->issuer_raw.p, cur->subject_raw.p,
01550                     crt->issuer_raw.len ) != 0 )
01551         {
01552             cur = cur->next;
01553             continue;
01554         }
01555 
01556         hash_id = crt->sig_oid1.p[8];
01557 
01558         x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
01559 
01560         if( rsa_pkcs1_verify( &cur->rsa, RSA_PUBLIC, hash_id,
01561                               0, hash, crt->sig.p ) != 0 )
01562             return( XYSSL_ERR_X509_CERT_VERIFY_FAILED );
01563 
01564         pathlen++;
01565 
01566         crt = cur;
01567         cur = crt->next;
01568     }
01569 
01570     /*
01571      * Atempt to validate topmost cert with our CA chain.
01572      */
01573     while( trust_ca->version != 0 )
01574     {
01575         if( crt->issuer_raw.len != trust_ca->subject_raw.len ||
01576             memcmp( crt->issuer_raw.p, trust_ca->subject_raw.p,
01577                     crt->issuer_raw.len ) != 0 )
01578         {
01579             trust_ca = trust_ca->next;
01580             continue;
01581         }
01582 
01583         if( trust_ca->max_pathlen > 0 &&
01584             trust_ca->max_pathlen < pathlen )
01585             break;
01586 
01587         hash_id = crt->sig_oid1.p[8];
01588 
01589         x509_hash( crt->tbs.p, crt->tbs.len, hash_id, hash );
01590 
01591         if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
01592                               0, hash, crt->sig.p ) == 0 )
01593         {
01594             /*
01595              * cert. is signed by a trusted CA
01596              */
01597             *flags &= ~BADCERT_NOT_TRUSTED;
01598             break;
01599         }
01600 
01601         trust_ca = trust_ca->next;
01602     }
01603 
01604     if( *flags != 0 )
01605         return( XYSSL_ERR_X509_CERT_VERIFY_FAILED );
01606 
01607     return( 0 );
01608 }
01609 
01610 /*
01611  * Unallocate all certificate data
01612  */
01613 void x509_free( x509_cert *crt )
01614 {
01615     x509_cert *cert_cur = crt;
01616     x509_cert *cert_prv;
01617     x509_name *name_cur;
01618     x509_name *name_prv;
01619 
01620     if( crt == NULL )
01621         return;
01622 
01623     do
01624     {
01625         rsa_free( &cert_cur->rsa );
01626 
01627         name_cur = cert_cur->issuer.next;
01628         while( name_cur != NULL )
01629         {
01630             name_prv = name_cur;
01631             name_cur = name_cur->next;
01632             memset( name_prv, 0, sizeof( x509_name ) );
01633             free( name_prv );
01634         }
01635 
01636         name_cur = cert_cur->subject.next;
01637         while( name_cur != NULL )
01638         {
01639             name_prv = name_cur;
01640             name_cur = name_cur->next;
01641             memset( name_prv, 0, sizeof( x509_name ) );
01642             free( name_prv );
01643         }
01644 
01645         if( cert_cur->raw.p != NULL )
01646         {
01647             memset( cert_cur->raw.p, 0, cert_cur->raw.len );
01648             free( cert_cur->raw.p );
01649         }
01650 
01651         cert_cur = cert_cur->next;
01652     }
01653     while( cert_cur != NULL );
01654 
01655     cert_cur = crt;
01656     do
01657     {
01658         cert_prv = cert_cur;
01659         cert_cur = cert_cur->next;
01660 
01661         memset( cert_prv, 0, sizeof( x509_cert ) );
01662         if( cert_prv != crt )
01663             free( cert_prv );
01664     }
01665     while( cert_cur != NULL );
01666 }
01667 
01668 #if defined(XYSSL_SELF_TEST)
01669 
01670 #include "xyssl/certs.h"
01671 
01672 /*
01673  * Checkup routine
01674  */
01675 int x509_self_test( int verbose )
01676 {
01677     int ret, i, j;
01678     x509_cert cacert;
01679     x509_cert clicert;
01680     rsa_context rsa;
01681 
01682     if( verbose != 0 )
01683         printf( "  X.509 certificate load: " );
01684 
01685     memset( &clicert, 0, sizeof( x509_cert ) );
01686 
01687     ret = x509parse_crt( &clicert, (unsigned char *) test_cli_crt,
01688                          strlen( test_cli_crt ) );
01689     if( ret != 0 )
01690     {
01691         if( verbose != 0 )
01692             printf( "failed\n" );
01693 
01694         return( ret );
01695     }
01696 
01697     memset( &cacert, 0, sizeof( x509_cert ) );
01698 
01699     ret = x509parse_crt( &cacert, (unsigned char *) test_ca_crt,
01700                          strlen( test_ca_crt ) );
01701     if( ret != 0 )
01702     {
01703         if( verbose != 0 )
01704             printf( "failed\n" );
01705 
01706         return( ret );
01707     }
01708 
01709     if( verbose != 0 )
01710         printf( "passed\n  X.509 private key load: " );
01711 
01712     i = strlen( test_ca_key );
01713     j = strlen( test_ca_pwd );
01714 
01715     if( ( ret = x509parse_key( &rsa,
01716                     (unsigned char *) test_ca_key, i,
01717                     (unsigned char *) test_ca_pwd, j ) ) != 0 )
01718     {
01719         if( verbose != 0 )
01720             printf( "failed\n" );
01721 
01722         return( ret );
01723     }
01724 
01725     if( verbose != 0 )
01726         printf( "passed\n  X.509 signature verify: ");
01727 
01728     ret = x509parse_verify( &clicert, &cacert, "Joe User", &i );
01729     if( ret != 0 )
01730     {
01731         if( verbose != 0 )
01732             printf( "failed\n" );
01733 
01734         return( ret );
01735     }
01736 
01737     if( verbose != 0 )
01738         printf( "passed\n\n" );
01739 
01740     x509_free( &cacert  );
01741     x509_free( &clicert );
01742     rsa_free( &rsa );
01743 
01744     return( 0 );
01745 }
01746 
01747 #endif
01748 
01749 #endif

Generated on Fri Jul 11 17:59:46 2008 for Mobile-C by  doxygen 1.5.4