mbed TLS library
Dependents: HTTPClient-SSL WS_SERVER
x509_crt.c
00001 /* 00002 * X.509 certificate parsing and verification 00003 * 00004 * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved 00005 * 00006 * This file is part of mbed TLS (https://tls.mbed.org) 00007 * 00008 * This program is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation; either version 2 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License along 00019 * with this program; if not, write to the Free Software Foundation, Inc., 00020 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00021 */ 00022 /* 00023 * The ITU-T X.509 standard defines a certificate format for PKI. 00024 * 00025 * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs) 00026 * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs) 00027 * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10) 00028 * 00029 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf 00030 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf 00031 */ 00032 00033 #if !defined(POLARSSL_CONFIG_FILE) 00034 #include "polarssl/config.h" 00035 #else 00036 #include POLARSSL_CONFIG_FILE 00037 #endif 00038 00039 #if defined(POLARSSL_X509_CRT_PARSE_C) 00040 00041 #include "polarssl/x509_crt.h" 00042 #include "polarssl/oid.h" 00043 00044 #include <stdio.h> 00045 #include <string.h> 00046 00047 #if defined(POLARSSL_PEM_PARSE_C) 00048 #include "polarssl/pem.h" 00049 #endif 00050 00051 #if defined(POLARSSL_PLATFORM_C) 00052 #include "polarssl/platform.h" 00053 #else 00054 #include <stdlib.h> 00055 #define polarssl_free free 00056 #define polarssl_malloc malloc 00057 #define polarssl_snprintf snprintf 00058 #endif 00059 00060 #if defined(POLARSSL_THREADING_C) 00061 #include "polarssl/threading.h" 00062 #endif 00063 00064 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) 00065 #include <windows.h> 00066 #else 00067 #include <time.h> 00068 #endif 00069 00070 #if defined(POLARSSL_FS_IO) 00071 #include <stdio.h> 00072 #if !defined(_WIN32) || defined(EFIX64) || defined(EFI32) 00073 #include <sys/types.h> 00074 #include <sys/stat.h> 00075 #include <dirent.h> 00076 #endif /* !_WIN32 || EFIX64 || EFI32 */ 00077 #endif 00078 00079 /* Implementation that should never be optimized out by the compiler */ 00080 static void polarssl_zeroize( void *v, size_t n ) { 00081 volatile unsigned char *p = v; while( n-- ) *p++ = 0; 00082 } 00083 00084 /* 00085 * Version ::= INTEGER { v1(0), v2(1), v3(2) } 00086 */ 00087 static int x509_get_version( unsigned char **p, 00088 const unsigned char *end, 00089 int *ver ) 00090 { 00091 int ret; 00092 size_t len; 00093 00094 if( ( ret = asn1_get_tag( p, end, &len, 00095 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) != 0 ) 00096 { 00097 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) 00098 { 00099 *ver = 0; 00100 return( 0 ); 00101 } 00102 00103 return( ret ); 00104 } 00105 00106 end = *p + len; 00107 00108 if( ( ret = asn1_get_int( p, end, ver ) ) != 0 ) 00109 return( POLARSSL_ERR_X509_INVALID_VERSION + ret ); 00110 00111 if( *p != end ) 00112 return( POLARSSL_ERR_X509_INVALID_VERSION + 00113 POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); 00114 00115 return( 0 ); 00116 } 00117 00118 /* 00119 * Validity ::= SEQUENCE { 00120 * notBefore Time, 00121 * notAfter Time } 00122 */ 00123 static int x509_get_dates( unsigned char **p, 00124 const unsigned char *end, 00125 x509_time *from, 00126 x509_time *to ) 00127 { 00128 int ret; 00129 size_t len; 00130 00131 if( ( ret = asn1_get_tag( p, end, &len, 00132 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) 00133 return( POLARSSL_ERR_X509_INVALID_DATE + ret ); 00134 00135 end = *p + len; 00136 00137 if( ( ret = x509_get_time( p, end, from ) ) != 0 ) 00138 return( ret ); 00139 00140 if( ( ret = x509_get_time( p, end, to ) ) != 0 ) 00141 return( ret ); 00142 00143 if( *p != end ) 00144 return( POLARSSL_ERR_X509_INVALID_DATE + 00145 POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); 00146 00147 return( 0 ); 00148 } 00149 00150 /* 00151 * X.509 v2/v3 unique identifier (not parsed) 00152 */ 00153 static int x509_get_uid( unsigned char **p, 00154 const unsigned char *end, 00155 x509_buf *uid, int n ) 00156 { 00157 int ret; 00158 00159 if( *p == end ) 00160 return( 0 ); 00161 00162 uid->tag = **p; 00163 00164 if( ( ret = asn1_get_tag( p, end, &uid->len, 00165 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | n ) ) != 0 ) 00166 { 00167 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) 00168 return( 0 ); 00169 00170 return( ret ); 00171 } 00172 00173 uid->p = *p; 00174 *p += uid->len; 00175 00176 return( 0 ); 00177 } 00178 00179 static int x509_get_basic_constraints( unsigned char **p, 00180 const unsigned char *end, 00181 int *ca_istrue, 00182 int *max_pathlen ) 00183 { 00184 int ret; 00185 size_t len; 00186 00187 /* 00188 * BasicConstraints ::= SEQUENCE { 00189 * cA BOOLEAN DEFAULT FALSE, 00190 * pathLenConstraint INTEGER (0..MAX) OPTIONAL } 00191 */ 00192 *ca_istrue = 0; /* DEFAULT FALSE */ 00193 *max_pathlen = 0; /* endless */ 00194 00195 if( ( ret = asn1_get_tag( p, end, &len, 00196 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) 00197 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret ); 00198 00199 if( *p == end ) 00200 return( 0 ); 00201 00202 if( ( ret = asn1_get_bool( p, end, ca_istrue ) ) != 0 ) 00203 { 00204 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) 00205 ret = asn1_get_int( p, end, ca_istrue ); 00206 00207 if( ret != 0 ) 00208 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret ); 00209 00210 if( *ca_istrue != 0 ) 00211 *ca_istrue = 1; 00212 } 00213 00214 if( *p == end ) 00215 return( 0 ); 00216 00217 if( ( ret = asn1_get_int( p, end, max_pathlen ) ) != 0 ) 00218 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret ); 00219 00220 if( *p != end ) 00221 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + 00222 POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); 00223 00224 (*max_pathlen)++; 00225 00226 return( 0 ); 00227 } 00228 00229 static int x509_get_ns_cert_type( unsigned char **p, 00230 const unsigned char *end, 00231 unsigned char *ns_cert_type) 00232 { 00233 int ret; 00234 x509_bitstring bs = { 0, 0, NULL }; 00235 00236 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 ) 00237 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret ); 00238 00239 if( bs.len != 1 ) 00240 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + 00241 POLARSSL_ERR_ASN1_INVALID_LENGTH ); 00242 00243 /* Get actual bitstring */ 00244 *ns_cert_type = *bs.p; 00245 return( 0 ); 00246 } 00247 00248 static int x509_get_key_usage( unsigned char **p, 00249 const unsigned char *end, 00250 unsigned char *key_usage) 00251 { 00252 int ret; 00253 x509_bitstring bs = { 0, 0, NULL }; 00254 00255 if( ( ret = asn1_get_bitstring( p, end, &bs ) ) != 0 ) 00256 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret ); 00257 00258 if( bs.len < 1 ) 00259 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + 00260 POLARSSL_ERR_ASN1_INVALID_LENGTH ); 00261 00262 /* Get actual bitstring */ 00263 *key_usage = *bs.p; 00264 return( 0 ); 00265 } 00266 00267 /* 00268 * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId 00269 * 00270 * KeyPurposeId ::= OBJECT IDENTIFIER 00271 */ 00272 static int x509_get_ext_key_usage( unsigned char **p, 00273 const unsigned char *end, 00274 x509_sequence *ext_key_usage) 00275 { 00276 int ret; 00277 00278 if( ( ret = asn1_get_sequence_of( p, end, ext_key_usage, ASN1_OID ) ) != 0 ) 00279 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret ); 00280 00281 /* Sequence length must be >= 1 */ 00282 if( ext_key_usage->buf.p == NULL ) 00283 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + 00284 POLARSSL_ERR_ASN1_INVALID_LENGTH ); 00285 00286 return( 0 ); 00287 } 00288 00289 /* 00290 * SubjectAltName ::= GeneralNames 00291 * 00292 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName 00293 * 00294 * GeneralName ::= CHOICE { 00295 * otherName [0] OtherName, 00296 * rfc822Name [1] IA5String, 00297 * dNSName [2] IA5String, 00298 * x400Address [3] ORAddress, 00299 * directoryName [4] Name, 00300 * ediPartyName [5] EDIPartyName, 00301 * uniformResourceIdentifier [6] IA5String, 00302 * iPAddress [7] OCTET STRING, 00303 * registeredID [8] OBJECT IDENTIFIER } 00304 * 00305 * OtherName ::= SEQUENCE { 00306 * type-id OBJECT IDENTIFIER, 00307 * value [0] EXPLICIT ANY DEFINED BY type-id } 00308 * 00309 * EDIPartyName ::= SEQUENCE { 00310 * nameAssigner [0] DirectoryString OPTIONAL, 00311 * partyName [1] DirectoryString } 00312 * 00313 * NOTE: we only parse and use dNSName at this point. 00314 */ 00315 static int x509_get_subject_alt_name( unsigned char **p, 00316 const unsigned char *end, 00317 x509_sequence *subject_alt_name ) 00318 { 00319 int ret; 00320 size_t len, tag_len; 00321 asn1_buf *buf; 00322 unsigned char tag; 00323 asn1_sequence *cur = subject_alt_name; 00324 00325 /* Get main sequence tag */ 00326 if( ( ret = asn1_get_tag( p, end, &len, 00327 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) 00328 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret ); 00329 00330 if( *p + len != end ) 00331 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + 00332 POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); 00333 00334 while( *p < end ) 00335 { 00336 if( ( end - *p ) < 1 ) 00337 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + 00338 POLARSSL_ERR_ASN1_OUT_OF_DATA ); 00339 00340 tag = **p; 00341 (*p)++; 00342 if( ( ret = asn1_get_len( p, end, &tag_len ) ) != 0 ) 00343 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret ); 00344 00345 if( ( tag & ASN1_CONTEXT_SPECIFIC ) != ASN1_CONTEXT_SPECIFIC ) 00346 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + 00347 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ); 00348 00349 /* Skip everything but DNS name */ 00350 if( tag != ( ASN1_CONTEXT_SPECIFIC | 2 ) ) 00351 { 00352 *p += tag_len; 00353 continue; 00354 } 00355 00356 /* Allocate and assign next pointer */ 00357 if( cur->buf.p != NULL ) 00358 { 00359 if( cur->next != NULL ) 00360 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS ); 00361 00362 cur->next = polarssl_malloc( sizeof( asn1_sequence ) ); 00363 00364 if( cur->next == NULL ) 00365 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + 00366 POLARSSL_ERR_ASN1_MALLOC_FAILED ); 00367 00368 memset( cur->next, 0, sizeof( asn1_sequence ) ); 00369 cur = cur->next; 00370 } 00371 00372 buf = &(cur->buf); 00373 buf->tag = tag; 00374 buf->p = *p; 00375 buf->len = tag_len; 00376 *p += buf->len; 00377 } 00378 00379 /* Set final sequence entry's next pointer to NULL */ 00380 cur->next = NULL; 00381 00382 if( *p != end ) 00383 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + 00384 POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); 00385 00386 return( 0 ); 00387 } 00388 00389 /* 00390 * X.509 v3 extensions 00391 * 00392 * TODO: Perform all of the basic constraints tests required by the RFC 00393 * TODO: Set values for undetected extensions to a sane default? 00394 * 00395 */ 00396 static int x509_get_crt_ext( unsigned char **p, 00397 const unsigned char *end, 00398 x509_crt *crt ) 00399 { 00400 int ret; 00401 size_t len; 00402 unsigned char *end_ext_data, *end_ext_octet; 00403 00404 if( ( ret = x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 ) 00405 { 00406 if( ret == POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) 00407 return( 0 ); 00408 00409 return( ret ); 00410 } 00411 00412 while( *p < end ) 00413 { 00414 /* 00415 * Extension ::= SEQUENCE { 00416 * extnID OBJECT IDENTIFIER, 00417 * critical BOOLEAN DEFAULT FALSE, 00418 * extnValue OCTET STRING } 00419 */ 00420 x509_buf extn_oid = {0, 0, NULL}; 00421 int is_critical = 0; /* DEFAULT FALSE */ 00422 int ext_type = 0; 00423 00424 if( ( ret = asn1_get_tag( p, end, &len, 00425 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) 00426 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret ); 00427 00428 end_ext_data = *p + len; 00429 00430 /* Get extension ID */ 00431 extn_oid.tag = **p; 00432 00433 if( ( ret = asn1_get_tag( p, end, &extn_oid.len, ASN1_OID ) ) != 0 ) 00434 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret ); 00435 00436 extn_oid.p = *p; 00437 *p += extn_oid.len; 00438 00439 if( ( end - *p ) < 1 ) 00440 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + 00441 POLARSSL_ERR_ASN1_OUT_OF_DATA ); 00442 00443 /* Get optional critical */ 00444 if( ( ret = asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 && 00445 ( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG ) ) 00446 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret ); 00447 00448 /* Data should be octet string type */ 00449 if( ( ret = asn1_get_tag( p, end_ext_data, &len, 00450 ASN1_OCTET_STRING ) ) != 0 ) 00451 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + ret ); 00452 00453 end_ext_octet = *p + len; 00454 00455 if( end_ext_octet != end_ext_data ) 00456 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + 00457 POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); 00458 00459 /* 00460 * Detect supported extensions 00461 */ 00462 ret = oid_get_x509_ext_type( &extn_oid, &ext_type ); 00463 00464 if( ret != 0 ) 00465 { 00466 /* No parser found, skip extension */ 00467 *p = end_ext_octet; 00468 00469 #if !defined(POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION) 00470 if( is_critical ) 00471 { 00472 /* Data is marked as critical: fail */ 00473 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + 00474 POLARSSL_ERR_ASN1_UNEXPECTED_TAG ); 00475 } 00476 #endif 00477 continue; 00478 } 00479 00480 /* Forbid repeated extensions */ 00481 if( ( crt->ext_types & ext_type ) != 0 ) 00482 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS ); 00483 00484 crt->ext_types |= ext_type; 00485 00486 switch( ext_type ) 00487 { 00488 case EXT_BASIC_CONSTRAINTS: 00489 /* Parse basic constraints */ 00490 if( ( ret = x509_get_basic_constraints( p, end_ext_octet, 00491 &crt->ca_istrue, &crt->max_pathlen ) ) != 0 ) 00492 return( ret ); 00493 break; 00494 00495 case EXT_KEY_USAGE: 00496 /* Parse key usage */ 00497 if( ( ret = x509_get_key_usage( p, end_ext_octet, 00498 &crt->key_usage ) ) != 0 ) 00499 return( ret ); 00500 break; 00501 00502 case EXT_EXTENDED_KEY_USAGE: 00503 /* Parse extended key usage */ 00504 if( ( ret = x509_get_ext_key_usage( p, end_ext_octet, 00505 &crt->ext_key_usage ) ) != 0 ) 00506 return( ret ); 00507 break; 00508 00509 case EXT_SUBJECT_ALT_NAME: 00510 /* Parse subject alt name */ 00511 if( ( ret = x509_get_subject_alt_name( p, end_ext_octet, 00512 &crt->subject_alt_names ) ) != 0 ) 00513 return( ret ); 00514 break; 00515 00516 case EXT_NS_CERT_TYPE: 00517 /* Parse netscape certificate type */ 00518 if( ( ret = x509_get_ns_cert_type( p, end_ext_octet, 00519 &crt->ns_cert_type ) ) != 0 ) 00520 return( ret ); 00521 break; 00522 00523 default: 00524 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE ); 00525 } 00526 } 00527 00528 if( *p != end ) 00529 return( POLARSSL_ERR_X509_INVALID_EXTENSIONS + 00530 POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); 00531 00532 return( 0 ); 00533 } 00534 00535 /* 00536 * Parse and fill a single X.509 certificate in DER format 00537 */ 00538 static int x509_crt_parse_der_core( x509_crt *crt, const unsigned char *buf, 00539 size_t buflen ) 00540 { 00541 int ret; 00542 size_t len; 00543 unsigned char *p, *end, *crt_end; 00544 x509_buf sig_params1, sig_params2; 00545 00546 memset( &sig_params1, 0, sizeof( x509_buf ) ); 00547 memset( &sig_params2, 0, sizeof( x509_buf ) ); 00548 00549 /* 00550 * Check for valid input 00551 */ 00552 if( crt == NULL || buf == NULL ) 00553 return( POLARSSL_ERR_X509_BAD_INPUT_DATA ); 00554 00555 p = polarssl_malloc( len = buflen ); 00556 00557 if( p == NULL ) 00558 return( POLARSSL_ERR_X509_MALLOC_FAILED ); 00559 00560 memcpy( p, buf, buflen ); 00561 00562 crt->raw.p = p; 00563 crt->raw.len = len; 00564 end = p + len; 00565 00566 /* 00567 * Certificate ::= SEQUENCE { 00568 * tbsCertificate TBSCertificate, 00569 * signatureAlgorithm AlgorithmIdentifier, 00570 * signatureValue BIT STRING } 00571 */ 00572 if( ( ret = asn1_get_tag( &p, end, &len, 00573 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) 00574 { 00575 x509_crt_free( crt ); 00576 return( POLARSSL_ERR_X509_INVALID_FORMAT ); 00577 } 00578 00579 if( len > (size_t) ( end - p ) ) 00580 { 00581 x509_crt_free( crt ); 00582 return( POLARSSL_ERR_X509_INVALID_FORMAT + 00583 POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); 00584 } 00585 crt_end = p + len; 00586 00587 /* 00588 * TBSCertificate ::= SEQUENCE { 00589 */ 00590 crt->tbs.p = p; 00591 00592 if( ( ret = asn1_get_tag( &p, end, &len, 00593 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) 00594 { 00595 x509_crt_free( crt ); 00596 return( POLARSSL_ERR_X509_INVALID_FORMAT + ret ); 00597 } 00598 00599 end = p + len; 00600 crt->tbs.len = end - crt->tbs.p; 00601 00602 /* 00603 * Version ::= INTEGER { v1(0), v2(1), v3(2) } 00604 * 00605 * CertificateSerialNumber ::= INTEGER 00606 * 00607 * signature AlgorithmIdentifier 00608 */ 00609 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 || 00610 ( ret = x509_get_serial( &p, end, &crt->serial ) ) != 0 || 00611 ( ret = x509_get_alg( &p, end, &crt->sig_oid1, 00612 &sig_params1 ) ) != 0 ) 00613 { 00614 x509_crt_free( crt ); 00615 return( ret ); 00616 } 00617 00618 crt->version++; 00619 00620 if( crt->version > 3 ) 00621 { 00622 x509_crt_free( crt ); 00623 return( POLARSSL_ERR_X509_UNKNOWN_VERSION ); 00624 } 00625 00626 if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &sig_params1, 00627 &crt->sig_md, &crt->sig_pk, 00628 &crt->sig_opts ) ) != 0 ) 00629 { 00630 x509_crt_free( crt ); 00631 return( ret ); 00632 } 00633 00634 /* 00635 * issuer Name 00636 */ 00637 crt->issuer_raw.p = p; 00638 00639 if( ( ret = asn1_get_tag( &p, end, &len, 00640 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) 00641 { 00642 x509_crt_free( crt ); 00643 return( POLARSSL_ERR_X509_INVALID_FORMAT + ret ); 00644 } 00645 00646 if( ( ret = x509_get_name( &p, p + len, &crt->issuer ) ) != 0 ) 00647 { 00648 x509_crt_free( crt ); 00649 return( ret ); 00650 } 00651 00652 crt->issuer_raw.len = p - crt->issuer_raw.p; 00653 00654 /* 00655 * Validity ::= SEQUENCE { 00656 * notBefore Time, 00657 * notAfter Time } 00658 * 00659 */ 00660 if( ( ret = x509_get_dates( &p, end, &crt->valid_from, 00661 &crt->valid_to ) ) != 0 ) 00662 { 00663 x509_crt_free( crt ); 00664 return( ret ); 00665 } 00666 00667 /* 00668 * subject Name 00669 */ 00670 crt->subject_raw.p = p; 00671 00672 if( ( ret = asn1_get_tag( &p, end, &len, 00673 ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) 00674 { 00675 x509_crt_free( crt ); 00676 return( POLARSSL_ERR_X509_INVALID_FORMAT + ret ); 00677 } 00678 00679 if( len && ( ret = x509_get_name( &p, p + len, &crt->subject ) ) != 0 ) 00680 { 00681 x509_crt_free( crt ); 00682 return( ret ); 00683 } 00684 00685 crt->subject_raw.len = p - crt->subject_raw.p; 00686 00687 /* 00688 * SubjectPublicKeyInfo 00689 */ 00690 if( ( ret = pk_parse_subpubkey( &p, end, &crt->pk ) ) != 0 ) 00691 { 00692 x509_crt_free( crt ); 00693 return( ret ); 00694 } 00695 00696 /* 00697 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, 00698 * -- If present, version shall be v2 or v3 00699 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, 00700 * -- If present, version shall be v2 or v3 00701 * extensions [3] EXPLICIT Extensions OPTIONAL 00702 * -- If present, version shall be v3 00703 */ 00704 if( crt->version == 2 || crt->version == 3 ) 00705 { 00706 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 ); 00707 if( ret != 0 ) 00708 { 00709 x509_crt_free( crt ); 00710 return( ret ); 00711 } 00712 } 00713 00714 if( crt->version == 2 || crt->version == 3 ) 00715 { 00716 ret = x509_get_uid( &p, end, &crt->subject_id, 2 ); 00717 if( ret != 0 ) 00718 { 00719 x509_crt_free( crt ); 00720 return( ret ); 00721 } 00722 } 00723 00724 #if !defined(POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3) 00725 if( crt->version == 3 ) 00726 { 00727 #endif 00728 ret = x509_get_crt_ext( &p, end, crt ); 00729 if( ret != 0 ) 00730 { 00731 x509_crt_free( crt ); 00732 return( ret ); 00733 } 00734 #if !defined(POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3) 00735 } 00736 #endif 00737 00738 if( p != end ) 00739 { 00740 x509_crt_free( crt ); 00741 return( POLARSSL_ERR_X509_INVALID_FORMAT + 00742 POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); 00743 } 00744 00745 end = crt_end; 00746 00747 /* 00748 * } 00749 * -- end of TBSCertificate 00750 * 00751 * signatureAlgorithm AlgorithmIdentifier, 00752 * signatureValue BIT STRING 00753 */ 00754 if( ( ret = x509_get_alg( &p, end, &crt->sig_oid2, &sig_params2 ) ) != 0 ) 00755 { 00756 x509_crt_free( crt ); 00757 return( ret ); 00758 } 00759 00760 if( crt->sig_oid1.len != crt->sig_oid2.len || 00761 memcmp( crt->sig_oid1.p, crt->sig_oid2.p, crt->sig_oid1.len ) != 0 || 00762 sig_params1.len != sig_params2.len || 00763 ( sig_params1.len != 0 && 00764 memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) ) 00765 { 00766 x509_crt_free( crt ); 00767 return( POLARSSL_ERR_X509_SIG_MISMATCH ); 00768 } 00769 00770 if( ( ret = x509_get_sig( &p, end, &crt->sig ) ) != 0 ) 00771 { 00772 x509_crt_free( crt ); 00773 return( ret ); 00774 } 00775 00776 if( p != end ) 00777 { 00778 x509_crt_free( crt ); 00779 return( POLARSSL_ERR_X509_INVALID_FORMAT + 00780 POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); 00781 } 00782 00783 return( 0 ); 00784 } 00785 00786 /* 00787 * Parse one X.509 certificate in DER format from a buffer and add them to a 00788 * chained list 00789 */ 00790 int x509_crt_parse_der( x509_crt *chain, const unsigned char *buf, 00791 size_t buflen ) 00792 { 00793 int ret; 00794 x509_crt *crt = chain, *prev = NULL; 00795 00796 /* 00797 * Check for valid input 00798 */ 00799 if( crt == NULL || buf == NULL ) 00800 return( POLARSSL_ERR_X509_BAD_INPUT_DATA ); 00801 00802 while( crt->version != 0 && crt->next != NULL ) 00803 { 00804 prev = crt; 00805 crt = crt->next; 00806 } 00807 00808 /* 00809 * Add new certificate on the end of the chain if needed. 00810 */ 00811 if( crt->version != 0 && crt->next == NULL ) 00812 { 00813 crt->next = polarssl_malloc( sizeof( x509_crt ) ); 00814 00815 if( crt->next == NULL ) 00816 return( POLARSSL_ERR_X509_MALLOC_FAILED ); 00817 00818 prev = crt; 00819 x509_crt_init( crt->next ); 00820 crt = crt->next; 00821 } 00822 00823 if( ( ret = x509_crt_parse_der_core( crt, buf, buflen ) ) != 0 ) 00824 { 00825 if( prev ) 00826 prev->next = NULL; 00827 00828 if( crt != chain ) 00829 polarssl_free( crt ); 00830 00831 return( ret ); 00832 } 00833 00834 return( 0 ); 00835 } 00836 00837 /* 00838 * Parse one or more PEM certificates from a buffer and add them to the chained 00839 * list 00840 */ 00841 int x509_crt_parse( x509_crt *chain, const unsigned char *buf, size_t buflen ) 00842 { 00843 int success = 0, first_error = 0, total_failed = 0; 00844 int buf_format = X509_FORMAT_DER; 00845 00846 /* 00847 * Check for valid input 00848 */ 00849 if( chain == NULL || buf == NULL ) 00850 return( POLARSSL_ERR_X509_BAD_INPUT_DATA ); 00851 00852 /* 00853 * Determine buffer content. Buffer contains either one DER certificate or 00854 * one or more PEM certificates. 00855 */ 00856 #if defined(POLARSSL_PEM_PARSE_C) 00857 if( strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL ) 00858 buf_format = X509_FORMAT_PEM; 00859 #endif 00860 00861 if( buf_format == X509_FORMAT_DER ) 00862 return x509_crt_parse_der( chain, buf, buflen ); 00863 00864 #if defined(POLARSSL_PEM_PARSE_C) 00865 if( buf_format == X509_FORMAT_PEM ) 00866 { 00867 int ret; 00868 pem_context pem; 00869 00870 while( buflen > 0 ) 00871 { 00872 size_t use_len; 00873 pem_init( &pem ); 00874 00875 ret = pem_read_buffer( &pem, 00876 "-----BEGIN CERTIFICATE-----", 00877 "-----END CERTIFICATE-----", 00878 buf, NULL, 0, &use_len ); 00879 00880 if( ret == 0 ) 00881 { 00882 /* 00883 * Was PEM encoded 00884 */ 00885 buflen -= use_len; 00886 buf += use_len; 00887 } 00888 else if( ret == POLARSSL_ERR_PEM_BAD_INPUT_DATA ) 00889 { 00890 return( ret ); 00891 } 00892 else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) 00893 { 00894 pem_free( &pem ); 00895 00896 /* 00897 * PEM header and footer were found 00898 */ 00899 buflen -= use_len; 00900 buf += use_len; 00901 00902 if( first_error == 0 ) 00903 first_error = ret; 00904 00905 total_failed++; 00906 continue; 00907 } 00908 else 00909 break; 00910 00911 ret = x509_crt_parse_der( chain, pem.buf , pem.buflen ); 00912 00913 pem_free( &pem ); 00914 00915 if( ret != 0 ) 00916 { 00917 /* 00918 * Quit parsing on a memory error 00919 */ 00920 if( ret == POLARSSL_ERR_X509_MALLOC_FAILED ) 00921 return( ret ); 00922 00923 if( first_error == 0 ) 00924 first_error = ret; 00925 00926 total_failed++; 00927 continue; 00928 } 00929 00930 success = 1; 00931 } 00932 } 00933 #endif /* POLARSSL_PEM_PARSE_C */ 00934 00935 if( success ) 00936 return( total_failed ); 00937 else if( first_error ) 00938 return( first_error ); 00939 else 00940 return( POLARSSL_ERR_X509_CERT_UNKNOWN_FORMAT ); 00941 } 00942 00943 #if defined(POLARSSL_FS_IO) 00944 /* 00945 * Load one or more certificates and add them to the chained list 00946 */ 00947 int x509_crt_parse_file( x509_crt *chain, const char *path ) 00948 { 00949 int ret; 00950 size_t n; 00951 unsigned char *buf; 00952 00953 if( ( ret = pk_load_file( path, &buf, &n ) ) != 0 ) 00954 return( ret ); 00955 00956 ret = x509_crt_parse( chain, buf, n ); 00957 00958 polarssl_zeroize( buf, n + 1 ); 00959 polarssl_free( buf ); 00960 00961 return( ret ); 00962 } 00963 00964 #if defined(POLARSSL_THREADING_PTHREAD) 00965 static threading_mutex_t readdir_mutex = PTHREAD_MUTEX_INITIALIZER; 00966 #endif 00967 00968 int x509_crt_parse_path( x509_crt *chain, const char *path ) 00969 { 00970 int ret = 0; 00971 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) 00972 int w_ret; 00973 WCHAR szDir[MAX_PATH]; 00974 char filename[MAX_PATH]; 00975 char *p; 00976 int len = (int) strlen( path ); 00977 00978 WIN32_FIND_DATAW file_data; 00979 HANDLE hFind; 00980 00981 if( len > MAX_PATH - 3 ) 00982 return( POLARSSL_ERR_X509_BAD_INPUT_DATA ); 00983 00984 memset( szDir, 0, sizeof(szDir) ); 00985 memset( filename, 0, MAX_PATH ); 00986 memcpy( filename, path, len ); 00987 filename[len++] = '\\'; 00988 p = filename + len; 00989 filename[len++] = '*'; 00990 00991 w_ret = MultiByteToWideChar( CP_ACP, 0, filename, len, szDir, 00992 MAX_PATH - 3 ); 00993 if( w_ret == 0 ) 00994 return( POLARSSL_ERR_X509_BAD_INPUT_DATA ); 00995 00996 hFind = FindFirstFileW( szDir, &file_data ); 00997 if( hFind == INVALID_HANDLE_VALUE ) 00998 return( POLARSSL_ERR_X509_FILE_IO_ERROR ); 00999 01000 len = MAX_PATH - len; 01001 do 01002 { 01003 memset( p, 0, len ); 01004 01005 if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) 01006 continue; 01007 01008 w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName, 01009 lstrlenW( file_data.cFileName ), 01010 p, len - 1, 01011 NULL, NULL ); 01012 if( w_ret == 0 ) 01013 return( POLARSSL_ERR_X509_FILE_IO_ERROR ); 01014 01015 w_ret = x509_crt_parse_file( chain, filename ); 01016 if( w_ret < 0 ) 01017 ret++; 01018 else 01019 ret += w_ret; 01020 } 01021 while( FindNextFileW( hFind, &file_data ) != 0 ); 01022 01023 if( GetLastError() != ERROR_NO_MORE_FILES ) 01024 ret = POLARSSL_ERR_X509_FILE_IO_ERROR; 01025 01026 FindClose( hFind ); 01027 #else /* _WIN32 */ 01028 int t_ret; 01029 struct stat sb; 01030 struct dirent *entry; 01031 char entry_name[255]; 01032 DIR *dir = opendir( path ); 01033 01034 if( dir == NULL ) 01035 return( POLARSSL_ERR_X509_FILE_IO_ERROR ); 01036 01037 #if defined(POLARSSL_THREADING_PTHREAD) 01038 if( ( ret = polarssl_mutex_lock( &readdir_mutex ) ) != 0 ) 01039 return( ret ); 01040 #endif 01041 01042 while( ( entry = readdir( dir ) ) != NULL ) 01043 { 01044 polarssl_snprintf( entry_name, sizeof entry_name, "%s/%s", path, entry->d_name ); 01045 01046 if( stat( entry_name, &sb ) == -1 ) 01047 { 01048 closedir( dir ); 01049 ret = POLARSSL_ERR_X509_FILE_IO_ERROR; 01050 goto cleanup; 01051 } 01052 01053 if( !S_ISREG( sb.st_mode ) ) 01054 continue; 01055 01056 // Ignore parse errors 01057 // 01058 t_ret = x509_crt_parse_file( chain, entry_name ); 01059 if( t_ret < 0 ) 01060 ret++; 01061 else 01062 ret += t_ret; 01063 } 01064 closedir( dir ); 01065 01066 cleanup: 01067 #if defined(POLARSSL_THREADING_PTHREAD) 01068 if( polarssl_mutex_unlock( &readdir_mutex ) != 0 ) 01069 ret = POLARSSL_ERR_THREADING_MUTEX_ERROR; 01070 #endif 01071 01072 #endif /* _WIN32 */ 01073 01074 return( ret ); 01075 } 01076 #endif /* POLARSSL_FS_IO */ 01077 01078 #if defined(_MSC_VER) && !defined snprintf && !defined(EFIX64) && \ 01079 !defined(EFI32) 01080 #include <stdarg.h> 01081 01082 #if !defined vsnprintf 01083 #define vsnprintf _vsnprintf 01084 #endif // vsnprintf 01085 01086 /* 01087 * Windows _snprintf and _vsnprintf are not compatible to linux versions. 01088 * Result value is not size of buffer needed, but -1 if no fit is possible. 01089 * 01090 * This fuction tries to 'fix' this by at least suggesting enlarging the 01091 * size by 20. 01092 */ 01093 static int compat_snprintf( char *str, size_t size, const char *format, ... ) 01094 { 01095 va_list ap; 01096 int res = -1; 01097 01098 va_start( ap, format ); 01099 01100 res = vsnprintf( str, size, format, ap ); 01101 01102 va_end( ap ); 01103 01104 // No quick fix possible 01105 if( res < 0 ) 01106 return( (int) size + 20 ); 01107 01108 return( res ); 01109 } 01110 01111 #define snprintf compat_snprintf 01112 #endif /* _MSC_VER && !snprintf && !EFIX64 && !EFI32 */ 01113 01114 #define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2 01115 01116 #define SAFE_SNPRINTF() \ 01117 { \ 01118 if( ret == -1 ) \ 01119 return( -1 ); \ 01120 \ 01121 if( (unsigned int) ret > n ) { \ 01122 p[n - 1] = '\0'; \ 01123 return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL ); \ 01124 } \ 01125 \ 01126 n -= (unsigned int) ret; \ 01127 p += (unsigned int) ret; \ 01128 } 01129 01130 static int x509_info_subject_alt_name( char **buf, size_t *size, 01131 const x509_sequence *subject_alt_name ) 01132 { 01133 size_t i; 01134 size_t n = *size; 01135 char *p = *buf; 01136 const x509_sequence *cur = subject_alt_name; 01137 const char *sep = ""; 01138 size_t sep_len = 0; 01139 01140 while( cur != NULL ) 01141 { 01142 if( cur->buf.len + sep_len >= n ) 01143 { 01144 *p = '\0'; 01145 return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL ); 01146 } 01147 01148 n -= cur->buf.len + sep_len; 01149 for( i = 0; i < sep_len; i++ ) 01150 *p++ = sep[i]; 01151 for( i = 0; i < cur->buf.len; i++ ) 01152 *p++ = cur->buf.p[i]; 01153 01154 sep = ", "; 01155 sep_len = 2; 01156 01157 cur = cur->next; 01158 } 01159 01160 *p = '\0'; 01161 01162 *size = n; 01163 *buf = p; 01164 01165 return( 0 ); 01166 } 01167 01168 #define PRINT_ITEM(i) \ 01169 { \ 01170 ret = polarssl_snprintf( p, n, "%s" i, sep ); \ 01171 SAFE_SNPRINTF(); \ 01172 sep = ", "; \ 01173 } 01174 01175 #define CERT_TYPE(type,name) \ 01176 if( ns_cert_type & type ) \ 01177 PRINT_ITEM( name ); 01178 01179 static int x509_info_cert_type( char **buf, size_t *size, 01180 unsigned char ns_cert_type ) 01181 { 01182 int ret; 01183 size_t n = *size; 01184 char *p = *buf; 01185 const char *sep = ""; 01186 01187 CERT_TYPE( NS_CERT_TYPE_SSL_CLIENT, "SSL Client" ); 01188 CERT_TYPE( NS_CERT_TYPE_SSL_SERVER, "SSL Server" ); 01189 CERT_TYPE( NS_CERT_TYPE_EMAIL, "Email" ); 01190 CERT_TYPE( NS_CERT_TYPE_OBJECT_SIGNING, "Object Signing" ); 01191 CERT_TYPE( NS_CERT_TYPE_RESERVED, "Reserved" ); 01192 CERT_TYPE( NS_CERT_TYPE_SSL_CA, "SSL CA" ); 01193 CERT_TYPE( NS_CERT_TYPE_EMAIL_CA, "Email CA" ); 01194 CERT_TYPE( NS_CERT_TYPE_OBJECT_SIGNING_CA, "Object Signing CA" ); 01195 01196 *size = n; 01197 *buf = p; 01198 01199 return( 0 ); 01200 } 01201 01202 #define KEY_USAGE(code,name) \ 01203 if( key_usage & code ) \ 01204 PRINT_ITEM( name ); 01205 01206 static int x509_info_key_usage( char **buf, size_t *size, 01207 unsigned char key_usage ) 01208 { 01209 int ret; 01210 size_t n = *size; 01211 char *p = *buf; 01212 const char *sep = ""; 01213 01214 KEY_USAGE( KU_DIGITAL_SIGNATURE, "Digital Signature" ); 01215 KEY_USAGE( KU_NON_REPUDIATION, "Non Repudiation" ); 01216 KEY_USAGE( KU_KEY_ENCIPHERMENT, "Key Encipherment" ); 01217 KEY_USAGE( KU_DATA_ENCIPHERMENT, "Data Encipherment" ); 01218 KEY_USAGE( KU_KEY_AGREEMENT, "Key Agreement" ); 01219 KEY_USAGE( KU_KEY_CERT_SIGN, "Key Cert Sign" ); 01220 KEY_USAGE( KU_CRL_SIGN, "CRL Sign" ); 01221 01222 *size = n; 01223 *buf = p; 01224 01225 return( 0 ); 01226 } 01227 01228 static int x509_info_ext_key_usage( char **buf, size_t *size, 01229 const x509_sequence *extended_key_usage ) 01230 { 01231 int ret; 01232 const char *desc; 01233 size_t n = *size; 01234 char *p = *buf; 01235 const x509_sequence *cur = extended_key_usage; 01236 const char *sep = ""; 01237 01238 while( cur != NULL ) 01239 { 01240 if( oid_get_extended_key_usage( &cur->buf, &desc ) != 0 ) 01241 desc = "???"; 01242 01243 ret = polarssl_snprintf( p, n, "%s%s", sep, desc ); 01244 SAFE_SNPRINTF(); 01245 01246 sep = ", "; 01247 01248 cur = cur->next; 01249 } 01250 01251 *size = n; 01252 *buf = p; 01253 01254 return( 0 ); 01255 } 01256 01257 /* 01258 * Return an informational string about the certificate. 01259 */ 01260 #define BEFORE_COLON 18 01261 #define BC "18" 01262 int x509_crt_info( char *buf, size_t size, const char *prefix, 01263 const x509_crt *crt ) 01264 { 01265 int ret; 01266 size_t n; 01267 char *p; 01268 char key_size_str[BEFORE_COLON]; 01269 01270 p = buf; 01271 n = size; 01272 01273 ret = polarssl_snprintf( p, n, "%scert. version : %d\n", 01274 prefix, crt->version ); 01275 SAFE_SNPRINTF(); 01276 ret = polarssl_snprintf( p, n, "%sserial number : ", 01277 prefix ); 01278 SAFE_SNPRINTF(); 01279 01280 ret = x509_serial_gets( p, n, &crt->serial ); 01281 SAFE_SNPRINTF(); 01282 01283 ret = polarssl_snprintf( p, n, "\n%sissuer name : ", prefix ); 01284 SAFE_SNPRINTF(); 01285 ret = x509_dn_gets( p, n, &crt->issuer ); 01286 SAFE_SNPRINTF(); 01287 01288 ret = polarssl_snprintf( p, n, "\n%ssubject name : ", prefix ); 01289 SAFE_SNPRINTF(); 01290 ret = x509_dn_gets( p, n, &crt->subject ); 01291 SAFE_SNPRINTF(); 01292 01293 ret = polarssl_snprintf( p, n, "\n%sissued on : " \ 01294 "%04d-%02d-%02d %02d:%02d:%02d", prefix, 01295 crt->valid_from.year, crt->valid_from.mon, 01296 crt->valid_from.day, crt->valid_from.hour, 01297 crt->valid_from.min, crt->valid_from.sec ); 01298 SAFE_SNPRINTF(); 01299 01300 ret = polarssl_snprintf( p, n, "\n%sexpires on : " \ 01301 "%04d-%02d-%02d %02d:%02d:%02d", prefix, 01302 crt->valid_to.year, crt->valid_to.mon, 01303 crt->valid_to.day, crt->valid_to.hour, 01304 crt->valid_to.min, crt->valid_to.sec ); 01305 SAFE_SNPRINTF(); 01306 01307 ret = polarssl_snprintf( p, n, "\n%ssigned using : ", prefix ); 01308 SAFE_SNPRINTF(); 01309 01310 ret = x509_sig_alg_gets( p, n, &crt->sig_oid1, crt->sig_pk, 01311 crt->sig_md, crt->sig_opts ); 01312 SAFE_SNPRINTF(); 01313 01314 /* Key size */ 01315 if( ( ret = x509_key_size_helper( key_size_str, BEFORE_COLON, 01316 pk_get_name( &crt->pk ) ) ) != 0 ) 01317 { 01318 return( ret ); 01319 } 01320 01321 ret = polarssl_snprintf( p, n, "\n%s%-" BC "s: %d bits", prefix, key_size_str, 01322 (int) pk_get_size( &crt->pk ) ); 01323 SAFE_SNPRINTF(); 01324 01325 /* 01326 * Optional extensions 01327 */ 01328 01329 if( crt->ext_types & EXT_BASIC_CONSTRAINTS ) 01330 { 01331 ret = polarssl_snprintf( p, n, "\n%sbasic constraints : CA=%s", prefix, 01332 crt->ca_istrue ? "true" : "false" ); 01333 SAFE_SNPRINTF(); 01334 01335 if( crt->max_pathlen > 0 ) 01336 { 01337 ret = polarssl_snprintf( p, n, ", max_pathlen=%d", crt->max_pathlen - 1 ); 01338 SAFE_SNPRINTF(); 01339 } 01340 } 01341 01342 if( crt->ext_types & EXT_SUBJECT_ALT_NAME ) 01343 { 01344 ret = polarssl_snprintf( p, n, "\n%ssubject alt name : ", prefix ); 01345 SAFE_SNPRINTF(); 01346 01347 if( ( ret = x509_info_subject_alt_name( &p, &n, 01348 &crt->subject_alt_names ) ) != 0 ) 01349 return( ret ); 01350 } 01351 01352 if( crt->ext_types & EXT_NS_CERT_TYPE ) 01353 { 01354 ret = polarssl_snprintf( p, n, "\n%scert. type : ", prefix ); 01355 SAFE_SNPRINTF(); 01356 01357 if( ( ret = x509_info_cert_type( &p, &n, crt->ns_cert_type ) ) != 0 ) 01358 return( ret ); 01359 } 01360 01361 if( crt->ext_types & EXT_KEY_USAGE ) 01362 { 01363 ret = polarssl_snprintf( p, n, "\n%skey usage : ", prefix ); 01364 SAFE_SNPRINTF(); 01365 01366 if( ( ret = x509_info_key_usage( &p, &n, crt->key_usage ) ) != 0 ) 01367 return( ret ); 01368 } 01369 01370 if( crt->ext_types & EXT_EXTENDED_KEY_USAGE ) 01371 { 01372 ret = polarssl_snprintf( p, n, "\n%sext key usage : ", prefix ); 01373 SAFE_SNPRINTF(); 01374 01375 if( ( ret = x509_info_ext_key_usage( &p, &n, 01376 &crt->ext_key_usage ) ) != 0 ) 01377 return( ret ); 01378 } 01379 01380 ret = polarssl_snprintf( p, n, "\n" ); 01381 SAFE_SNPRINTF(); 01382 01383 return( (int) ( size - n ) ); 01384 } 01385 01386 struct x509_crt_verify_string { 01387 int code; 01388 const char *string; 01389 }; 01390 01391 static const struct x509_crt_verify_string x509_crt_verify_strings[] = { 01392 { BADCERT_EXPIRED, "The certificate validity has expired" }, 01393 { BADCERT_REVOKED, "The certificate has been revoked (is on a CRL)" }, 01394 { BADCERT_CN_MISMATCH, "The certificate Common Name (CN) does not match with the expected CN" }, 01395 { BADCERT_NOT_TRUSTED, "The certificate is not correctly signed by the trusted CA" }, 01396 { BADCRL_NOT_TRUSTED, "The CRL is not correctly signed by the trusted CA" }, 01397 { BADCRL_EXPIRED, "The CRL is expired" }, 01398 { BADCERT_MISSING, "Certificate was missing" }, 01399 { BADCERT_SKIP_VERIFY, "Certificate verification was skipped" }, 01400 { BADCERT_OTHER, "Other reason (can be used by verify callback)" }, 01401 { BADCERT_FUTURE, "The certificate validity starts in the future" }, 01402 { BADCRL_FUTURE, "The CRL is from the future" }, 01403 { BADCERT_KEY_USAGE, "Usage does not match the keyUsage extension" }, 01404 { BADCERT_EXT_KEY_USAGE, "Usage does not match the extendedKeyUsage extension" }, 01405 { BADCERT_NS_CERT_TYPE, "Usage does not match the nsCertType extension" }, 01406 { 0, NULL } 01407 }; 01408 01409 int x509_crt_verify_info( char *buf, size_t size, const char *prefix, 01410 int flags ) 01411 { 01412 int ret; 01413 const struct x509_crt_verify_string *cur; 01414 char *p = buf; 01415 size_t n = size; 01416 01417 for( cur = x509_crt_verify_strings; cur->string != NULL ; cur++ ) 01418 { 01419 if( ( flags & cur->code ) == 0 ) 01420 continue; 01421 01422 ret = polarssl_snprintf( p, n, "%s%s\n", prefix, cur->string ); 01423 SAFE_SNPRINTF(); 01424 flags ^= cur->code; 01425 } 01426 01427 if( flags != 0 ) 01428 { 01429 ret = polarssl_snprintf( p, n, "%sUnknown reason " 01430 "(this should not happen)\n", prefix ); 01431 SAFE_SNPRINTF(); 01432 } 01433 01434 return( (int) ( size - n ) ); 01435 } 01436 01437 #if defined(POLARSSL_X509_CHECK_KEY_USAGE) 01438 int x509_crt_check_key_usage( const x509_crt *crt, int usage ) 01439 { 01440 if( ( crt->ext_types & EXT_KEY_USAGE ) != 0 && 01441 ( crt->key_usage & usage ) != usage ) 01442 return( POLARSSL_ERR_X509_BAD_INPUT_DATA ); 01443 01444 return( 0 ); 01445 } 01446 #endif 01447 01448 #if defined(POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE) 01449 int x509_crt_check_extended_key_usage( const x509_crt *crt, 01450 const char *usage_oid, 01451 size_t usage_len ) 01452 { 01453 const x509_sequence *cur; 01454 01455 /* Extension is not mandatory, absent means no restriction */ 01456 if( ( crt->ext_types & EXT_EXTENDED_KEY_USAGE ) == 0 ) 01457 return( 0 ); 01458 01459 /* 01460 * Look for the requested usage (or wildcard ANY) in our list 01461 */ 01462 for( cur = &crt->ext_key_usage; cur != NULL; cur = cur->next ) 01463 { 01464 const x509_buf *cur_oid = &cur->buf; 01465 01466 if( cur_oid->len == usage_len && 01467 memcmp( cur_oid->p, usage_oid, usage_len ) == 0 ) 01468 { 01469 return( 0 ); 01470 } 01471 01472 if( OID_CMP( OID_ANY_EXTENDED_KEY_USAGE, cur_oid ) ) 01473 return( 0 ); 01474 } 01475 01476 return( POLARSSL_ERR_X509_BAD_INPUT_DATA ); 01477 } 01478 #endif /* POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE */ 01479 01480 #if defined(POLARSSL_X509_CRL_PARSE_C) 01481 /* 01482 * Return 1 if the certificate is revoked, or 0 otherwise. 01483 */ 01484 int x509_crt_revoked( const x509_crt *crt, const x509_crl *crl ) 01485 { 01486 const x509_crl_entry *cur = &crl->entry; 01487 01488 while( cur != NULL && cur->serial.len != 0 ) 01489 { 01490 if( crt->serial.len == cur->serial.len && 01491 memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 ) 01492 { 01493 if( x509_time_expired( &cur->revocation_date ) ) 01494 return( 1 ); 01495 } 01496 01497 cur = cur->next; 01498 } 01499 01500 return( 0 ); 01501 } 01502 01503 /* 01504 * Check that the given certificate is valid according to the CRL. 01505 */ 01506 static int x509_crt_verifycrl( x509_crt *crt, x509_crt *ca, 01507 x509_crl *crl_list) 01508 { 01509 int flags = 0; 01510 unsigned char hash[POLARSSL_MD_MAX_SIZE]; 01511 const md_info_t *md_info; 01512 01513 if( ca == NULL ) 01514 return( flags ); 01515 01516 /* 01517 * TODO: What happens if no CRL is present? 01518 * Suggestion: Revocation state should be unknown if no CRL is present. 01519 * For backwards compatibility this is not yet implemented. 01520 */ 01521 01522 while( crl_list != NULL ) 01523 { 01524 if( crl_list->version == 0 || 01525 crl_list->issuer_raw.len != ca->subject_raw.len || 01526 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p, 01527 crl_list->issuer_raw.len ) != 0 ) 01528 { 01529 crl_list = crl_list->next; 01530 continue; 01531 } 01532 01533 /* 01534 * Check if the CA is configured to sign CRLs 01535 */ 01536 #if defined(POLARSSL_X509_CHECK_KEY_USAGE) 01537 if( x509_crt_check_key_usage( ca, KU_CRL_SIGN ) != 0 ) 01538 { 01539 flags |= BADCRL_NOT_TRUSTED; 01540 break; 01541 } 01542 #endif 01543 01544 /* 01545 * Check if CRL is correctly signed by the trusted CA 01546 */ 01547 md_info = md_info_from_type( crl_list->sig_md ); 01548 if( md_info == NULL ) 01549 { 01550 /* 01551 * Cannot check 'unknown' hash 01552 */ 01553 flags |= BADCRL_NOT_TRUSTED; 01554 break; 01555 } 01556 01557 md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash ); 01558 01559 if( pk_verify_ext( crl_list->sig_pk, crl_list->sig_opts, &ca->pk, 01560 crl_list->sig_md, hash, md_info->size, 01561 crl_list->sig.p, crl_list->sig.len ) != 0 ) 01562 { 01563 flags |= BADCRL_NOT_TRUSTED; 01564 break; 01565 } 01566 01567 /* 01568 * Check for validity of CRL (Do not drop out) 01569 */ 01570 if( x509_time_expired( &crl_list->next_update ) ) 01571 flags |= BADCRL_EXPIRED; 01572 01573 if( x509_time_future( &crl_list->this_update ) ) 01574 flags |= BADCRL_FUTURE; 01575 01576 /* 01577 * Check if certificate is revoked 01578 */ 01579 if( x509_crt_revoked( crt, crl_list ) ) 01580 { 01581 flags |= BADCERT_REVOKED; 01582 break; 01583 } 01584 01585 crl_list = crl_list->next; 01586 } 01587 return( flags ); 01588 } 01589 #endif /* POLARSSL_X509_CRL_PARSE_C */ 01590 01591 /* 01592 * Like memcmp, but case-insensitive and always returns -1 if different 01593 */ 01594 static int x509_memcasecmp( const void *s1, const void *s2, size_t len ) 01595 { 01596 size_t i; 01597 unsigned char diff; 01598 const unsigned char *n1 = s1, *n2 = s2; 01599 01600 for( i = 0; i < len; i++ ) 01601 { 01602 diff = n1[i] ^ n2[i]; 01603 01604 if( diff == 0 ) 01605 continue; 01606 01607 if( diff == 32 && 01608 ( ( n1[i] >= 'a' && n1[i] <= 'z' ) || 01609 ( n1[i] >= 'A' && n1[i] <= 'Z' ) ) ) 01610 { 01611 continue; 01612 } 01613 01614 return( -1 ); 01615 } 01616 01617 return( 0 ); 01618 } 01619 01620 /* 01621 * Return 1 if match, 0 if not 01622 * TODO: inverted return value! 01623 */ 01624 static int x509_wildcard_verify( const char *cn, x509_buf *name ) 01625 { 01626 size_t i; 01627 size_t cn_idx = 0, cn_len = strlen( cn ); 01628 01629 if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' ) 01630 return( 0 ); 01631 01632 for( i = 0; i < cn_len; ++i ) 01633 { 01634 if( cn[i] == '.' ) 01635 { 01636 cn_idx = i; 01637 break; 01638 } 01639 } 01640 01641 if( cn_idx == 0 ) 01642 return( 0 ); 01643 01644 if( cn_len - cn_idx == name->len - 1 && 01645 x509_memcasecmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 ) 01646 { 01647 return( 1 ); 01648 } 01649 01650 return( 0 ); 01651 } 01652 01653 /* 01654 * Compare two X.509 strings, case-insensitive, and allowing for some encoding 01655 * variations (but not all). 01656 * 01657 * Return 0 if equal, -1 otherwise. 01658 */ 01659 static int x509_string_cmp( const x509_buf *a, const x509_buf *b ) 01660 { 01661 if( a->tag == b->tag && 01662 a->len == b->len && 01663 memcmp( a->p, b->p, b->len ) == 0 ) 01664 { 01665 return( 0 ); 01666 } 01667 01668 if( ( a->tag == ASN1_UTF8_STRING || a->tag == ASN1_PRINTABLE_STRING ) && 01669 ( b->tag == ASN1_UTF8_STRING || b->tag == ASN1_PRINTABLE_STRING ) && 01670 a->len == b->len && 01671 x509_memcasecmp( a->p, b->p, b->len ) == 0 ) 01672 { 01673 return( 0 ); 01674 } 01675 01676 return( -1 ); 01677 } 01678 01679 /* 01680 * Compare two X.509 Names (aka rdnSequence). 01681 * 01682 * See RFC 5280 section 7.1, though we don't implement the whole algorithm: 01683 * we sometimes return unequal when the full algorithm would return equal, 01684 * but never the other way. (In particular, we don't do Unicode normalisation 01685 * or space folding.) 01686 * 01687 * Return 0 if equal, -1 otherwise. 01688 */ 01689 static int x509_name_cmp( const x509_name *a, const x509_name *b ) 01690 { 01691 /* Avoid recursion, it might not be optimised by the compiler */ 01692 while( a != NULL || b != NULL ) 01693 { 01694 if( a == NULL || b == NULL ) 01695 return( -1 ); 01696 01697 /* type */ 01698 if( a->oid.tag != b->oid.tag || 01699 a->oid.len != b->oid.len || 01700 memcmp( a->oid.p, b->oid.p, b->oid.len ) != 0 ) 01701 { 01702 return( -1 ); 01703 } 01704 01705 /* value */ 01706 if( x509_string_cmp( &a->val, &b->val ) != 0 ) 01707 return( -1 ); 01708 01709 /* structure of the list of sets */ 01710 if( a->next_merged != b->next_merged ) 01711 return( -1 ); 01712 01713 a = a->next; 01714 b = b->next; 01715 } 01716 01717 /* a == NULL == b */ 01718 return( 0 ); 01719 } 01720 01721 /* 01722 * Check if 'parent' is a suitable parent (signing CA) for 'child'. 01723 * Return 0 if yes, -1 if not. 01724 * 01725 * top means parent is a locally-trusted certificate 01726 * bottom means child is the end entity cert 01727 */ 01728 static int x509_crt_check_parent( const x509_crt *child, 01729 const x509_crt *parent, 01730 int top, int bottom ) 01731 { 01732 int need_ca_bit; 01733 01734 /* Parent must be the issuer */ 01735 if( x509_name_cmp( &child->issuer, &parent->subject ) != 0 ) 01736 return( -1 ); 01737 01738 /* Parent must have the basicConstraints CA bit set as a general rule */ 01739 need_ca_bit = 1; 01740 01741 /* Exception: v1/v2 certificates that are locally trusted. */ 01742 if( top && parent->version < 3 ) 01743 need_ca_bit = 0; 01744 01745 /* Exception: self-signed end-entity certs that are locally trusted. */ 01746 if( top && bottom && 01747 child->raw.len == parent->raw.len && 01748 memcmp( child->raw.p, parent->raw.p, child->raw.len ) == 0 ) 01749 { 01750 need_ca_bit = 0; 01751 } 01752 01753 if( need_ca_bit && ! parent->ca_istrue ) 01754 return( -1 ); 01755 01756 #if defined(POLARSSL_X509_CHECK_KEY_USAGE) 01757 if( need_ca_bit && 01758 x509_crt_check_key_usage( parent, KU_KEY_CERT_SIGN ) != 0 ) 01759 { 01760 return( -1 ); 01761 } 01762 #endif 01763 01764 return( 0 ); 01765 } 01766 01767 static int x509_crt_verify_top( 01768 x509_crt *child, x509_crt *trust_ca, 01769 x509_crl *ca_crl, int path_cnt, int *flags, 01770 int (*f_vrfy)(void *, x509_crt *, int, int *), 01771 void *p_vrfy ) 01772 { 01773 int ret; 01774 int ca_flags = 0, check_path_cnt; 01775 unsigned char hash[POLARSSL_MD_MAX_SIZE]; 01776 const md_info_t *md_info; 01777 01778 if( x509_time_expired( &child->valid_to ) ) 01779 *flags |= BADCERT_EXPIRED; 01780 01781 if( x509_time_future( &child->valid_from ) ) 01782 *flags |= BADCERT_FUTURE; 01783 01784 /* 01785 * Child is the top of the chain. Check against the trust_ca list. 01786 */ 01787 *flags |= BADCERT_NOT_TRUSTED; 01788 01789 md_info = md_info_from_type( child->sig_md ); 01790 if( md_info == NULL ) 01791 { 01792 /* 01793 * Cannot check 'unknown', no need to try any CA 01794 */ 01795 trust_ca = NULL; 01796 } 01797 else 01798 md( md_info, child->tbs.p, child->tbs.len, hash ); 01799 01800 for( /* trust_ca */ ; trust_ca != NULL; trust_ca = trust_ca->next ) 01801 { 01802 if( x509_crt_check_parent( child, trust_ca, 1, path_cnt == 0 ) != 0 ) 01803 continue; 01804 01805 check_path_cnt = path_cnt + 1; 01806 01807 /* 01808 * Reduce check_path_cnt to check against if top of the chain is 01809 * the same as the trusted CA 01810 */ 01811 if( child->subject_raw.len == trust_ca->subject_raw.len && 01812 memcmp( child->subject_raw.p, trust_ca->subject_raw.p, 01813 child->issuer_raw.len ) == 0 ) 01814 { 01815 check_path_cnt--; 01816 } 01817 01818 if( trust_ca->max_pathlen > 0 && 01819 trust_ca->max_pathlen < check_path_cnt ) 01820 { 01821 continue; 01822 } 01823 01824 if( pk_verify_ext( child->sig_pk, child->sig_opts, &trust_ca->pk, 01825 child->sig_md, hash, md_info->size, 01826 child->sig.p, child->sig.len ) != 0 ) 01827 { 01828 continue; 01829 } 01830 01831 /* 01832 * Top of chain is signed by a trusted CA 01833 */ 01834 *flags &= ~BADCERT_NOT_TRUSTED; 01835 break; 01836 } 01837 01838 /* 01839 * If top of chain is not the same as the trusted CA send a verify request 01840 * to the callback for any issues with validity and CRL presence for the 01841 * trusted CA certificate. 01842 */ 01843 if( trust_ca != NULL && 01844 ( child->subject_raw.len != trust_ca->subject_raw.len || 01845 memcmp( child->subject_raw.p, trust_ca->subject_raw.p, 01846 child->issuer_raw.len ) != 0 ) ) 01847 { 01848 #if defined(POLARSSL_X509_CRL_PARSE_C) 01849 /* Check trusted CA's CRL for the chain's top crt */ 01850 *flags |= x509_crt_verifycrl( child, trust_ca, ca_crl ); 01851 #else 01852 ((void) ca_crl); 01853 #endif 01854 01855 if( x509_time_expired( &trust_ca->valid_to ) ) 01856 ca_flags |= BADCERT_EXPIRED; 01857 01858 if( x509_time_future( &trust_ca->valid_from ) ) 01859 ca_flags |= BADCERT_FUTURE; 01860 01861 if( NULL != f_vrfy ) 01862 { 01863 if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1, 01864 &ca_flags ) ) != 0 ) 01865 { 01866 return( ret ); 01867 } 01868 } 01869 } 01870 01871 /* Call callback on top cert */ 01872 if( NULL != f_vrfy ) 01873 { 01874 if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 ) 01875 return( ret ); 01876 } 01877 01878 *flags |= ca_flags; 01879 01880 return( 0 ); 01881 } 01882 01883 static int x509_crt_verify_child( 01884 x509_crt *child, x509_crt *parent, x509_crt *trust_ca, 01885 x509_crl *ca_crl, int path_cnt, int *flags, 01886 int (*f_vrfy)(void *, x509_crt *, int, int *), 01887 void *p_vrfy ) 01888 { 01889 int ret; 01890 int parent_flags = 0; 01891 unsigned char hash[POLARSSL_MD_MAX_SIZE]; 01892 x509_crt *grandparent; 01893 const md_info_t *md_info; 01894 01895 /* path_cnt is 0 for the first intermediate CA */ 01896 if( 1 + path_cnt > POLARSSL_X509_MAX_INTERMEDIATE_CA ) 01897 { 01898 *flags |= BADCERT_NOT_TRUSTED; 01899 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED ); 01900 } 01901 01902 if( x509_time_expired( &child->valid_to ) ) 01903 *flags |= BADCERT_EXPIRED; 01904 01905 if( x509_time_future( &child->valid_from ) ) 01906 *flags |= BADCERT_FUTURE; 01907 01908 md_info = md_info_from_type( child->sig_md ); 01909 if( md_info == NULL ) 01910 { 01911 /* 01912 * Cannot check 'unknown' hash 01913 */ 01914 *flags |= BADCERT_NOT_TRUSTED; 01915 } 01916 else 01917 { 01918 md( md_info, child->tbs.p, child->tbs.len, hash ); 01919 01920 if( pk_verify_ext( child->sig_pk, child->sig_opts, &parent->pk, 01921 child->sig_md, hash, md_info->size, 01922 child->sig.p, child->sig.len ) != 0 ) 01923 { 01924 *flags |= BADCERT_NOT_TRUSTED; 01925 } 01926 } 01927 01928 #if defined(POLARSSL_X509_CRL_PARSE_C) 01929 /* Check trusted CA's CRL for the given crt */ 01930 *flags |= x509_crt_verifycrl(child, parent, ca_crl); 01931 #endif 01932 01933 /* Look for a grandparent upwards the chain */ 01934 for( grandparent = parent->next; 01935 grandparent != NULL; 01936 grandparent = grandparent->next ) 01937 { 01938 if( x509_crt_check_parent( parent, grandparent, 01939 0, path_cnt == 0 ) == 0 ) 01940 break; 01941 } 01942 01943 /* Is our parent part of the chain or at the top? */ 01944 if( grandparent != NULL ) 01945 { 01946 ret = x509_crt_verify_child( parent, grandparent, trust_ca, ca_crl, 01947 path_cnt + 1, &parent_flags, f_vrfy, p_vrfy ); 01948 if( ret != 0 ) 01949 return( ret ); 01950 } 01951 else 01952 { 01953 ret = x509_crt_verify_top( parent, trust_ca, ca_crl, 01954 path_cnt + 1, &parent_flags, f_vrfy, p_vrfy ); 01955 if( ret != 0 ) 01956 return( ret ); 01957 } 01958 01959 /* child is verified to be a child of the parent, call verify callback */ 01960 if( NULL != f_vrfy ) 01961 if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 ) 01962 return( ret ); 01963 01964 *flags |= parent_flags; 01965 01966 return( 0 ); 01967 } 01968 01969 /* 01970 * Verify the certificate validity 01971 */ 01972 int x509_crt_verify( x509_crt *crt, 01973 x509_crt *trust_ca, 01974 x509_crl *ca_crl, 01975 const char *cn, int *flags, 01976 int (*f_vrfy)(void *, x509_crt *, int, int *), 01977 void *p_vrfy ) 01978 { 01979 size_t cn_len; 01980 int ret; 01981 int pathlen = 0; 01982 x509_crt *parent; 01983 x509_name *name; 01984 x509_sequence *cur = NULL; 01985 01986 *flags = 0; 01987 01988 if( cn != NULL ) 01989 { 01990 name = &crt->subject; 01991 cn_len = strlen( cn ); 01992 01993 if( crt->ext_types & EXT_SUBJECT_ALT_NAME ) 01994 { 01995 cur = &crt->subject_alt_names; 01996 01997 while( cur != NULL ) 01998 { 01999 if( cur->buf.len == cn_len && 02000 x509_memcasecmp( cn, cur->buf.p, cn_len ) == 0 ) 02001 break; 02002 02003 if( cur->buf.len > 2 && 02004 memcmp( cur->buf.p, "*.", 2 ) == 0 && 02005 x509_wildcard_verify( cn, &cur->buf ) ) 02006 break; 02007 02008 cur = cur->next; 02009 } 02010 02011 if( cur == NULL ) 02012 *flags |= BADCERT_CN_MISMATCH; 02013 } 02014 else 02015 { 02016 while( name != NULL ) 02017 { 02018 if( OID_CMP( OID_AT_CN, &name->oid ) ) 02019 { 02020 if( name->val.len == cn_len && 02021 x509_memcasecmp( name->val.p, cn, cn_len ) == 0 ) 02022 break; 02023 02024 if( name->val.len > 2 && 02025 memcmp( name->val.p, "*.", 2 ) == 0 && 02026 x509_wildcard_verify( cn, &name->val ) ) 02027 break; 02028 } 02029 02030 name = name->next; 02031 } 02032 02033 if( name == NULL ) 02034 *flags |= BADCERT_CN_MISMATCH; 02035 } 02036 } 02037 02038 /* Look for a parent upwards the chain */ 02039 for( parent = crt->next; parent != NULL; parent = parent->next ) 02040 { 02041 if( x509_crt_check_parent( crt, parent, 0, pathlen == 0 ) == 0 ) 02042 break; 02043 } 02044 02045 /* Are we part of the chain or at the top? */ 02046 if( parent != NULL ) 02047 { 02048 ret = x509_crt_verify_child( crt, parent, trust_ca, ca_crl, 02049 pathlen, flags, f_vrfy, p_vrfy ); 02050 if( ret != 0 ) 02051 return( ret ); 02052 } 02053 else 02054 { 02055 ret = x509_crt_verify_top( crt, trust_ca, ca_crl, 02056 pathlen, flags, f_vrfy, p_vrfy ); 02057 if( ret != 0 ) 02058 return( ret ); 02059 } 02060 02061 if( *flags != 0 ) 02062 return( POLARSSL_ERR_X509_CERT_VERIFY_FAILED ); 02063 02064 return( 0 ); 02065 } 02066 02067 /* 02068 * Initialize a certificate chain 02069 */ 02070 void x509_crt_init( x509_crt *crt ) 02071 { 02072 memset( crt, 0, sizeof(x509_crt) ); 02073 } 02074 02075 /* 02076 * Unallocate all certificate data 02077 */ 02078 void x509_crt_free( x509_crt *crt ) 02079 { 02080 x509_crt *cert_cur = crt; 02081 x509_crt *cert_prv; 02082 x509_name *name_cur; 02083 x509_name *name_prv; 02084 x509_sequence *seq_cur; 02085 x509_sequence *seq_prv; 02086 02087 if( crt == NULL ) 02088 return; 02089 02090 do 02091 { 02092 pk_free( &cert_cur->pk ); 02093 02094 #if defined(POLARSSL_X509_RSASSA_PSS_SUPPORT) 02095 polarssl_free( cert_cur->sig_opts ); 02096 #endif 02097 02098 name_cur = cert_cur->issuer.next; 02099 while( name_cur != NULL ) 02100 { 02101 name_prv = name_cur; 02102 name_cur = name_cur->next; 02103 polarssl_zeroize( name_prv, sizeof( x509_name ) ); 02104 polarssl_free( name_prv ); 02105 } 02106 02107 name_cur = cert_cur->subject.next; 02108 while( name_cur != NULL ) 02109 { 02110 name_prv = name_cur; 02111 name_cur = name_cur->next; 02112 polarssl_zeroize( name_prv, sizeof( x509_name ) ); 02113 polarssl_free( name_prv ); 02114 } 02115 02116 seq_cur = cert_cur->ext_key_usage.next; 02117 while( seq_cur != NULL ) 02118 { 02119 seq_prv = seq_cur; 02120 seq_cur = seq_cur->next; 02121 polarssl_zeroize( seq_prv, sizeof( x509_sequence ) ); 02122 polarssl_free( seq_prv ); 02123 } 02124 02125 seq_cur = cert_cur->subject_alt_names.next; 02126 while( seq_cur != NULL ) 02127 { 02128 seq_prv = seq_cur; 02129 seq_cur = seq_cur->next; 02130 polarssl_zeroize( seq_prv, sizeof( x509_sequence ) ); 02131 polarssl_free( seq_prv ); 02132 } 02133 02134 if( cert_cur->raw.p != NULL ) 02135 { 02136 polarssl_zeroize( cert_cur->raw.p, cert_cur->raw.len ); 02137 polarssl_free( cert_cur->raw.p ); 02138 } 02139 02140 cert_cur = cert_cur->next; 02141 } 02142 while( cert_cur != NULL ); 02143 02144 cert_cur = crt; 02145 do 02146 { 02147 cert_prv = cert_cur; 02148 cert_cur = cert_cur->next; 02149 02150 polarssl_zeroize( cert_prv, sizeof( x509_crt ) ); 02151 if( cert_prv != crt ) 02152 polarssl_free( cert_prv ); 02153 } 02154 while( cert_cur != NULL ); 02155 } 02156 02157 #endif /* POLARSSL_X509_CRT_PARSE_C */ 02158
Generated on Tue Jul 12 2022 13:50:39 by 1.7.2