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