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