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