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