Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
x509_crt.c
00001 /* 00002 * X.509 certificate parsing and verification 00003 * 00004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 00005 * SPDX-License-Identifier: Apache-2.0 00006 * 00007 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00008 * not use this file except in compliance with the License. 00009 * You may obtain a copy of the License at 00010 * 00011 * http://www.apache.org/licenses/LICENSE-2.0 00012 * 00013 * Unless required by applicable law or agreed to in writing, software 00014 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00015 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00016 * See the License for the specific language governing permissions and 00017 * limitations under the License. 00018 * 00019 * This file is part of mbed TLS (https://tls.mbed.org) 00020 */ 00021 /* 00022 * The ITU-T X.509 standard defines a certificate format for PKI. 00023 * 00024 * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs) 00025 * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs) 00026 * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10) 00027 * 00028 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf 00029 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf 00030 * 00031 * [SIRO] https://cabforum.org/wp-content/uploads/Chunghwatelecom201503cabforumV4.pdf 00032 */ 00033 00034 #if !defined(MBEDTLS_CONFIG_FILE) 00035 #include "mbedtls/config.h" 00036 #else 00037 #include MBEDTLS_CONFIG_FILE 00038 #endif 00039 00040 #if defined(MBEDTLS_X509_CRT_PARSE_C) 00041 00042 #include "mbedtls/x509_crt.h" 00043 #include "mbedtls/oid.h" 00044 #include "mbedtls/platform_util.h" 00045 00046 #include <stdio.h> 00047 #include <string.h> 00048 00049 #if defined(MBEDTLS_PEM_PARSE_C) 00050 #include "mbedtls/pem.h" 00051 #endif 00052 00053 #if defined(MBEDTLS_PLATFORM_C) 00054 #include "mbedtls/platform.h" 00055 #else 00056 #include <stdlib.h> 00057 #define mbedtls_free free 00058 #define mbedtls_calloc calloc 00059 #define mbedtls_snprintf snprintf 00060 #endif 00061 00062 #if defined(MBEDTLS_THREADING_C) 00063 #include "mbedtls/threading.h" 00064 #endif 00065 00066 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) 00067 #include <windows.h> 00068 #else 00069 #include <time.h> 00070 #endif 00071 00072 #if defined(MBEDTLS_FS_IO) 00073 #include <stdio.h> 00074 #if !defined(_WIN32) || defined(EFIX64) || defined(EFI32) 00075 #include <sys/types.h> 00076 #include <sys/stat.h> 00077 #include <dirent.h> 00078 #endif /* !_WIN32 || EFIX64 || EFI32 */ 00079 #endif 00080 00081 /* 00082 * Item in a verification chain: cert and flags for it 00083 */ 00084 typedef struct { 00085 mbedtls_x509_crt *crt; 00086 uint32_t flags; 00087 } x509_crt_verify_chain_item; 00088 00089 /* 00090 * Max size of verification chain: end-entity + intermediates + trusted root 00091 */ 00092 #define X509_MAX_VERIFY_CHAIN_SIZE ( MBEDTLS_X509_MAX_INTERMEDIATE_CA + 2 ) 00093 00094 /* 00095 * Default profile 00096 */ 00097 const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default = 00098 { 00099 #if defined(MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES) 00100 /* Allow SHA-1 (weak, but still safe in controlled environments) */ 00101 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 ) | 00102 #endif 00103 /* Only SHA-2 hashes */ 00104 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224 ) | 00105 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) | 00106 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) | 00107 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ), 00108 0xFFFFFFF, /* Any PK alg */ 00109 0xFFFFFFF, /* Any curve */ 00110 2048, 00111 }; 00112 00113 /* 00114 * Next-default profile 00115 */ 00116 const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_next = 00117 { 00118 /* Hashes from SHA-256 and above */ 00119 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) | 00120 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) | 00121 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ), 00122 0xFFFFFFF, /* Any PK alg */ 00123 #if defined(MBEDTLS_ECP_C) 00124 /* Curves at or above 128-bit security level */ 00125 MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) | 00126 MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ) | 00127 MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP521R1 ) | 00128 MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP256R1 ) | 00129 MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP384R1 ) | 00130 MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP512R1 ) | 00131 MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256K1 ), 00132 #else 00133 0, 00134 #endif 00135 2048, 00136 }; 00137 00138 /* 00139 * NSA Suite B Profile 00140 */ 00141 const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb = 00142 { 00143 /* Only SHA-256 and 384 */ 00144 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) | 00145 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ), 00146 /* Only ECDSA */ 00147 MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECDSA ) | 00148 MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECKEY ), 00149 #if defined(MBEDTLS_ECP_C) 00150 /* Only NIST P-256 and P-384 */ 00151 MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) | 00152 MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ), 00153 #else 00154 0, 00155 #endif 00156 0, 00157 }; 00158 00159 /* 00160 * Check md_alg against profile 00161 * Return 0 if md_alg is acceptable for this profile, -1 otherwise 00162 */ 00163 static int x509_profile_check_md_alg( const mbedtls_x509_crt_profile *profile, 00164 mbedtls_md_type_t md_alg ) 00165 { 00166 if( md_alg == MBEDTLS_MD_NONE ) 00167 return( -1 ); 00168 00169 if( ( profile->allowed_mds & MBEDTLS_X509_ID_FLAG( md_alg ) ) != 0 ) 00170 return( 0 ); 00171 00172 return( -1 ); 00173 } 00174 00175 /* 00176 * Check pk_alg against profile 00177 * Return 0 if pk_alg is acceptable for this profile, -1 otherwise 00178 */ 00179 static int x509_profile_check_pk_alg( const mbedtls_x509_crt_profile *profile, 00180 mbedtls_pk_type_t pk_alg ) 00181 { 00182 if( pk_alg == MBEDTLS_PK_NONE ) 00183 return( -1 ); 00184 00185 if( ( profile->allowed_pks & MBEDTLS_X509_ID_FLAG( pk_alg ) ) != 0 ) 00186 return( 0 ); 00187 00188 return( -1 ); 00189 } 00190 00191 /* 00192 * Check key against profile 00193 * Return 0 if pk is acceptable for this profile, -1 otherwise 00194 */ 00195 static int x509_profile_check_key( const mbedtls_x509_crt_profile *profile, 00196 const mbedtls_pk_context *pk ) 00197 { 00198 const mbedtls_pk_type_t pk_alg = mbedtls_pk_get_type( pk ); 00199 00200 #if defined(MBEDTLS_RSA_C) 00201 if( pk_alg == MBEDTLS_PK_RSA || pk_alg == MBEDTLS_PK_RSASSA_PSS ) 00202 { 00203 if( mbedtls_pk_get_bitlen( pk ) >= profile->rsa_min_bitlen ) 00204 return( 0 ); 00205 00206 return( -1 ); 00207 } 00208 #endif 00209 00210 #if defined(MBEDTLS_ECP_C) 00211 if( pk_alg == MBEDTLS_PK_ECDSA || 00212 pk_alg == MBEDTLS_PK_ECKEY || 00213 pk_alg == MBEDTLS_PK_ECKEY_DH ) 00214 { 00215 const mbedtls_ecp_group_id gid = mbedtls_pk_ec( *pk )->grp .id ; 00216 00217 if( gid == MBEDTLS_ECP_DP_NONE ) 00218 return( -1 ); 00219 00220 if( ( profile->allowed_curves & MBEDTLS_X509_ID_FLAG( gid ) ) != 0 ) 00221 return( 0 ); 00222 00223 return( -1 ); 00224 } 00225 #endif 00226 00227 return( -1 ); 00228 } 00229 00230 /* 00231 * Version ::= INTEGER { v1(0), v2(1), v3(2) } 00232 */ 00233 static int x509_get_version( unsigned char **p, 00234 const unsigned char *end, 00235 int *ver ) 00236 { 00237 int ret; 00238 size_t len; 00239 00240 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, 00241 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) != 0 ) 00242 { 00243 if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) 00244 { 00245 *ver = 0; 00246 return( 0 ); 00247 } 00248 00249 return( ret ); 00250 } 00251 00252 end = *p + len; 00253 00254 if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 ) 00255 return( MBEDTLS_ERR_X509_INVALID_VERSION + ret ); 00256 00257 if( *p != end ) 00258 return( MBEDTLS_ERR_X509_INVALID_VERSION + 00259 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00260 00261 return( 0 ); 00262 } 00263 00264 /* 00265 * Validity ::= SEQUENCE { 00266 * notBefore Time, 00267 * notAfter Time } 00268 */ 00269 static int x509_get_dates( unsigned char **p, 00270 const unsigned char *end, 00271 mbedtls_x509_time *from, 00272 mbedtls_x509_time *to ) 00273 { 00274 int ret; 00275 size_t len; 00276 00277 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, 00278 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 00279 return( MBEDTLS_ERR_X509_INVALID_DATE + ret ); 00280 00281 end = *p + len; 00282 00283 if( ( ret = mbedtls_x509_get_time( p, end, from ) ) != 0 ) 00284 return( ret ); 00285 00286 if( ( ret = mbedtls_x509_get_time( p, end, to ) ) != 0 ) 00287 return( ret ); 00288 00289 if( *p != end ) 00290 return( MBEDTLS_ERR_X509_INVALID_DATE + 00291 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00292 00293 return( 0 ); 00294 } 00295 00296 /* 00297 * X.509 v2/v3 unique identifier (not parsed) 00298 */ 00299 static int x509_get_uid( unsigned char **p, 00300 const unsigned char *end, 00301 mbedtls_x509_buf *uid, int n ) 00302 { 00303 int ret; 00304 00305 if( *p == end ) 00306 return( 0 ); 00307 00308 uid->tag = **p; 00309 00310 if( ( ret = mbedtls_asn1_get_tag( p, end, &uid->len, 00311 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | n ) ) != 0 ) 00312 { 00313 if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) 00314 return( 0 ); 00315 00316 return( ret ); 00317 } 00318 00319 uid->p = *p; 00320 *p += uid->len; 00321 00322 return( 0 ); 00323 } 00324 00325 static int x509_get_basic_constraints( unsigned char **p, 00326 const unsigned char *end, 00327 int *ca_istrue, 00328 int *max_pathlen ) 00329 { 00330 int ret; 00331 size_t len; 00332 00333 /* 00334 * BasicConstraints ::= SEQUENCE { 00335 * cA BOOLEAN DEFAULT FALSE, 00336 * pathLenConstraint INTEGER (0..MAX) OPTIONAL } 00337 */ 00338 *ca_istrue = 0; /* DEFAULT FALSE */ 00339 *max_pathlen = 0; /* endless */ 00340 00341 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, 00342 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 00343 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); 00344 00345 if( *p == end ) 00346 return( 0 ); 00347 00348 if( ( ret = mbedtls_asn1_get_bool( p, end, ca_istrue ) ) != 0 ) 00349 { 00350 if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) 00351 ret = mbedtls_asn1_get_int( p, end, ca_istrue ); 00352 00353 if( ret != 0 ) 00354 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); 00355 00356 if( *ca_istrue != 0 ) 00357 *ca_istrue = 1; 00358 } 00359 00360 if( *p == end ) 00361 return( 0 ); 00362 00363 if( ( ret = mbedtls_asn1_get_int( p, end, max_pathlen ) ) != 0 ) 00364 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); 00365 00366 if( *p != end ) 00367 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + 00368 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00369 00370 (*max_pathlen)++; 00371 00372 return( 0 ); 00373 } 00374 00375 static int x509_get_ns_cert_type( unsigned char **p, 00376 const unsigned char *end, 00377 unsigned char *ns_cert_type) 00378 { 00379 int ret; 00380 mbedtls_x509_bitstring bs = { 0, 0, NULL }; 00381 00382 if( ( ret = mbedtls_asn1_get_bitstring( p, end, &bs ) ) != 0 ) 00383 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); 00384 00385 if( bs.len != 1 ) 00386 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + 00387 MBEDTLS_ERR_ASN1_INVALID_LENGTH ); 00388 00389 /* Get actual bitstring */ 00390 *ns_cert_type = *bs.p; 00391 return( 0 ); 00392 } 00393 00394 static int x509_get_key_usage( unsigned char **p, 00395 const unsigned char *end, 00396 unsigned int *key_usage) 00397 { 00398 int ret; 00399 size_t i; 00400 mbedtls_x509_bitstring bs = { 0, 0, NULL }; 00401 00402 if( ( ret = mbedtls_asn1_get_bitstring( p, end, &bs ) ) != 0 ) 00403 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); 00404 00405 if( bs.len < 1 ) 00406 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + 00407 MBEDTLS_ERR_ASN1_INVALID_LENGTH ); 00408 00409 /* Get actual bitstring */ 00410 *key_usage = 0; 00411 for( i = 0; i < bs.len && i < sizeof( unsigned int ); i++ ) 00412 { 00413 *key_usage |= (unsigned int) bs.p[i] << (8*i); 00414 } 00415 00416 return( 0 ); 00417 } 00418 00419 /* 00420 * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId 00421 * 00422 * KeyPurposeId ::= OBJECT IDENTIFIER 00423 */ 00424 static int x509_get_ext_key_usage( unsigned char **p, 00425 const unsigned char *end, 00426 mbedtls_x509_sequence *ext_key_usage) 00427 { 00428 int ret; 00429 00430 if( ( ret = mbedtls_asn1_get_sequence_of( p, end, ext_key_usage, MBEDTLS_ASN1_OID ) ) != 0 ) 00431 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); 00432 00433 /* Sequence length must be >= 1 */ 00434 if( ext_key_usage->buf.p == NULL ) 00435 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + 00436 MBEDTLS_ERR_ASN1_INVALID_LENGTH ); 00437 00438 return( 0 ); 00439 } 00440 00441 /* 00442 * SubjectAltName ::= GeneralNames 00443 * 00444 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName 00445 * 00446 * GeneralName ::= CHOICE { 00447 * otherName [0] OtherName, 00448 * rfc822Name [1] IA5String, 00449 * dNSName [2] IA5String, 00450 * x400Address [3] ORAddress, 00451 * directoryName [4] Name, 00452 * ediPartyName [5] EDIPartyName, 00453 * uniformResourceIdentifier [6] IA5String, 00454 * iPAddress [7] OCTET STRING, 00455 * registeredID [8] OBJECT IDENTIFIER } 00456 * 00457 * OtherName ::= SEQUENCE { 00458 * type-id OBJECT IDENTIFIER, 00459 * value [0] EXPLICIT ANY DEFINED BY type-id } 00460 * 00461 * EDIPartyName ::= SEQUENCE { 00462 * nameAssigner [0] DirectoryString OPTIONAL, 00463 * partyName [1] DirectoryString } 00464 * 00465 * NOTE: we only parse and use dNSName at this point. 00466 */ 00467 static int x509_get_subject_alt_name( unsigned char **p, 00468 const unsigned char *end, 00469 mbedtls_x509_sequence *subject_alt_name ) 00470 { 00471 int ret; 00472 size_t len, tag_len; 00473 mbedtls_asn1_buf *buf; 00474 unsigned char tag; 00475 mbedtls_asn1_sequence *cur = subject_alt_name; 00476 00477 /* Get main sequence tag */ 00478 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, 00479 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 00480 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); 00481 00482 if( *p + len != end ) 00483 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + 00484 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00485 00486 while( *p < end ) 00487 { 00488 if( ( end - *p ) < 1 ) 00489 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + 00490 MBEDTLS_ERR_ASN1_OUT_OF_DATA ); 00491 00492 tag = **p; 00493 (*p)++; 00494 if( ( ret = mbedtls_asn1_get_len( p, end, &tag_len ) ) != 0 ) 00495 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); 00496 00497 if( ( tag & MBEDTLS_ASN1_TAG_CLASS_MASK ) != 00498 MBEDTLS_ASN1_CONTEXT_SPECIFIC ) 00499 { 00500 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + 00501 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); 00502 } 00503 00504 /* Skip everything but DNS name */ 00505 if( tag != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | 2 ) ) 00506 { 00507 *p += tag_len; 00508 continue; 00509 } 00510 00511 /* Allocate and assign next pointer */ 00512 if( cur->buf.p != NULL ) 00513 { 00514 if( cur->next != NULL ) 00515 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS ); 00516 00517 cur->next = mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence ) ); 00518 00519 if( cur->next == NULL ) 00520 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + 00521 MBEDTLS_ERR_ASN1_ALLOC_FAILED ); 00522 00523 cur = cur->next; 00524 } 00525 00526 buf = &(cur->buf); 00527 buf->tag = tag; 00528 buf->p = *p; 00529 buf->len = tag_len; 00530 *p += buf->len; 00531 } 00532 00533 /* Set final sequence entry's next pointer to NULL */ 00534 cur->next = NULL; 00535 00536 if( *p != end ) 00537 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + 00538 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00539 00540 return( 0 ); 00541 } 00542 00543 /* 00544 * X.509 v3 extensions 00545 * 00546 */ 00547 static int x509_get_crt_ext( unsigned char **p, 00548 const unsigned char *end, 00549 mbedtls_x509_crt *crt ) 00550 { 00551 int ret; 00552 size_t len; 00553 unsigned char *end_ext_data, *end_ext_octet; 00554 00555 if( ( ret = mbedtls_x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 ) 00556 { 00557 if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) 00558 return( 0 ); 00559 00560 return( ret ); 00561 } 00562 00563 while( *p < end ) 00564 { 00565 /* 00566 * Extension ::= SEQUENCE { 00567 * extnID OBJECT IDENTIFIER, 00568 * critical BOOLEAN DEFAULT FALSE, 00569 * extnValue OCTET STRING } 00570 */ 00571 mbedtls_x509_buf extn_oid = {0, 0, NULL}; 00572 int is_critical = 0; /* DEFAULT FALSE */ 00573 int ext_type = 0; 00574 00575 if( ( ret = mbedtls_asn1_get_tag( p, end, &len, 00576 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 00577 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); 00578 00579 end_ext_data = *p + len; 00580 00581 /* Get extension ID */ 00582 if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &extn_oid.len, 00583 MBEDTLS_ASN1_OID ) ) != 0 ) 00584 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); 00585 00586 extn_oid.tag = MBEDTLS_ASN1_OID; 00587 extn_oid.p = *p; 00588 *p += extn_oid.len; 00589 00590 /* Get optional critical */ 00591 if( ( ret = mbedtls_asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 && 00592 ( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) ) 00593 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); 00594 00595 /* Data should be octet string type */ 00596 if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &len, 00597 MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) 00598 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); 00599 00600 end_ext_octet = *p + len; 00601 00602 if( end_ext_octet != end_ext_data ) 00603 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + 00604 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00605 00606 /* 00607 * Detect supported extensions 00608 */ 00609 ret = mbedtls_oid_get_x509_ext_type( &extn_oid, &ext_type ); 00610 00611 if( ret != 0 ) 00612 { 00613 /* No parser found, skip extension */ 00614 *p = end_ext_octet; 00615 00616 #if !defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION) 00617 if( is_critical ) 00618 { 00619 /* Data is marked as critical: fail */ 00620 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + 00621 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); 00622 } 00623 #endif 00624 continue; 00625 } 00626 00627 /* Forbid repeated extensions */ 00628 if( ( crt->ext_types & ext_type ) != 0 ) 00629 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS ); 00630 00631 crt->ext_types |= ext_type; 00632 00633 switch( ext_type ) 00634 { 00635 case MBEDTLS_X509_EXT_BASIC_CONSTRAINTS: 00636 /* Parse basic constraints */ 00637 if( ( ret = x509_get_basic_constraints( p, end_ext_octet, 00638 &crt->ca_istrue, &crt->max_pathlen ) ) != 0 ) 00639 return( ret ); 00640 break; 00641 00642 case MBEDTLS_X509_EXT_KEY_USAGE: 00643 /* Parse key usage */ 00644 if( ( ret = x509_get_key_usage( p, end_ext_octet, 00645 &crt->key_usage ) ) != 0 ) 00646 return( ret ); 00647 break; 00648 00649 case MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE: 00650 /* Parse extended key usage */ 00651 if( ( ret = x509_get_ext_key_usage( p, end_ext_octet, 00652 &crt->ext_key_usage ) ) != 0 ) 00653 return( ret ); 00654 break; 00655 00656 case MBEDTLS_X509_EXT_SUBJECT_ALT_NAME: 00657 /* Parse subject alt name */ 00658 if( ( ret = x509_get_subject_alt_name( p, end_ext_octet, 00659 &crt->subject_alt_names ) ) != 0 ) 00660 return( ret ); 00661 break; 00662 00663 case MBEDTLS_X509_EXT_NS_CERT_TYPE: 00664 /* Parse netscape certificate type */ 00665 if( ( ret = x509_get_ns_cert_type( p, end_ext_octet, 00666 &crt->ns_cert_type ) ) != 0 ) 00667 return( ret ); 00668 break; 00669 00670 default: 00671 return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE ); 00672 } 00673 } 00674 00675 if( *p != end ) 00676 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + 00677 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00678 00679 return( 0 ); 00680 } 00681 00682 /* 00683 * Parse and fill a single X.509 certificate in DER format 00684 */ 00685 static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *buf, 00686 size_t buflen ) 00687 { 00688 int ret; 00689 size_t len; 00690 unsigned char *p, *end, *crt_end; 00691 mbedtls_x509_buf sig_params1, sig_params2, sig_oid2; 00692 00693 memset( &sig_params1, 0, sizeof( mbedtls_x509_buf ) ); 00694 memset( &sig_params2, 0, sizeof( mbedtls_x509_buf ) ); 00695 memset( &sig_oid2, 0, sizeof( mbedtls_x509_buf ) ); 00696 00697 /* 00698 * Check for valid input 00699 */ 00700 if( crt == NULL || buf == NULL ) 00701 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); 00702 00703 // Use the original buffer until we figure out actual length 00704 p = (unsigned char*) buf; 00705 len = buflen; 00706 end = p + len; 00707 00708 /* 00709 * Certificate ::= SEQUENCE { 00710 * tbsCertificate TBSCertificate, 00711 * signatureAlgorithm AlgorithmIdentifier, 00712 * signatureValue BIT STRING } 00713 */ 00714 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, 00715 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 00716 { 00717 mbedtls_x509_crt_free( crt ); 00718 return( MBEDTLS_ERR_X509_INVALID_FORMAT ); 00719 } 00720 00721 if( len > (size_t) ( end - p ) ) 00722 { 00723 mbedtls_x509_crt_free( crt ); 00724 return( MBEDTLS_ERR_X509_INVALID_FORMAT + 00725 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00726 } 00727 crt_end = p + len; 00728 00729 // Create and populate a new buffer for the raw field 00730 crt->raw.len = crt_end - buf; 00731 crt->raw.p = p = mbedtls_calloc( 1, crt->raw.len ); 00732 if( p == NULL ) 00733 return( MBEDTLS_ERR_X509_ALLOC_FAILED ); 00734 00735 memcpy( p, buf, crt->raw.len ); 00736 00737 // Direct pointers to the new buffer 00738 p += crt->raw.len - len; 00739 end = crt_end = p + len; 00740 00741 /* 00742 * TBSCertificate ::= SEQUENCE { 00743 */ 00744 crt->tbs.p = p; 00745 00746 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, 00747 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 00748 { 00749 mbedtls_x509_crt_free( crt ); 00750 return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); 00751 } 00752 00753 end = p + len; 00754 crt->tbs.len = end - crt->tbs.p; 00755 00756 /* 00757 * Version ::= INTEGER { v1(0), v2(1), v3(2) } 00758 * 00759 * CertificateSerialNumber ::= INTEGER 00760 * 00761 * signature AlgorithmIdentifier 00762 */ 00763 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 || 00764 ( ret = mbedtls_x509_get_serial( &p, end, &crt->serial ) ) != 0 || 00765 ( ret = mbedtls_x509_get_alg( &p, end, &crt->sig_oid, 00766 &sig_params1 ) ) != 0 ) 00767 { 00768 mbedtls_x509_crt_free( crt ); 00769 return( ret ); 00770 } 00771 00772 if( crt->version < 0 || crt->version > 2 ) 00773 { 00774 mbedtls_x509_crt_free( crt ); 00775 return( MBEDTLS_ERR_X509_UNKNOWN_VERSION ); 00776 } 00777 00778 crt->version++; 00779 00780 if( ( ret = mbedtls_x509_get_sig_alg( &crt->sig_oid, &sig_params1, 00781 &crt->sig_md, &crt->sig_pk, 00782 &crt->sig_opts ) ) != 0 ) 00783 { 00784 mbedtls_x509_crt_free( crt ); 00785 return( ret ); 00786 } 00787 00788 /* 00789 * issuer Name 00790 */ 00791 crt->issuer_raw.p = p; 00792 00793 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, 00794 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 00795 { 00796 mbedtls_x509_crt_free( crt ); 00797 return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); 00798 } 00799 00800 if( ( ret = mbedtls_x509_get_name( &p, p + len, &crt->issuer ) ) != 0 ) 00801 { 00802 mbedtls_x509_crt_free( crt ); 00803 return( ret ); 00804 } 00805 00806 crt->issuer_raw.len = p - crt->issuer_raw.p; 00807 00808 /* 00809 * Validity ::= SEQUENCE { 00810 * notBefore Time, 00811 * notAfter Time } 00812 * 00813 */ 00814 if( ( ret = x509_get_dates( &p, end, &crt->valid_from, 00815 &crt->valid_to ) ) != 0 ) 00816 { 00817 mbedtls_x509_crt_free( crt ); 00818 return( ret ); 00819 } 00820 00821 /* 00822 * subject Name 00823 */ 00824 crt->subject_raw.p = p; 00825 00826 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, 00827 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) 00828 { 00829 mbedtls_x509_crt_free( crt ); 00830 return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); 00831 } 00832 00833 if( len && ( ret = mbedtls_x509_get_name( &p, p + len, &crt->subject ) ) != 0 ) 00834 { 00835 mbedtls_x509_crt_free( crt ); 00836 return( ret ); 00837 } 00838 00839 crt->subject_raw.len = p - crt->subject_raw.p; 00840 00841 /* 00842 * SubjectPublicKeyInfo 00843 */ 00844 if( ( ret = mbedtls_pk_parse_subpubkey( &p, end, &crt->pk ) ) != 0 ) 00845 { 00846 mbedtls_x509_crt_free( crt ); 00847 return( ret ); 00848 } 00849 00850 /* 00851 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, 00852 * -- If present, version shall be v2 or v3 00853 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, 00854 * -- If present, version shall be v2 or v3 00855 * extensions [3] EXPLICIT Extensions OPTIONAL 00856 * -- If present, version shall be v3 00857 */ 00858 if( crt->version == 2 || crt->version == 3 ) 00859 { 00860 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 ); 00861 if( ret != 0 ) 00862 { 00863 mbedtls_x509_crt_free( crt ); 00864 return( ret ); 00865 } 00866 } 00867 00868 if( crt->version == 2 || crt->version == 3 ) 00869 { 00870 ret = x509_get_uid( &p, end, &crt->subject_id, 2 ); 00871 if( ret != 0 ) 00872 { 00873 mbedtls_x509_crt_free( crt ); 00874 return( ret ); 00875 } 00876 } 00877 00878 #if !defined(MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3) 00879 if( crt->version == 3 ) 00880 #endif 00881 { 00882 ret = x509_get_crt_ext( &p, end, crt ); 00883 if( ret != 0 ) 00884 { 00885 mbedtls_x509_crt_free( crt ); 00886 return( ret ); 00887 } 00888 } 00889 00890 if( p != end ) 00891 { 00892 mbedtls_x509_crt_free( crt ); 00893 return( MBEDTLS_ERR_X509_INVALID_FORMAT + 00894 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00895 } 00896 00897 end = crt_end; 00898 00899 /* 00900 * } 00901 * -- end of TBSCertificate 00902 * 00903 * signatureAlgorithm AlgorithmIdentifier, 00904 * signatureValue BIT STRING 00905 */ 00906 if( ( ret = mbedtls_x509_get_alg( &p, end, &sig_oid2, &sig_params2 ) ) != 0 ) 00907 { 00908 mbedtls_x509_crt_free( crt ); 00909 return( ret ); 00910 } 00911 00912 if( crt->sig_oid.len != sig_oid2.len || 00913 memcmp( crt->sig_oid.p, sig_oid2.p, crt->sig_oid.len ) != 0 || 00914 sig_params1.len != sig_params2.len || 00915 ( sig_params1.len != 0 && 00916 memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) ) 00917 { 00918 mbedtls_x509_crt_free( crt ); 00919 return( MBEDTLS_ERR_X509_SIG_MISMATCH ); 00920 } 00921 00922 if( ( ret = mbedtls_x509_get_sig( &p, end, &crt->sig ) ) != 0 ) 00923 { 00924 mbedtls_x509_crt_free( crt ); 00925 return( ret ); 00926 } 00927 00928 if( p != end ) 00929 { 00930 mbedtls_x509_crt_free( crt ); 00931 return( MBEDTLS_ERR_X509_INVALID_FORMAT + 00932 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); 00933 } 00934 00935 return( 0 ); 00936 } 00937 00938 /* 00939 * Parse one X.509 certificate in DER format from a buffer and add them to a 00940 * chained list 00941 */ 00942 int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, const unsigned char *buf, 00943 size_t buflen ) 00944 { 00945 int ret; 00946 mbedtls_x509_crt *crt = chain, *prev = NULL; 00947 00948 /* 00949 * Check for valid input 00950 */ 00951 if( crt == NULL || buf == NULL ) 00952 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); 00953 00954 while( crt->version != 0 && crt->next != NULL ) 00955 { 00956 prev = crt; 00957 crt = crt->next; 00958 } 00959 00960 /* 00961 * Add new certificate on the end of the chain if needed. 00962 */ 00963 if( crt->version != 0 && crt->next == NULL ) 00964 { 00965 crt->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) ); 00966 00967 if( crt->next == NULL ) 00968 return( MBEDTLS_ERR_X509_ALLOC_FAILED ); 00969 00970 prev = crt; 00971 mbedtls_x509_crt_init( crt->next ); 00972 crt = crt->next; 00973 } 00974 00975 if( ( ret = x509_crt_parse_der_core( crt, buf, buflen ) ) != 0 ) 00976 { 00977 if( prev ) 00978 prev->next = NULL; 00979 00980 if( crt != chain ) 00981 mbedtls_free( crt ); 00982 00983 return( ret ); 00984 } 00985 00986 return( 0 ); 00987 } 00988 00989 /* 00990 * Parse one or more PEM certificates from a buffer and add them to the chained 00991 * list 00992 */ 00993 int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, size_t buflen ) 00994 { 00995 #if defined(MBEDTLS_PEM_PARSE_C) 00996 int success = 0, first_error = 0, total_failed = 0; 00997 int buf_format = MBEDTLS_X509_FORMAT_DER; 00998 #endif 00999 01000 /* 01001 * Check for valid input 01002 */ 01003 if( chain == NULL || buf == NULL ) 01004 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); 01005 01006 /* 01007 * Determine buffer content. Buffer contains either one DER certificate or 01008 * one or more PEM certificates. 01009 */ 01010 #if defined(MBEDTLS_PEM_PARSE_C) 01011 if( buflen != 0 && buf[buflen - 1] == '\0' && 01012 strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL ) 01013 { 01014 buf_format = MBEDTLS_X509_FORMAT_PEM; 01015 } 01016 01017 if( buf_format == MBEDTLS_X509_FORMAT_DER ) 01018 return mbedtls_x509_crt_parse_der( chain, buf, buflen ); 01019 #else 01020 return mbedtls_x509_crt_parse_der( chain, buf, buflen ); 01021 #endif 01022 01023 #if defined(MBEDTLS_PEM_PARSE_C) 01024 if( buf_format == MBEDTLS_X509_FORMAT_PEM ) 01025 { 01026 int ret; 01027 mbedtls_pem_context pem; 01028 01029 /* 1 rather than 0 since the terminating NULL byte is counted in */ 01030 while( buflen > 1 ) 01031 { 01032 size_t use_len; 01033 mbedtls_pem_init( &pem ); 01034 01035 /* If we get there, we know the string is null-terminated */ 01036 ret = mbedtls_pem_read_buffer( &pem, 01037 "-----BEGIN CERTIFICATE-----", 01038 "-----END CERTIFICATE-----", 01039 buf, NULL, 0, &use_len ); 01040 01041 if( ret == 0 ) 01042 { 01043 /* 01044 * Was PEM encoded 01045 */ 01046 buflen -= use_len; 01047 buf += use_len; 01048 } 01049 else if( ret == MBEDTLS_ERR_PEM_BAD_INPUT_DATA ) 01050 { 01051 return( ret ); 01052 } 01053 else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) 01054 { 01055 mbedtls_pem_free( &pem ); 01056 01057 /* 01058 * PEM header and footer were found 01059 */ 01060 buflen -= use_len; 01061 buf += use_len; 01062 01063 if( first_error == 0 ) 01064 first_error = ret; 01065 01066 total_failed++; 01067 continue; 01068 } 01069 else 01070 break; 01071 01072 ret = mbedtls_x509_crt_parse_der( chain, pem.buf , pem.buflen ); 01073 01074 mbedtls_pem_free( &pem ); 01075 01076 if( ret != 0 ) 01077 { 01078 /* 01079 * Quit parsing on a memory error 01080 */ 01081 if( ret == MBEDTLS_ERR_X509_ALLOC_FAILED ) 01082 return( ret ); 01083 01084 if( first_error == 0 ) 01085 first_error = ret; 01086 01087 total_failed++; 01088 continue; 01089 } 01090 01091 success = 1; 01092 } 01093 } 01094 01095 if( success ) 01096 return( total_failed ); 01097 else if( first_error ) 01098 return( first_error ); 01099 else 01100 return( MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT ); 01101 #endif /* MBEDTLS_PEM_PARSE_C */ 01102 } 01103 01104 #if defined(MBEDTLS_FS_IO) 01105 /* 01106 * Load one or more certificates and add them to the chained list 01107 */ 01108 int mbedtls_x509_crt_parse_file( mbedtls_x509_crt *chain, const char *path ) 01109 { 01110 int ret; 01111 size_t n; 01112 unsigned char *buf; 01113 01114 if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 ) 01115 return( ret ); 01116 01117 ret = mbedtls_x509_crt_parse( chain, buf, n ); 01118 01119 mbedtls_platform_zeroize( buf, n ); 01120 mbedtls_free( buf ); 01121 01122 return( ret ); 01123 } 01124 01125 int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ) 01126 { 01127 int ret = 0; 01128 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) 01129 int w_ret; 01130 WCHAR szDir[MAX_PATH]; 01131 char filename[MAX_PATH]; 01132 char *p; 01133 size_t len = strlen( path ); 01134 01135 WIN32_FIND_DATAW file_data; 01136 HANDLE hFind; 01137 01138 if( len > MAX_PATH - 3 ) 01139 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); 01140 01141 memset( szDir, 0, sizeof(szDir) ); 01142 memset( filename, 0, MAX_PATH ); 01143 memcpy( filename, path, len ); 01144 filename[len++] = '\\'; 01145 p = filename + len; 01146 filename[len++] = '*'; 01147 01148 w_ret = MultiByteToWideChar( CP_ACP, 0, filename, (int)len, szDir, 01149 MAX_PATH - 3 ); 01150 if( w_ret == 0 ) 01151 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); 01152 01153 hFind = FindFirstFileW( szDir, &file_data ); 01154 if( hFind == INVALID_HANDLE_VALUE ) 01155 return( MBEDTLS_ERR_X509_FILE_IO_ERROR ); 01156 01157 len = MAX_PATH - len; 01158 do 01159 { 01160 memset( p, 0, len ); 01161 01162 if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) 01163 continue; 01164 01165 w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName, 01166 lstrlenW( file_data.cFileName ), 01167 p, (int) len - 1, 01168 NULL, NULL ); 01169 if( w_ret == 0 ) 01170 { 01171 ret = MBEDTLS_ERR_X509_FILE_IO_ERROR; 01172 goto cleanup; 01173 } 01174 01175 w_ret = mbedtls_x509_crt_parse_file( chain, filename ); 01176 if( w_ret < 0 ) 01177 ret++; 01178 else 01179 ret += w_ret; 01180 } 01181 while( FindNextFileW( hFind, &file_data ) != 0 ); 01182 01183 if( GetLastError() != ERROR_NO_MORE_FILES ) 01184 ret = MBEDTLS_ERR_X509_FILE_IO_ERROR; 01185 01186 cleanup: 01187 FindClose( hFind ); 01188 #else /* _WIN32 */ 01189 int t_ret; 01190 int snp_ret; 01191 struct stat sb; 01192 struct dirent *entry; 01193 char entry_name[MBEDTLS_X509_MAX_FILE_PATH_LEN]; 01194 DIR *dir = opendir( path ); 01195 01196 if( dir == NULL ) 01197 return( MBEDTLS_ERR_X509_FILE_IO_ERROR ); 01198 01199 #if defined(MBEDTLS_THREADING_C) 01200 if( ( ret = mbedtls_mutex_lock( &mbedtls_threading_readdir_mutex ) ) != 0 ) 01201 { 01202 closedir( dir ); 01203 return( ret ); 01204 } 01205 #endif /* MBEDTLS_THREADING_C */ 01206 01207 while( ( entry = readdir( dir ) ) != NULL ) 01208 { 01209 snp_ret = mbedtls_snprintf( entry_name, sizeof entry_name, 01210 "%s/%s", path, entry->d_name ); 01211 01212 if( snp_ret < 0 || (size_t)snp_ret >= sizeof entry_name ) 01213 { 01214 ret = MBEDTLS_ERR_X509_BUFFER_TOO_SMALL; 01215 goto cleanup; 01216 } 01217 else if( stat( entry_name, &sb ) == -1 ) 01218 { 01219 ret = MBEDTLS_ERR_X509_FILE_IO_ERROR; 01220 goto cleanup; 01221 } 01222 01223 if( !S_ISREG( sb.st_mode ) ) 01224 continue; 01225 01226 // Ignore parse errors 01227 // 01228 t_ret = mbedtls_x509_crt_parse_file( chain, entry_name ); 01229 if( t_ret < 0 ) 01230 ret++; 01231 else 01232 ret += t_ret; 01233 } 01234 01235 cleanup: 01236 closedir( dir ); 01237 01238 #if defined(MBEDTLS_THREADING_C) 01239 if( mbedtls_mutex_unlock( &mbedtls_threading_readdir_mutex ) != 0 ) 01240 ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR; 01241 #endif /* MBEDTLS_THREADING_C */ 01242 01243 #endif /* _WIN32 */ 01244 01245 return( ret ); 01246 } 01247 #endif /* MBEDTLS_FS_IO */ 01248 01249 static int x509_info_subject_alt_name( char **buf, size_t *size, 01250 const mbedtls_x509_sequence *subject_alt_name ) 01251 { 01252 size_t i; 01253 size_t n = *size; 01254 char *p = *buf; 01255 const mbedtls_x509_sequence *cur = subject_alt_name; 01256 const char *sep = ""; 01257 size_t sep_len = 0; 01258 01259 while( cur != NULL ) 01260 { 01261 if( cur->buf.len + sep_len >= n ) 01262 { 01263 *p = '\0'; 01264 return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL ); 01265 } 01266 01267 n -= cur->buf.len + sep_len; 01268 for( i = 0; i < sep_len; i++ ) 01269 *p++ = sep[i]; 01270 for( i = 0; i < cur->buf.len; i++ ) 01271 *p++ = cur->buf.p[i]; 01272 01273 sep = ", "; 01274 sep_len = 2; 01275 01276 cur = cur->next; 01277 } 01278 01279 *p = '\0'; 01280 01281 *size = n; 01282 *buf = p; 01283 01284 return( 0 ); 01285 } 01286 01287 #define PRINT_ITEM(i) \ 01288 { \ 01289 ret = mbedtls_snprintf( p, n, "%s" i, sep ); \ 01290 MBEDTLS_X509_SAFE_SNPRINTF; \ 01291 sep = ", "; \ 01292 } 01293 01294 #define CERT_TYPE(type,name) \ 01295 if( ns_cert_type & type ) \ 01296 PRINT_ITEM( name ); 01297 01298 static int x509_info_cert_type( char **buf, size_t *size, 01299 unsigned char ns_cert_type ) 01300 { 01301 int ret; 01302 size_t n = *size; 01303 char *p = *buf; 01304 const char *sep = ""; 01305 01306 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT, "SSL Client" ); 01307 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER, "SSL Server" ); 01308 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_EMAIL, "Email" ); 01309 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING, "Object Signing" ); 01310 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_RESERVED, "Reserved" ); 01311 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_CA, "SSL CA" ); 01312 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA, "Email CA" ); 01313 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA, "Object Signing CA" ); 01314 01315 *size = n; 01316 *buf = p; 01317 01318 return( 0 ); 01319 } 01320 01321 #define KEY_USAGE(code,name) \ 01322 if( key_usage & code ) \ 01323 PRINT_ITEM( name ); 01324 01325 static int x509_info_key_usage( char **buf, size_t *size, 01326 unsigned int key_usage ) 01327 { 01328 int ret; 01329 size_t n = *size; 01330 char *p = *buf; 01331 const char *sep = ""; 01332 01333 KEY_USAGE( MBEDTLS_X509_KU_DIGITAL_SIGNATURE, "Digital Signature" ); 01334 KEY_USAGE( MBEDTLS_X509_KU_NON_REPUDIATION, "Non Repudiation" ); 01335 KEY_USAGE( MBEDTLS_X509_KU_KEY_ENCIPHERMENT, "Key Encipherment" ); 01336 KEY_USAGE( MBEDTLS_X509_KU_DATA_ENCIPHERMENT, "Data Encipherment" ); 01337 KEY_USAGE( MBEDTLS_X509_KU_KEY_AGREEMENT, "Key Agreement" ); 01338 KEY_USAGE( MBEDTLS_X509_KU_KEY_CERT_SIGN, "Key Cert Sign" ); 01339 KEY_USAGE( MBEDTLS_X509_KU_CRL_SIGN, "CRL Sign" ); 01340 KEY_USAGE( MBEDTLS_X509_KU_ENCIPHER_ONLY, "Encipher Only" ); 01341 KEY_USAGE( MBEDTLS_X509_KU_DECIPHER_ONLY, "Decipher Only" ); 01342 01343 *size = n; 01344 *buf = p; 01345 01346 return( 0 ); 01347 } 01348 01349 static int x509_info_ext_key_usage( char **buf, size_t *size, 01350 const mbedtls_x509_sequence *extended_key_usage ) 01351 { 01352 int ret; 01353 const char *desc; 01354 size_t n = *size; 01355 char *p = *buf; 01356 const mbedtls_x509_sequence *cur = extended_key_usage; 01357 const char *sep = ""; 01358 01359 while( cur != NULL ) 01360 { 01361 if( mbedtls_oid_get_extended_key_usage( &cur->buf, &desc ) != 0 ) 01362 desc = "???"; 01363 01364 ret = mbedtls_snprintf( p, n, "%s%s", sep, desc ); 01365 MBEDTLS_X509_SAFE_SNPRINTF; 01366 01367 sep = ", "; 01368 01369 cur = cur->next; 01370 } 01371 01372 *size = n; 01373 *buf = p; 01374 01375 return( 0 ); 01376 } 01377 01378 /* 01379 * Return an informational string about the certificate. 01380 */ 01381 #define BEFORE_COLON 18 01382 #define BC "18" 01383 int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix, 01384 const mbedtls_x509_crt *crt ) 01385 { 01386 int ret; 01387 size_t n; 01388 char *p; 01389 char key_size_str[BEFORE_COLON]; 01390 01391 p = buf; 01392 n = size; 01393 01394 if( NULL == crt ) 01395 { 01396 ret = mbedtls_snprintf( p, n, "\nCertificate is uninitialised!\n" ); 01397 MBEDTLS_X509_SAFE_SNPRINTF; 01398 01399 return( (int) ( size - n ) ); 01400 } 01401 01402 ret = mbedtls_snprintf( p, n, "%scert. version : %d\n", 01403 prefix, crt->version ); 01404 MBEDTLS_X509_SAFE_SNPRINTF; 01405 ret = mbedtls_snprintf( p, n, "%sserial number : ", 01406 prefix ); 01407 MBEDTLS_X509_SAFE_SNPRINTF; 01408 01409 ret = mbedtls_x509_serial_gets( p, n, &crt->serial ); 01410 MBEDTLS_X509_SAFE_SNPRINTF; 01411 01412 ret = mbedtls_snprintf( p, n, "\n%sissuer name : ", prefix ); 01413 MBEDTLS_X509_SAFE_SNPRINTF; 01414 ret = mbedtls_x509_dn_gets( p, n, &crt->issuer ); 01415 MBEDTLS_X509_SAFE_SNPRINTF; 01416 01417 ret = mbedtls_snprintf( p, n, "\n%ssubject name : ", prefix ); 01418 MBEDTLS_X509_SAFE_SNPRINTF; 01419 ret = mbedtls_x509_dn_gets( p, n, &crt->subject ); 01420 MBEDTLS_X509_SAFE_SNPRINTF; 01421 01422 ret = mbedtls_snprintf( p, n, "\n%sissued on : " \ 01423 "%04d-%02d-%02d %02d:%02d:%02d", prefix, 01424 crt->valid_from.year, crt->valid_from.mon, 01425 crt->valid_from.day, crt->valid_from.hour, 01426 crt->valid_from.min, crt->valid_from.sec ); 01427 MBEDTLS_X509_SAFE_SNPRINTF; 01428 01429 ret = mbedtls_snprintf( p, n, "\n%sexpires on : " \ 01430 "%04d-%02d-%02d %02d:%02d:%02d", prefix, 01431 crt->valid_to.year, crt->valid_to.mon, 01432 crt->valid_to.day, crt->valid_to.hour, 01433 crt->valid_to.min, crt->valid_to.sec ); 01434 MBEDTLS_X509_SAFE_SNPRINTF; 01435 01436 ret = mbedtls_snprintf( p, n, "\n%ssigned using : ", prefix ); 01437 MBEDTLS_X509_SAFE_SNPRINTF; 01438 01439 ret = mbedtls_x509_sig_alg_gets( p, n, &crt->sig_oid, crt->sig_pk, 01440 crt->sig_md, crt->sig_opts ); 01441 MBEDTLS_X509_SAFE_SNPRINTF; 01442 01443 /* Key size */ 01444 if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON, 01445 mbedtls_pk_get_name( &crt->pk ) ) ) != 0 ) 01446 { 01447 return( ret ); 01448 } 01449 01450 ret = mbedtls_snprintf( p, n, "\n%s%-" BC "s: %d bits", prefix, key_size_str, 01451 (int) mbedtls_pk_get_bitlen( &crt->pk ) ); 01452 MBEDTLS_X509_SAFE_SNPRINTF; 01453 01454 /* 01455 * Optional extensions 01456 */ 01457 01458 if( crt->ext_types & MBEDTLS_X509_EXT_BASIC_CONSTRAINTS ) 01459 { 01460 ret = mbedtls_snprintf( p, n, "\n%sbasic constraints : CA=%s", prefix, 01461 crt->ca_istrue ? "true" : "false" ); 01462 MBEDTLS_X509_SAFE_SNPRINTF; 01463 01464 if( crt->max_pathlen > 0 ) 01465 { 01466 ret = mbedtls_snprintf( p, n, ", max_pathlen=%d", crt->max_pathlen - 1 ); 01467 MBEDTLS_X509_SAFE_SNPRINTF; 01468 } 01469 } 01470 01471 if( crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME ) 01472 { 01473 ret = mbedtls_snprintf( p, n, "\n%ssubject alt name : ", prefix ); 01474 MBEDTLS_X509_SAFE_SNPRINTF; 01475 01476 if( ( ret = x509_info_subject_alt_name( &p, &n, 01477 &crt->subject_alt_names ) ) != 0 ) 01478 return( ret ); 01479 } 01480 01481 if( crt->ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE ) 01482 { 01483 ret = mbedtls_snprintf( p, n, "\n%scert. type : ", prefix ); 01484 MBEDTLS_X509_SAFE_SNPRINTF; 01485 01486 if( ( ret = x509_info_cert_type( &p, &n, crt->ns_cert_type ) ) != 0 ) 01487 return( ret ); 01488 } 01489 01490 if( crt->ext_types & MBEDTLS_X509_EXT_KEY_USAGE ) 01491 { 01492 ret = mbedtls_snprintf( p, n, "\n%skey usage : ", prefix ); 01493 MBEDTLS_X509_SAFE_SNPRINTF; 01494 01495 if( ( ret = x509_info_key_usage( &p, &n, crt->key_usage ) ) != 0 ) 01496 return( ret ); 01497 } 01498 01499 if( crt->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE ) 01500 { 01501 ret = mbedtls_snprintf( p, n, "\n%sext key usage : ", prefix ); 01502 MBEDTLS_X509_SAFE_SNPRINTF; 01503 01504 if( ( ret = x509_info_ext_key_usage( &p, &n, 01505 &crt->ext_key_usage ) ) != 0 ) 01506 return( ret ); 01507 } 01508 01509 ret = mbedtls_snprintf( p, n, "\n" ); 01510 MBEDTLS_X509_SAFE_SNPRINTF; 01511 01512 return( (int) ( size - n ) ); 01513 } 01514 01515 struct x509_crt_verify_string { 01516 int code; 01517 const char *string; 01518 }; 01519 01520 static const struct x509_crt_verify_string x509_crt_verify_strings[] = { 01521 { MBEDTLS_X509_BADCERT_EXPIRED, "The certificate validity has expired" }, 01522 { MBEDTLS_X509_BADCERT_REVOKED, "The certificate has been revoked (is on a CRL)" }, 01523 { MBEDTLS_X509_BADCERT_CN_MISMATCH, "The certificate Common Name (CN) does not match with the expected CN" }, 01524 { MBEDTLS_X509_BADCERT_NOT_TRUSTED, "The certificate is not correctly signed by the trusted CA" }, 01525 { MBEDTLS_X509_BADCRL_NOT_TRUSTED, "The CRL is not correctly signed by the trusted CA" }, 01526 { MBEDTLS_X509_BADCRL_EXPIRED, "The CRL is expired" }, 01527 { MBEDTLS_X509_BADCERT_MISSING, "Certificate was missing" }, 01528 { MBEDTLS_X509_BADCERT_SKIP_VERIFY, "Certificate verification was skipped" }, 01529 { MBEDTLS_X509_BADCERT_OTHER, "Other reason (can be used by verify callback)" }, 01530 { MBEDTLS_X509_BADCERT_FUTURE, "The certificate validity starts in the future" }, 01531 { MBEDTLS_X509_BADCRL_FUTURE, "The CRL is from the future" }, 01532 { MBEDTLS_X509_BADCERT_KEY_USAGE, "Usage does not match the keyUsage extension" }, 01533 { MBEDTLS_X509_BADCERT_EXT_KEY_USAGE, "Usage does not match the extendedKeyUsage extension" }, 01534 { MBEDTLS_X509_BADCERT_NS_CERT_TYPE, "Usage does not match the nsCertType extension" }, 01535 { MBEDTLS_X509_BADCERT_BAD_MD, "The certificate is signed with an unacceptable hash." }, 01536 { MBEDTLS_X509_BADCERT_BAD_PK, "The certificate is signed with an unacceptable PK alg (eg RSA vs ECDSA)." }, 01537 { MBEDTLS_X509_BADCERT_BAD_KEY, "The certificate is signed with an unacceptable key (eg bad curve, RSA too short)." }, 01538 { MBEDTLS_X509_BADCRL_BAD_MD, "The CRL is signed with an unacceptable hash." }, 01539 { MBEDTLS_X509_BADCRL_BAD_PK, "The CRL is signed with an unacceptable PK alg (eg RSA vs ECDSA)." }, 01540 { MBEDTLS_X509_BADCRL_BAD_KEY, "The CRL is signed with an unacceptable key (eg bad curve, RSA too short)." }, 01541 { 0, NULL } 01542 }; 01543 01544 int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix, 01545 uint32_t flags ) 01546 { 01547 int ret; 01548 const struct x509_crt_verify_string *cur; 01549 char *p = buf; 01550 size_t n = size; 01551 01552 for( cur = x509_crt_verify_strings; cur->string != NULL ; cur++ ) 01553 { 01554 if( ( flags & cur->code ) == 0 ) 01555 continue; 01556 01557 ret = mbedtls_snprintf( p, n, "%s%s\n", prefix, cur->string ); 01558 MBEDTLS_X509_SAFE_SNPRINTF; 01559 flags ^= cur->code; 01560 } 01561 01562 if( flags != 0 ) 01563 { 01564 ret = mbedtls_snprintf( p, n, "%sUnknown reason " 01565 "(this should not happen)\n", prefix ); 01566 MBEDTLS_X509_SAFE_SNPRINTF; 01567 } 01568 01569 return( (int) ( size - n ) ); 01570 } 01571 01572 #if defined(MBEDTLS_X509_CHECK_KEY_USAGE) 01573 int mbedtls_x509_crt_check_key_usage( const mbedtls_x509_crt *crt, 01574 unsigned int usage ) 01575 { 01576 unsigned int usage_must, usage_may; 01577 unsigned int may_mask = MBEDTLS_X509_KU_ENCIPHER_ONLY 01578 | MBEDTLS_X509_KU_DECIPHER_ONLY; 01579 01580 if( ( crt->ext_types & MBEDTLS_X509_EXT_KEY_USAGE ) == 0 ) 01581 return( 0 ); 01582 01583 usage_must = usage & ~may_mask; 01584 01585 if( ( ( crt->key_usage & ~may_mask ) & usage_must ) != usage_must ) 01586 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); 01587 01588 usage_may = usage & may_mask; 01589 01590 if( ( ( crt->key_usage & may_mask ) | usage_may ) != usage_may ) 01591 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); 01592 01593 return( 0 ); 01594 } 01595 #endif 01596 01597 #if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE) 01598 int mbedtls_x509_crt_check_extended_key_usage( const mbedtls_x509_crt *crt, 01599 const char *usage_oid, 01600 size_t usage_len ) 01601 { 01602 const mbedtls_x509_sequence *cur; 01603 01604 /* Extension is not mandatory, absent means no restriction */ 01605 if( ( crt->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE ) == 0 ) 01606 return( 0 ); 01607 01608 /* 01609 * Look for the requested usage (or wildcard ANY) in our list 01610 */ 01611 for( cur = &crt->ext_key_usage; cur != NULL; cur = cur->next ) 01612 { 01613 const mbedtls_x509_buf *cur_oid = &cur->buf; 01614 01615 if( cur_oid->len == usage_len && 01616 memcmp( cur_oid->p, usage_oid, usage_len ) == 0 ) 01617 { 01618 return( 0 ); 01619 } 01620 01621 if( MBEDTLS_OID_CMP( MBEDTLS_OID_ANY_EXTENDED_KEY_USAGE, cur_oid ) == 0 ) 01622 return( 0 ); 01623 } 01624 01625 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); 01626 } 01627 #endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */ 01628 01629 #if defined(MBEDTLS_X509_CRL_PARSE_C) 01630 /* 01631 * Return 1 if the certificate is revoked, or 0 otherwise. 01632 */ 01633 int mbedtls_x509_crt_is_revoked( const mbedtls_x509_crt *crt, const mbedtls_x509_crl *crl ) 01634 { 01635 const mbedtls_x509_crl_entry *cur = &crl->entry; 01636 01637 while( cur != NULL && cur->serial.len != 0 ) 01638 { 01639 if( crt->serial.len == cur->serial.len && 01640 memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 ) 01641 { 01642 if( mbedtls_x509_time_is_past( &cur->revocation_date ) ) 01643 return( 1 ); 01644 } 01645 01646 cur = cur->next; 01647 } 01648 01649 return( 0 ); 01650 } 01651 01652 /* 01653 * Check that the given certificate is not revoked according to the CRL. 01654 * Skip validation if no CRL for the given CA is present. 01655 */ 01656 static int x509_crt_verifycrl( mbedtls_x509_crt *crt, mbedtls_x509_crt *ca, 01657 mbedtls_x509_crl *crl_list, 01658 const mbedtls_x509_crt_profile *profile ) 01659 { 01660 int flags = 0; 01661 unsigned char hash[MBEDTLS_MD_MAX_SIZE]; 01662 const mbedtls_md_info_t *md_info; 01663 01664 if( ca == NULL ) 01665 return( flags ); 01666 01667 while( crl_list != NULL ) 01668 { 01669 if( crl_list->version == 0 || 01670 crl_list->issuer_raw.len != ca->subject_raw.len || 01671 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p, 01672 crl_list->issuer_raw.len ) != 0 ) 01673 { 01674 crl_list = crl_list->next; 01675 continue; 01676 } 01677 01678 /* 01679 * Check if the CA is configured to sign CRLs 01680 */ 01681 #if defined(MBEDTLS_X509_CHECK_KEY_USAGE) 01682 if( mbedtls_x509_crt_check_key_usage( ca, MBEDTLS_X509_KU_CRL_SIGN ) != 0 ) 01683 { 01684 flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED; 01685 break; 01686 } 01687 #endif 01688 01689 /* 01690 * Check if CRL is correctly signed by the trusted CA 01691 */ 01692 if( x509_profile_check_md_alg( profile, crl_list->sig_md ) != 0 ) 01693 flags |= MBEDTLS_X509_BADCRL_BAD_MD; 01694 01695 if( x509_profile_check_pk_alg( profile, crl_list->sig_pk ) != 0 ) 01696 flags |= MBEDTLS_X509_BADCRL_BAD_PK; 01697 01698 md_info = mbedtls_md_info_from_type( crl_list->sig_md ); 01699 if( mbedtls_md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash ) != 0 ) 01700 { 01701 /* Note: this can't happen except after an internal error */ 01702 flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED; 01703 break; 01704 } 01705 01706 if( x509_profile_check_key( profile, &ca->pk ) != 0 ) 01707 flags |= MBEDTLS_X509_BADCERT_BAD_KEY; 01708 01709 if( mbedtls_pk_verify_ext( crl_list->sig_pk, crl_list->sig_opts, &ca->pk, 01710 crl_list->sig_md, hash, mbedtls_md_get_size( md_info ), 01711 crl_list->sig.p, crl_list->sig.len ) != 0 ) 01712 { 01713 flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED; 01714 break; 01715 } 01716 01717 /* 01718 * Check for validity of CRL (Do not drop out) 01719 */ 01720 if( mbedtls_x509_time_is_past( &crl_list->next_update ) ) 01721 flags |= MBEDTLS_X509_BADCRL_EXPIRED; 01722 01723 if( mbedtls_x509_time_is_future( &crl_list->this_update ) ) 01724 flags |= MBEDTLS_X509_BADCRL_FUTURE; 01725 01726 /* 01727 * Check if certificate is revoked 01728 */ 01729 if( mbedtls_x509_crt_is_revoked( crt, crl_list ) ) 01730 { 01731 flags |= MBEDTLS_X509_BADCERT_REVOKED; 01732 break; 01733 } 01734 01735 crl_list = crl_list->next; 01736 } 01737 01738 return( flags ); 01739 } 01740 #endif /* MBEDTLS_X509_CRL_PARSE_C */ 01741 01742 /* 01743 * Like memcmp, but case-insensitive and always returns -1 if different 01744 */ 01745 static int x509_memcasecmp( const void *s1, const void *s2, size_t len ) 01746 { 01747 size_t i; 01748 unsigned char diff; 01749 const unsigned char *n1 = s1, *n2 = s2; 01750 01751 for( i = 0; i < len; i++ ) 01752 { 01753 diff = n1[i] ^ n2[i]; 01754 01755 if( diff == 0 ) 01756 continue; 01757 01758 if( diff == 32 && 01759 ( ( n1[i] >= 'a' && n1[i] <= 'z' ) || 01760 ( n1[i] >= 'A' && n1[i] <= 'Z' ) ) ) 01761 { 01762 continue; 01763 } 01764 01765 return( -1 ); 01766 } 01767 01768 return( 0 ); 01769 } 01770 01771 /* 01772 * Return 0 if name matches wildcard, -1 otherwise 01773 */ 01774 static int x509_check_wildcard( const char *cn, const mbedtls_x509_buf *name ) 01775 { 01776 size_t i; 01777 size_t cn_idx = 0, cn_len = strlen( cn ); 01778 01779 /* We can't have a match if there is no wildcard to match */ 01780 if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' ) 01781 return( -1 ); 01782 01783 for( i = 0; i < cn_len; ++i ) 01784 { 01785 if( cn[i] == '.' ) 01786 { 01787 cn_idx = i; 01788 break; 01789 } 01790 } 01791 01792 if( cn_idx == 0 ) 01793 return( -1 ); 01794 01795 if( cn_len - cn_idx == name->len - 1 && 01796 x509_memcasecmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 ) 01797 { 01798 return( 0 ); 01799 } 01800 01801 return( -1 ); 01802 } 01803 01804 /* 01805 * Compare two X.509 strings, case-insensitive, and allowing for some encoding 01806 * variations (but not all). 01807 * 01808 * Return 0 if equal, -1 otherwise. 01809 */ 01810 static int x509_string_cmp( const mbedtls_x509_buf *a, const mbedtls_x509_buf *b ) 01811 { 01812 if( a->tag == b->tag && 01813 a->len == b->len && 01814 memcmp( a->p, b->p, b->len ) == 0 ) 01815 { 01816 return( 0 ); 01817 } 01818 01819 if( ( a->tag == MBEDTLS_ASN1_UTF8_STRING || a->tag == MBEDTLS_ASN1_PRINTABLE_STRING ) && 01820 ( b->tag == MBEDTLS_ASN1_UTF8_STRING || b->tag == MBEDTLS_ASN1_PRINTABLE_STRING ) && 01821 a->len == b->len && 01822 x509_memcasecmp( a->p, b->p, b->len ) == 0 ) 01823 { 01824 return( 0 ); 01825 } 01826 01827 return( -1 ); 01828 } 01829 01830 /* 01831 * Compare two X.509 Names (aka rdnSequence). 01832 * 01833 * See RFC 5280 section 7.1, though we don't implement the whole algorithm: 01834 * we sometimes return unequal when the full algorithm would return equal, 01835 * but never the other way. (In particular, we don't do Unicode normalisation 01836 * or space folding.) 01837 * 01838 * Return 0 if equal, -1 otherwise. 01839 */ 01840 static int x509_name_cmp( const mbedtls_x509_name *a, const mbedtls_x509_name *b ) 01841 { 01842 /* Avoid recursion, it might not be optimised by the compiler */ 01843 while( a != NULL || b != NULL ) 01844 { 01845 if( a == NULL || b == NULL ) 01846 return( -1 ); 01847 01848 /* type */ 01849 if( a->oid.tag != b->oid.tag || 01850 a->oid.len != b->oid.len || 01851 memcmp( a->oid.p, b->oid.p, b->oid.len ) != 0 ) 01852 { 01853 return( -1 ); 01854 } 01855 01856 /* value */ 01857 if( x509_string_cmp( &a->val, &b->val ) != 0 ) 01858 return( -1 ); 01859 01860 /* structure of the list of sets */ 01861 if( a->next_merged != b->next_merged ) 01862 return( -1 ); 01863 01864 a = a->next; 01865 b = b->next; 01866 } 01867 01868 /* a == NULL == b */ 01869 return( 0 ); 01870 } 01871 01872 /* 01873 * Check the signature of a certificate by its parent 01874 */ 01875 static int x509_crt_check_signature( const mbedtls_x509_crt *child, 01876 mbedtls_x509_crt *parent ) 01877 { 01878 const mbedtls_md_info_t *md_info; 01879 unsigned char hash[MBEDTLS_MD_MAX_SIZE]; 01880 01881 md_info = mbedtls_md_info_from_type( child->sig_md ); 01882 if( mbedtls_md( md_info, child->tbs.p, child->tbs.len, hash ) != 0 ) 01883 { 01884 /* Note: this can't happen except after an internal error */ 01885 return( -1 ); 01886 } 01887 01888 if( mbedtls_pk_verify_ext( child->sig_pk, child->sig_opts, &parent->pk, 01889 child->sig_md, hash, mbedtls_md_get_size( md_info ), 01890 child->sig.p, child->sig.len ) != 0 ) 01891 { 01892 return( -1 ); 01893 } 01894 01895 return( 0 ); 01896 } 01897 01898 /* 01899 * Check if 'parent' is a suitable parent (signing CA) for 'child'. 01900 * Return 0 if yes, -1 if not. 01901 * 01902 * top means parent is a locally-trusted certificate 01903 */ 01904 static int x509_crt_check_parent( const mbedtls_x509_crt *child, 01905 const mbedtls_x509_crt *parent, 01906 int top ) 01907 { 01908 int need_ca_bit; 01909 01910 /* Parent must be the issuer */ 01911 if( x509_name_cmp( &child->issuer, &parent->subject ) != 0 ) 01912 return( -1 ); 01913 01914 /* Parent must have the basicConstraints CA bit set as a general rule */ 01915 need_ca_bit = 1; 01916 01917 /* Exception: v1/v2 certificates that are locally trusted. */ 01918 if( top && parent->version < 3 ) 01919 need_ca_bit = 0; 01920 01921 if( need_ca_bit && ! parent->ca_istrue ) 01922 return( -1 ); 01923 01924 #if defined(MBEDTLS_X509_CHECK_KEY_USAGE) 01925 if( need_ca_bit && 01926 mbedtls_x509_crt_check_key_usage( parent, MBEDTLS_X509_KU_KEY_CERT_SIGN ) != 0 ) 01927 { 01928 return( -1 ); 01929 } 01930 #endif 01931 01932 return( 0 ); 01933 } 01934 01935 /* 01936 * Find a suitable parent for child in candidates, or return NULL. 01937 * 01938 * Here suitable is defined as: 01939 * 1. subject name matches child's issuer 01940 * 2. if necessary, the CA bit is set and key usage allows signing certs 01941 * 3. for trusted roots, the signature is correct 01942 * 4. pathlen constraints are satisfied 01943 * 01944 * If there's a suitable candidate which is also time-valid, return the first 01945 * such. Otherwise, return the first suitable candidate (or NULL if there is 01946 * none). 01947 * 01948 * The rationale for this rule is that someone could have a list of trusted 01949 * roots with two versions on the same root with different validity periods. 01950 * (At least one user reported having such a list and wanted it to just work.) 01951 * The reason we don't just require time-validity is that generally there is 01952 * only one version, and if it's expired we want the flags to state that 01953 * rather than NOT_TRUSTED, as would be the case if we required it here. 01954 * 01955 * The rationale for rule 3 (signature for trusted roots) is that users might 01956 * have two versions of the same CA with different keys in their list, and the 01957 * way we select the correct one is by checking the signature (as we don't 01958 * rely on key identifier extensions). (This is one way users might choose to 01959 * handle key rollover, another relies on self-issued certs, see [SIRO].) 01960 * 01961 * Arguments: 01962 * - [in] child: certificate for which we're looking for a parent 01963 * - [in] candidates: chained list of potential parents 01964 * - [in] top: 1 if candidates consists of trusted roots, ie we're at the top 01965 * of the chain, 0 otherwise 01966 * - [in] path_cnt: number of intermediates seen so far 01967 * - [in] self_cnt: number of self-signed intermediates seen so far 01968 * (will never be greater than path_cnt) 01969 * 01970 * Return value: 01971 * - the first suitable parent found (see above regarding time-validity) 01972 * - NULL if no suitable parent was found 01973 */ 01974 static mbedtls_x509_crt *x509_crt_find_parent_in( mbedtls_x509_crt *child, 01975 mbedtls_x509_crt *candidates, 01976 int top, 01977 size_t path_cnt, 01978 size_t self_cnt ) 01979 { 01980 mbedtls_x509_crt *parent, *badtime_parent = NULL; 01981 01982 for( parent = candidates; parent != NULL; parent = parent->next ) 01983 { 01984 /* basic parenting skills (name, CA bit, key usage) */ 01985 if( x509_crt_check_parent( child, parent, top ) != 0 ) 01986 continue; 01987 01988 /* +1 because stored max_pathlen is 1 higher that the actual value */ 01989 if( parent->max_pathlen > 0 && 01990 (size_t) parent->max_pathlen < 1 + path_cnt - self_cnt ) 01991 { 01992 continue; 01993 } 01994 01995 /* Signature */ 01996 if( top && x509_crt_check_signature( child, parent ) != 0 ) 01997 { 01998 continue; 01999 } 02000 02001 /* optional time check */ 02002 if( mbedtls_x509_time_is_past( &parent->valid_to ) || 02003 mbedtls_x509_time_is_future( &parent->valid_from ) ) 02004 { 02005 if( badtime_parent == NULL ) 02006 badtime_parent = parent; 02007 02008 continue; 02009 } 02010 02011 break; 02012 } 02013 02014 if( parent == NULL ) 02015 parent = badtime_parent; 02016 02017 return( parent ); 02018 } 02019 02020 /* 02021 * Find a parent in trusted CAs or the provided chain, or return NULL. 02022 * 02023 * Searches in trusted CAs first, and return the first suitable parent found 02024 * (see find_parent_in() for definition of suitable). 02025 * 02026 * Arguments: 02027 * - [in] child: certificate for which we're looking for a parent, followed 02028 * by a chain of possible intermediates 02029 * - [in] trust_ca: locally trusted CAs 02030 * - [out] 1 if parent was found in trust_ca, 0 if found in provided chain 02031 * - [in] path_cnt: number of intermediates seen so far 02032 * - [in] self_cnt: number of self-signed intermediates seen so far 02033 * (will always be no greater than path_cnt) 02034 * 02035 * Return value: 02036 * - the first suitable parent found (see find_parent_in() for "suitable") 02037 * - NULL if no suitable parent was found 02038 */ 02039 static mbedtls_x509_crt *x509_crt_find_parent( mbedtls_x509_crt *child, 02040 mbedtls_x509_crt *trust_ca, 02041 int *parent_is_trusted, 02042 size_t path_cnt, 02043 size_t self_cnt ) 02044 { 02045 mbedtls_x509_crt *parent; 02046 02047 /* Look for a parent in trusted CAs */ 02048 *parent_is_trusted = 1; 02049 parent = x509_crt_find_parent_in( child, trust_ca, 1, path_cnt, self_cnt ); 02050 02051 if( parent != NULL ) 02052 return( parent ); 02053 02054 /* Look for a parent upwards the chain */ 02055 *parent_is_trusted = 0; 02056 return( x509_crt_find_parent_in( child, child->next, 0, path_cnt, self_cnt ) ); 02057 } 02058 02059 /* 02060 * Check if an end-entity certificate is locally trusted 02061 * 02062 * Currently we require such certificates to be self-signed (actually only 02063 * check for self-issued as self-signatures are not checked) 02064 */ 02065 static int x509_crt_check_ee_locally_trusted( 02066 mbedtls_x509_crt *crt, 02067 mbedtls_x509_crt *trust_ca ) 02068 { 02069 mbedtls_x509_crt *cur; 02070 02071 /* must be self-issued */ 02072 if( x509_name_cmp( &crt->issuer, &crt->subject ) != 0 ) 02073 return( -1 ); 02074 02075 /* look for an exact match with trusted cert */ 02076 for( cur = trust_ca; cur != NULL; cur = cur->next ) 02077 { 02078 if( crt->raw.len == cur->raw.len && 02079 memcmp( crt->raw.p, cur->raw.p, crt->raw.len ) == 0 ) 02080 { 02081 return( 0 ); 02082 } 02083 } 02084 02085 /* too bad */ 02086 return( -1 ); 02087 } 02088 02089 /* 02090 * Build and verify a certificate chain 02091 * 02092 * Given a peer-provided list of certificates EE, C1, ..., Cn and 02093 * a list of trusted certs R1, ... Rp, try to build and verify a chain 02094 * EE, Ci1, ... Ciq [, Rj] 02095 * such that every cert in the chain is a child of the next one, 02096 * jumping to a trusted root as early as possible. 02097 * 02098 * Verify that chain and return it with flags for all issues found. 02099 * 02100 * Special cases: 02101 * - EE == Rj -> return a one-element list containing it 02102 * - EE, Ci1, ..., Ciq cannot be continued with a trusted root 02103 * -> return that chain with NOT_TRUSTED set on Ciq 02104 * 02105 * Arguments: 02106 * - [in] crt: the cert list EE, C1, ..., Cn 02107 * - [in] trust_ca: the trusted list R1, ..., Rp 02108 * - [in] ca_crl, profile: as in verify_with_profile() 02109 * - [out] ver_chain, chain_len: the built and verified chain 02110 * 02111 * Return value: 02112 * - non-zero if the chain could not be fully built and examined 02113 * - 0 is the chain was successfully built and examined, 02114 * even if it was found to be invalid 02115 */ 02116 static int x509_crt_verify_chain( 02117 mbedtls_x509_crt *crt, 02118 mbedtls_x509_crt *trust_ca, 02119 mbedtls_x509_crl *ca_crl, 02120 const mbedtls_x509_crt_profile *profile, 02121 x509_crt_verify_chain_item ver_chain[X509_MAX_VERIFY_CHAIN_SIZE], 02122 size_t *chain_len ) 02123 { 02124 uint32_t *flags; 02125 mbedtls_x509_crt *child; 02126 mbedtls_x509_crt *parent; 02127 int parent_is_trusted = 0; 02128 int child_is_trusted = 0; 02129 size_t self_cnt = 0; 02130 02131 child = crt; 02132 *chain_len = 0; 02133 02134 while( 1 ) { 02135 /* Add certificate to the verification chain */ 02136 ver_chain[*chain_len].crt = child; 02137 flags = &ver_chain[*chain_len].flags; 02138 ++*chain_len; 02139 02140 /* Check time-validity (all certificates) */ 02141 if( mbedtls_x509_time_is_past( &child->valid_to ) ) 02142 *flags |= MBEDTLS_X509_BADCERT_EXPIRED; 02143 02144 if( mbedtls_x509_time_is_future( &child->valid_from ) ) 02145 *flags |= MBEDTLS_X509_BADCERT_FUTURE; 02146 02147 /* Stop here for trusted roots (but not for trusted EE certs) */ 02148 if( child_is_trusted ) 02149 return( 0 ); 02150 02151 /* Check signature algorithm: MD & PK algs */ 02152 if( x509_profile_check_md_alg( profile, child->sig_md ) != 0 ) 02153 *flags |= MBEDTLS_X509_BADCERT_BAD_MD; 02154 02155 if( x509_profile_check_pk_alg( profile, child->sig_pk ) != 0 ) 02156 *flags |= MBEDTLS_X509_BADCERT_BAD_PK; 02157 02158 /* Special case: EE certs that are locally trusted */ 02159 if( *chain_len == 1 && 02160 x509_crt_check_ee_locally_trusted( child, trust_ca ) == 0 ) 02161 { 02162 return( 0 ); 02163 } 02164 02165 /* Look for a parent in trusted CAs or up the chain */ 02166 parent = x509_crt_find_parent( child, trust_ca, &parent_is_trusted, 02167 *chain_len - 1, self_cnt ); 02168 02169 /* No parent? We're done here */ 02170 if( parent == NULL ) 02171 { 02172 *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED; 02173 return( 0 ); 02174 } 02175 02176 /* Count intermediate self-issued (not necessarily self-signed) certs. 02177 * These can occur with some strategies for key rollover, see [SIRO], 02178 * and should be excluded from max_pathlen checks. */ 02179 if( *chain_len != 1 && 02180 x509_name_cmp( &child->issuer, &child->subject ) == 0 ) 02181 { 02182 self_cnt++; 02183 } 02184 02185 /* path_cnt is 0 for the first intermediate CA, 02186 * and if parent is trusted it's not an intermediate CA */ 02187 if( ! parent_is_trusted && 02188 *chain_len > MBEDTLS_X509_MAX_INTERMEDIATE_CA ) 02189 { 02190 /* return immediately to avoid overflow the chain array */ 02191 return( MBEDTLS_ERR_X509_FATAL_ERROR ); 02192 } 02193 02194 /* if parent is trusted, the signature was checked by find_parent() */ 02195 if( ! parent_is_trusted && x509_crt_check_signature( child, parent ) != 0 ) 02196 *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED; 02197 02198 /* check size of signing key */ 02199 if( x509_profile_check_key( profile, &parent->pk ) != 0 ) 02200 *flags |= MBEDTLS_X509_BADCERT_BAD_KEY; 02201 02202 #if defined(MBEDTLS_X509_CRL_PARSE_C) 02203 /* Check trusted CA's CRL for the given crt */ 02204 *flags |= x509_crt_verifycrl( child, parent, ca_crl, profile ); 02205 #else 02206 (void) ca_crl; 02207 #endif 02208 02209 /* prepare for next iteration */ 02210 child = parent; 02211 parent = NULL; 02212 child_is_trusted = parent_is_trusted; 02213 } 02214 } 02215 02216 /* 02217 * Check for CN match 02218 */ 02219 static int x509_crt_check_cn( const mbedtls_x509_buf *name, 02220 const char *cn, size_t cn_len ) 02221 { 02222 /* try exact match */ 02223 if( name->len == cn_len && 02224 x509_memcasecmp( cn, name->p, cn_len ) == 0 ) 02225 { 02226 return( 0 ); 02227 } 02228 02229 /* try wildcard match */ 02230 if( x509_check_wildcard( cn, name ) == 0 ) 02231 { 02232 return( 0 ); 02233 } 02234 02235 return( -1 ); 02236 } 02237 02238 /* 02239 * Verify the requested CN - only call this if cn is not NULL! 02240 */ 02241 static void x509_crt_verify_name( const mbedtls_x509_crt *crt, 02242 const char *cn, 02243 uint32_t *flags ) 02244 { 02245 const mbedtls_x509_name *name; 02246 const mbedtls_x509_sequence *cur; 02247 size_t cn_len = strlen( cn ); 02248 02249 if( crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME ) 02250 { 02251 for( cur = &crt->subject_alt_names; cur != NULL; cur = cur->next ) 02252 { 02253 if( x509_crt_check_cn( &cur->buf, cn, cn_len ) == 0 ) 02254 break; 02255 } 02256 02257 if( cur == NULL ) 02258 *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; 02259 } 02260 else 02261 { 02262 for( name = &crt->subject; name != NULL; name = name->next ) 02263 { 02264 if( MBEDTLS_OID_CMP( MBEDTLS_OID_AT_CN, &name->oid ) == 0 && 02265 x509_crt_check_cn( &name->val, cn, cn_len ) == 0 ) 02266 { 02267 break; 02268 } 02269 } 02270 02271 if( name == NULL ) 02272 *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; 02273 } 02274 } 02275 02276 /* 02277 * Merge the flags for all certs in the chain, after calling callback 02278 */ 02279 static int x509_crt_merge_flags_with_cb( 02280 uint32_t *flags, 02281 x509_crt_verify_chain_item ver_chain[X509_MAX_VERIFY_CHAIN_SIZE], 02282 size_t chain_len, 02283 int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), 02284 void *p_vrfy ) 02285 { 02286 int ret; 02287 size_t i; 02288 uint32_t cur_flags; 02289 02290 for( i = chain_len; i != 0; --i ) 02291 { 02292 cur_flags = ver_chain[i-1].flags; 02293 02294 if( NULL != f_vrfy ) 02295 if( ( ret = f_vrfy( p_vrfy, ver_chain[i-1].crt, (int) i-1, &cur_flags ) ) != 0 ) 02296 return( ret ); 02297 02298 *flags |= cur_flags; 02299 } 02300 02301 return( 0 ); 02302 } 02303 02304 /* 02305 * Verify the certificate validity 02306 */ 02307 int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt, 02308 mbedtls_x509_crt *trust_ca, 02309 mbedtls_x509_crl *ca_crl, 02310 const char *cn, uint32_t *flags, 02311 int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), 02312 void *p_vrfy ) 02313 { 02314 return( mbedtls_x509_crt_verify_with_profile( crt, trust_ca, ca_crl, 02315 &mbedtls_x509_crt_profile_default, cn, flags, f_vrfy, p_vrfy ) ); 02316 } 02317 02318 /* 02319 * Verify the certificate validity, with profile 02320 * 02321 * This function: 02322 * - checks the requested CN (if any) 02323 * - checks the type and size of the EE cert's key, 02324 * as that isn't done as part of chain building/verification currently 02325 * - builds and verifies the chain 02326 * - then calls the callback and merges the flags 02327 */ 02328 int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt, 02329 mbedtls_x509_crt *trust_ca, 02330 mbedtls_x509_crl *ca_crl, 02331 const mbedtls_x509_crt_profile *profile, 02332 const char *cn, uint32_t *flags, 02333 int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), 02334 void *p_vrfy ) 02335 { 02336 int ret; 02337 mbedtls_pk_type_t pk_type; 02338 x509_crt_verify_chain_item ver_chain[X509_MAX_VERIFY_CHAIN_SIZE]; 02339 size_t chain_len; 02340 uint32_t *ee_flags = &ver_chain[0].flags; 02341 02342 *flags = 0; 02343 memset( ver_chain, 0, sizeof( ver_chain ) ); 02344 chain_len = 0; 02345 02346 if( profile == NULL ) 02347 { 02348 ret = MBEDTLS_ERR_X509_BAD_INPUT_DATA; 02349 goto exit; 02350 } 02351 02352 /* check name if requested */ 02353 if( cn != NULL ) 02354 x509_crt_verify_name( crt, cn, ee_flags ); 02355 02356 /* Check the type and size of the key */ 02357 pk_type = mbedtls_pk_get_type( &crt->pk ); 02358 02359 if( x509_profile_check_pk_alg( profile, pk_type ) != 0 ) 02360 *ee_flags |= MBEDTLS_X509_BADCERT_BAD_PK; 02361 02362 if( x509_profile_check_key( profile, &crt->pk ) != 0 ) 02363 *ee_flags |= MBEDTLS_X509_BADCERT_BAD_KEY; 02364 02365 /* Check the chain */ 02366 ret = x509_crt_verify_chain( crt, trust_ca, ca_crl, profile, 02367 ver_chain, &chain_len ); 02368 if( ret != 0 ) 02369 goto exit; 02370 02371 /* Build final flags, calling callback on the way if any */ 02372 ret = x509_crt_merge_flags_with_cb( flags, 02373 ver_chain, chain_len, f_vrfy, p_vrfy ); 02374 02375 exit: 02376 /* prevent misuse of the vrfy callback - VERIFY_FAILED would be ignored by 02377 * the SSL module for authmode optional, but non-zero return from the 02378 * callback means a fatal error so it shouldn't be ignored */ 02379 if( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ) 02380 ret = MBEDTLS_ERR_X509_FATAL_ERROR; 02381 02382 if( ret != 0 ) 02383 { 02384 *flags = (uint32_t) -1; 02385 return( ret ); 02386 } 02387 02388 if( *flags != 0 ) 02389 return( MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ); 02390 02391 return( 0 ); 02392 } 02393 02394 /* 02395 * Initialize a certificate chain 02396 */ 02397 void mbedtls_x509_crt_init( mbedtls_x509_crt *crt ) 02398 { 02399 memset( crt, 0, sizeof(mbedtls_x509_crt) ); 02400 } 02401 02402 /* 02403 * Unallocate all certificate data 02404 */ 02405 void mbedtls_x509_crt_free( mbedtls_x509_crt *crt ) 02406 { 02407 mbedtls_x509_crt *cert_cur = crt; 02408 mbedtls_x509_crt *cert_prv; 02409 mbedtls_x509_name *name_cur; 02410 mbedtls_x509_name *name_prv; 02411 mbedtls_x509_sequence *seq_cur; 02412 mbedtls_x509_sequence *seq_prv; 02413 02414 if( crt == NULL ) 02415 return; 02416 02417 do 02418 { 02419 mbedtls_pk_free( &cert_cur->pk ); 02420 02421 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) 02422 mbedtls_free( cert_cur->sig_opts ); 02423 #endif 02424 02425 name_cur = cert_cur->issuer.next; 02426 while( name_cur != NULL ) 02427 { 02428 name_prv = name_cur; 02429 name_cur = name_cur->next; 02430 mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) ); 02431 mbedtls_free( name_prv ); 02432 } 02433 02434 name_cur = cert_cur->subject.next; 02435 while( name_cur != NULL ) 02436 { 02437 name_prv = name_cur; 02438 name_cur = name_cur->next; 02439 mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) ); 02440 mbedtls_free( name_prv ); 02441 } 02442 02443 seq_cur = cert_cur->ext_key_usage.next; 02444 while( seq_cur != NULL ) 02445 { 02446 seq_prv = seq_cur; 02447 seq_cur = seq_cur->next; 02448 mbedtls_platform_zeroize( seq_prv, 02449 sizeof( mbedtls_x509_sequence ) ); 02450 mbedtls_free( seq_prv ); 02451 } 02452 02453 seq_cur = cert_cur->subject_alt_names.next; 02454 while( seq_cur != NULL ) 02455 { 02456 seq_prv = seq_cur; 02457 seq_cur = seq_cur->next; 02458 mbedtls_platform_zeroize( seq_prv, 02459 sizeof( mbedtls_x509_sequence ) ); 02460 mbedtls_free( seq_prv ); 02461 } 02462 02463 if( cert_cur->raw.p != NULL ) 02464 { 02465 mbedtls_platform_zeroize( cert_cur->raw.p, cert_cur->raw.len ); 02466 mbedtls_free( cert_cur->raw.p ); 02467 } 02468 02469 cert_cur = cert_cur->next; 02470 } 02471 while( cert_cur != NULL ); 02472 02473 cert_cur = crt; 02474 do 02475 { 02476 cert_prv = cert_cur; 02477 cert_cur = cert_cur->next; 02478 02479 mbedtls_platform_zeroize( cert_prv, sizeof( mbedtls_x509_crt ) ); 02480 if( cert_prv != crt ) 02481 mbedtls_free( cert_prv ); 02482 } 02483 while( cert_cur != NULL ); 02484 } 02485 02486 #endif /* MBEDTLS_X509_CRT_PARSE_C */
Generated on Tue Aug 9 2022 00:37:25 by
1.7.2