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