This Trac instance is not used for development anymore!

We migrated our development workflow to git and Gitea.
To test the future redirection, replace trac by ariadne in the page URL.

source: ps/trunk/build/premake/premake5/contrib/mbedtls/library/x509_crt.c

Last change on this file was 20366, checked in by Itms, 7 years ago

Alpha 12 version of Premake 5, including prebuilt binary for Windows.
Directly taken from https://premake.github.io/.

Refs #3729.

File size: 67.9 KB
Line 
1/*
2 * X.509 certificate parsing and verification
3 *
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * This file is part of mbed TLS (https://tls.mbed.org)
20 */
21/*
22 * The ITU-T X.509 standard defines a certificate format for PKI.
23 *
24 * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
25 * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
26 * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
27 *
28 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
29 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
30 */
31
32#if !defined(MBEDTLS_CONFIG_FILE)
33#include "mbedtls/config.h"
34#else
35#include MBEDTLS_CONFIG_FILE
36#endif
37
38#if defined(MBEDTLS_X509_CRT_PARSE_C)
39
40#include "mbedtls/x509_crt.h"
41#include "mbedtls/oid.h"
42
43#include <stdio.h>
44#include <string.h>
45
46#if defined(MBEDTLS_PEM_PARSE_C)
47#include "mbedtls/pem.h"
48#endif
49
50#if defined(MBEDTLS_PLATFORM_C)
51#include "mbedtls/platform.h"
52#else
53#include <stdlib.h>
54#define mbedtls_free free
55#define mbedtls_calloc calloc
56#define mbedtls_snprintf snprintf
57#endif
58
59#if defined(MBEDTLS_THREADING_C)
60#include "mbedtls/threading.h"
61#endif
62
63#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
64#include <windows.h>
65#else
66#include <time.h>
67#endif
68
69#if defined(MBEDTLS_FS_IO)
70#include <stdio.h>
71#if !defined(_WIN32) || defined(EFIX64) || defined(EFI32)
72#include <sys/types.h>
73#include <sys/stat.h>
74#include <dirent.h>
75#endif /* !_WIN32 || EFIX64 || EFI32 */
76#endif
77
78/* Implementation that should never be optimized out by the compiler */
79static void mbedtls_zeroize( void *v, size_t n ) {
80 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
81}
82
83/*
84 * Default profile
85 */
86const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default =
87{
88 /* Hashes from SHA-1 and above */
89 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 ) |
90 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_RIPEMD160 ) |
91 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224 ) |
92 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
93 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) |
94 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ),
95 0xFFFFFFF, /* Any PK alg */
96 0xFFFFFFF, /* Any curve */
97 2048,
98};
99
100/*
101 * Next-default profile
102 */
103const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_next =
104{
105 /* Hashes from SHA-256 and above */
106 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
107 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) |
108 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ),
109 0xFFFFFFF, /* Any PK alg */
110#if defined(MBEDTLS_ECP_C)
111 /* Curves at or above 128-bit security level */
112 MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) |
113 MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ) |
114 MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP521R1 ) |
115 MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP256R1 ) |
116 MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP384R1 ) |
117 MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP512R1 ) |
118 MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256K1 ),
119#else
120 0,
121#endif
122 2048,
123};
124
125/*
126 * NSA Suite B Profile
127 */
128const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb =
129{
130 /* Only SHA-256 and 384 */
131 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) |
132 MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ),
133 /* Only ECDSA */
134 MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECDSA ),
135#if defined(MBEDTLS_ECP_C)
136 /* Only NIST P-256 and P-384 */
137 MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) |
138 MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ),
139#else
140 0,
141#endif
142 0,
143};
144
145/*
146 * Check md_alg against profile
147 * Return 0 if md_alg acceptable for this profile, -1 otherwise
148 */
149static int x509_profile_check_md_alg( const mbedtls_x509_crt_profile *profile,
150 mbedtls_md_type_t md_alg )
151{
152 if( ( profile->allowed_mds & MBEDTLS_X509_ID_FLAG( md_alg ) ) != 0 )
153 return( 0 );
154
155 return( -1 );
156}
157
158/*
159 * Check pk_alg against profile
160 * Return 0 if pk_alg acceptable for this profile, -1 otherwise
161 */
162static int x509_profile_check_pk_alg( const mbedtls_x509_crt_profile *profile,
163 mbedtls_pk_type_t pk_alg )
164{
165 if( ( profile->allowed_pks & MBEDTLS_X509_ID_FLAG( pk_alg ) ) != 0 )
166 return( 0 );
167
168 return( -1 );
169}
170
171/*
172 * Check key against profile
173 * Return 0 if pk_alg acceptable for this profile, -1 otherwise
174 */
175static int x509_profile_check_key( const mbedtls_x509_crt_profile *profile,
176 mbedtls_pk_type_t pk_alg,
177 const mbedtls_pk_context *pk )
178{
179#if defined(MBEDTLS_RSA_C)
180 if( pk_alg == MBEDTLS_PK_RSA || pk_alg == MBEDTLS_PK_RSASSA_PSS )
181 {
182 if( mbedtls_pk_get_bitlen( pk ) >= profile->rsa_min_bitlen )
183 return( 0 );
184
185 return( -1 );
186 }
187#endif
188
189#if defined(MBEDTLS_ECP_C)
190 if( pk_alg == MBEDTLS_PK_ECDSA ||
191 pk_alg == MBEDTLS_PK_ECKEY ||
192 pk_alg == MBEDTLS_PK_ECKEY_DH )
193 {
194 mbedtls_ecp_group_id gid = mbedtls_pk_ec( *pk )->grp.id;
195
196 if( ( profile->allowed_curves & MBEDTLS_X509_ID_FLAG( gid ) ) != 0 )
197 return( 0 );
198
199 return( -1 );
200 }
201#endif
202
203 return( -1 );
204}
205
206/*
207 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
208 */
209static int x509_get_version( unsigned char **p,
210 const unsigned char *end,
211 int *ver )
212{
213 int ret;
214 size_t len;
215
216 if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
217 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) != 0 )
218 {
219 if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
220 {
221 *ver = 0;
222 return( 0 );
223 }
224
225 return( ret );
226 }
227
228 end = *p + len;
229
230 if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 )
231 return( MBEDTLS_ERR_X509_INVALID_VERSION + ret );
232
233 if( *p != end )
234 return( MBEDTLS_ERR_X509_INVALID_VERSION +
235 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
236
237 return( 0 );
238}
239
240/*
241 * Validity ::= SEQUENCE {
242 * notBefore Time,
243 * notAfter Time }
244 */
245static int x509_get_dates( unsigned char **p,
246 const unsigned char *end,
247 mbedtls_x509_time *from,
248 mbedtls_x509_time *to )
249{
250 int ret;
251 size_t len;
252
253 if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
254 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
255 return( MBEDTLS_ERR_X509_INVALID_DATE + ret );
256
257 end = *p + len;
258
259 if( ( ret = mbedtls_x509_get_time( p, end, from ) ) != 0 )
260 return( ret );
261
262 if( ( ret = mbedtls_x509_get_time( p, end, to ) ) != 0 )
263 return( ret );
264
265 if( *p != end )
266 return( MBEDTLS_ERR_X509_INVALID_DATE +
267 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
268
269 return( 0 );
270}
271
272/*
273 * X.509 v2/v3 unique identifier (not parsed)
274 */
275static int x509_get_uid( unsigned char **p,
276 const unsigned char *end,
277 mbedtls_x509_buf *uid, int n )
278{
279 int ret;
280
281 if( *p == end )
282 return( 0 );
283
284 uid->tag = **p;
285
286 if( ( ret = mbedtls_asn1_get_tag( p, end, &uid->len,
287 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | n ) ) != 0 )
288 {
289 if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
290 return( 0 );
291
292 return( ret );
293 }
294
295 uid->p = *p;
296 *p += uid->len;
297
298 return( 0 );
299}
300
301static int x509_get_basic_constraints( unsigned char **p,
302 const unsigned char *end,
303 int *ca_istrue,
304 int *max_pathlen )
305{
306 int ret;
307 size_t len;
308
309 /*
310 * BasicConstraints ::= SEQUENCE {
311 * cA BOOLEAN DEFAULT FALSE,
312 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
313 */
314 *ca_istrue = 0; /* DEFAULT FALSE */
315 *max_pathlen = 0; /* endless */
316
317 if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
318 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
319 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
320
321 if( *p == end )
322 return( 0 );
323
324 if( ( ret = mbedtls_asn1_get_bool( p, end, ca_istrue ) ) != 0 )
325 {
326 if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
327 ret = mbedtls_asn1_get_int( p, end, ca_istrue );
328
329 if( ret != 0 )
330 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
331
332 if( *ca_istrue != 0 )
333 *ca_istrue = 1;
334 }
335
336 if( *p == end )
337 return( 0 );
338
339 if( ( ret = mbedtls_asn1_get_int( p, end, max_pathlen ) ) != 0 )
340 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
341
342 if( *p != end )
343 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
344 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
345
346 (*max_pathlen)++;
347
348 return( 0 );
349}
350
351static int x509_get_ns_cert_type( unsigned char **p,
352 const unsigned char *end,
353 unsigned char *ns_cert_type)
354{
355 int ret;
356 mbedtls_x509_bitstring bs = { 0, 0, NULL };
357
358 if( ( ret = mbedtls_asn1_get_bitstring( p, end, &bs ) ) != 0 )
359 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
360
361 if( bs.len != 1 )
362 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
363 MBEDTLS_ERR_ASN1_INVALID_LENGTH );
364
365 /* Get actual bitstring */
366 *ns_cert_type = *bs.p;
367 return( 0 );
368}
369
370static int x509_get_key_usage( unsigned char **p,
371 const unsigned char *end,
372 unsigned int *key_usage)
373{
374 int ret;
375 size_t i;
376 mbedtls_x509_bitstring bs = { 0, 0, NULL };
377
378 if( ( ret = mbedtls_asn1_get_bitstring( p, end, &bs ) ) != 0 )
379 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
380
381 if( bs.len < 1 )
382 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
383 MBEDTLS_ERR_ASN1_INVALID_LENGTH );
384
385 /* Get actual bitstring */
386 *key_usage = 0;
387 for( i = 0; i < bs.len && i < sizeof( unsigned int ); i++ )
388 {
389 *key_usage |= (unsigned int) bs.p[i] << (8*i);
390 }
391
392 return( 0 );
393}
394
395/*
396 * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
397 *
398 * KeyPurposeId ::= OBJECT IDENTIFIER
399 */
400static int x509_get_ext_key_usage( unsigned char **p,
401 const unsigned char *end,
402 mbedtls_x509_sequence *ext_key_usage)
403{
404 int ret;
405
406 if( ( ret = mbedtls_asn1_get_sequence_of( p, end, ext_key_usage, MBEDTLS_ASN1_OID ) ) != 0 )
407 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
408
409 /* Sequence length must be >= 1 */
410 if( ext_key_usage->buf.p == NULL )
411 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
412 MBEDTLS_ERR_ASN1_INVALID_LENGTH );
413
414 return( 0 );
415}
416
417/*
418 * SubjectAltName ::= GeneralNames
419 *
420 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
421 *
422 * GeneralName ::= CHOICE {
423 * otherName [0] OtherName,
424 * rfc822Name [1] IA5String,
425 * dNSName [2] IA5String,
426 * x400Address [3] ORAddress,
427 * directoryName [4] Name,
428 * ediPartyName [5] EDIPartyName,
429 * uniformResourceIdentifier [6] IA5String,
430 * iPAddress [7] OCTET STRING,
431 * registeredID [8] OBJECT IDENTIFIER }
432 *
433 * OtherName ::= SEQUENCE {
434 * type-id OBJECT IDENTIFIER,
435 * value [0] EXPLICIT ANY DEFINED BY type-id }
436 *
437 * EDIPartyName ::= SEQUENCE {
438 * nameAssigner [0] DirectoryString OPTIONAL,
439 * partyName [1] DirectoryString }
440 *
441 * NOTE: we only parse and use dNSName at this point.
442 */
443static int x509_get_subject_alt_name( unsigned char **p,
444 const unsigned char *end,
445 mbedtls_x509_sequence *subject_alt_name )
446{
447 int ret;
448 size_t len, tag_len;
449 mbedtls_asn1_buf *buf;
450 unsigned char tag;
451 mbedtls_asn1_sequence *cur = subject_alt_name;
452
453 /* Get main sequence tag */
454 if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
455 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
456 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
457
458 if( *p + len != end )
459 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
460 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
461
462 while( *p < end )
463 {
464 if( ( end - *p ) < 1 )
465 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
466 MBEDTLS_ERR_ASN1_OUT_OF_DATA );
467
468 tag = **p;
469 (*p)++;
470 if( ( ret = mbedtls_asn1_get_len( p, end, &tag_len ) ) != 0 )
471 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
472
473 if( ( tag & MBEDTLS_ASN1_CONTEXT_SPECIFIC ) != MBEDTLS_ASN1_CONTEXT_SPECIFIC )
474 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
475 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
476
477 /* Skip everything but DNS name */
478 if( tag != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | 2 ) )
479 {
480 *p += tag_len;
481 continue;
482 }
483
484 /* Allocate and assign next pointer */
485 if( cur->buf.p != NULL )
486 {
487 if( cur->next != NULL )
488 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS );
489
490 cur->next = mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence ) );
491
492 if( cur->next == NULL )
493 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
494 MBEDTLS_ERR_ASN1_ALLOC_FAILED );
495
496 cur = cur->next;
497 }
498
499 buf = &(cur->buf);
500 buf->tag = tag;
501 buf->p = *p;
502 buf->len = tag_len;
503 *p += buf->len;
504 }
505
506 /* Set final sequence entry's next pointer to NULL */
507 cur->next = NULL;
508
509 if( *p != end )
510 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
511 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
512
513 return( 0 );
514}
515
516/*
517 * X.509 v3 extensions
518 *
519 * TODO: Perform all of the basic constraints tests required by the RFC
520 * TODO: Set values for undetected extensions to a sane default?
521 *
522 */
523static int x509_get_crt_ext( unsigned char **p,
524 const unsigned char *end,
525 mbedtls_x509_crt *crt )
526{
527 int ret;
528 size_t len;
529 unsigned char *end_ext_data, *end_ext_octet;
530
531 if( ( ret = mbedtls_x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 )
532 {
533 if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
534 return( 0 );
535
536 return( ret );
537 }
538
539 while( *p < end )
540 {
541 /*
542 * Extension ::= SEQUENCE {
543 * extnID OBJECT IDENTIFIER,
544 * critical BOOLEAN DEFAULT FALSE,
545 * extnValue OCTET STRING }
546 */
547 mbedtls_x509_buf extn_oid = {0, 0, NULL};
548 int is_critical = 0; /* DEFAULT FALSE */
549 int ext_type = 0;
550
551 if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
552 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
553 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
554
555 end_ext_data = *p + len;
556
557 /* Get extension ID */
558 extn_oid.tag = **p;
559
560 if( ( ret = mbedtls_asn1_get_tag( p, end, &extn_oid.len, MBEDTLS_ASN1_OID ) ) != 0 )
561 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
562
563 extn_oid.p = *p;
564 *p += extn_oid.len;
565
566 if( ( end - *p ) < 1 )
567 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
568 MBEDTLS_ERR_ASN1_OUT_OF_DATA );
569
570 /* Get optional critical */
571 if( ( ret = mbedtls_asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
572 ( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) )
573 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
574
575 /* Data should be octet string type */
576 if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &len,
577 MBEDTLS_ASN1_OCTET_STRING ) ) != 0 )
578 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
579
580 end_ext_octet = *p + len;
581
582 if( end_ext_octet != end_ext_data )
583 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
584 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
585
586 /*
587 * Detect supported extensions
588 */
589 ret = mbedtls_oid_get_x509_ext_type( &extn_oid, &ext_type );
590
591 if( ret != 0 )
592 {
593 /* No parser found, skip extension */
594 *p = end_ext_octet;
595
596#if !defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
597 if( is_critical )
598 {
599 /* Data is marked as critical: fail */
600 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
601 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
602 }
603#endif
604 continue;
605 }
606
607 /* Forbid repeated extensions */
608 if( ( crt->ext_types & ext_type ) != 0 )
609 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS );
610
611 crt->ext_types |= ext_type;
612
613 switch( ext_type )
614 {
615 case MBEDTLS_X509_EXT_BASIC_CONSTRAINTS:
616 /* Parse basic constraints */
617 if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
618 &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
619 return( ret );
620 break;
621
622 case MBEDTLS_X509_EXT_KEY_USAGE:
623 /* Parse key usage */
624 if( ( ret = x509_get_key_usage( p, end_ext_octet,
625 &crt->key_usage ) ) != 0 )
626 return( ret );
627 break;
628
629 case MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE:
630 /* Parse extended key usage */
631 if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
632 &crt->ext_key_usage ) ) != 0 )
633 return( ret );
634 break;
635
636 case MBEDTLS_X509_EXT_SUBJECT_ALT_NAME:
637 /* Parse subject alt name */
638 if( ( ret = x509_get_subject_alt_name( p, end_ext_octet,
639 &crt->subject_alt_names ) ) != 0 )
640 return( ret );
641 break;
642
643 case MBEDTLS_X509_EXT_NS_CERT_TYPE:
644 /* Parse netscape certificate type */
645 if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
646 &crt->ns_cert_type ) ) != 0 )
647 return( ret );
648 break;
649
650 default:
651 return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE );
652 }
653 }
654
655 if( *p != end )
656 return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
657 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
658
659 return( 0 );
660}
661
662/*
663 * Parse and fill a single X.509 certificate in DER format
664 */
665static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *buf,
666 size_t buflen )
667{
668 int ret;
669 size_t len;
670 unsigned char *p, *end, *crt_end;
671 mbedtls_x509_buf sig_params1, sig_params2, sig_oid2;
672
673 memset( &sig_params1, 0, sizeof( mbedtls_x509_buf ) );
674 memset( &sig_params2, 0, sizeof( mbedtls_x509_buf ) );
675 memset( &sig_oid2, 0, sizeof( mbedtls_x509_buf ) );
676
677 /*
678 * Check for valid input
679 */
680 if( crt == NULL || buf == NULL )
681 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
682
683 p = mbedtls_calloc( 1, len = buflen );
684 if( p == NULL )
685 return( MBEDTLS_ERR_X509_ALLOC_FAILED );
686
687 memcpy( p, buf, buflen );
688
689 crt->raw.p = p;
690 crt->raw.len = len;
691 end = p + len;
692
693 /*
694 * Certificate ::= SEQUENCE {
695 * tbsCertificate TBSCertificate,
696 * signatureAlgorithm AlgorithmIdentifier,
697 * signatureValue BIT STRING }
698 */
699 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
700 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
701 {
702 mbedtls_x509_crt_free( crt );
703 return( MBEDTLS_ERR_X509_INVALID_FORMAT );
704 }
705
706 if( len > (size_t) ( end - p ) )
707 {
708 mbedtls_x509_crt_free( crt );
709 return( MBEDTLS_ERR_X509_INVALID_FORMAT +
710 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
711 }
712 crt_end = p + len;
713
714 /*
715 * TBSCertificate ::= SEQUENCE {
716 */
717 crt->tbs.p = p;
718
719 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
720 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
721 {
722 mbedtls_x509_crt_free( crt );
723 return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
724 }
725
726 end = p + len;
727 crt->tbs.len = end - crt->tbs.p;
728
729 /*
730 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
731 *
732 * CertificateSerialNumber ::= INTEGER
733 *
734 * signature AlgorithmIdentifier
735 */
736 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
737 ( ret = mbedtls_x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
738 ( ret = mbedtls_x509_get_alg( &p, end, &crt->sig_oid,
739 &sig_params1 ) ) != 0 )
740 {
741 mbedtls_x509_crt_free( crt );
742 return( ret );
743 }
744
745 crt->version++;
746
747 if( crt->version > 3 )
748 {
749 mbedtls_x509_crt_free( crt );
750 return( MBEDTLS_ERR_X509_UNKNOWN_VERSION );
751 }
752
753 if( ( ret = mbedtls_x509_get_sig_alg( &crt->sig_oid, &sig_params1,
754 &crt->sig_md, &crt->sig_pk,
755 &crt->sig_opts ) ) != 0 )
756 {
757 mbedtls_x509_crt_free( crt );
758 return( ret );
759 }
760
761 /*
762 * issuer Name
763 */
764 crt->issuer_raw.p = p;
765
766 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
767 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
768 {
769 mbedtls_x509_crt_free( crt );
770 return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
771 }
772
773 if( ( ret = mbedtls_x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
774 {
775 mbedtls_x509_crt_free( crt );
776 return( ret );
777 }
778
779 crt->issuer_raw.len = p - crt->issuer_raw.p;
780
781 /*
782 * Validity ::= SEQUENCE {
783 * notBefore Time,
784 * notAfter Time }
785 *
786 */
787 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
788 &crt->valid_to ) ) != 0 )
789 {
790 mbedtls_x509_crt_free( crt );
791 return( ret );
792 }
793
794 /*
795 * subject Name
796 */
797 crt->subject_raw.p = p;
798
799 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
800 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
801 {
802 mbedtls_x509_crt_free( crt );
803 return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret );
804 }
805
806 if( len && ( ret = mbedtls_x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
807 {
808 mbedtls_x509_crt_free( crt );
809 return( ret );
810 }
811
812 crt->subject_raw.len = p - crt->subject_raw.p;
813
814 /*
815 * SubjectPublicKeyInfo
816 */
817 if( ( ret = mbedtls_pk_parse_subpubkey( &p, end, &crt->pk ) ) != 0 )
818 {
819 mbedtls_x509_crt_free( crt );
820 return( ret );
821 }
822
823 /*
824 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
825 * -- If present, version shall be v2 or v3
826 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
827 * -- If present, version shall be v2 or v3
828 * extensions [3] EXPLICIT Extensions OPTIONAL
829 * -- If present, version shall be v3
830 */
831 if( crt->version == 2 || crt->version == 3 )
832 {
833 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
834 if( ret != 0 )
835 {
836 mbedtls_x509_crt_free( crt );
837 return( ret );
838 }
839 }
840
841 if( crt->version == 2 || crt->version == 3 )
842 {
843 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
844 if( ret != 0 )
845 {
846 mbedtls_x509_crt_free( crt );
847 return( ret );
848 }
849 }
850
851#if !defined(MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3)
852 if( crt->version == 3 )
853#endif
854 {
855 ret = x509_get_crt_ext( &p, end, crt );
856 if( ret != 0 )
857 {
858 mbedtls_x509_crt_free( crt );
859 return( ret );
860 }
861 }
862
863 if( p != end )
864 {
865 mbedtls_x509_crt_free( crt );
866 return( MBEDTLS_ERR_X509_INVALID_FORMAT +
867 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
868 }
869
870 end = crt_end;
871
872 /*
873 * }
874 * -- end of TBSCertificate
875 *
876 * signatureAlgorithm AlgorithmIdentifier,
877 * signatureValue BIT STRING
878 */
879 if( ( ret = mbedtls_x509_get_alg( &p, end, &sig_oid2, &sig_params2 ) ) != 0 )
880 {
881 mbedtls_x509_crt_free( crt );
882 return( ret );
883 }
884
885 if( crt->sig_oid.len != sig_oid2.len ||
886 memcmp( crt->sig_oid.p, sig_oid2.p, crt->sig_oid.len ) != 0 ||
887 sig_params1.len != sig_params2.len ||
888 ( sig_params1.len != 0 &&
889 memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) )
890 {
891 mbedtls_x509_crt_free( crt );
892 return( MBEDTLS_ERR_X509_SIG_MISMATCH );
893 }
894
895 if( ( ret = mbedtls_x509_get_sig( &p, end, &crt->sig ) ) != 0 )
896 {
897 mbedtls_x509_crt_free( crt );
898 return( ret );
899 }
900
901 if( p != end )
902 {
903 mbedtls_x509_crt_free( crt );
904 return( MBEDTLS_ERR_X509_INVALID_FORMAT +
905 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
906 }
907
908 return( 0 );
909}
910
911/*
912 * Parse one X.509 certificate in DER format from a buffer and add them to a
913 * chained list
914 */
915int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, const unsigned char *buf,
916 size_t buflen )
917{
918 int ret;
919 mbedtls_x509_crt *crt = chain, *prev = NULL;
920
921 /*
922 * Check for valid input
923 */
924 if( crt == NULL || buf == NULL )
925 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
926
927 while( crt->version != 0 && crt->next != NULL )
928 {
929 prev = crt;
930 crt = crt->next;
931 }
932
933 /*
934 * Add new certificate on the end of the chain if needed.
935 */
936 if( crt->version != 0 && crt->next == NULL )
937 {
938 crt->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) );
939
940 if( crt->next == NULL )
941 return( MBEDTLS_ERR_X509_ALLOC_FAILED );
942
943 prev = crt;
944 mbedtls_x509_crt_init( crt->next );
945 crt = crt->next;
946 }
947
948 if( ( ret = x509_crt_parse_der_core( crt, buf, buflen ) ) != 0 )
949 {
950 if( prev )
951 prev->next = NULL;
952
953 if( crt != chain )
954 mbedtls_free( crt );
955
956 return( ret );
957 }
958
959 return( 0 );
960}
961
962/*
963 * Parse one or more PEM certificates from a buffer and add them to the chained
964 * list
965 */
966int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, size_t buflen )
967{
968 int success = 0, first_error = 0, total_failed = 0;
969 int buf_format = MBEDTLS_X509_FORMAT_DER;
970
971 /*
972 * Check for valid input
973 */
974 if( chain == NULL || buf == NULL )
975 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
976
977 /*
978 * Determine buffer content. Buffer contains either one DER certificate or
979 * one or more PEM certificates.
980 */
981#if defined(MBEDTLS_PEM_PARSE_C)
982 if( buflen != 0 && buf[buflen - 1] == '\0' &&
983 strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL )
984 {
985 buf_format = MBEDTLS_X509_FORMAT_PEM;
986 }
987#endif
988
989 if( buf_format == MBEDTLS_X509_FORMAT_DER )
990 return mbedtls_x509_crt_parse_der( chain, buf, buflen );
991
992#if defined(MBEDTLS_PEM_PARSE_C)
993 if( buf_format == MBEDTLS_X509_FORMAT_PEM )
994 {
995 int ret;
996 mbedtls_pem_context pem;
997
998 /* 1 rather than 0 since the terminating NULL byte is counted in */
999 while( buflen > 1 )
1000 {
1001 size_t use_len;
1002 mbedtls_pem_init( &pem );
1003
1004 /* If we get there, we know the string is null-terminated */
1005 ret = mbedtls_pem_read_buffer( &pem,
1006 "-----BEGIN CERTIFICATE-----",
1007 "-----END CERTIFICATE-----",
1008 buf, NULL, 0, &use_len );
1009
1010 if( ret == 0 )
1011 {
1012 /*
1013 * Was PEM encoded
1014 */
1015 buflen -= use_len;
1016 buf += use_len;
1017 }
1018 else if( ret == MBEDTLS_ERR_PEM_BAD_INPUT_DATA )
1019 {
1020 return( ret );
1021 }
1022 else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
1023 {
1024 mbedtls_pem_free( &pem );
1025
1026 /*
1027 * PEM header and footer were found
1028 */
1029 buflen -= use_len;
1030 buf += use_len;
1031
1032 if( first_error == 0 )
1033 first_error = ret;
1034
1035 total_failed++;
1036 continue;
1037 }
1038 else
1039 break;
1040
1041 ret = mbedtls_x509_crt_parse_der( chain, pem.buf, pem.buflen );
1042
1043 mbedtls_pem_free( &pem );
1044
1045 if( ret != 0 )
1046 {
1047 /*
1048 * Quit parsing on a memory error
1049 */
1050 if( ret == MBEDTLS_ERR_X509_ALLOC_FAILED )
1051 return( ret );
1052
1053 if( first_error == 0 )
1054 first_error = ret;
1055
1056 total_failed++;
1057 continue;
1058 }
1059
1060 success = 1;
1061 }
1062 }
1063#endif /* MBEDTLS_PEM_PARSE_C */
1064
1065 if( success )
1066 return( total_failed );
1067 else if( first_error )
1068 return( first_error );
1069 else
1070 return( MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT );
1071}
1072
1073#if defined(MBEDTLS_FS_IO)
1074/*
1075 * Load one or more certificates and add them to the chained list
1076 */
1077int mbedtls_x509_crt_parse_file( mbedtls_x509_crt *chain, const char *path )
1078{
1079 int ret;
1080 size_t n;
1081 unsigned char *buf;
1082
1083 if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
1084 return( ret );
1085
1086 ret = mbedtls_x509_crt_parse( chain, buf, n );
1087
1088 mbedtls_zeroize( buf, n );
1089 mbedtls_free( buf );
1090
1091 return( ret );
1092}
1093
1094int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path )
1095{
1096 int ret = 0;
1097#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
1098 int w_ret;
1099 WCHAR szDir[MAX_PATH];
1100 char filename[MAX_PATH];
1101 char *p;
1102 size_t len = strlen( path );
1103
1104 WIN32_FIND_DATAW file_data;
1105 HANDLE hFind;
1106
1107 if( len > MAX_PATH - 3 )
1108 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
1109
1110 memset( szDir, 0, sizeof(szDir) );
1111 memset( filename, 0, MAX_PATH );
1112 memcpy( filename, path, len );
1113 filename[len++] = '\\';
1114 p = filename + len;
1115 filename[len++] = '*';
1116
1117 w_ret = MultiByteToWideChar( CP_ACP, 0, filename, len, szDir,
1118 MAX_PATH - 3 );
1119 if( w_ret == 0 )
1120 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
1121
1122 hFind = FindFirstFileW( szDir, &file_data );
1123 if( hFind == INVALID_HANDLE_VALUE )
1124 return( MBEDTLS_ERR_X509_FILE_IO_ERROR );
1125
1126 len = MAX_PATH - len;
1127 do
1128 {
1129 memset( p, 0, len );
1130
1131 if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
1132 continue;
1133
1134 w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName,
1135 lstrlenW( file_data.cFileName ),
1136 p, (int) len - 1,
1137 NULL, NULL );
1138 if( w_ret == 0 )
1139 return( MBEDTLS_ERR_X509_FILE_IO_ERROR );
1140
1141 w_ret = mbedtls_x509_crt_parse_file( chain, filename );
1142 if( w_ret < 0 )
1143 ret++;
1144 else
1145 ret += w_ret;
1146 }
1147 while( FindNextFileW( hFind, &file_data ) != 0 );
1148
1149 if( GetLastError() != ERROR_NO_MORE_FILES )
1150 ret = MBEDTLS_ERR_X509_FILE_IO_ERROR;
1151
1152 FindClose( hFind );
1153#else /* _WIN32 */
1154 int t_ret;
1155 struct stat sb;
1156 struct dirent *entry;
1157 char entry_name[255];
1158 DIR *dir = opendir( path );
1159
1160 if( dir == NULL )
1161 return( MBEDTLS_ERR_X509_FILE_IO_ERROR );
1162
1163#if defined(MBEDTLS_THREADING_PTHREAD)
1164 if( ( ret = mbedtls_mutex_lock( &mbedtls_threading_readdir_mutex ) ) != 0 )
1165 {
1166 closedir( dir );
1167 return( ret );
1168 }
1169#endif
1170
1171 while( ( entry = readdir( dir ) ) != NULL )
1172 {
1173 mbedtls_snprintf( entry_name, sizeof entry_name, "%s/%s", path, entry->d_name );
1174
1175 if( stat( entry_name, &sb ) == -1 )
1176 {
1177 closedir( dir );
1178 ret = MBEDTLS_ERR_X509_FILE_IO_ERROR;
1179 goto cleanup;
1180 }
1181
1182 if( !S_ISREG( sb.st_mode ) )
1183 continue;
1184
1185 // Ignore parse errors
1186 //
1187 t_ret = mbedtls_x509_crt_parse_file( chain, entry_name );
1188 if( t_ret < 0 )
1189 ret++;
1190 else
1191 ret += t_ret;
1192 }
1193 closedir( dir );
1194
1195cleanup:
1196#if defined(MBEDTLS_THREADING_PTHREAD)
1197 if( mbedtls_mutex_unlock( &mbedtls_threading_readdir_mutex ) != 0 )
1198 ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR;
1199#endif
1200
1201#endif /* _WIN32 */
1202
1203 return( ret );
1204}
1205#endif /* MBEDTLS_FS_IO */
1206
1207static int x509_info_subject_alt_name( char **buf, size_t *size,
1208 const mbedtls_x509_sequence *subject_alt_name )
1209{
1210 size_t i;
1211 size_t n = *size;
1212 char *p = *buf;
1213 const mbedtls_x509_sequence *cur = subject_alt_name;
1214 const char *sep = "";
1215 size_t sep_len = 0;
1216
1217 while( cur != NULL )
1218 {
1219 if( cur->buf.len + sep_len >= n )
1220 {
1221 *p = '\0';
1222 return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL );
1223 }
1224
1225 n -= cur->buf.len + sep_len;
1226 for( i = 0; i < sep_len; i++ )
1227 *p++ = sep[i];
1228 for( i = 0; i < cur->buf.len; i++ )
1229 *p++ = cur->buf.p[i];
1230
1231 sep = ", ";
1232 sep_len = 2;
1233
1234 cur = cur->next;
1235 }
1236
1237 *p = '\0';
1238
1239 *size = n;
1240 *buf = p;
1241
1242 return( 0 );
1243}
1244
1245#define PRINT_ITEM(i) \
1246 { \
1247 ret = mbedtls_snprintf( p, n, "%s" i, sep ); \
1248 MBEDTLS_X509_SAFE_SNPRINTF; \
1249 sep = ", "; \
1250 }
1251
1252#define CERT_TYPE(type,name) \
1253 if( ns_cert_type & type ) \
1254 PRINT_ITEM( name );
1255
1256static int x509_info_cert_type( char **buf, size_t *size,
1257 unsigned char ns_cert_type )
1258{
1259 int ret;
1260 size_t n = *size;
1261 char *p = *buf;
1262 const char *sep = "";
1263
1264 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT, "SSL Client" );
1265 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER, "SSL Server" );
1266 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_EMAIL, "Email" );
1267 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING, "Object Signing" );
1268 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_RESERVED, "Reserved" );
1269 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_CA, "SSL CA" );
1270 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA, "Email CA" );
1271 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA, "Object Signing CA" );
1272
1273 *size = n;
1274 *buf = p;
1275
1276 return( 0 );
1277}
1278
1279#define KEY_USAGE(code,name) \
1280 if( key_usage & code ) \
1281 PRINT_ITEM( name );
1282
1283static int x509_info_key_usage( char **buf, size_t *size,
1284 unsigned int key_usage )
1285{
1286 int ret;
1287 size_t n = *size;
1288 char *p = *buf;
1289 const char *sep = "";
1290
1291 KEY_USAGE( MBEDTLS_X509_KU_DIGITAL_SIGNATURE, "Digital Signature" );
1292 KEY_USAGE( MBEDTLS_X509_KU_NON_REPUDIATION, "Non Repudiation" );
1293 KEY_USAGE( MBEDTLS_X509_KU_KEY_ENCIPHERMENT, "Key Encipherment" );
1294 KEY_USAGE( MBEDTLS_X509_KU_DATA_ENCIPHERMENT, "Data Encipherment" );
1295 KEY_USAGE( MBEDTLS_X509_KU_KEY_AGREEMENT, "Key Agreement" );
1296 KEY_USAGE( MBEDTLS_X509_KU_KEY_CERT_SIGN, "Key Cert Sign" );
1297 KEY_USAGE( MBEDTLS_X509_KU_CRL_SIGN, "CRL Sign" );
1298 KEY_USAGE( MBEDTLS_X509_KU_ENCIPHER_ONLY, "Encipher Only" );
1299 KEY_USAGE( MBEDTLS_X509_KU_DECIPHER_ONLY, "Decipher Only" );
1300
1301 *size = n;
1302 *buf = p;
1303
1304 return( 0 );
1305}
1306
1307static int x509_info_ext_key_usage( char **buf, size_t *size,
1308 const mbedtls_x509_sequence *extended_key_usage )
1309{
1310 int ret;
1311 const char *desc;
1312 size_t n = *size;
1313 char *p = *buf;
1314 const mbedtls_x509_sequence *cur = extended_key_usage;
1315 const char *sep = "";
1316
1317 while( cur != NULL )
1318 {
1319 if( mbedtls_oid_get_extended_key_usage( &cur->buf, &desc ) != 0 )
1320 desc = "???";
1321
1322 ret = mbedtls_snprintf( p, n, "%s%s", sep, desc );
1323 MBEDTLS_X509_SAFE_SNPRINTF;
1324
1325 sep = ", ";
1326
1327 cur = cur->next;
1328 }
1329
1330 *size = n;
1331 *buf = p;
1332
1333 return( 0 );
1334}
1335
1336/*
1337 * Return an informational string about the certificate.
1338 */
1339#define BEFORE_COLON 18
1340#define BC "18"
1341int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix,
1342 const mbedtls_x509_crt *crt )
1343{
1344 int ret;
1345 size_t n;
1346 char *p;
1347 char key_size_str[BEFORE_COLON];
1348
1349 p = buf;
1350 n = size;
1351
1352 ret = mbedtls_snprintf( p, n, "%scert. version : %d\n",
1353 prefix, crt->version );
1354 MBEDTLS_X509_SAFE_SNPRINTF;
1355 ret = mbedtls_snprintf( p, n, "%sserial number : ",
1356 prefix );
1357 MBEDTLS_X509_SAFE_SNPRINTF;
1358
1359 ret = mbedtls_x509_serial_gets( p, n, &crt->serial );
1360 MBEDTLS_X509_SAFE_SNPRINTF;
1361
1362 ret = mbedtls_snprintf( p, n, "\n%sissuer name : ", prefix );
1363 MBEDTLS_X509_SAFE_SNPRINTF;
1364 ret = mbedtls_x509_dn_gets( p, n, &crt->issuer );
1365 MBEDTLS_X509_SAFE_SNPRINTF;
1366
1367 ret = mbedtls_snprintf( p, n, "\n%ssubject name : ", prefix );
1368 MBEDTLS_X509_SAFE_SNPRINTF;
1369 ret = mbedtls_x509_dn_gets( p, n, &crt->subject );
1370 MBEDTLS_X509_SAFE_SNPRINTF;
1371
1372 ret = mbedtls_snprintf( p, n, "\n%sissued on : " \
1373 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
1374 crt->valid_from.year, crt->valid_from.mon,
1375 crt->valid_from.day, crt->valid_from.hour,
1376 crt->valid_from.min, crt->valid_from.sec );
1377 MBEDTLS_X509_SAFE_SNPRINTF;
1378
1379 ret = mbedtls_snprintf( p, n, "\n%sexpires on : " \
1380 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
1381 crt->valid_to.year, crt->valid_to.mon,
1382 crt->valid_to.day, crt->valid_to.hour,
1383 crt->valid_to.min, crt->valid_to.sec );
1384 MBEDTLS_X509_SAFE_SNPRINTF;
1385
1386 ret = mbedtls_snprintf( p, n, "\n%ssigned using : ", prefix );
1387 MBEDTLS_X509_SAFE_SNPRINTF;
1388
1389 ret = mbedtls_x509_sig_alg_gets( p, n, &crt->sig_oid, crt->sig_pk,
1390 crt->sig_md, crt->sig_opts );
1391 MBEDTLS_X509_SAFE_SNPRINTF;
1392
1393 /* Key size */
1394 if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON,
1395 mbedtls_pk_get_name( &crt->pk ) ) ) != 0 )
1396 {
1397 return( ret );
1398 }
1399
1400 ret = mbedtls_snprintf( p, n, "\n%s%-" BC "s: %d bits", prefix, key_size_str,
1401 (int) mbedtls_pk_get_bitlen( &crt->pk ) );
1402 MBEDTLS_X509_SAFE_SNPRINTF;
1403
1404 /*
1405 * Optional extensions
1406 */
1407
1408 if( crt->ext_types & MBEDTLS_X509_EXT_BASIC_CONSTRAINTS )
1409 {
1410 ret = mbedtls_snprintf( p, n, "\n%sbasic constraints : CA=%s", prefix,
1411 crt->ca_istrue ? "true" : "false" );
1412 MBEDTLS_X509_SAFE_SNPRINTF;
1413
1414 if( crt->max_pathlen > 0 )
1415 {
1416 ret = mbedtls_snprintf( p, n, ", max_pathlen=%d", crt->max_pathlen - 1 );
1417 MBEDTLS_X509_SAFE_SNPRINTF;
1418 }
1419 }
1420
1421 if( crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME )
1422 {
1423 ret = mbedtls_snprintf( p, n, "\n%ssubject alt name : ", prefix );
1424 MBEDTLS_X509_SAFE_SNPRINTF;
1425
1426 if( ( ret = x509_info_subject_alt_name( &p, &n,
1427 &crt->subject_alt_names ) ) != 0 )
1428 return( ret );
1429 }
1430
1431 if( crt->ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE )
1432 {
1433 ret = mbedtls_snprintf( p, n, "\n%scert. type : ", prefix );
1434 MBEDTLS_X509_SAFE_SNPRINTF;
1435
1436 if( ( ret = x509_info_cert_type( &p, &n, crt->ns_cert_type ) ) != 0 )
1437 return( ret );
1438 }
1439
1440 if( crt->ext_types & MBEDTLS_X509_EXT_KEY_USAGE )
1441 {
1442 ret = mbedtls_snprintf( p, n, "\n%skey usage : ", prefix );
1443 MBEDTLS_X509_SAFE_SNPRINTF;
1444
1445 if( ( ret = x509_info_key_usage( &p, &n, crt->key_usage ) ) != 0 )
1446 return( ret );
1447 }
1448
1449 if( crt->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE )
1450 {
1451 ret = mbedtls_snprintf( p, n, "\n%sext key usage : ", prefix );
1452 MBEDTLS_X509_SAFE_SNPRINTF;
1453
1454 if( ( ret = x509_info_ext_key_usage( &p, &n,
1455 &crt->ext_key_usage ) ) != 0 )
1456 return( ret );
1457 }
1458
1459 ret = mbedtls_snprintf( p, n, "\n" );
1460 MBEDTLS_X509_SAFE_SNPRINTF;
1461
1462 return( (int) ( size - n ) );
1463}
1464
1465struct x509_crt_verify_string {
1466 int code;
1467 const char *string;
1468};
1469
1470static const struct x509_crt_verify_string x509_crt_verify_strings[] = {
1471 { MBEDTLS_X509_BADCERT_EXPIRED, "The certificate validity has expired" },
1472 { MBEDTLS_X509_BADCERT_REVOKED, "The certificate has been revoked (is on a CRL)" },
1473 { MBEDTLS_X509_BADCERT_CN_MISMATCH, "The certificate Common Name (CN) does not match with the expected CN" },
1474 { MBEDTLS_X509_BADCERT_NOT_TRUSTED, "The certificate is not correctly signed by the trusted CA" },
1475 { MBEDTLS_X509_BADCRL_NOT_TRUSTED, "The CRL is not correctly signed by the trusted CA" },
1476 { MBEDTLS_X509_BADCRL_EXPIRED, "The CRL is expired" },
1477 { MBEDTLS_X509_BADCERT_MISSING, "Certificate was missing" },
1478 { MBEDTLS_X509_BADCERT_SKIP_VERIFY, "Certificate verification was skipped" },
1479 { MBEDTLS_X509_BADCERT_OTHER, "Other reason (can be used by verify callback)" },
1480 { MBEDTLS_X509_BADCERT_FUTURE, "The certificate validity starts in the future" },
1481 { MBEDTLS_X509_BADCRL_FUTURE, "The CRL is from the future" },
1482 { MBEDTLS_X509_BADCERT_KEY_USAGE, "Usage does not match the keyUsage extension" },
1483 { MBEDTLS_X509_BADCERT_EXT_KEY_USAGE, "Usage does not match the extendedKeyUsage extension" },
1484 { MBEDTLS_X509_BADCERT_NS_CERT_TYPE, "Usage does not match the nsCertType extension" },
1485 { MBEDTLS_X509_BADCERT_BAD_MD, "The certificate is signed with an unacceptable hash." },
1486 { MBEDTLS_X509_BADCERT_BAD_PK, "The certificate is signed with an unacceptable PK alg (eg RSA vs ECDSA)." },
1487 { MBEDTLS_X509_BADCERT_BAD_KEY, "The certificate is signed with an unacceptable key (eg bad curve, RSA too short)." },
1488 { MBEDTLS_X509_BADCRL_BAD_MD, "The CRL is signed with an unacceptable hash." },
1489 { MBEDTLS_X509_BADCRL_BAD_PK, "The CRL is signed with an unacceptable PK alg (eg RSA vs ECDSA)." },
1490 { MBEDTLS_X509_BADCRL_BAD_KEY, "The CRL is signed with an unacceptable key (eg bad curve, RSA too short)." },
1491 { 0, NULL }
1492};
1493
1494int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix,
1495 uint32_t flags )
1496{
1497 int ret;
1498 const struct x509_crt_verify_string *cur;
1499 char *p = buf;
1500 size_t n = size;
1501
1502 for( cur = x509_crt_verify_strings; cur->string != NULL ; cur++ )
1503 {
1504 if( ( flags & cur->code ) == 0 )
1505 continue;
1506
1507 ret = mbedtls_snprintf( p, n, "%s%s\n", prefix, cur->string );
1508 MBEDTLS_X509_SAFE_SNPRINTF;
1509 flags ^= cur->code;
1510 }
1511
1512 if( flags != 0 )
1513 {
1514 ret = mbedtls_snprintf( p, n, "%sUnknown reason "
1515 "(this should not happen)\n", prefix );
1516 MBEDTLS_X509_SAFE_SNPRINTF;
1517 }
1518
1519 return( (int) ( size - n ) );
1520}
1521
1522#if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
1523int mbedtls_x509_crt_check_key_usage( const mbedtls_x509_crt *crt,
1524 unsigned int usage )
1525{
1526 unsigned int usage_must, usage_may;
1527 unsigned int may_mask = MBEDTLS_X509_KU_ENCIPHER_ONLY
1528 | MBEDTLS_X509_KU_DECIPHER_ONLY;
1529
1530 if( ( crt->ext_types & MBEDTLS_X509_EXT_KEY_USAGE ) == 0 )
1531 return( 0 );
1532
1533 usage_must = usage & ~may_mask;
1534
1535 if( ( ( crt->key_usage & ~may_mask ) & usage_must ) != usage_must )
1536 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
1537
1538 usage_may = usage & may_mask;
1539
1540 if( ( ( crt->key_usage & may_mask ) | usage_may ) != usage_may )
1541 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
1542
1543 return( 0 );
1544}
1545#endif
1546
1547#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
1548int mbedtls_x509_crt_check_extended_key_usage( const mbedtls_x509_crt *crt,
1549 const char *usage_oid,
1550 size_t usage_len )
1551{
1552 const mbedtls_x509_sequence *cur;
1553
1554 /* Extension is not mandatory, absent means no restriction */
1555 if( ( crt->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE ) == 0 )
1556 return( 0 );
1557
1558 /*
1559 * Look for the requested usage (or wildcard ANY) in our list
1560 */
1561 for( cur = &crt->ext_key_usage; cur != NULL; cur = cur->next )
1562 {
1563 const mbedtls_x509_buf *cur_oid = &cur->buf;
1564
1565 if( cur_oid->len == usage_len &&
1566 memcmp( cur_oid->p, usage_oid, usage_len ) == 0 )
1567 {
1568 return( 0 );
1569 }
1570
1571 if( MBEDTLS_OID_CMP( MBEDTLS_OID_ANY_EXTENDED_KEY_USAGE, cur_oid ) == 0 )
1572 return( 0 );
1573 }
1574
1575 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
1576}
1577#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */
1578
1579#if defined(MBEDTLS_X509_CRL_PARSE_C)
1580/*
1581 * Return 1 if the certificate is revoked, or 0 otherwise.
1582 */
1583int mbedtls_x509_crt_is_revoked( const mbedtls_x509_crt *crt, const mbedtls_x509_crl *crl )
1584{
1585 const mbedtls_x509_crl_entry *cur = &crl->entry;
1586
1587 while( cur != NULL && cur->serial.len != 0 )
1588 {
1589 if( crt->serial.len == cur->serial.len &&
1590 memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
1591 {
1592 if( mbedtls_x509_time_is_past( &cur->revocation_date ) )
1593 return( 1 );
1594 }
1595
1596 cur = cur->next;
1597 }
1598
1599 return( 0 );
1600}
1601
1602/*
1603 * Check that the given certificate is valid according to the CRL.
1604 */
1605static int x509_crt_verifycrl( mbedtls_x509_crt *crt, mbedtls_x509_crt *ca,
1606 mbedtls_x509_crl *crl_list,
1607 const mbedtls_x509_crt_profile *profile )
1608{
1609 int flags = 0;
1610 unsigned char hash[MBEDTLS_MD_MAX_SIZE];
1611 const mbedtls_md_info_t *md_info;
1612
1613 if( ca == NULL )
1614 return( flags );
1615
1616 /*
1617 * TODO: What happens if no CRL is present?
1618 * Suggestion: Revocation state should be unknown if no CRL is present.
1619 * For backwards compatibility this is not yet implemented.
1620 */
1621
1622 while( crl_list != NULL )
1623 {
1624 if( crl_list->version == 0 ||
1625 crl_list->issuer_raw.len != ca->subject_raw.len ||
1626 memcmp( crl_list->issuer_raw.p, ca->subject_raw.p,
1627 crl_list->issuer_raw.len ) != 0 )
1628 {
1629 crl_list = crl_list->next;
1630 continue;
1631 }
1632
1633 /*
1634 * Check if the CA is configured to sign CRLs
1635 */
1636#if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
1637 if( mbedtls_x509_crt_check_key_usage( ca, MBEDTLS_X509_KU_CRL_SIGN ) != 0 )
1638 {
1639 flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
1640 break;
1641 }
1642#endif
1643
1644 /*
1645 * Check if CRL is correctly signed by the trusted CA
1646 */
1647 if( x509_profile_check_md_alg( profile, crl_list->sig_md ) != 0 )
1648 flags |= MBEDTLS_X509_BADCRL_BAD_MD;
1649
1650 if( x509_profile_check_pk_alg( profile, crl_list->sig_pk ) != 0 )
1651 flags |= MBEDTLS_X509_BADCRL_BAD_PK;
1652
1653 md_info = mbedtls_md_info_from_type( crl_list->sig_md );
1654 if( md_info == NULL )
1655 {
1656 /*
1657 * Cannot check 'unknown' hash
1658 */
1659 flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
1660 break;
1661 }
1662
1663 mbedtls_md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash );
1664
1665 if( x509_profile_check_key( profile, crl_list->sig_pk, &ca->pk ) != 0 )
1666 flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
1667
1668 if( mbedtls_pk_verify_ext( crl_list->sig_pk, crl_list->sig_opts, &ca->pk,
1669 crl_list->sig_md, hash, mbedtls_md_get_size( md_info ),
1670 crl_list->sig.p, crl_list->sig.len ) != 0 )
1671 {
1672 flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED;
1673 break;
1674 }
1675
1676 /*
1677 * Check for validity of CRL (Do not drop out)
1678 */
1679 if( mbedtls_x509_time_is_past( &crl_list->next_update ) )
1680 flags |= MBEDTLS_X509_BADCRL_EXPIRED;
1681
1682 if( mbedtls_x509_time_is_future( &crl_list->this_update ) )
1683 flags |= MBEDTLS_X509_BADCRL_FUTURE;
1684
1685 /*
1686 * Check if certificate is revoked
1687 */
1688 if( mbedtls_x509_crt_is_revoked( crt, crl_list ) )
1689 {
1690 flags |= MBEDTLS_X509_BADCERT_REVOKED;
1691 break;
1692 }
1693
1694 crl_list = crl_list->next;
1695 }
1696
1697 return( flags );
1698}
1699#endif /* MBEDTLS_X509_CRL_PARSE_C */
1700
1701/*
1702 * Like memcmp, but case-insensitive and always returns -1 if different
1703 */
1704static int x509_memcasecmp( const void *s1, const void *s2, size_t len )
1705{
1706 size_t i;
1707 unsigned char diff;
1708 const unsigned char *n1 = s1, *n2 = s2;
1709
1710 for( i = 0; i < len; i++ )
1711 {
1712 diff = n1[i] ^ n2[i];
1713
1714 if( diff == 0 )
1715 continue;
1716
1717 if( diff == 32 &&
1718 ( ( n1[i] >= 'a' && n1[i] <= 'z' ) ||
1719 ( n1[i] >= 'A' && n1[i] <= 'Z' ) ) )
1720 {
1721 continue;
1722 }
1723
1724 return( -1 );
1725 }
1726
1727 return( 0 );
1728}
1729
1730/*
1731 * Return 0 if name matches wildcard, -1 otherwise
1732 */
1733static int x509_check_wildcard( const char *cn, mbedtls_x509_buf *name )
1734{
1735 size_t i;
1736 size_t cn_idx = 0, cn_len = strlen( cn );
1737
1738 if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' )
1739 return( 0 );
1740
1741 for( i = 0; i < cn_len; ++i )
1742 {
1743 if( cn[i] == '.' )
1744 {
1745 cn_idx = i;
1746 break;
1747 }
1748 }
1749
1750 if( cn_idx == 0 )
1751 return( -1 );
1752
1753 if( cn_len - cn_idx == name->len - 1 &&
1754 x509_memcasecmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
1755 {
1756 return( 0 );
1757 }
1758
1759 return( -1 );
1760}
1761
1762/*
1763 * Compare two X.509 strings, case-insensitive, and allowing for some encoding
1764 * variations (but not all).
1765 *
1766 * Return 0 if equal, -1 otherwise.
1767 */
1768static int x509_string_cmp( const mbedtls_x509_buf *a, const mbedtls_x509_buf *b )
1769{
1770 if( a->tag == b->tag &&
1771 a->len == b->len &&
1772 memcmp( a->p, b->p, b->len ) == 0 )
1773 {
1774 return( 0 );
1775 }
1776
1777 if( ( a->tag == MBEDTLS_ASN1_UTF8_STRING || a->tag == MBEDTLS_ASN1_PRINTABLE_STRING ) &&
1778 ( b->tag == MBEDTLS_ASN1_UTF8_STRING || b->tag == MBEDTLS_ASN1_PRINTABLE_STRING ) &&
1779 a->len == b->len &&
1780 x509_memcasecmp( a->p, b->p, b->len ) == 0 )
1781 {
1782 return( 0 );
1783 }
1784
1785 return( -1 );
1786}
1787
1788/*
1789 * Compare two X.509 Names (aka rdnSequence).
1790 *
1791 * See RFC 5280 section 7.1, though we don't implement the whole algorithm:
1792 * we sometimes return unequal when the full algorithm would return equal,
1793 * but never the other way. (In particular, we don't do Unicode normalisation
1794 * or space folding.)
1795 *
1796 * Return 0 if equal, -1 otherwise.
1797 */
1798static int x509_name_cmp( const mbedtls_x509_name *a, const mbedtls_x509_name *b )
1799{
1800 /* Avoid recursion, it might not be optimised by the compiler */
1801 while( a != NULL || b != NULL )
1802 {
1803 if( a == NULL || b == NULL )
1804 return( -1 );
1805
1806 /* type */
1807 if( a->oid.tag != b->oid.tag ||
1808 a->oid.len != b->oid.len ||
1809 memcmp( a->oid.p, b->oid.p, b->oid.len ) != 0 )
1810 {
1811 return( -1 );
1812 }
1813
1814 /* value */
1815 if( x509_string_cmp( &a->val, &b->val ) != 0 )
1816 return( -1 );
1817
1818 /* structure of the list of sets */
1819 if( a->next_merged != b->next_merged )
1820 return( -1 );
1821
1822 a = a->next;
1823 b = b->next;
1824 }
1825
1826 /* a == NULL == b */
1827 return( 0 );
1828}
1829
1830/*
1831 * Check if 'parent' is a suitable parent (signing CA) for 'child'.
1832 * Return 0 if yes, -1 if not.
1833 *
1834 * top means parent is a locally-trusted certificate
1835 * bottom means child is the end entity cert
1836 */
1837static int x509_crt_check_parent( const mbedtls_x509_crt *child,
1838 const mbedtls_x509_crt *parent,
1839 int top, int bottom )
1840{
1841 int need_ca_bit;
1842
1843 /* Parent must be the issuer */
1844 if( x509_name_cmp( &child->issuer, &parent->subject ) != 0 )
1845 return( -1 );
1846
1847 /* Parent must have the basicConstraints CA bit set as a general rule */
1848 need_ca_bit = 1;
1849
1850 /* Exception: v1/v2 certificates that are locally trusted. */
1851 if( top && parent->version < 3 )
1852 need_ca_bit = 0;
1853
1854 /* Exception: self-signed end-entity certs that are locally trusted. */
1855 if( top && bottom &&
1856 child->raw.len == parent->raw.len &&
1857 memcmp( child->raw.p, parent->raw.p, child->raw.len ) == 0 )
1858 {
1859 need_ca_bit = 0;
1860 }
1861
1862 if( need_ca_bit && ! parent->ca_istrue )
1863 return( -1 );
1864
1865#if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
1866 if( need_ca_bit &&
1867 mbedtls_x509_crt_check_key_usage( parent, MBEDTLS_X509_KU_KEY_CERT_SIGN ) != 0 )
1868 {
1869 return( -1 );
1870 }
1871#endif
1872
1873 return( 0 );
1874}
1875
1876static int x509_crt_verify_top(
1877 mbedtls_x509_crt *child, mbedtls_x509_crt *trust_ca,
1878 mbedtls_x509_crl *ca_crl,
1879 const mbedtls_x509_crt_profile *profile,
1880 int path_cnt, int self_cnt, uint32_t *flags,
1881 int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
1882 void *p_vrfy )
1883{
1884 int ret;
1885 uint32_t ca_flags = 0;
1886 int check_path_cnt;
1887 unsigned char hash[MBEDTLS_MD_MAX_SIZE];
1888 const mbedtls_md_info_t *md_info;
1889
1890 if( mbedtls_x509_time_is_past( &child->valid_to ) )
1891 *flags |= MBEDTLS_X509_BADCERT_EXPIRED;
1892
1893 if( mbedtls_x509_time_is_future( &child->valid_from ) )
1894 *flags |= MBEDTLS_X509_BADCERT_FUTURE;
1895
1896 if( x509_profile_check_md_alg( profile, child->sig_md ) != 0 )
1897 *flags |= MBEDTLS_X509_BADCERT_BAD_MD;
1898
1899 if( x509_profile_check_pk_alg( profile, child->sig_pk ) != 0 )
1900 *flags |= MBEDTLS_X509_BADCERT_BAD_PK;
1901
1902 /*
1903 * Child is the top of the chain. Check against the trust_ca list.
1904 */
1905 *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
1906
1907 md_info = mbedtls_md_info_from_type( child->sig_md );
1908 if( md_info == NULL )
1909 {
1910 /*
1911 * Cannot check 'unknown', no need to try any CA
1912 */
1913 trust_ca = NULL;
1914 }
1915 else
1916 mbedtls_md( md_info, child->tbs.p, child->tbs.len, hash );
1917
1918 for( /* trust_ca */ ; trust_ca != NULL; trust_ca = trust_ca->next )
1919 {
1920 if( x509_crt_check_parent( child, trust_ca, 1, path_cnt == 0 ) != 0 )
1921 continue;
1922
1923 check_path_cnt = path_cnt + 1;
1924
1925 /*
1926 * Reduce check_path_cnt to check against if top of the chain is
1927 * the same as the trusted CA
1928 */
1929 if( child->subject_raw.len == trust_ca->subject_raw.len &&
1930 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
1931 child->issuer_raw.len ) == 0 )
1932 {
1933 check_path_cnt--;
1934 }
1935
1936 /* Self signed certificates do not count towards the limit */
1937 if( trust_ca->max_pathlen > 0 &&
1938 trust_ca->max_pathlen < check_path_cnt - self_cnt )
1939 {
1940 continue;
1941 }
1942
1943 if( mbedtls_pk_verify_ext( child->sig_pk, child->sig_opts, &trust_ca->pk,
1944 child->sig_md, hash, mbedtls_md_get_size( md_info ),
1945 child->sig.p, child->sig.len ) != 0 )
1946 {
1947 continue;
1948 }
1949
1950 /*
1951 * Top of chain is signed by a trusted CA
1952 */
1953 *flags &= ~MBEDTLS_X509_BADCERT_NOT_TRUSTED;
1954
1955 if( x509_profile_check_key( profile, child->sig_pk, &trust_ca->pk ) != 0 )
1956 *flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
1957
1958 break;
1959 }
1960
1961 /*
1962 * If top of chain is not the same as the trusted CA send a verify request
1963 * to the callback for any issues with validity and CRL presence for the
1964 * trusted CA certificate.
1965 */
1966 if( trust_ca != NULL &&
1967 ( child->subject_raw.len != trust_ca->subject_raw.len ||
1968 memcmp( child->subject_raw.p, trust_ca->subject_raw.p,
1969 child->issuer_raw.len ) != 0 ) )
1970 {
1971#if defined(MBEDTLS_X509_CRL_PARSE_C)
1972 /* Check trusted CA's CRL for the chain's top crt */
1973 *flags |= x509_crt_verifycrl( child, trust_ca, ca_crl, profile );
1974#else
1975 ((void) ca_crl);
1976#endif
1977
1978 if( mbedtls_x509_time_is_past( &trust_ca->valid_to ) )
1979 ca_flags |= MBEDTLS_X509_BADCERT_EXPIRED;
1980
1981 if( mbedtls_x509_time_is_future( &trust_ca->valid_from ) )
1982 ca_flags |= MBEDTLS_X509_BADCERT_FUTURE;
1983
1984 if( NULL != f_vrfy )
1985 {
1986 if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1,
1987 &ca_flags ) ) != 0 )
1988 {
1989 return( ret );
1990 }
1991 }
1992 }
1993
1994 /* Call callback on top cert */
1995 if( NULL != f_vrfy )
1996 {
1997 if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
1998 return( ret );
1999 }
2000
2001 *flags |= ca_flags;
2002
2003 return( 0 );
2004}
2005
2006static int x509_crt_verify_child(
2007 mbedtls_x509_crt *child, mbedtls_x509_crt *parent,
2008 mbedtls_x509_crt *trust_ca, mbedtls_x509_crl *ca_crl,
2009 const mbedtls_x509_crt_profile *profile,
2010 int path_cnt, int self_cnt, uint32_t *flags,
2011 int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
2012 void *p_vrfy )
2013{
2014 int ret;
2015 uint32_t parent_flags = 0;
2016 unsigned char hash[MBEDTLS_MD_MAX_SIZE];
2017 mbedtls_x509_crt *grandparent;
2018 const mbedtls_md_info_t *md_info;
2019
2020 /* Counting intermediate self signed certificates */
2021 if( ( path_cnt != 0 ) && x509_name_cmp( &child->issuer, &child->subject ) == 0 )
2022 self_cnt++;
2023
2024 /* path_cnt is 0 for the first intermediate CA */
2025 if( 1 + path_cnt > MBEDTLS_X509_MAX_INTERMEDIATE_CA )
2026 {
2027 *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
2028 return( MBEDTLS_ERR_X509_CERT_VERIFY_FAILED );
2029 }
2030
2031 if( mbedtls_x509_time_is_past( &child->valid_to ) )
2032 *flags |= MBEDTLS_X509_BADCERT_EXPIRED;
2033
2034 if( mbedtls_x509_time_is_future( &child->valid_from ) )
2035 *flags |= MBEDTLS_X509_BADCERT_FUTURE;
2036
2037 if( x509_profile_check_md_alg( profile, child->sig_md ) != 0 )
2038 *flags |= MBEDTLS_X509_BADCERT_BAD_MD;
2039
2040 if( x509_profile_check_pk_alg( profile, child->sig_pk ) != 0 )
2041 *flags |= MBEDTLS_X509_BADCERT_BAD_PK;
2042
2043 md_info = mbedtls_md_info_from_type( child->sig_md );
2044 if( md_info == NULL )
2045 {
2046 /*
2047 * Cannot check 'unknown' hash
2048 */
2049 *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
2050 }
2051 else
2052 {
2053 mbedtls_md( md_info, child->tbs.p, child->tbs.len, hash );
2054
2055 if( x509_profile_check_key( profile, child->sig_pk, &parent->pk ) != 0 )
2056 *flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
2057
2058 if( mbedtls_pk_verify_ext( child->sig_pk, child->sig_opts, &parent->pk,
2059 child->sig_md, hash, mbedtls_md_get_size( md_info ),
2060 child->sig.p, child->sig.len ) != 0 )
2061 {
2062 *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED;
2063 }
2064 }
2065
2066#if defined(MBEDTLS_X509_CRL_PARSE_C)
2067 /* Check trusted CA's CRL for the given crt */
2068 *flags |= x509_crt_verifycrl(child, parent, ca_crl, profile );
2069#endif
2070
2071 /* Look for a grandparent in trusted CAs */
2072 for( grandparent = trust_ca;
2073 grandparent != NULL;
2074 grandparent = grandparent->next )
2075 {
2076 if( x509_crt_check_parent( parent, grandparent,
2077 0, path_cnt == 0 ) == 0 )
2078 break;
2079 }
2080
2081 if( grandparent != NULL )
2082 {
2083 ret = x509_crt_verify_top( parent, grandparent, ca_crl, profile,
2084 path_cnt + 1, self_cnt, &parent_flags, f_vrfy, p_vrfy );
2085 if( ret != 0 )
2086 return( ret );
2087 }
2088 else
2089 {
2090 /* Look for a grandparent upwards the chain */
2091 for( grandparent = parent->next;
2092 grandparent != NULL;
2093 grandparent = grandparent->next )
2094 {
2095 /* +2 because the current step is not yet accounted for
2096 * and because max_pathlen is one higher than it should be.
2097 * Also self signed certificates do not count to the limit. */
2098 if( grandparent->max_pathlen > 0 &&
2099 grandparent->max_pathlen < 2 + path_cnt - self_cnt )
2100 {
2101 continue;
2102 }
2103
2104 if( x509_crt_check_parent( parent, grandparent,
2105 0, path_cnt == 0 ) == 0 )
2106 break;
2107 }
2108
2109 /* Is our parent part of the chain or at the top? */
2110 if( grandparent != NULL )
2111 {
2112 ret = x509_crt_verify_child( parent, grandparent, trust_ca, ca_crl,
2113 profile, path_cnt + 1, self_cnt, &parent_flags,
2114 f_vrfy, p_vrfy );
2115 if( ret != 0 )
2116 return( ret );
2117 }
2118 else
2119 {
2120 ret = x509_crt_verify_top( parent, trust_ca, ca_crl, profile,
2121 path_cnt + 1, self_cnt, &parent_flags,
2122 f_vrfy, p_vrfy );
2123 if( ret != 0 )
2124 return( ret );
2125 }
2126 }
2127
2128 /* child is verified to be a child of the parent, call verify callback */
2129 if( NULL != f_vrfy )
2130 if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 )
2131 return( ret );
2132
2133 *flags |= parent_flags;
2134
2135 return( 0 );
2136}
2137
2138/*
2139 * Verify the certificate validity
2140 */
2141int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt,
2142 mbedtls_x509_crt *trust_ca,
2143 mbedtls_x509_crl *ca_crl,
2144 const char *cn, uint32_t *flags,
2145 int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
2146 void *p_vrfy )
2147{
2148 return( mbedtls_x509_crt_verify_with_profile( crt, trust_ca, ca_crl,
2149 &mbedtls_x509_crt_profile_default, cn, flags, f_vrfy, p_vrfy ) );
2150}
2151
2152
2153/*
2154 * Verify the certificate validity, with profile
2155 */
2156int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt,
2157 mbedtls_x509_crt *trust_ca,
2158 mbedtls_x509_crl *ca_crl,
2159 const mbedtls_x509_crt_profile *profile,
2160 const char *cn, uint32_t *flags,
2161 int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
2162 void *p_vrfy )
2163{
2164 size_t cn_len;
2165 int ret;
2166 int pathlen = 0, selfsigned = 0;
2167 mbedtls_x509_crt *parent;
2168 mbedtls_x509_name *name;
2169 mbedtls_x509_sequence *cur = NULL;
2170 mbedtls_pk_type_t pk_type;
2171
2172 if( profile == NULL )
2173 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
2174
2175 *flags = 0;
2176
2177 if( cn != NULL )
2178 {
2179 name = &crt->subject;
2180 cn_len = strlen( cn );
2181
2182 if( crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME )
2183 {
2184 cur = &crt->subject_alt_names;
2185
2186 while( cur != NULL )
2187 {
2188 if( cur->buf.len == cn_len &&
2189 x509_memcasecmp( cn, cur->buf.p, cn_len ) == 0 )
2190 break;
2191
2192 if( cur->buf.len > 2 &&
2193 memcmp( cur->buf.p, "*.", 2 ) == 0 &&
2194 x509_check_wildcard( cn, &cur->buf ) == 0 )
2195 {
2196 break;
2197 }
2198
2199 cur = cur->next;
2200 }
2201
2202 if( cur == NULL )
2203 *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH;
2204 }
2205 else
2206 {
2207 while( name != NULL )
2208 {
2209 if( MBEDTLS_OID_CMP( MBEDTLS_OID_AT_CN, &name->oid ) == 0 )
2210 {
2211 if( name->val.len == cn_len &&
2212 x509_memcasecmp( name->val.p, cn, cn_len ) == 0 )
2213 break;
2214
2215 if( name->val.len > 2 &&
2216 memcmp( name->val.p, "*.", 2 ) == 0 &&
2217 x509_check_wildcard( cn, &name->val ) == 0 )
2218 break;
2219 }
2220
2221 name = name->next;
2222 }
2223
2224 if( name == NULL )
2225 *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH;
2226 }
2227 }
2228
2229 /* Check the type and size of the key */
2230 pk_type = mbedtls_pk_get_type( &crt->pk );
2231
2232 if( x509_profile_check_pk_alg( profile, pk_type ) != 0 )
2233 *flags |= MBEDTLS_X509_BADCERT_BAD_PK;
2234
2235 if( x509_profile_check_key( profile, pk_type, &crt->pk ) != 0 )
2236 *flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
2237
2238 /* Look for a parent in trusted CAs */
2239 for( parent = trust_ca; parent != NULL; parent = parent->next )
2240 {
2241 if( x509_crt_check_parent( crt, parent, 0, pathlen == 0 ) == 0 )
2242 break;
2243 }
2244
2245 if( parent != NULL )
2246 {
2247 ret = x509_crt_verify_top( crt, parent, ca_crl, profile,
2248 pathlen, selfsigned, flags, f_vrfy, p_vrfy );
2249 if( ret != 0 )
2250 return( ret );
2251 }
2252 else
2253 {
2254 /* Look for a parent upwards the chain */
2255 for( parent = crt->next; parent != NULL; parent = parent->next )
2256 if( x509_crt_check_parent( crt, parent, 0, pathlen == 0 ) == 0 )
2257 break;
2258
2259 /* Are we part of the chain or at the top? */
2260 if( parent != NULL )
2261 {
2262 ret = x509_crt_verify_child( crt, parent, trust_ca, ca_crl, profile,
2263 pathlen, selfsigned, flags, f_vrfy, p_vrfy );
2264 if( ret != 0 )
2265 return( ret );
2266 }
2267 else
2268 {
2269 ret = x509_crt_verify_top( crt, trust_ca, ca_crl, profile,
2270 pathlen, selfsigned, flags, f_vrfy, p_vrfy );
2271 if( ret != 0 )
2272 return( ret );
2273 }
2274 }
2275
2276 if( *flags != 0 )
2277 return( MBEDTLS_ERR_X509_CERT_VERIFY_FAILED );
2278
2279 return( 0 );
2280}
2281
2282/*
2283 * Initialize a certificate chain
2284 */
2285void mbedtls_x509_crt_init( mbedtls_x509_crt *crt )
2286{
2287 memset( crt, 0, sizeof(mbedtls_x509_crt) );
2288}
2289
2290/*
2291 * Unallocate all certificate data
2292 */
2293void mbedtls_x509_crt_free( mbedtls_x509_crt *crt )
2294{
2295 mbedtls_x509_crt *cert_cur = crt;
2296 mbedtls_x509_crt *cert_prv;
2297 mbedtls_x509_name *name_cur;
2298 mbedtls_x509_name *name_prv;
2299 mbedtls_x509_sequence *seq_cur;
2300 mbedtls_x509_sequence *seq_prv;
2301
2302 if( crt == NULL )
2303 return;
2304
2305 do
2306 {
2307 mbedtls_pk_free( &cert_cur->pk );
2308
2309#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
2310 mbedtls_free( cert_cur->sig_opts );
2311#endif
2312
2313 name_cur = cert_cur->issuer.next;
2314 while( name_cur != NULL )
2315 {
2316 name_prv = name_cur;
2317 name_cur = name_cur->next;
2318 mbedtls_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
2319 mbedtls_free( name_prv );
2320 }
2321
2322 name_cur = cert_cur->subject.next;
2323 while( name_cur != NULL )
2324 {
2325 name_prv = name_cur;
2326 name_cur = name_cur->next;
2327 mbedtls_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
2328 mbedtls_free( name_prv );
2329 }
2330
2331 seq_cur = cert_cur->ext_key_usage.next;
2332 while( seq_cur != NULL )
2333 {
2334 seq_prv = seq_cur;
2335 seq_cur = seq_cur->next;
2336 mbedtls_zeroize( seq_prv, sizeof( mbedtls_x509_sequence ) );
2337 mbedtls_free( seq_prv );
2338 }
2339
2340 seq_cur = cert_cur->subject_alt_names.next;
2341 while( seq_cur != NULL )
2342 {
2343 seq_prv = seq_cur;
2344 seq_cur = seq_cur->next;
2345 mbedtls_zeroize( seq_prv, sizeof( mbedtls_x509_sequence ) );
2346 mbedtls_free( seq_prv );
2347 }
2348
2349 if( cert_cur->raw.p != NULL )
2350 {
2351 mbedtls_zeroize( cert_cur->raw.p, cert_cur->raw.len );
2352 mbedtls_free( cert_cur->raw.p );
2353 }
2354
2355 cert_cur = cert_cur->next;
2356 }
2357 while( cert_cur != NULL );
2358
2359 cert_cur = crt;
2360 do
2361 {
2362 cert_prv = cert_cur;
2363 cert_cur = cert_cur->next;
2364
2365 mbedtls_zeroize( cert_prv, sizeof( mbedtls_x509_crt ) );
2366 if( cert_prv != crt )
2367 mbedtls_free( cert_prv );
2368 }
2369 while( cert_cur != NULL );
2370}
2371
2372#endif /* MBEDTLS_X509_CRT_PARSE_C */
Note: See TracBrowser for help on using the repository browser.