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