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
00036
00037 #include "polarssl/config.h"
00038
00039 #if defined(POLARSSL_X509_CRT_PARSE_C)
00040
00041 #include "polarssl/x509_crt.h"
00042 #include "polarssl/oid.h"
00043 #if defined(POLARSSL_PEM_PARSE_C)
00044 #include "polarssl/pem.h"
00045 #endif
00046
00047 #if defined(POLARSSL_MEMORY_C)
00048 #include "polarssl/memory.h"
00049 #else
00050 #define polarssl_malloc malloc
00051 #define polarssl_free free
00052 #endif
00053
00054 #include <string.h>
00055 #include <stdlib.h>
00056 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
00057 #include <windows.h>
00058 #else
00059 #include <time.h>
00060 #endif
00061
00062 #if defined(EFIX64) || defined(EFI32)
00063 #include <stdio.h>
00064 #endif
00065
00066 #if defined(POLARSSL_FS_IO)
00067 #include <stdio.h>
00068 #if !defined(_WIN32)
00069 #include <sys/types.h>
00070 #include <sys/stat.h>
00071 #include <dirent.h>
00072 #endif
00073 #endif
00074
00075
00076
00077
00078 static int x509_get_version( unsigned char **p,
00079 const unsigned char *end,
00080 int *ver )
00081 {
00082 int ret;
00083 size_t len;
00084
00085 if( ( ret = asn1_get_tag( p, end, &len,
00086 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) != 0 )
00087 {
00088 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
00089 {
00090 *ver = 0;
00091 return( 0 );
00092 }
00093
00094 return( ret );
00095 }
00096
00097 end = *p + len;
00098
00099 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 )
00100 return( POLARSSL_ERR_X509_INVALID_VERSION + ret );
00101
00102 if( *p != end )
00103 return( POLARSSL_ERR_X509_INVALID_VERSION +
00104 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00105
00106 return( 0 );
00107 }
00108
00109
00110
00111
00112
00113
00114 static int x509_get_dates( unsigned char **p,
00115 const unsigned char *end,
00116 x509_time *from,
00117 x509_time *to )
00118 {
00119 int ret;
00120 size_t len;
00121
00122 if( ( ret = asn1_get_tag( p, end, &len,
00123 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00124 return( POLARSSL_ERR_X509_INVALID_DATE + ret );
00125
00126 end = *p + len;
00127
00128 if( ( ret = x509_get_time( p, end, from ) ) != 0 )
00129 return( ret );
00130
00131 if( ( ret = x509_get_time( p, end, to ) ) != 0 )
00132 return( ret );
00133
00134 if( *p != end )
00135 return( POLARSSL_ERR_X509_INVALID_DATE +
00136 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00137
00138 return( 0 );
00139 }
00140
00141
00142
00143
00144 static int x509_get_uid( unsigned char **p,
00145 const unsigned char *end,
00146 x509_buf *uid, int n )
00147 {
00148 int ret;
00149
00150 if( *p == end )
00151 return( 0 );
00152
00153 uid->tag = **p;
00154
00155 if( ( ret = asn1_get_tag( p, end, &uid->len,
00156 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 )
00157 {
00158 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
00159 return( 0 );
00160
00161 return( ret );
00162 }
00163
00164 uid->p = *p;
00165 *p += uid->len;
00166
00167 return( 0 );
00168 }
00169
00170 static int x509_get_basic_constraints( unsigned char **p,
00171 const unsigned char *end,
00172 int *ca_istrue,
00173 int *max_pathlen )
00174 {
00175 int ret;
00176 size_t len;
00177
00178
00179
00180
00181
00182
00183 *ca_istrue = 0;
00184 *max_pathlen = 0;
00185
00186 if( ( ret = asn1_get_tag( p, end, &len,
00187 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00188 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
00189
00190 if( *p == end )
00191 return 0;
00192
00193 if( ( ret = asn1_get_bool( p, end, ca_istrue ) ) != 0 )
00194 {
00195 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
00196 ret = asn1_get_int( p, end, ca_istrue );
00197
00198 if( ret != 0 )
00199 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
00200
00201 if( *ca_istrue != 0 )
00202 *ca_istrue = 1;
00203 }
00204
00205 if( *p == end )
00206 return 0;
00207
00208 if( ( ret = asn1_get_int( p, end, max_pathlen ) ) != 0 )
00209 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
00210
00211 if( *p != end )
00212 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
00213 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00214
00215 (*max_pathlen)++;
00216
00217 return 0;
00218 }
00219
00220 static int x509_get_ns_cert_type( unsigned char **p,
00221 const unsigned char *end,
00222 unsigned char *ns_cert_type)
00223 {
00224 int ret;
00225 x509_bitstring bs = { 0, 0, NULL };
00226
00227 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
00228 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
00229
00230 if( bs.len != 1 )
00231 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
00232 POLARSSL_ERR_ASN1_INVALID_LENGTH );
00233
00234
00235 *ns_cert_type = *bs.p;
00236 return 0;
00237 }
00238
00239 static int x509_get_key_usage( unsigned char **p,
00240 const unsigned char *end,
00241 unsigned char *key_usage)
00242 {
00243 int ret;
00244 x509_bitstring bs = { 0, 0, NULL };
00245
00246 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 )
00247 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
00248
00249 if( bs.len < 1 )
00250 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
00251 POLARSSL_ERR_ASN1_INVALID_LENGTH );
00252
00253
00254 *key_usage = *bs.p;
00255 return 0;
00256 }
00257
00258
00259
00260
00261
00262
00263 static int x509_get_ext_key_usage( unsigned char **p,
00264 const unsigned char *end,
00265 x509_sequence *ext_key_usage)
00266 {
00267 int ret;
00268
00269 if( ( ret = asn1_get_sequence_of( p, end, ext_key_usage, ASN1_OID ) ) != 0 )
00270 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
00271
00272
00273 if( ext_key_usage->buf.p == NULL )
00274 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
00275 POLARSSL_ERR_ASN1_INVALID_LENGTH );
00276
00277 return 0;
00278 }
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306 static int x509_get_subject_alt_name( unsigned char **p,
00307 const unsigned char *end,
00308 x509_sequence *subject_alt_name )
00309 {
00310 int ret;
00311 size_t len, tag_len;
00312 asn1_buf *buf;
00313 unsigned char tag;
00314 asn1_sequence *cur = subject_alt_name;
00315
00316
00317 if( ( ret = asn1_get_tag( p, end, &len,
00318 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00319 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
00320
00321 if( *p + len != end )
00322 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
00323 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00324
00325 while( *p < end )
00326 {
00327 if( ( end - *p ) < 1 )
00328 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
00329 POLARSSL_ERR_ASN1_OUT_OF_DATA );
00330
00331 tag = **p;
00332 (*p)++;
00333 if( ( ret = asn1_get_len( p, end, &tag_len ) ) != 0 )
00334 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
00335
00336 if( ( tag & ASN1_CONTEXT_SPECIFIC ) != ASN1_CONTEXT_SPECIFIC )
00337 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
00338 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
00339
00340 if( tag != ( ASN1_CONTEXT_SPECIFIC | 2 ) )
00341 {
00342 *p += tag_len;
00343 continue;
00344 }
00345
00346 buf = &(cur->buf);
00347 buf->tag = tag;
00348 buf->p = *p;
00349 buf->len = tag_len;
00350 *p += buf->len;
00351
00352
00353 if (*p < end)
00354 {
00355 cur->next = (asn1_sequence *) polarssl_malloc(
00356 sizeof( asn1_sequence ) );
00357
00358 if( cur->next == NULL )
00359 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
00360 POLARSSL_ERR_ASN1_MALLOC_FAILED );
00361
00362 memset( cur->next, 0, sizeof( asn1_sequence ) );
00363 cur = cur->next;
00364 }
00365 }
00366
00367
00368 cur->next = NULL;
00369
00370 if( *p != end )
00371 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
00372 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00373
00374 return( 0 );
00375 }
00376
00377
00378
00379
00380
00381
00382
00383
00384 static int x509_get_crt_ext( unsigned char **p,
00385 const unsigned char *end,
00386 x509_crt *crt )
00387 {
00388 int ret;
00389 size_t len;
00390 unsigned char *end_ext_data, *end_ext_octet;
00391
00392 if( ( ret = x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 )
00393 {
00394 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
00395 return( 0 );
00396
00397 return( ret );
00398 }
00399
00400 while( *p < end )
00401 {
00402
00403
00404
00405
00406
00407
00408 x509_buf extn_oid = {0, 0, NULL};
00409 int is_critical = 0;
00410 int ext_type = 0;
00411
00412 if( ( ret = asn1_get_tag( p, end, &len,
00413 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00414 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
00415
00416 end_ext_data = *p + len;
00417
00418
00419 extn_oid.tag = **p;
00420
00421 if( ( ret = asn1_get_tag( p, end, &extn_oid.len, ASN1_OID ) ) != 0 )
00422 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
00423
00424 extn_oid.p = *p;
00425 *p += extn_oid.len;
00426
00427 if( ( end - *p ) < 1 )
00428 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
00429 POLARSSL_ERR_ASN1_OUT_OF_DATA );
00430
00431
00432 if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
00433 ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) )
00434 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
00435
00436
00437 if( ( ret = asn1_get_tag( p, end_ext_data, &len,
00438 ASN1_OCTET_STRING ) ) != 0 )
00439 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret );
00440
00441 end_ext_octet = *p + len;
00442
00443 if( end_ext_octet != end_ext_data )
00444 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
00445 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00446
00447
00448
00449
00450 ret = oid_get_x509_ext_type( &extn_oid, &ext_type );
00451
00452 if( ret != 0 )
00453 {
00454
00455 *p = end_ext_octet;
00456
00457 #if !defined(POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
00458 if( is_critical )
00459 {
00460
00461 return ( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
00462 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
00463 }
00464 #endif
00465 continue;
00466 }
00467
00468 crt->ext_types |= ext_type;
00469
00470 switch( ext_type )
00471 {
00472 case EXT_BASIC_CONSTRAINTS:
00473
00474 if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
00475 &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
00476 return ( ret );
00477 break;
00478
00479 case EXT_KEY_USAGE:
00480
00481 if( ( ret = x509_get_key_usage( p, end_ext_octet,
00482 &crt->key_usage ) ) != 0 )
00483 return ( ret );
00484 break;
00485
00486 case EXT_EXTENDED_KEY_USAGE:
00487
00488 if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
00489 &crt->ext_key_usage ) ) != 0 )
00490 return ( ret );
00491 break;
00492
00493 case EXT_SUBJECT_ALT_NAME:
00494
00495 if( ( ret = x509_get_subject_alt_name( p, end_ext_octet,
00496 &crt->subject_alt_names ) ) != 0 )
00497 return ( ret );
00498 break;
00499
00500 case EXT_NS_CERT_TYPE:
00501
00502 if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
00503 &crt->ns_cert_type ) ) != 0 )
00504 return ( ret );
00505 break;
00506
00507 default:
00508 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
00509 }
00510 }
00511
00512 if( *p != end )
00513 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS +
00514 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00515
00516 return( 0 );
00517 }
00518
00519
00520
00521
00522 static int x509_crt_parse_der_core( x509_crt *crt, const unsigned char *buf,
00523 size_t buflen )
00524 {
00525 int ret;
00526 size_t len;
00527 unsigned char *p, *end, *crt_end;
00528
00529
00530
00531
00532 if( crt == NULL || buf == NULL )
00533 return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
00534
00535 p = (unsigned char *) polarssl_malloc( len = buflen );
00536
00537 if( p == NULL )
00538 return( POLARSSL_ERR_X509_MALLOC_FAILED );
00539
00540 memcpy( p, buf, buflen );
00541
00542 buflen = 0;
00543
00544 crt->raw.p = p;
00545 crt->raw.len = len;
00546 end = p + len;
00547
00548
00549
00550
00551
00552
00553
00554 if( ( ret = asn1_get_tag( &p, end, &len,
00555 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00556 {
00557 x509_crt_free( crt );
00558 return( POLARSSL_ERR_X509_INVALID_FORMAT );
00559 }
00560
00561 if( len > (size_t) ( end - p ) )
00562 {
00563 x509_crt_free( crt );
00564 return( POLARSSL_ERR_X509_INVALID_FORMAT +
00565 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00566 }
00567 crt_end = p + len;
00568
00569
00570
00571
00572 crt->tbs.p = p;
00573
00574 if( ( ret = asn1_get_tag( &p, end, &len,
00575 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00576 {
00577 x509_crt_free( crt );
00578 return( POLARSSL_ERR_X509_INVALID_FORMAT + ret );
00579 }
00580
00581 end = p + len;
00582 crt->tbs.len = end - crt->tbs.p;
00583
00584
00585
00586
00587
00588
00589
00590
00591 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
00592 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
00593 ( ret = x509_get_alg_null( &p, end, &crt->sig_oid1 ) ) != 0 )
00594 {
00595 x509_crt_free( crt );
00596 return( ret );
00597 }
00598
00599 crt->version++;
00600
00601 if( crt->version > 3 )
00602 {
00603 x509_crt_free( crt );
00604 return( POLARSSL_ERR_X509_UNKNOWN_VERSION );
00605 }
00606
00607 if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &crt->sig_md,
00608 &crt->sig_pk ) ) != 0 )
00609 {
00610 x509_crt_free( crt );
00611 return( ret );
00612 }
00613
00614
00615
00616
00617 crt->issuer_raw.p = p;
00618
00619 if( ( ret = asn1_get_tag( &p, end, &len,
00620 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00621 {
00622 x509_crt_free( crt );
00623 return( POLARSSL_ERR_X509_INVALID_FORMAT + ret );
00624 }
00625
00626 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
00627 {
00628 x509_crt_free( crt );
00629 return( ret );
00630 }
00631
00632 crt->issuer_raw.len = p - crt->issuer_raw.p;
00633
00634
00635
00636
00637
00638
00639
00640 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
00641 &crt->valid_to ) ) != 0 )
00642 {
00643 x509_crt_free( crt );
00644 return( ret );
00645 }
00646
00647
00648
00649
00650 crt->subject_raw.p = p;
00651
00652 if( ( ret = asn1_get_tag( &p, end, &len,
00653 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00654 {
00655 x509_crt_free( crt );
00656 return( POLARSSL_ERR_X509_INVALID_FORMAT + ret );
00657 }
00658
00659 if( len && ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
00660 {
00661 x509_crt_free( crt );
00662 return( ret );
00663 }
00664
00665 crt->subject_raw.len = p - crt->subject_raw.p;
00666
00667
00668
00669
00670 if( ( ret = pk_parse_subpubkey( &p, end, &crt->pk ) ) != 0 )
00671 {
00672 x509_crt_free( crt );
00673 return( ret );
00674 }
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684 if( crt->version == 2 || crt->version == 3 )
00685 {
00686 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
00687 if( ret != 0 )
00688 {
00689 x509_crt_free( crt );
00690 return( ret );
00691 }
00692 }
00693
00694 if( crt->version == 2 || crt->version == 3 )
00695 {
00696 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
00697 if( ret != 0 )
00698 {
00699 x509_crt_free( crt );
00700 return( ret );
00701 }
00702 }
00703
00704 #if !defined(POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3)
00705 if( crt->version == 3 )
00706 {
00707 #endif
00708 ret = x509_get_crt_ext( &p, end, crt);
00709 if( ret != 0 )
00710 {
00711 x509_crt_free( crt );
00712 return( ret );
00713 }
00714 #if !defined(POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3)
00715 }
00716 #endif
00717
00718 if( p != end )
00719 {
00720 x509_crt_free( crt );
00721 return( POLARSSL_ERR_X509_INVALID_FORMAT +
00722 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00723 }
00724
00725 end = crt_end;
00726
00727
00728
00729
00730
00731
00732
00733
00734 if( ( ret = x509_get_alg_null( &p, end, &crt->sig_oid2 ) ) != 0 )
00735 {
00736 x509_crt_free( crt );
00737 return( ret );
00738 }
00739
00740 if( crt->sig_oid1.len != crt->sig_oid2.len ||
00741 memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 )
00742 {
00743 x509_crt_free( crt );
00744 return( POLARSSL_ERR_X509_SIG_MISMATCH );
00745 }
00746
00747 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 )
00748 {
00749 x509_crt_free( crt );
00750 return( ret );
00751 }
00752
00753 if( p != end )
00754 {
00755 x509_crt_free( crt );
00756 return( POLARSSL_ERR_X509_INVALID_FORMAT +
00757 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00758 }
00759
00760 return( 0 );
00761 }
00762
00763
00764
00765
00766
00767 int x509_crt_parse_der( x509_crt *chain, const unsigned char *buf,
00768 size_t buflen )
00769 {
00770 int ret;
00771 x509_crt *crt = chain, *prev = NULL;
00772
00773
00774
00775
00776 if( crt == NULL || buf == NULL )
00777 return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
00778
00779 while( crt->version != 0 && crt->next != NULL )
00780 {
00781 prev = crt;
00782 crt = crt->next;
00783 }
00784
00785
00786
00787
00788 if ( crt->version != 0 && crt->next == NULL)
00789 {
00790 crt->next = (x509_crt *) polarssl_malloc( sizeof( x509_crt ) );
00791
00792 if( crt->next == NULL )
00793 return( POLARSSL_ERR_X509_MALLOC_FAILED );
00794
00795 prev = crt;
00796 crt = crt->next;
00797 x509_crt_init( crt );
00798 }
00799
00800 if( ( ret = x509_crt_parse_der_core( crt, buf, buflen ) ) != 0 )
00801 {
00802 if( prev )
00803 prev->next = NULL;
00804
00805 if( crt != chain )
00806 polarssl_free( crt );
00807
00808 return( ret );
00809 }
00810
00811 return( 0 );
00812 }
00813
00814
00815
00816
00817 int x509_crt_parse( x509_crt *chain, const unsigned char *buf, size_t buflen )
00818 {
00819 int success = 0, first_error = 0, total_failed = 0;
00820 int buf_format = X509_FORMAT_DER;
00821
00822
00823
00824
00825 if( chain == NULL || buf == NULL )
00826 return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
00827
00828
00829
00830
00831
00832 #if defined(POLARSSL_PEM_PARSE_C)
00833 if( strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL )
00834 buf_format = X509_FORMAT_PEM;
00835 #endif
00836
00837 if( buf_format == X509_FORMAT_DER )
00838 return x509_crt_parse_der( chain, buf, buflen );
00839
00840 #if defined(POLARSSL_PEM_PARSE_C)
00841 if( buf_format == X509_FORMAT_PEM )
00842 {
00843 int ret;
00844 pem_context pem;
00845
00846 while( buflen > 0 )
00847 {
00848 size_t use_len;
00849 pem_init( &pem );
00850
00851 ret = pem_read_buffer( &pem,
00852 "-----BEGIN CERTIFICATE-----",
00853 "-----END CERTIFICATE-----",
00854 buf, NULL, 0, &use_len );
00855
00856 if( ret == 0 )
00857 {
00858
00859
00860
00861 buflen -= use_len;
00862 buf += use_len;
00863 }
00864 else if( ret == POLARSSL_ERR_PEM_BAD_INPUT_DATA )
00865 {
00866 return( ret );
00867 }
00868 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
00869 {
00870 pem_free( &pem );
00871
00872
00873
00874
00875 buflen -= use_len;
00876 buf += use_len;
00877
00878 if( first_error == 0 )
00879 first_error = ret;
00880
00881 continue;
00882 }
00883 else
00884 break;
00885
00886 ret = x509_crt_parse_der( chain, pem.buf, pem.buflen );
00887
00888 pem_free( &pem );
00889
00890 if( ret != 0 )
00891 {
00892
00893
00894
00895 if( ret == POLARSSL_ERR_X509_MALLOC_FAILED )
00896 return( ret );
00897
00898 if( first_error == 0 )
00899 first_error = ret;
00900
00901 total_failed++;
00902 continue;
00903 }
00904
00905 success = 1;
00906 }
00907 }
00908 #endif
00909
00910 if( success )
00911 return( total_failed );
00912 else if( first_error )
00913 return( first_error );
00914 else
00915 return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT );
00916 }
00917
00918 #if defined(POLARSSL_FS_IO)
00919
00920
00921
00922 int x509_crt_parse_file( x509_crt *chain, const char *path )
00923 {
00924 int ret;
00925 size_t n;
00926 unsigned char *buf;
00927
00928 if ( ( ret = x509_load_file( path, &buf, &n ) ) != 0 )
00929 return( ret );
00930
00931 ret = x509_crt_parse( chain, buf, n );
00932
00933 memset( buf, 0, n + 1 );
00934 polarssl_free( buf );
00935
00936 return( ret );
00937 }
00938
00939 int x509_crt_parse_path( x509_crt *chain, const char *path )
00940 {
00941 int ret = 0;
00942 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
00943 int w_ret;
00944 WCHAR szDir[MAX_PATH];
00945 char filename[MAX_PATH];
00946 char *p;
00947 int len = (int) strlen( path );
00948
00949 WIN32_FIND_DATAW file_data;
00950 HANDLE hFind;
00951
00952 if( len > MAX_PATH - 3 )
00953 return( POLARSSL_ERR_X509_BAD_INPUT_DATA );
00954
00955 memset( szDir, 0, sizeof(szDir) );
00956 memset( filename, 0, MAX_PATH );
00957 memcpy( filename, path, len );
00958 filename[len++] = '\\';
00959 p = filename + len;
00960 filename[len++] = '*';
00961
00962 w_ret = MultiByteToWideChar( CP_ACP, 0, path, len, szDir, MAX_PATH - 3 );
00963
00964 hFind = FindFirstFileW( szDir, &file_data );
00965 if (hFind == INVALID_HANDLE_VALUE)
00966 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
00967
00968 len = MAX_PATH - len;
00969 do
00970 {
00971 memset( p, 0, len );
00972
00973 if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
00974 continue;
00975
00976 w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName,
00977 lstrlenW(file_data.cFileName),
00978 p, len - 1,
00979 NULL, NULL );
00980
00981 w_ret = x509_crt_parse_file( chain, filename );
00982 if( w_ret < 0 )
00983 ret++;
00984 else
00985 ret += w_ret;
00986 }
00987 while( FindNextFileW( hFind, &file_data ) != 0 );
00988
00989 if (GetLastError() != ERROR_NO_MORE_FILES)
00990 ret = POLARSSL_ERR_X509_FILE_IO_ERROR;
00991
00992 FindClose( hFind );
00993 #else
00994 #if defined(POLARSSL_HAVE_READDIR_R)
00995 int t_ret, i;
00996 struct stat sb;
00997 struct dirent entry, *result = NULL;
00998 char entry_name[255];
00999 DIR *dir = opendir( path );
01000
01001 if( dir == NULL)
01002 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
01003
01004 while( ( t_ret = readdir_r( dir, &entry, &result ) ) == 0 )
01005 {
01006 if( result == NULL )
01007 break;
01008
01009 snprintf( entry_name, sizeof(entry_name), "%s/%s", path, entry.d_name );
01010
01011 i = stat( entry_name, &sb );
01012
01013 if( i == -1 )
01014 {
01015 closedir( dir );
01016 return( POLARSSL_ERR_X509_FILE_IO_ERROR );
01017 }
01018
01019 if( !S_ISREG( sb.st_mode ) )
01020 continue;
01021
01022
01023
01024 t_ret = x509_crt_parse_file( chain, entry_name );
01025 if( t_ret < 0 )
01026 ret++;
01027 else
01028 ret += t_ret;
01029 }
01030 closedir( dir );
01031 #else
01032 ((void) chain);
01033 ((void) path);
01034 ret = POLARSSL_ERR_X509_FEATURE_UNAVAILABLE;
01035 #endif
01036 #endif
01037
01038 return( ret );
01039 }
01040 #endif
01041
01042 #if defined(_MSC_VER) && !defined snprintf && !defined(EFIX64) && \
01043 !defined(EFI32)
01044 #include <stdarg.h>
01045
01046 #if !defined vsnprintf
01047 #define vsnprintf _vsnprintf
01048 #endif // vsnprintf
01049
01050
01051
01052
01053
01054
01055
01056
01057 static int compat_snprintf(char *str, size_t size, const char *format, ...)
01058 {
01059 va_list ap;
01060 int res = -1;
01061
01062 va_start( ap, format );
01063
01064 res = vsnprintf( str, size, format, ap );
01065
01066 va_end( ap );
01067
01068
01069 if ( res < 0 )
01070 return( (int) size + 20 );
01071
01072 return res;
01073 }
01074
01075 #define snprintf compat_snprintf
01076 #endif
01077
01078 #define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
01079
01080 #define SAFE_SNPRINTF() \
01081 { \
01082 if( ret == -1 ) \
01083 return( -1 ); \
01084 \
01085 if ( (unsigned int) ret > n ) { \
01086 p[n - 1] = '\0'; \
01087 return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
01088 } \
01089 \
01090 n -= (unsigned int) ret; \
01091 p += (unsigned int) ret; \
01092 }
01093
01094
01095
01096
01097 #define BEFORE_COLON 14
01098 #define BC "14"
01099 int x509_crt_info( char *buf, size_t size, const char *prefix,
01100 const x509_crt *crt )
01101 {
01102 int ret;
01103 size_t n;
01104 char *p;
01105 const char *desc = NULL;
01106 char key_size_str[BEFORE_COLON];
01107
01108 p = buf;
01109 n = size;
01110
01111 ret = snprintf( p, n, "%scert. version : %d\n",
01112 prefix, crt->version );
01113 SAFE_SNPRINTF();
01114 ret = snprintf( p, n, "%sserial number : ",
01115 prefix );
01116 SAFE_SNPRINTF();
01117
01118 ret = x509_serial_gets( p, n, &crt->serial);
01119 SAFE_SNPRINTF();
01120
01121 ret = snprintf( p, n, "\n%sissuer name : ", prefix );
01122 SAFE_SNPRINTF();
01123 ret = x509_dn_gets( p, n, &crt->issuer );
01124 SAFE_SNPRINTF();
01125
01126 ret = snprintf( p, n, "\n%ssubject name : ", prefix );
01127 SAFE_SNPRINTF();
01128 ret = x509_dn_gets( p, n, &crt->subject );
01129 SAFE_SNPRINTF();
01130
01131 ret = snprintf( p, n, "\n%sissued on : " \
01132 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
01133 crt->valid_from.year, crt->valid_from.mon,
01134 crt->valid_from.day, crt->valid_from.hour,
01135 crt->valid_from.min, crt->valid_from.sec );
01136 SAFE_SNPRINTF();
01137
01138 ret = snprintf( p, n, "\n%sexpires on : " \
01139 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
01140 crt->valid_to.year, crt->valid_to.mon,
01141 crt->valid_to.day, crt->valid_to.hour,
01142 crt->valid_to.min, crt->valid_to.sec );
01143 SAFE_SNPRINTF();
01144
01145 ret = snprintf( p, n, "\n%ssigned using : ", prefix );
01146 SAFE_SNPRINTF();
01147
01148 ret = oid_get_sig_alg_desc( &crt->sig_oid1, &desc );
01149 if( ret != 0 )
01150 ret = snprintf( p, n, "???" );
01151 else
01152 ret = snprintf( p, n, "%s", desc );
01153 SAFE_SNPRINTF();
01154
01155 if( ( ret = x509_key_size_helper( key_size_str, BEFORE_COLON,
01156 pk_get_name( &crt->pk ) ) ) != 0 )
01157 {
01158 return( ret );
01159 }
01160
01161 ret = snprintf( p, n, "\n%s%-" BC "s: %d bits\n", prefix, key_size_str,
01162 (int) pk_get_size( &crt->pk ) );
01163 SAFE_SNPRINTF();
01164
01165 return( (int) ( size - n ) );
01166 }
01167
01168 #if defined(POLARSSL_X509_CRL_PARSE_C)
01169
01170
01171
01172 int x509_crt_revoked( const x509_crt *crt, const x509_crl *crl )
01173 {
01174 const x509_crl_entry *cur = &crl->entry;
01175
01176 while( cur != NULL && cur->serial.len != 0 )
01177 {
01178 if( crt->serial.len == cur->serial.len &&
01179 memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
01180 {
01181 if( x509_time_expired( &cur->revocation_date ) )
01182 return( 1 );
01183 }
01184
01185 cur = cur->next;
01186 }
01187
01188 return( 0 );
01189 }
01190
01191
01192
01193
01194 static int x509_crt_verifycrl( x509_crt *crt, x509_crt *ca,
01195 x509_crl *crl_list)
01196 {
01197 int flags = 0;
01198 unsigned char hash[POLARSSL_MD_MAX_SIZE];
01199 const md_info_t *md_info;
01200
01201 if( ca == NULL )
01202 return( flags );
01203
01204
01205
01206
01207
01208
01209
01210 while( crl_list != NULL )
01211 {
01212 if( crl_list->version == 0 ||
01213 crl_list->issuer_raw.len != ca->subject_raw.len ||
01214 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
01215 crl_list->issuer_raw.len ) != 0 )
01216 {
01217 crl_list = crl_list->next;
01218 continue;
01219 }
01220
01221
01222
01223
01224 md_info = md_info_from_type( crl_list->sig_md );
01225 if( md_info == NULL )
01226 {
01227
01228
01229
01230 flags |= BADCRL_NOT_TRUSTED;
01231 break;
01232 }
01233
01234 md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash );
01235
01236 if( pk_can_do( &ca->pk, crl_list->sig_pk ) == 0 ||
01237 pk_verify( &ca->pk, crl_list->sig_md, hash, md_info->size,
01238 crl_list->sig.p, crl_list->sig.len ) != 0 )
01239 {
01240 flags |= BADCRL_NOT_TRUSTED;
01241 break;
01242 }
01243
01244
01245
01246
01247 if( x509_time_expired( &crl_list->next_update ) )
01248 flags |= BADCRL_EXPIRED;
01249
01250
01251
01252
01253 if( x509_crt_revoked(crt, crl_list) )
01254 {
01255 flags |= BADCERT_REVOKED;
01256 break;
01257 }
01258
01259 crl_list = crl_list->next;
01260 }
01261 return flags;
01262 }
01263 #endif
01264
01265
01266 static int x509_name_cmp( const void *s1, const void *s2, size_t len )
01267 {
01268 size_t i;
01269 unsigned char diff;
01270 const unsigned char *n1 = s1, *n2 = s2;
01271
01272 for( i = 0; i < len; i++ )
01273 {
01274 diff = n1[i] ^ n2[i];
01275
01276 if( ( n1[i] >= 'a' || n1[i] <= 'z' ) && ( diff == 0 || diff == 32 ) )
01277 continue;
01278
01279 if( ( n1[i] >= 'A' || n1[i] <= 'Z' ) && ( diff == 0 || diff == 32 ) )
01280 continue;
01281
01282 return( 1 );
01283 }
01284
01285 return( 0 );
01286 }
01287
01288 static int x509_wildcard_verify( const char *cn, x509_buf *name )
01289 {
01290 size_t i;
01291 size_t cn_idx = 0;
01292
01293 if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' )
01294 return( 0 );
01295
01296 for( i = 0; i < strlen( cn ); ++i )
01297 {
01298 if( cn[i] == '.' )
01299 {
01300 cn_idx = i;
01301 break;
01302 }
01303 }
01304
01305 if( cn_idx == 0 )
01306 return( 0 );
01307
01308 if( strlen( cn ) - cn_idx == name->len - 1 &&
01309 x509_name_cmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
01310 {
01311 return( 1 );
01312 }
01313
01314 return( 0 );
01315 }
01316
01317 static int x509_crt_verify_top(
01318 x509_crt *child, x509_crt *trust_ca,
01319 x509_crl *ca_crl, int path_cnt, int *flags,
01320 int (*f_vrfy)(void *, x509_crt *, int, int *),
01321 void *p_vrfy )
01322 {
01323 int ret;
01324 int ca_flags = 0, check_path_cnt = path_cnt + 1;
01325 unsigned char hash[POLARSSL_MD_MAX_SIZE];
01326 const md_info_t *md_info;
01327
01328 if( x509_time_expired( &child->valid_to ) )
01329 *flags |= BADCERT_EXPIRED;
01330
01331
01332
01333
01334 *flags |= BADCERT_NOT_TRUSTED;
01335
01336 md_info = md_info_from_type( child->sig_md );
01337 if( md_info == NULL )
01338 {
01339
01340
01341
01342 trust_ca = NULL;
01343 }
01344 else
01345 md( md_info, child->tbs.p, child->tbs.len, hash );
01346
01347 while( trust_ca != NULL )
01348 {
01349 if( trust_ca->version == 0 ||
01350 child->issuer_raw.len != trust_ca->subject_raw.len ||
01351 memcmp( child->issuer_raw.p, trust_ca->subject_raw.p,
01352 child->issuer_raw.len ) != 0 )
01353 {
01354 trust_ca = trust_ca->next;
01355 continue;
01356 }
01357
01358
01359
01360
01361
01362 if( child->subject_raw.len == trust_ca->subject_raw.len &&
01363 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
01364 child->issuer_raw.len ) == 0 )
01365 {
01366 check_path_cnt--;
01367 }
01368
01369 if( trust_ca->max_pathlen > 0 &&
01370 trust_ca->max_pathlen < check_path_cnt )
01371 {
01372 trust_ca = trust_ca->next;
01373 continue;
01374 }
01375
01376 if( pk_can_do( &trust_ca->pk, child->sig_pk ) == 0 ||
01377 pk_verify( &trust_ca->pk, child->sig_md, hash, md_info->size,
01378 child->sig.p, child->sig.len ) != 0 )
01379 {
01380 trust_ca = trust_ca->next;
01381 continue;
01382 }
01383
01384
01385
01386
01387 *flags &= ~BADCERT_NOT_TRUSTED;
01388 break;
01389 }
01390
01391
01392
01393
01394
01395
01396 if( trust_ca != NULL &&
01397 ( child->subject_raw.len != trust_ca->subject_raw.len ||
01398 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
01399 child->issuer_raw.len ) != 0 ) )
01400 {
01401 #if defined(POLARSSL_X509_CRL_PARSE_C)
01402
01403 *flags |= x509_crt_verifycrl( child, trust_ca, ca_crl );
01404 #else
01405 ((void) ca_crl);
01406 #endif
01407
01408 if( x509_time_expired( &trust_ca->valid_to ) )
01409 ca_flags |= BADCERT_EXPIRED;
01410
01411 if( NULL != f_vrfy )
01412 {
01413 if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1, &ca_flags ) ) != 0 )
01414 return( ret );
01415 }
01416 }
01417
01418
01419 if( NULL != f_vrfy )
01420 {
01421 if( ( ret = f_vrfy(p_vrfy, child, path_cnt, flags ) ) != 0 )
01422 return( ret );
01423 }
01424
01425 *flags |= ca_flags;
01426
01427 return( 0 );
01428 }
01429
01430 static int x509_crt_verify_child(
01431 x509_crt *child, x509_crt *parent, x509_crt *trust_ca,
01432 x509_crl *ca_crl, int path_cnt, int *flags,
01433 int (*f_vrfy)(void *, x509_crt *, int, int *),
01434 void *p_vrfy )
01435 {
01436 int ret;
01437 int parent_flags = 0;
01438 unsigned char hash[POLARSSL_MD_MAX_SIZE];
01439 x509_crt *grandparent;
01440 const md_info_t *md_info;
01441
01442 if( x509_time_expired( &child->valid_to ) )
01443 *flags |= BADCERT_EXPIRED;
01444
01445 md_info = md_info_from_type( child->sig_md );
01446 if( md_info == NULL )
01447 {
01448
01449
01450
01451 *flags |= BADCERT_NOT_TRUSTED;
01452 }
01453 else
01454 {
01455 md( md_info, child->tbs.p, child->tbs.len, hash );
01456
01457 if( pk_can_do( &parent->pk, child->sig_pk ) == 0 ||
01458 pk_verify( &parent->pk, child->sig_md, hash, md_info->size,
01459 child->sig.p, child->sig.len ) != 0 )
01460 {
01461 *flags |= BADCERT_NOT_TRUSTED;
01462 }
01463 }
01464
01465 #if defined(POLARSSL_X509_CRL_PARSE_C)
01466
01467 *flags |= x509_crt_verifycrl(child, parent, ca_crl);
01468 #endif
01469
01470 grandparent = parent->next;
01471
01472 while( grandparent != NULL )
01473 {
01474 if( grandparent->version == 0 ||
01475 grandparent->ca_istrue == 0 ||
01476 parent->issuer_raw.len != grandparent->subject_raw.len ||
01477 memcmp( parent->issuer_raw.p, grandparent->subject_raw.p,
01478 parent->issuer_raw.len ) != 0 )
01479 {
01480 grandparent = grandparent->next;
01481 continue;
01482 }
01483 break;
01484 }
01485
01486 if( grandparent != NULL )
01487 {
01488
01489
01490
01491 ret = x509_crt_verify_child( parent, grandparent, trust_ca, ca_crl, path_cnt + 1, &parent_flags, f_vrfy, p_vrfy );
01492 if( ret != 0 )
01493 return( ret );
01494 }
01495 else
01496 {
01497 ret = x509_crt_verify_top( parent, trust_ca, ca_crl, path_cnt + 1, &parent_flags, f_vrfy, p_vrfy );
01498 if( ret != 0 )
01499 return( ret );
01500 }
01501
01502
01503 if( NULL != f_vrfy )
01504 if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
01505 return( ret );
01506
01507 *flags |= parent_flags;
01508
01509 return( 0 );
01510 }
01511
01512
01513
01514
01515 int x509_crt_verify( x509_crt *crt,
01516 x509_crt *trust_ca,
01517 x509_crl *ca_crl,
01518 const char *cn, int *flags,
01519 int (*f_vrfy)(void *, x509_crt *, int, int *),
01520 void *p_vrfy )
01521 {
01522 size_t cn_len;
01523 int ret;
01524 int pathlen = 0;
01525 x509_crt *parent;
01526 x509_name *name;
01527 x509_sequence *cur = NULL;
01528
01529 *flags = 0;
01530
01531 if( cn != NULL )
01532 {
01533 name = &crt->subject;
01534 cn_len = strlen( cn );
01535
01536 if( crt->ext_types & EXT_SUBJECT_ALT_NAME )
01537 {
01538 cur = &crt->subject_alt_names;
01539
01540 while( cur != NULL )
01541 {
01542 if( cur->buf.len == cn_len &&
01543 x509_name_cmp( cn, cur->buf.p, cn_len ) == 0 )
01544 break;
01545
01546 if( cur->buf.len > 2 &&
01547 memcmp( cur->buf.p, "*.", 2 ) == 0 &&
01548 x509_wildcard_verify( cn, &cur->buf ) )
01549 break;
01550
01551 cur = cur->next;
01552 }
01553
01554 if( cur == NULL )
01555 *flags |= BADCERT_CN_MISMATCH;
01556 }
01557 else
01558 {
01559 while( name != NULL )
01560 {
01561 if( OID_CMP( OID_AT_CN, &name->oid ) )
01562 {
01563 if( name->val.len == cn_len &&
01564 x509_name_cmp( name->val.p, cn, cn_len ) == 0 )
01565 break;
01566
01567 if( name->val.len > 2 &&
01568 memcmp( name->val.p, "*.", 2 ) == 0 &&
01569 x509_wildcard_verify( cn, &name->val ) )
01570 break;
01571 }
01572
01573 name = name->next;
01574 }
01575
01576 if( name == NULL )
01577 *flags |= BADCERT_CN_MISMATCH;
01578 }
01579 }
01580
01581
01582
01583
01584
01585 parent = crt->next;
01586
01587 while( parent != NULL && parent->version != 0 )
01588 {
01589 if( parent->ca_istrue == 0 ||
01590 crt->issuer_raw.len != parent->subject_raw.len ||
01591 memcmp( crt->issuer_raw.p, parent->subject_raw.p,
01592 crt->issuer_raw.len ) != 0 )
01593 {
01594 parent = parent->next;
01595 continue;
01596 }
01597 break;
01598 }
01599
01600 if( parent != NULL )
01601 {
01602
01603
01604
01605 ret = x509_crt_verify_child( crt, parent, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
01606 if( ret != 0 )
01607 return( ret );
01608 }
01609 else
01610 {
01611 ret = x509_crt_verify_top( crt, trust_ca, ca_crl, pathlen, flags, f_vrfy, p_vrfy );
01612 if( ret != 0 )
01613 return( ret );
01614 }
01615
01616 if( *flags != 0 )
01617 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED );
01618
01619 return( 0 );
01620 }
01621
01622
01623
01624
01625 void x509_crt_init( x509_crt *crt )
01626 {
01627 memset( crt, 0, sizeof(x509_crt) );
01628 }
01629
01630
01631
01632
01633 void x509_crt_free( x509_crt *crt )
01634 {
01635 x509_crt *cert_cur = crt;
01636 x509_crt *cert_prv;
01637 x509_name *name_cur;
01638 x509_name *name_prv;
01639 x509_sequence *seq_cur;
01640 x509_sequence *seq_prv;
01641
01642 if( crt == NULL )
01643 return;
01644
01645 do
01646 {
01647 pk_free( &cert_cur->pk );
01648
01649 name_cur = cert_cur->issuer.next;
01650 while( name_cur != NULL )
01651 {
01652 name_prv = name_cur;
01653 name_cur = name_cur->next;
01654 memset( name_prv, 0, sizeof( x509_name ) );
01655 polarssl_free( name_prv );
01656 }
01657
01658 name_cur = cert_cur->subject.next;
01659 while( name_cur != NULL )
01660 {
01661 name_prv = name_cur;
01662 name_cur = name_cur->next;
01663 memset( name_prv, 0, sizeof( x509_name ) );
01664 polarssl_free( name_prv );
01665 }
01666
01667 seq_cur = cert_cur->ext_key_usage.next;
01668 while( seq_cur != NULL )
01669 {
01670 seq_prv = seq_cur;
01671 seq_cur = seq_cur->next;
01672 memset( seq_prv, 0, sizeof( x509_sequence ) );
01673 polarssl_free( seq_prv );
01674 }
01675
01676 seq_cur = cert_cur->subject_alt_names.next;
01677 while( seq_cur != NULL )
01678 {
01679 seq_prv = seq_cur;
01680 seq_cur = seq_cur->next;
01681 memset( seq_prv, 0, sizeof( x509_sequence ) );
01682 polarssl_free( seq_prv );
01683 }
01684
01685 if( cert_cur->raw.p != NULL )
01686 {
01687 memset( cert_cur->raw.p, 0, cert_cur->raw.len );
01688 polarssl_free( cert_cur->raw.p );
01689 }
01690
01691 cert_cur = cert_cur->next;
01692 }
01693 while( cert_cur != NULL );
01694
01695 cert_cur = crt;
01696 do
01697 {
01698 cert_prv = cert_cur;
01699 cert_cur = cert_cur->next;
01700
01701 memset( cert_prv, 0, sizeof( x509_crt ) );
01702 if( cert_prv != crt )
01703 polarssl_free( cert_prv );
01704 }
01705 while( cert_cur != NULL );
01706 }
01707
01708 #endif