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