00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
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 
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 
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 
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 
00226 
00227 
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 
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 
00266 
00267 
00268 
00269 
00270 
00271 
00272 
00273 
00274 
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 
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 
00351 
00352 
00353 
00354 
00355 
00356 
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 
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 
00418 
00419 
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 
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 
00453 
00454 
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 
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 
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 
00560 
00561 
00562 
00563 
00564 
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 
00598 
00599 
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 
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 
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 
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 
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 
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 
00732 
00733 
00734 
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 
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 
00767 
00768 
00769 
00770 
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 
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 
00824 
00825 
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 
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 
00857 
00858 
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 
00884 
00885 
00886 
00887 
00888 
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 
00932 
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 
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 
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 
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 
01053 
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 
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 
01181 
01182 
01183 
01184 
01185 
01186 
01187 
01188 
01189 
01190 
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 
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 
01314 
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 
01397 
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 
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 
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 
01539 
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 
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 
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 
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 
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