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