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