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