ReactOS 0.4.15-dev-8348-gc1b9bb5
x509_crt.c
Go to the documentation of this file.
1/*
2 * X.509 certificate parsing and verification
3 *
4 * Copyright The Mbed TLS Contributors
5 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6 *
7 * This file is provided under the Apache License 2.0, or the
8 * GNU General Public License v2.0 or later.
9 *
10 * **********
11 * Apache License 2.0:
12 *
13 * Licensed under the Apache License, Version 2.0 (the "License"); you may
14 * not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 * http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
21 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
24 *
25 * **********
26 *
27 * **********
28 * GNU General Public License v2.0 or later:
29 *
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 2 of the License, or
33 * (at your option) any later version.
34 *
35 * This program is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 * GNU General Public License for more details.
39 *
40 * You should have received a copy of the GNU General Public License along
41 * with this program; if not, write to the Free Software Foundation, Inc.,
42 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
43 *
44 * **********
45 */
46/*
47 * The ITU-T X.509 standard defines a certificate format for PKI.
48 *
49 * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
50 * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
51 * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
52 *
53 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
54 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
55 *
56 * [SIRO] https://cabforum.org/wp-content/uploads/Chunghwatelecom201503cabforumV4.pdf
57 */
58
59#if !defined(MBEDTLS_CONFIG_FILE)
60#include "mbedtls/config.h"
61#else
62#include MBEDTLS_CONFIG_FILE
63#endif
64
65#if defined(MBEDTLS_X509_CRT_PARSE_C)
66
67#include "mbedtls/x509_crt.h"
68#include "mbedtls/oid.h"
70
71#include <string.h>
72
73#if defined(MBEDTLS_PEM_PARSE_C)
74#include "mbedtls/pem.h"
75#endif
76
77#if defined(MBEDTLS_PLATFORM_C)
78#include "mbedtls/platform.h"
79#else
80#include <stdio.h>
81#include <stdlib.h>
82#define mbedtls_free free
83#define mbedtls_calloc calloc
84#define mbedtls_snprintf snprintf
85#endif
86
87#if defined(MBEDTLS_THREADING_C)
88#include "mbedtls/threading.h"
89#endif
90
91#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
92#include <windows.h>
93#else
94#include <time.h>
95#endif
96
97#if defined(MBEDTLS_FS_IO)
98#include <stdio.h>
99#if !defined(_WIN32) || defined(EFIX64) || defined(EFI32)
100#include <sys/types.h>
101#include <sys/stat.h>
102#include <dirent.h>
103#endif /* !_WIN32 || EFIX64 || EFI32 */
104#endif
105
106/*
107 * Item in a verification chain: cert and flags for it
108 */
109typedef struct {
110 mbedtls_x509_crt *crt;
112} x509_crt_verify_chain_item;
113
114/*
115 * Max size of verification chain: end-entity + intermediates + trusted root
116 */
117#define X509_MAX_VERIFY_CHAIN_SIZE ( MBEDTLS_X509_MAX_INTERMEDIATE_CA + 2 )
118
119/* Default profile. Do not remove items unless there are serious security
120 * concerns. */
122{
123#if defined(MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES)
124 /* Allow SHA-1 (weak, but still safe in controlled environments) */
126#endif
127 /* Only SHA-2 hashes */
132 0xFFFFFFF, /* Any PK alg */
133 0xFFFFFFF, /* Any curve */
134 2048,
135};
136
137/*
138 * Next-default profile
139 */
141{
142 /* Hashes from SHA-256 and above */
146 0xFFFFFFF, /* Any PK alg */
147#if defined(MBEDTLS_ECP_C)
148 /* Curves at or above 128-bit security level */
156#else
157 0,
158#endif
159 2048,
160};
161
162/*
163 * NSA Suite B Profile
164 */
166{
167 /* Only SHA-256 and 384 */
170 /* Only ECDSA */
173#if defined(MBEDTLS_ECP_C)
174 /* Only NIST P-256 and P-384 */
177#else
178 0,
179#endif
180 0,
181};
182
183/*
184 * Check md_alg against profile
185 * Return 0 if md_alg is acceptable for this profile, -1 otherwise
186 */
187static int x509_profile_check_md_alg( const mbedtls_x509_crt_profile *profile,
188 mbedtls_md_type_t md_alg )
189{
190 if( md_alg == MBEDTLS_MD_NONE )
191 return( -1 );
192
193 if( ( profile->allowed_mds & MBEDTLS_X509_ID_FLAG( md_alg ) ) != 0 )
194 return( 0 );
195
196 return( -1 );
197}
198
199/*
200 * Check pk_alg against profile
201 * Return 0 if pk_alg is acceptable for this profile, -1 otherwise
202 */
203static int x509_profile_check_pk_alg( const mbedtls_x509_crt_profile *profile,
204 mbedtls_pk_type_t pk_alg )
205{
206 if( pk_alg == MBEDTLS_PK_NONE )
207 return( -1 );
208
209 if( ( profile->allowed_pks & MBEDTLS_X509_ID_FLAG( pk_alg ) ) != 0 )
210 return( 0 );
211
212 return( -1 );
213}
214
215/*
216 * Check key against profile
217 * Return 0 if pk is acceptable for this profile, -1 otherwise
218 */
219static int x509_profile_check_key( const mbedtls_x509_crt_profile *profile,
220 const mbedtls_pk_context *pk )
221{
222 const mbedtls_pk_type_t pk_alg = mbedtls_pk_get_type( pk );
223
224#if defined(MBEDTLS_RSA_C)
225 if( pk_alg == MBEDTLS_PK_RSA || pk_alg == MBEDTLS_PK_RSASSA_PSS )
226 {
227 if( mbedtls_pk_get_bitlen( pk ) >= profile->rsa_min_bitlen )
228 return( 0 );
229
230 return( -1 );
231 }
232#endif
233
234#if defined(MBEDTLS_ECP_C)
235 if( pk_alg == MBEDTLS_PK_ECDSA ||
236 pk_alg == MBEDTLS_PK_ECKEY ||
237 pk_alg == MBEDTLS_PK_ECKEY_DH )
238 {
239 const mbedtls_ecp_group_id gid = mbedtls_pk_ec( *pk )->grp.id;
240
241 if( gid == MBEDTLS_ECP_DP_NONE )
242 return( -1 );
243
244 if( ( profile->allowed_curves & MBEDTLS_X509_ID_FLAG( gid ) ) != 0 )
245 return( 0 );
246
247 return( -1 );
248 }
249#endif
250
251 return( -1 );
252}
253
254/*
255 * Like memcmp, but case-insensitive and always returns -1 if different
256 */
257static int x509_memcasecmp( const void *s1, const void *s2, size_t len )
258{
259 size_t i;
260 unsigned char diff;
261 const unsigned char *n1 = s1, *n2 = s2;
262
263 for( i = 0; i < len; i++ )
264 {
265 diff = n1[i] ^ n2[i];
266
267 if( diff == 0 )
268 continue;
269
270 if( diff == 32 &&
271 ( ( n1[i] >= 'a' && n1[i] <= 'z' ) ||
272 ( n1[i] >= 'A' && n1[i] <= 'Z' ) ) )
273 {
274 continue;
275 }
276
277 return( -1 );
278 }
279
280 return( 0 );
281}
282
283/*
284 * Return 0 if name matches wildcard, -1 otherwise
285 */
286static int x509_check_wildcard( const char *cn, const mbedtls_x509_buf *name )
287{
288 size_t i;
289 size_t cn_idx = 0, cn_len = strlen( cn );
290
291 /* We can't have a match if there is no wildcard to match */
292 if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' )
293 return( -1 );
294
295 for( i = 0; i < cn_len; ++i )
296 {
297 if( cn[i] == '.' )
298 {
299 cn_idx = i;
300 break;
301 }
302 }
303
304 if( cn_idx == 0 )
305 return( -1 );
306
307 if( cn_len - cn_idx == name->len - 1 &&
308 x509_memcasecmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 )
309 {
310 return( 0 );
311 }
312
313 return( -1 );
314}
315
316/*
317 * Compare two X.509 strings, case-insensitive, and allowing for some encoding
318 * variations (but not all).
319 *
320 * Return 0 if equal, -1 otherwise.
321 */
322static int x509_string_cmp( const mbedtls_x509_buf *a, const mbedtls_x509_buf *b )
323{
324 if( a->tag == b->tag &&
325 a->len == b->len &&
326 memcmp( a->p, b->p, b->len ) == 0 )
327 {
328 return( 0 );
329 }
330
331 if( ( a->tag == MBEDTLS_ASN1_UTF8_STRING || a->tag == MBEDTLS_ASN1_PRINTABLE_STRING ) &&
333 a->len == b->len &&
334 x509_memcasecmp( a->p, b->p, b->len ) == 0 )
335 {
336 return( 0 );
337 }
338
339 return( -1 );
340}
341
342/*
343 * Compare two X.509 Names (aka rdnSequence).
344 *
345 * See RFC 5280 section 7.1, though we don't implement the whole algorithm:
346 * we sometimes return unequal when the full algorithm would return equal,
347 * but never the other way. (In particular, we don't do Unicode normalisation
348 * or space folding.)
349 *
350 * Return 0 if equal, -1 otherwise.
351 */
352static int x509_name_cmp( const mbedtls_x509_name *a, const mbedtls_x509_name *b )
353{
354 /* Avoid recursion, it might not be optimised by the compiler */
355 while( a != NULL || b != NULL )
356 {
357 if( a == NULL || b == NULL )
358 return( -1 );
359
360 /* type */
361 if( a->oid.tag != b->oid.tag ||
362 a->oid.len != b->oid.len ||
363 memcmp( a->oid.p, b->oid.p, b->oid.len ) != 0 )
364 {
365 return( -1 );
366 }
367
368 /* value */
369 if( x509_string_cmp( &a->val, &b->val ) != 0 )
370 return( -1 );
371
372 /* structure of the list of sets */
373 if( a->next_merged != b->next_merged )
374 return( -1 );
375
376 a = a->next;
377 b = b->next;
378 }
379
380 /* a == NULL == b */
381 return( 0 );
382}
383
384/*
385 * Reset (init or clear) a verify_chain
386 */
387static void x509_crt_verify_chain_reset(
389{
390 size_t i;
391
392 for( i = 0; i < MBEDTLS_X509_MAX_VERIFY_CHAIN_SIZE; i++ )
393 {
394 ver_chain->items[i].crt = NULL;
395 ver_chain->items[i].flags = (uint32_t) -1;
396 }
397
398 ver_chain->len = 0;
399}
400
401/*
402 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
403 */
404static int x509_get_version( unsigned char **p,
405 const unsigned char *end,
406 int *ver )
407{
408 int ret;
409 size_t len;
410
411 if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
413 {
415 {
416 *ver = 0;
417 return( 0 );
418 }
419
421 }
422
423 end = *p + len;
424
425 if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 )
427
428 if( *p != end )
431
432 return( 0 );
433}
434
435/*
436 * Validity ::= SEQUENCE {
437 * notBefore Time,
438 * notAfter Time }
439 */
440static int x509_get_dates( unsigned char **p,
441 const unsigned char *end,
444{
445 int ret;
446 size_t len;
447
448 if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
451
452 end = *p + len;
453
454 if( ( ret = mbedtls_x509_get_time( p, end, from ) ) != 0 )
455 return( ret );
456
457 if( ( ret = mbedtls_x509_get_time( p, end, to ) ) != 0 )
458 return( ret );
459
460 if( *p != end )
463
464 return( 0 );
465}
466
467/*
468 * X.509 v2/v3 unique identifier (not parsed)
469 */
470static int x509_get_uid( unsigned char **p,
471 const unsigned char *end,
472 mbedtls_x509_buf *uid, int n )
473{
474 int ret;
475
476 if( *p == end )
477 return( 0 );
478
479 uid->tag = **p;
480
481 if( ( ret = mbedtls_asn1_get_tag( p, end, &uid->len,
483 {
485 return( 0 );
486
488 }
489
490 uid->p = *p;
491 *p += uid->len;
492
493 return( 0 );
494}
495
496static int x509_get_basic_constraints( unsigned char **p,
497 const unsigned char *end,
498 int *ca_istrue,
499 int *max_pathlen )
500{
501 int ret;
502 size_t len;
503
504 /*
505 * BasicConstraints ::= SEQUENCE {
506 * cA BOOLEAN DEFAULT FALSE,
507 * pathLenConstraint INTEGER (0..MAX) OPTIONAL }
508 */
509 *ca_istrue = 0; /* DEFAULT FALSE */
510 *max_pathlen = 0; /* endless */
511
512 if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
515
516 if( *p == end )
517 return( 0 );
518
519 if( ( ret = mbedtls_asn1_get_bool( p, end, ca_istrue ) ) != 0 )
520 {
522 ret = mbedtls_asn1_get_int( p, end, ca_istrue );
523
524 if( ret != 0 )
526
527 if( *ca_istrue != 0 )
528 *ca_istrue = 1;
529 }
530
531 if( *p == end )
532 return( 0 );
533
534 if( ( ret = mbedtls_asn1_get_int( p, end, max_pathlen ) ) != 0 )
536
537 if( *p != end )
540
541 /* Do not accept max_pathlen equal to INT_MAX to avoid a signed integer
542 * overflow, which is an undefined behavior. */
543 if( *max_pathlen == INT_MAX )
546
547 (*max_pathlen)++;
548
549 return( 0 );
550}
551
552static int x509_get_ns_cert_type( unsigned char **p,
553 const unsigned char *end,
554 unsigned char *ns_cert_type)
555{
556 int ret;
557 mbedtls_x509_bitstring bs = { 0, 0, NULL };
558
559 if( ( ret = mbedtls_asn1_get_bitstring( p, end, &bs ) ) != 0 )
561
562 if( bs.len != 1 )
565
566 /* Get actual bitstring */
567 *ns_cert_type = *bs.p;
568 return( 0 );
569}
570
571static int x509_get_key_usage( unsigned char **p,
572 const unsigned char *end,
573 unsigned int *key_usage)
574{
575 int ret;
576 size_t i;
577 mbedtls_x509_bitstring bs = { 0, 0, NULL };
578
579 if( ( ret = mbedtls_asn1_get_bitstring( p, end, &bs ) ) != 0 )
581
582 if( bs.len < 1 )
585
586 /* Get actual bitstring */
587 *key_usage = 0;
588 for( i = 0; i < bs.len && i < sizeof( unsigned int ); i++ )
589 {
590 *key_usage |= (unsigned int) bs.p[i] << (8*i);
591 }
592
593 return( 0 );
594}
595
596/*
597 * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
598 *
599 * KeyPurposeId ::= OBJECT IDENTIFIER
600 */
601static int x509_get_ext_key_usage( unsigned char **p,
602 const unsigned char *end,
603 mbedtls_x509_sequence *ext_key_usage)
604{
605 int ret;
606
607 if( ( ret = mbedtls_asn1_get_sequence_of( p, end, ext_key_usage, MBEDTLS_ASN1_OID ) ) != 0 )
609
610 /* Sequence length must be >= 1 */
611 if( ext_key_usage->buf.p == NULL )
614
615 return( 0 );
616}
617
618/*
619 * SubjectAltName ::= GeneralNames
620 *
621 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
622 *
623 * GeneralName ::= CHOICE {
624 * otherName [0] OtherName,
625 * rfc822Name [1] IA5String,
626 * dNSName [2] IA5String,
627 * x400Address [3] ORAddress,
628 * directoryName [4] Name,
629 * ediPartyName [5] EDIPartyName,
630 * uniformResourceIdentifier [6] IA5String,
631 * iPAddress [7] OCTET STRING,
632 * registeredID [8] OBJECT IDENTIFIER }
633 *
634 * OtherName ::= SEQUENCE {
635 * type-id OBJECT IDENTIFIER,
636 * value [0] EXPLICIT ANY DEFINED BY type-id }
637 *
638 * EDIPartyName ::= SEQUENCE {
639 * nameAssigner [0] DirectoryString OPTIONAL,
640 * partyName [1] DirectoryString }
641 *
642 * NOTE: we only parse and use dNSName at this point.
643 */
644static int x509_get_subject_alt_name( unsigned char **p,
645 const unsigned char *end,
646 mbedtls_x509_sequence *subject_alt_name )
647{
648 int ret;
649 size_t len, tag_len;
651 unsigned char tag;
652 mbedtls_asn1_sequence *cur = subject_alt_name;
653
654 /* Get main sequence tag */
655 if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
658
659 if( *p + len != end )
662
663 while( *p < end )
664 {
665 if( ( end - *p ) < 1 )
668
669 tag = **p;
670 (*p)++;
671 if( ( ret = mbedtls_asn1_get_len( p, end, &tag_len ) ) != 0 )
673
676 {
679 }
680
681 /* Skip everything but DNS name */
682 if( tag != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | 2 ) )
683 {
684 *p += tag_len;
685 continue;
686 }
687
688 /* Allocate and assign next pointer */
689 if( cur->buf.p != NULL )
690 {
691 if( cur->next != NULL )
693
694 cur->next = mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence ) );
695
696 if( cur->next == NULL )
699
700 cur = cur->next;
701 }
702
703 buf = &(cur->buf);
704 buf->tag = tag;
705 buf->p = *p;
706 buf->len = tag_len;
707 *p += buf->len;
708 }
709
710 /* Set final sequence entry's next pointer to NULL */
711 cur->next = NULL;
712
713 if( *p != end )
716
717 return( 0 );
718}
719
720/*
721 * X.509 v3 extensions
722 *
723 */
724static int x509_get_crt_ext( unsigned char **p,
725 const unsigned char *end,
726 mbedtls_x509_crt *crt )
727{
728 int ret;
729 size_t len;
730 unsigned char *end_ext_data, *end_ext_octet;
731
732 if( *p == end )
733 return( 0 );
734
735 if( ( ret = mbedtls_x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 )
736 return( ret );
737
738 end = crt->v3_ext.p + crt->v3_ext.len;
739 while( *p < end )
740 {
741 /*
742 * Extension ::= SEQUENCE {
743 * extnID OBJECT IDENTIFIER,
744 * critical BOOLEAN DEFAULT FALSE,
745 * extnValue OCTET STRING }
746 */
747 mbedtls_x509_buf extn_oid = {0, 0, NULL};
748 int is_critical = 0; /* DEFAULT FALSE */
749 int ext_type = 0;
750
751 if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
754
755 end_ext_data = *p + len;
756
757 /* Get extension ID */
758 if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &extn_oid.len,
759 MBEDTLS_ASN1_OID ) ) != 0 )
761
762 extn_oid.tag = MBEDTLS_ASN1_OID;
763 extn_oid.p = *p;
764 *p += extn_oid.len;
765
766 /* Get optional critical */
767 if( ( ret = mbedtls_asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
770
771 /* Data should be octet string type */
772 if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &len,
775
776 end_ext_octet = *p + len;
777
778 if( end_ext_octet != end_ext_data )
781
782 /*
783 * Detect supported extensions
784 */
785 ret = mbedtls_oid_get_x509_ext_type( &extn_oid, &ext_type );
786
787 if( ret != 0 )
788 {
789 /* No parser found, skip extension */
790 *p = end_ext_octet;
791
792#if !defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION)
793 if( is_critical )
794 {
795 /* Data is marked as critical: fail */
798 }
799#endif
800 continue;
801 }
802
803 /* Forbid repeated extensions */
804 if( ( crt->ext_types & ext_type ) != 0 )
806
807 crt->ext_types |= ext_type;
808
809 switch( ext_type )
810 {
812 /* Parse basic constraints */
813 if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
814 &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
815 return( ret );
816 break;
817
819 /* Parse key usage */
820 if( ( ret = x509_get_key_usage( p, end_ext_octet,
821 &crt->key_usage ) ) != 0 )
822 return( ret );
823 break;
824
826 /* Parse extended key usage */
827 if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
828 &crt->ext_key_usage ) ) != 0 )
829 return( ret );
830 break;
831
833 /* Parse subject alt name */
834 if( ( ret = x509_get_subject_alt_name( p, end_ext_octet,
835 &crt->subject_alt_names ) ) != 0 )
836 return( ret );
837 break;
838
840 /* Parse netscape certificate type */
841 if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
842 &crt->ns_cert_type ) ) != 0 )
843 return( ret );
844 break;
845
846 default:
848 }
849 }
850
851 if( *p != end )
854
855 return( 0 );
856}
857
858/*
859 * Parse and fill a single X.509 certificate in DER format
860 */
861static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *buf,
862 size_t buflen )
863{
864 int ret;
865 size_t len;
866 unsigned char *p, *end, *crt_end;
867 mbedtls_x509_buf sig_params1, sig_params2, sig_oid2;
868
869 memset( &sig_params1, 0, sizeof( mbedtls_x509_buf ) );
870 memset( &sig_params2, 0, sizeof( mbedtls_x509_buf ) );
871 memset( &sig_oid2, 0, sizeof( mbedtls_x509_buf ) );
872
873 /*
874 * Check for valid input
875 */
876 if( crt == NULL || buf == NULL )
878
879 // Use the original buffer until we figure out actual length
880 p = (unsigned char*) buf;
881 len = buflen;
882 end = p + len;
883
884 /*
885 * Certificate ::= SEQUENCE {
886 * tbsCertificate TBSCertificate,
887 * signatureAlgorithm AlgorithmIdentifier,
888 * signatureValue BIT STRING }
889 */
890 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
892 {
895 }
896
897 if( len > (size_t) ( end - p ) )
898 {
902 }
903 crt_end = p + len;
904
905 // Create and populate a new buffer for the raw field
906 crt->raw.len = crt_end - buf;
907 crt->raw.p = p = mbedtls_calloc( 1, crt->raw.len );
908 if( p == NULL )
910
911 memcpy( p, buf, crt->raw.len );
912
913 // Direct pointers to the new buffer
914 p += crt->raw.len - len;
915 end = crt_end = p + len;
916
917 /*
918 * TBSCertificate ::= SEQUENCE {
919 */
920 crt->tbs.p = p;
921
922 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
924 {
927 }
928
929 end = p + len;
930 crt->tbs.len = end - crt->tbs.p;
931
932 /*
933 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
934 *
935 * CertificateSerialNumber ::= INTEGER
936 *
937 * signature AlgorithmIdentifier
938 */
939 if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 ||
940 ( ret = mbedtls_x509_get_serial( &p, end, &crt->serial ) ) != 0 ||
941 ( ret = mbedtls_x509_get_alg( &p, end, &crt->sig_oid,
942 &sig_params1 ) ) != 0 )
943 {
945 return( ret );
946 }
947
948 if( crt->version < 0 || crt->version > 2 )
949 {
952 }
953
954 crt->version++;
955
956 if( ( ret = mbedtls_x509_get_sig_alg( &crt->sig_oid, &sig_params1,
957 &crt->sig_md, &crt->sig_pk,
958 &crt->sig_opts ) ) != 0 )
959 {
961 return( ret );
962 }
963
964 /*
965 * issuer Name
966 */
967 crt->issuer_raw.p = p;
968
969 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
971 {
974 }
975
976 if( ( ret = mbedtls_x509_get_name( &p, p + len, &crt->issuer ) ) != 0 )
977 {
979 return( ret );
980 }
981
982 crt->issuer_raw.len = p - crt->issuer_raw.p;
983
984 /*
985 * Validity ::= SEQUENCE {
986 * notBefore Time,
987 * notAfter Time }
988 *
989 */
990 if( ( ret = x509_get_dates( &p, end, &crt->valid_from,
991 &crt->valid_to ) ) != 0 )
992 {
994 return( ret );
995 }
996
997 /*
998 * subject Name
999 */
1000 crt->subject_raw.p = p;
1001
1002 if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
1004 {
1005 mbedtls_x509_crt_free( crt );
1007 }
1008
1009 if( len && ( ret = mbedtls_x509_get_name( &p, p + len, &crt->subject ) ) != 0 )
1010 {
1011 mbedtls_x509_crt_free( crt );
1012 return( ret );
1013 }
1014
1015 crt->subject_raw.len = p - crt->subject_raw.p;
1016
1017 /*
1018 * SubjectPublicKeyInfo
1019 */
1020 if( ( ret = mbedtls_pk_parse_subpubkey( &p, end, &crt->pk ) ) != 0 )
1021 {
1022 mbedtls_x509_crt_free( crt );
1023 return( ret );
1024 }
1025
1026 /*
1027 * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
1028 * -- If present, version shall be v2 or v3
1029 * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
1030 * -- If present, version shall be v2 or v3
1031 * extensions [3] EXPLICIT Extensions OPTIONAL
1032 * -- If present, version shall be v3
1033 */
1034 if( crt->version == 2 || crt->version == 3 )
1035 {
1036 ret = x509_get_uid( &p, end, &crt->issuer_id, 1 );
1037 if( ret != 0 )
1038 {
1039 mbedtls_x509_crt_free( crt );
1040 return( ret );
1041 }
1042 }
1043
1044 if( crt->version == 2 || crt->version == 3 )
1045 {
1046 ret = x509_get_uid( &p, end, &crt->subject_id, 2 );
1047 if( ret != 0 )
1048 {
1049 mbedtls_x509_crt_free( crt );
1050 return( ret );
1051 }
1052 }
1053
1054#if !defined(MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3)
1055 if( crt->version == 3 )
1056#endif
1057 {
1058 ret = x509_get_crt_ext( &p, end, crt );
1059 if( ret != 0 )
1060 {
1061 mbedtls_x509_crt_free( crt );
1062 return( ret );
1063 }
1064 }
1065
1066 if( p != end )
1067 {
1068 mbedtls_x509_crt_free( crt );
1071 }
1072
1073 end = crt_end;
1074
1075 /*
1076 * }
1077 * -- end of TBSCertificate
1078 *
1079 * signatureAlgorithm AlgorithmIdentifier,
1080 * signatureValue BIT STRING
1081 */
1082 if( ( ret = mbedtls_x509_get_alg( &p, end, &sig_oid2, &sig_params2 ) ) != 0 )
1083 {
1084 mbedtls_x509_crt_free( crt );
1085 return( ret );
1086 }
1087
1088 if( crt->sig_oid.len != sig_oid2.len ||
1089 memcmp( crt->sig_oid.p, sig_oid2.p, crt->sig_oid.len ) != 0 ||
1090 sig_params1.tag != sig_params2.tag ||
1091 sig_params1.len != sig_params2.len ||
1092 ( sig_params1.len != 0 &&
1093 memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) )
1094 {
1095 mbedtls_x509_crt_free( crt );
1097 }
1098
1099 if( ( ret = mbedtls_x509_get_sig( &p, end, &crt->sig ) ) != 0 )
1100 {
1101 mbedtls_x509_crt_free( crt );
1102 return( ret );
1103 }
1104
1105 if( p != end )
1106 {
1107 mbedtls_x509_crt_free( crt );
1110 }
1111
1112 return( 0 );
1113}
1114
1115/*
1116 * Parse one X.509 certificate in DER format from a buffer and add them to a
1117 * chained list
1118 */
1119int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, const unsigned char *buf,
1120 size_t buflen )
1121{
1122 int ret;
1123 mbedtls_x509_crt *crt = chain, *prev = NULL;
1124
1125 /*
1126 * Check for valid input
1127 */
1128 if( crt == NULL || buf == NULL )
1130
1131 while( crt->version != 0 && crt->next != NULL )
1132 {
1133 prev = crt;
1134 crt = crt->next;
1135 }
1136
1137 /*
1138 * Add new certificate on the end of the chain if needed.
1139 */
1140 if( crt->version != 0 && crt->next == NULL )
1141 {
1142 crt->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) );
1143
1144 if( crt->next == NULL )
1146
1147 prev = crt;
1149 crt = crt->next;
1150 }
1151
1152 if( ( ret = x509_crt_parse_der_core( crt, buf, buflen ) ) != 0 )
1153 {
1154 if( prev )
1155 prev->next = NULL;
1156
1157 if( crt != chain )
1158 mbedtls_free( crt );
1159
1160 return( ret );
1161 }
1162
1163 return( 0 );
1164}
1165
1166/*
1167 * Parse one or more PEM certificates from a buffer and add them to the chained
1168 * list
1169 */
1170int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, size_t buflen )
1171{
1172#if defined(MBEDTLS_PEM_PARSE_C)
1173 int success = 0, first_error = 0, total_failed = 0;
1174 int buf_format = MBEDTLS_X509_FORMAT_DER;
1175#endif
1176
1177 /*
1178 * Check for valid input
1179 */
1180 if( chain == NULL || buf == NULL )
1182
1183 /*
1184 * Determine buffer content. Buffer contains either one DER certificate or
1185 * one or more PEM certificates.
1186 */
1187#if defined(MBEDTLS_PEM_PARSE_C)
1188 if( buflen != 0 && buf[buflen - 1] == '\0' &&
1189 strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL )
1190 {
1191 buf_format = MBEDTLS_X509_FORMAT_PEM;
1192 }
1193
1194 if( buf_format == MBEDTLS_X509_FORMAT_DER )
1195 return mbedtls_x509_crt_parse_der( chain, buf, buflen );
1196#else
1197 return mbedtls_x509_crt_parse_der( chain, buf, buflen );
1198#endif
1199
1200#if defined(MBEDTLS_PEM_PARSE_C)
1201 if( buf_format == MBEDTLS_X509_FORMAT_PEM )
1202 {
1203 int ret;
1204 mbedtls_pem_context pem;
1205
1206 /* 1 rather than 0 since the terminating NULL byte is counted in */
1207 while( buflen > 1 )
1208 {
1209 size_t use_len;
1210 mbedtls_pem_init( &pem );
1211
1212 /* If we get there, we know the string is null-terminated */
1213 ret = mbedtls_pem_read_buffer( &pem,
1214 "-----BEGIN CERTIFICATE-----",
1215 "-----END CERTIFICATE-----",
1216 buf, NULL, 0, &use_len );
1217
1218 if( ret == 0 )
1219 {
1220 /*
1221 * Was PEM encoded
1222 */
1223 buflen -= use_len;
1224 buf += use_len;
1225 }
1227 {
1228 return( ret );
1229 }
1231 {
1232 mbedtls_pem_free( &pem );
1233
1234 /*
1235 * PEM header and footer were found
1236 */
1237 buflen -= use_len;
1238 buf += use_len;
1239
1240 if( first_error == 0 )
1241 first_error = ret;
1242
1243 total_failed++;
1244 continue;
1245 }
1246 else
1247 break;
1248
1249 ret = mbedtls_x509_crt_parse_der( chain, pem.buf, pem.buflen );
1250
1251 mbedtls_pem_free( &pem );
1252
1253 if( ret != 0 )
1254 {
1255 /*
1256 * Quit parsing on a memory error
1257 */
1259 return( ret );
1260
1261 if( first_error == 0 )
1262 first_error = ret;
1263
1264 total_failed++;
1265 continue;
1266 }
1267
1268 success = 1;
1269 }
1270 }
1271
1272 if( success )
1273 return( total_failed );
1274 else if( first_error )
1275 return( first_error );
1276 else
1278#endif /* MBEDTLS_PEM_PARSE_C */
1279}
1280
1281#if defined(MBEDTLS_FS_IO)
1282/*
1283 * Load one or more certificates and add them to the chained list
1284 */
1285int mbedtls_x509_crt_parse_file( mbedtls_x509_crt *chain, const char *path )
1286{
1287 int ret;
1288 size_t n;
1289 unsigned char *buf;
1290
1291 if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
1292 return( ret );
1293
1295
1297 mbedtls_free( buf );
1298
1299 return( ret );
1300}
1301
1302int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path )
1303{
1304 int ret = 0;
1305#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
1306 int w_ret;
1307 WCHAR szDir[MAX_PATH];
1308 char filename[MAX_PATH];
1309 char *p;
1310 size_t len = strlen( path );
1311
1312 WIN32_FIND_DATAW file_data;
1313 HANDLE hFind;
1314
1315 if( len > MAX_PATH - 3 )
1317
1318 memset( szDir, 0, sizeof(szDir) );
1319 memset( filename, 0, MAX_PATH );
1320 memcpy( filename, path, len );
1321 filename[len++] = '\\';
1322 p = filename + len;
1323 filename[len++] = '*';
1324
1325 w_ret = MultiByteToWideChar( CP_ACP, 0, filename, (int)len, szDir,
1326 MAX_PATH - 3 );
1327 if( w_ret == 0 )
1329
1330 hFind = FindFirstFileW( szDir, &file_data );
1331 if( hFind == INVALID_HANDLE_VALUE )
1333
1334 len = MAX_PATH - len;
1335 do
1336 {
1337 memset( p, 0, len );
1338
1339 if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
1340 continue;
1341
1342 w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName,
1343 lstrlenW( file_data.cFileName ),
1344 p, (int) len - 1,
1345 NULL, NULL );
1346 if( w_ret == 0 )
1347 {
1349 goto cleanup;
1350 }
1351
1352 w_ret = mbedtls_x509_crt_parse_file( chain, filename );
1353 if( w_ret < 0 )
1354 ret++;
1355 else
1356 ret += w_ret;
1357 }
1358 while( FindNextFileW( hFind, &file_data ) != 0 );
1359
1362
1363cleanup:
1364 FindClose( hFind );
1365#else /* _WIN32 */
1366 int t_ret;
1367 int snp_ret;
1368 struct stat sb;
1369 struct dirent *entry;
1370 char entry_name[MBEDTLS_X509_MAX_FILE_PATH_LEN];
1371 DIR *dir = opendir( path );
1372
1373 if( dir == NULL )
1375
1376#if defined(MBEDTLS_THREADING_C)
1377 if( ( ret = mbedtls_mutex_lock( &mbedtls_threading_readdir_mutex ) ) != 0 )
1378 {
1379 closedir( dir );
1380 return( ret );
1381 }
1382#endif /* MBEDTLS_THREADING_C */
1383
1384 while( ( entry = readdir( dir ) ) != NULL )
1385 {
1386 snp_ret = mbedtls_snprintf( entry_name, sizeof entry_name,
1387 "%s/%s", path, entry->d_name );
1388
1389 if( snp_ret < 0 || (size_t)snp_ret >= sizeof entry_name )
1390 {
1392 goto cleanup;
1393 }
1394 else if( stat( entry_name, &sb ) == -1 )
1395 {
1397 goto cleanup;
1398 }
1399
1400 if( !S_ISREG( sb.st_mode ) )
1401 continue;
1402
1403 // Ignore parse errors
1404 //
1405 t_ret = mbedtls_x509_crt_parse_file( chain, entry_name );
1406 if( t_ret < 0 )
1407 ret++;
1408 else
1409 ret += t_ret;
1410 }
1411
1412cleanup:
1413 closedir( dir );
1414
1415#if defined(MBEDTLS_THREADING_C)
1416 if( mbedtls_mutex_unlock( &mbedtls_threading_readdir_mutex ) != 0 )
1418#endif /* MBEDTLS_THREADING_C */
1419
1420#endif /* _WIN32 */
1421
1422 return( ret );
1423}
1424#endif /* MBEDTLS_FS_IO */
1425
1426static int x509_info_subject_alt_name( char **buf, size_t *size,
1427 const mbedtls_x509_sequence *subject_alt_name )
1428{
1429 size_t i;
1430 size_t n = *size;
1431 char *p = *buf;
1432 const mbedtls_x509_sequence *cur = subject_alt_name;
1433 const char *sep = "";
1434 size_t sep_len = 0;
1435
1436 while( cur != NULL )
1437 {
1438 if( cur->buf.len + sep_len >= n )
1439 {
1440 *p = '\0';
1442 }
1443
1444 n -= cur->buf.len + sep_len;
1445 for( i = 0; i < sep_len; i++ )
1446 *p++ = sep[i];
1447 for( i = 0; i < cur->buf.len; i++ )
1448 *p++ = cur->buf.p[i];
1449
1450 sep = ", ";
1451 sep_len = 2;
1452
1453 cur = cur->next;
1454 }
1455
1456 *p = '\0';
1457
1458 *size = n;
1459 *buf = p;
1460
1461 return( 0 );
1462}
1463
1464#define PRINT_ITEM(i) \
1465 { \
1466 ret = mbedtls_snprintf( p, n, "%s" i, sep ); \
1467 MBEDTLS_X509_SAFE_SNPRINTF; \
1468 sep = ", "; \
1469 }
1470
1471#define CERT_TYPE(type,name) \
1472 if( ns_cert_type & (type) ) \
1473 PRINT_ITEM( name );
1474
1475static int x509_info_cert_type( char **buf, size_t *size,
1476 unsigned char ns_cert_type )
1477{
1478 int ret;
1479 size_t n = *size;
1480 char *p = *buf;
1481 const char *sep = "";
1482
1483 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT, "SSL Client" );
1484 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER, "SSL Server" );
1485 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_EMAIL, "Email" );
1486 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING, "Object Signing" );
1487 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_RESERVED, "Reserved" );
1488 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_CA, "SSL CA" );
1489 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA, "Email CA" );
1490 CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA, "Object Signing CA" );
1491
1492 *size = n;
1493 *buf = p;
1494
1495 return( 0 );
1496}
1497
1498#define KEY_USAGE(code,name) \
1499 if( key_usage & (code) ) \
1500 PRINT_ITEM( name );
1501
1502static int x509_info_key_usage( char **buf, size_t *size,
1503 unsigned int key_usage )
1504{
1505 int ret;
1506 size_t n = *size;
1507 char *p = *buf;
1508 const char *sep = "";
1509
1510 KEY_USAGE( MBEDTLS_X509_KU_DIGITAL_SIGNATURE, "Digital Signature" );
1511 KEY_USAGE( MBEDTLS_X509_KU_NON_REPUDIATION, "Non Repudiation" );
1512 KEY_USAGE( MBEDTLS_X509_KU_KEY_ENCIPHERMENT, "Key Encipherment" );
1513 KEY_USAGE( MBEDTLS_X509_KU_DATA_ENCIPHERMENT, "Data Encipherment" );
1514 KEY_USAGE( MBEDTLS_X509_KU_KEY_AGREEMENT, "Key Agreement" );
1515 KEY_USAGE( MBEDTLS_X509_KU_KEY_CERT_SIGN, "Key Cert Sign" );
1516 KEY_USAGE( MBEDTLS_X509_KU_CRL_SIGN, "CRL Sign" );
1517 KEY_USAGE( MBEDTLS_X509_KU_ENCIPHER_ONLY, "Encipher Only" );
1518 KEY_USAGE( MBEDTLS_X509_KU_DECIPHER_ONLY, "Decipher Only" );
1519
1520 *size = n;
1521 *buf = p;
1522
1523 return( 0 );
1524}
1525
1526static int x509_info_ext_key_usage( char **buf, size_t *size,
1527 const mbedtls_x509_sequence *extended_key_usage )
1528{
1529 int ret;
1530 const char *desc;
1531 size_t n = *size;
1532 char *p = *buf;
1533 const mbedtls_x509_sequence *cur = extended_key_usage;
1534 const char *sep = "";
1535
1536 while( cur != NULL )
1537 {
1538 if( mbedtls_oid_get_extended_key_usage( &cur->buf, &desc ) != 0 )
1539 desc = "???";
1540
1541 ret = mbedtls_snprintf( p, n, "%s%s", sep, desc );
1543
1544 sep = ", ";
1545
1546 cur = cur->next;
1547 }
1548
1549 *size = n;
1550 *buf = p;
1551
1552 return( 0 );
1553}
1554
1555/*
1556 * Return an informational string about the certificate.
1557 */
1558#define BEFORE_COLON 18
1559#define BC "18"
1560int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix,
1561 const mbedtls_x509_crt *crt )
1562{
1563 int ret;
1564 size_t n;
1565 char *p;
1566 char key_size_str[BEFORE_COLON];
1567
1568 p = buf;
1569 n = size;
1570
1571 if( NULL == crt )
1572 {
1573 ret = mbedtls_snprintf( p, n, "\nCertificate is uninitialised!\n" );
1575
1576 return( (int) ( size - n ) );
1577 }
1578
1579 ret = mbedtls_snprintf( p, n, "%scert. version : %d\n",
1580 prefix, crt->version );
1582 ret = mbedtls_snprintf( p, n, "%sserial number : ",
1583 prefix );
1585
1586 ret = mbedtls_x509_serial_gets( p, n, &crt->serial );
1588
1589 ret = mbedtls_snprintf( p, n, "\n%sissuer name : ", prefix );
1591 ret = mbedtls_x509_dn_gets( p, n, &crt->issuer );
1593
1594 ret = mbedtls_snprintf( p, n, "\n%ssubject name : ", prefix );
1596 ret = mbedtls_x509_dn_gets( p, n, &crt->subject );
1598
1599 ret = mbedtls_snprintf( p, n, "\n%sissued on : " \
1600 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
1601 crt->valid_from.year, crt->valid_from.mon,
1602 crt->valid_from.day, crt->valid_from.hour,
1603 crt->valid_from.min, crt->valid_from.sec );
1605
1606 ret = mbedtls_snprintf( p, n, "\n%sexpires on : " \
1607 "%04d-%02d-%02d %02d:%02d:%02d", prefix,
1608 crt->valid_to.year, crt->valid_to.mon,
1609 crt->valid_to.day, crt->valid_to.hour,
1610 crt->valid_to.min, crt->valid_to.sec );
1612
1613 ret = mbedtls_snprintf( p, n, "\n%ssigned using : ", prefix );
1615
1616 ret = mbedtls_x509_sig_alg_gets( p, n, &crt->sig_oid, crt->sig_pk,
1617 crt->sig_md, crt->sig_opts );
1619
1620 /* Key size */
1621 if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON,
1622 mbedtls_pk_get_name( &crt->pk ) ) ) != 0 )
1623 {
1624 return( ret );
1625 }
1626
1627 ret = mbedtls_snprintf( p, n, "\n%s%-" BC "s: %d bits", prefix, key_size_str,
1628 (int) mbedtls_pk_get_bitlen( &crt->pk ) );
1630
1631 /*
1632 * Optional extensions
1633 */
1634
1636 {
1637 ret = mbedtls_snprintf( p, n, "\n%sbasic constraints : CA=%s", prefix,
1638 crt->ca_istrue ? "true" : "false" );
1640
1641 if( crt->max_pathlen > 0 )
1642 {
1643 ret = mbedtls_snprintf( p, n, ", max_pathlen=%d", crt->max_pathlen - 1 );
1645 }
1646 }
1647
1649 {
1650 ret = mbedtls_snprintf( p, n, "\n%ssubject alt name : ", prefix );
1652
1653 if( ( ret = x509_info_subject_alt_name( &p, &n,
1654 &crt->subject_alt_names ) ) != 0 )
1655 return( ret );
1656 }
1657
1659 {
1660 ret = mbedtls_snprintf( p, n, "\n%scert. type : ", prefix );
1662
1663 if( ( ret = x509_info_cert_type( &p, &n, crt->ns_cert_type ) ) != 0 )
1664 return( ret );
1665 }
1666
1668 {
1669 ret = mbedtls_snprintf( p, n, "\n%skey usage : ", prefix );
1671
1672 if( ( ret = x509_info_key_usage( &p, &n, crt->key_usage ) ) != 0 )
1673 return( ret );
1674 }
1675
1677 {
1678 ret = mbedtls_snprintf( p, n, "\n%sext key usage : ", prefix );
1680
1681 if( ( ret = x509_info_ext_key_usage( &p, &n,
1682 &crt->ext_key_usage ) ) != 0 )
1683 return( ret );
1684 }
1685
1686 ret = mbedtls_snprintf( p, n, "\n" );
1688
1689 return( (int) ( size - n ) );
1690}
1691
1692struct x509_crt_verify_string {
1693 int code;
1694 const char *string;
1695};
1696
1697static const struct x509_crt_verify_string x509_crt_verify_strings[] = {
1698 { MBEDTLS_X509_BADCERT_EXPIRED, "The certificate validity has expired" },
1699 { MBEDTLS_X509_BADCERT_REVOKED, "The certificate has been revoked (is on a CRL)" },
1700 { MBEDTLS_X509_BADCERT_CN_MISMATCH, "The certificate Common Name (CN) does not match with the expected CN" },
1701 { MBEDTLS_X509_BADCERT_NOT_TRUSTED, "The certificate is not correctly signed by the trusted CA" },
1702 { MBEDTLS_X509_BADCRL_NOT_TRUSTED, "The CRL is not correctly signed by the trusted CA" },
1703 { MBEDTLS_X509_BADCRL_EXPIRED, "The CRL is expired" },
1704 { MBEDTLS_X509_BADCERT_MISSING, "Certificate was missing" },
1705 { MBEDTLS_X509_BADCERT_SKIP_VERIFY, "Certificate verification was skipped" },
1706 { MBEDTLS_X509_BADCERT_OTHER, "Other reason (can be used by verify callback)" },
1707 { MBEDTLS_X509_BADCERT_FUTURE, "The certificate validity starts in the future" },
1708 { MBEDTLS_X509_BADCRL_FUTURE, "The CRL is from the future" },
1709 { MBEDTLS_X509_BADCERT_KEY_USAGE, "Usage does not match the keyUsage extension" },
1710 { MBEDTLS_X509_BADCERT_EXT_KEY_USAGE, "Usage does not match the extendedKeyUsage extension" },
1711 { MBEDTLS_X509_BADCERT_NS_CERT_TYPE, "Usage does not match the nsCertType extension" },
1712 { MBEDTLS_X509_BADCERT_BAD_MD, "The certificate is signed with an unacceptable hash." },
1713 { MBEDTLS_X509_BADCERT_BAD_PK, "The certificate is signed with an unacceptable PK alg (eg RSA vs ECDSA)." },
1714 { MBEDTLS_X509_BADCERT_BAD_KEY, "The certificate is signed with an unacceptable key (eg bad curve, RSA too short)." },
1715 { MBEDTLS_X509_BADCRL_BAD_MD, "The CRL is signed with an unacceptable hash." },
1716 { MBEDTLS_X509_BADCRL_BAD_PK, "The CRL is signed with an unacceptable PK alg (eg RSA vs ECDSA)." },
1717 { MBEDTLS_X509_BADCRL_BAD_KEY, "The CRL is signed with an unacceptable key (eg bad curve, RSA too short)." },
1718 { 0, NULL }
1719};
1720
1721int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix,
1722 uint32_t flags )
1723{
1724 int ret;
1725 const struct x509_crt_verify_string *cur;
1726 char *p = buf;
1727 size_t n = size;
1728
1729 for( cur = x509_crt_verify_strings; cur->string != NULL ; cur++ )
1730 {
1731 if( ( flags & cur->code ) == 0 )
1732 continue;
1733
1734 ret = mbedtls_snprintf( p, n, "%s%s\n", prefix, cur->string );
1736 flags ^= cur->code;
1737 }
1738
1739 if( flags != 0 )
1740 {
1741 ret = mbedtls_snprintf( p, n, "%sUnknown reason "
1742 "(this should not happen)\n", prefix );
1744 }
1745
1746 return( (int) ( size - n ) );
1747}
1748
1749#if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
1751 unsigned int usage )
1752{
1753 unsigned int usage_must, usage_may;
1754 unsigned int may_mask = MBEDTLS_X509_KU_ENCIPHER_ONLY
1756
1757 if( ( crt->ext_types & MBEDTLS_X509_EXT_KEY_USAGE ) == 0 )
1758 return( 0 );
1759
1760 usage_must = usage & ~may_mask;
1761
1762 if( ( ( crt->key_usage & ~may_mask ) & usage_must ) != usage_must )
1764
1765 usage_may = usage & may_mask;
1766
1767 if( ( ( crt->key_usage & may_mask ) | usage_may ) != usage_may )
1769
1770 return( 0 );
1771}
1772#endif
1773
1774#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
1776 const char *usage_oid,
1777 size_t usage_len )
1778{
1780
1781 /* Extension is not mandatory, absent means no restriction */
1783 return( 0 );
1784
1785 /*
1786 * Look for the requested usage (or wildcard ANY) in our list
1787 */
1788 for( cur = &crt->ext_key_usage; cur != NULL; cur = cur->next )
1789 {
1790 const mbedtls_x509_buf *cur_oid = &cur->buf;
1791
1792 if( cur_oid->len == usage_len &&
1793 memcmp( cur_oid->p, usage_oid, usage_len ) == 0 )
1794 {
1795 return( 0 );
1796 }
1797
1799 return( 0 );
1800 }
1801
1803}
1804#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */
1805
1806#if defined(MBEDTLS_X509_CRL_PARSE_C)
1807/*
1808 * Return 1 if the certificate is revoked, or 0 otherwise.
1809 */
1810int mbedtls_x509_crt_is_revoked( const mbedtls_x509_crt *crt, const mbedtls_x509_crl *crl )
1811{
1812 const mbedtls_x509_crl_entry *cur = &crl->entry;
1813
1814 while( cur != NULL && cur->serial.len != 0 )
1815 {
1816 if( crt->serial.len == cur->serial.len &&
1817 memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 )
1818 {
1819 return( 1 );
1820 }
1821
1822 cur = cur->next;
1823 }
1824
1825 return( 0 );
1826}
1827
1828/*
1829 * Check that the given certificate is not revoked according to the CRL.
1830 * Skip validation if no CRL for the given CA is present.
1831 */
1832static int x509_crt_verifycrl( mbedtls_x509_crt *crt, mbedtls_x509_crt *ca,
1833 mbedtls_x509_crl *crl_list,
1835{
1836 int flags = 0;
1837 unsigned char hash[MBEDTLS_MD_MAX_SIZE];
1838 const mbedtls_md_info_t *md_info;
1839
1840 if( ca == NULL )
1841 return( flags );
1842
1843 while( crl_list != NULL )
1844 {
1845 if( crl_list->version == 0 ||
1846 x509_name_cmp( &crl_list->issuer, &ca->subject ) != 0 )
1847 {
1848 crl_list = crl_list->next;
1849 continue;
1850 }
1851
1852 /*
1853 * Check if the CA is configured to sign CRLs
1854 */
1855#if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
1858 {
1860 break;
1861 }
1862#endif
1863
1864 /*
1865 * Check if CRL is correctly signed by the trusted CA
1866 */
1867 if( x509_profile_check_md_alg( profile, crl_list->sig_md ) != 0 )
1869
1870 if( x509_profile_check_pk_alg( profile, crl_list->sig_pk ) != 0 )
1872
1873 md_info = mbedtls_md_info_from_type( crl_list->sig_md );
1874 if( mbedtls_md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash ) != 0 )
1875 {
1876 /* Note: this can't happen except after an internal error */
1878 break;
1879 }
1880
1881 if( x509_profile_check_key( profile, &ca->pk ) != 0 )
1883
1884 if( mbedtls_pk_verify_ext( crl_list->sig_pk, crl_list->sig_opts, &ca->pk,
1885 crl_list->sig_md, hash, mbedtls_md_get_size( md_info ),
1886 crl_list->sig.p, crl_list->sig.len ) != 0 )
1887 {
1889 break;
1890 }
1891
1892 /*
1893 * Check for validity of CRL (Do not drop out)
1894 */
1895 if( mbedtls_x509_time_is_past( &crl_list->next_update ) )
1897
1898 if( mbedtls_x509_time_is_future( &crl_list->this_update ) )
1900
1901 /*
1902 * Check if certificate is revoked
1903 */
1904 if( mbedtls_x509_crt_is_revoked( crt, crl_list ) )
1905 {
1907 break;
1908 }
1909
1910 crl_list = crl_list->next;
1911 }
1912
1913 return( flags );
1914}
1915#endif /* MBEDTLS_X509_CRL_PARSE_C */
1916
1917/*
1918 * Check the signature of a certificate by its parent
1919 */
1920static int x509_crt_check_signature( const mbedtls_x509_crt *child,
1923{
1924 const mbedtls_md_info_t *md_info;
1925 unsigned char hash[MBEDTLS_MD_MAX_SIZE];
1926
1927 md_info = mbedtls_md_info_from_type( child->sig_md );
1928 if( mbedtls_md( md_info, child->tbs.p, child->tbs.len, hash ) != 0 )
1929 {
1930 /* Note: this can't happen except after an internal error */
1931 return( -1 );
1932 }
1933
1934 /* Skip expensive computation on obvious mismatch */
1935 if( ! mbedtls_pk_can_do( &parent->pk, child->sig_pk ) )
1936 return( -1 );
1937
1938#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
1939 if( rs_ctx != NULL && child->sig_pk == MBEDTLS_PK_ECDSA )
1940 {
1942 child->sig_md, hash, mbedtls_md_get_size( md_info ),
1943 child->sig.p, child->sig.len, &rs_ctx->pk ) );
1944 }
1945#else
1946 (void) rs_ctx;
1947#endif
1948
1949 return( mbedtls_pk_verify_ext( child->sig_pk, child->sig_opts, &parent->pk,
1950 child->sig_md, hash, mbedtls_md_get_size( md_info ),
1951 child->sig.p, child->sig.len ) );
1952}
1953
1954/*
1955 * Check if 'parent' is a suitable parent (signing CA) for 'child'.
1956 * Return 0 if yes, -1 if not.
1957 *
1958 * top means parent is a locally-trusted certificate
1959 */
1960static int x509_crt_check_parent( const mbedtls_x509_crt *child,
1961 const mbedtls_x509_crt *parent,
1962 int top )
1963{
1964 int need_ca_bit;
1965
1966 /* Parent must be the issuer */
1967 if( x509_name_cmp( &child->issuer, &parent->subject ) != 0 )
1968 return( -1 );
1969
1970 /* Parent must have the basicConstraints CA bit set as a general rule */
1971 need_ca_bit = 1;
1972
1973 /* Exception: v1/v2 certificates that are locally trusted. */
1974 if( top && parent->version < 3 )
1975 need_ca_bit = 0;
1976
1977 if( need_ca_bit && ! parent->ca_istrue )
1978 return( -1 );
1979
1980#if defined(MBEDTLS_X509_CHECK_KEY_USAGE)
1981 if( need_ca_bit &&
1983 {
1984 return( -1 );
1985 }
1986#endif
1987
1988 return( 0 );
1989}
1990
1991/*
1992 * Find a suitable parent for child in candidates, or return NULL.
1993 *
1994 * Here suitable is defined as:
1995 * 1. subject name matches child's issuer
1996 * 2. if necessary, the CA bit is set and key usage allows signing certs
1997 * 3. for trusted roots, the signature is correct
1998 * (for intermediates, the signature is checked and the result reported)
1999 * 4. pathlen constraints are satisfied
2000 *
2001 * If there's a suitable candidate which is also time-valid, return the first
2002 * such. Otherwise, return the first suitable candidate (or NULL if there is
2003 * none).
2004 *
2005 * The rationale for this rule is that someone could have a list of trusted
2006 * roots with two versions on the same root with different validity periods.
2007 * (At least one user reported having such a list and wanted it to just work.)
2008 * The reason we don't just require time-validity is that generally there is
2009 * only one version, and if it's expired we want the flags to state that
2010 * rather than NOT_TRUSTED, as would be the case if we required it here.
2011 *
2012 * The rationale for rule 3 (signature for trusted roots) is that users might
2013 * have two versions of the same CA with different keys in their list, and the
2014 * way we select the correct one is by checking the signature (as we don't
2015 * rely on key identifier extensions). (This is one way users might choose to
2016 * handle key rollover, another relies on self-issued certs, see [SIRO].)
2017 *
2018 * Arguments:
2019 * - [in] child: certificate for which we're looking for a parent
2020 * - [in] candidates: chained list of potential parents
2021 * - [out] r_parent: parent found (or NULL)
2022 * - [out] r_signature_is_good: 1 if child signature by parent is valid, or 0
2023 * - [in] top: 1 if candidates consists of trusted roots, ie we're at the top
2024 * of the chain, 0 otherwise
2025 * - [in] path_cnt: number of intermediates seen so far
2026 * - [in] self_cnt: number of self-signed intermediates seen so far
2027 * (will never be greater than path_cnt)
2028 * - [in-out] rs_ctx: context for restarting operations
2029 *
2030 * Return value:
2031 * - 0 on success
2032 * - MBEDTLS_ERR_ECP_IN_PROGRESS otherwise
2033 */
2034static int x509_crt_find_parent_in(
2036 mbedtls_x509_crt *candidates,
2037 mbedtls_x509_crt **r_parent,
2038 int *r_signature_is_good,
2039 int top,
2040 unsigned path_cnt,
2041 unsigned self_cnt,
2043{
2044 int ret;
2045 mbedtls_x509_crt *parent, *fallback_parent;
2046 int signature_is_good, fallback_signature_is_good;
2047
2048#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
2049 /* did we have something in progress? */
2050 if( rs_ctx != NULL && rs_ctx->parent != NULL )
2051 {
2052 /* restore saved state */
2053 parent = rs_ctx->parent;
2054 fallback_parent = rs_ctx->fallback_parent;
2055 fallback_signature_is_good = rs_ctx->fallback_signature_is_good;
2056
2057 /* clear saved state */
2058 rs_ctx->parent = NULL;
2059 rs_ctx->fallback_parent = NULL;
2060 rs_ctx->fallback_signature_is_good = 0;
2061
2062 /* resume where we left */
2063 goto check_signature;
2064 }
2065#endif
2066
2067 fallback_parent = NULL;
2068 fallback_signature_is_good = 0;
2069
2070 for( parent = candidates; parent != NULL; parent = parent->next )
2071 {
2072 /* basic parenting skills (name, CA bit, key usage) */
2073 if( x509_crt_check_parent( child, parent, top ) != 0 )
2074 continue;
2075
2076 /* +1 because stored max_pathlen is 1 higher that the actual value */
2077 if( parent->max_pathlen > 0 &&
2078 (size_t) parent->max_pathlen < 1 + path_cnt - self_cnt )
2079 {
2080 continue;
2081 }
2082
2083 /* Signature */
2084#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
2085check_signature:
2086#endif
2087 ret = x509_crt_check_signature( child, parent, rs_ctx );
2088
2089#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
2090 if( rs_ctx != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
2091 {
2092 /* save state */
2093 rs_ctx->parent = parent;
2094 rs_ctx->fallback_parent = fallback_parent;
2095 rs_ctx->fallback_signature_is_good = fallback_signature_is_good;
2096
2097 return( ret );
2098 }
2099#else
2100 (void) ret;
2101#endif
2102
2103 signature_is_good = ret == 0;
2104 if( top && ! signature_is_good )
2105 continue;
2106
2107 /* optional time check */
2108 if( mbedtls_x509_time_is_past( &parent->valid_to ) ||
2109 mbedtls_x509_time_is_future( &parent->valid_from ) )
2110 {
2111 if( fallback_parent == NULL )
2112 {
2113 fallback_parent = parent;
2114 fallback_signature_is_good = signature_is_good;
2115 }
2116
2117 continue;
2118 }
2119
2120 *r_parent = parent;
2121 *r_signature_is_good = signature_is_good;
2122
2123 break;
2124 }
2125
2126 if( parent == NULL )
2127 {
2128 *r_parent = fallback_parent;
2129 *r_signature_is_good = fallback_signature_is_good;
2130 }
2131
2132 return( 0 );
2133}
2134
2135/*
2136 * Find a parent in trusted CAs or the provided chain, or return NULL.
2137 *
2138 * Searches in trusted CAs first, and return the first suitable parent found
2139 * (see find_parent_in() for definition of suitable).
2140 *
2141 * Arguments:
2142 * - [in] child: certificate for which we're looking for a parent, followed
2143 * by a chain of possible intermediates
2144 * - [in] trust_ca: list of locally trusted certificates
2145 * - [out] parent: parent found (or NULL)
2146 * - [out] parent_is_trusted: 1 if returned `parent` is trusted, or 0
2147 * - [out] signature_is_good: 1 if child signature by parent is valid, or 0
2148 * - [in] path_cnt: number of links in the chain so far (EE -> ... -> child)
2149 * - [in] self_cnt: number of self-signed certs in the chain so far
2150 * (will always be no greater than path_cnt)
2151 * - [in-out] rs_ctx: context for restarting operations
2152 *
2153 * Return value:
2154 * - 0 on success
2155 * - MBEDTLS_ERR_ECP_IN_PROGRESS otherwise
2156 */
2157static int x509_crt_find_parent(
2159 mbedtls_x509_crt *trust_ca,
2161 int *parent_is_trusted,
2162 int *signature_is_good,
2163 unsigned path_cnt,
2164 unsigned self_cnt,
2166{
2167 int ret;
2168 mbedtls_x509_crt *search_list;
2169
2170 *parent_is_trusted = 1;
2171
2172#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
2173 /* restore then clear saved state if we have some stored */
2174 if( rs_ctx != NULL && rs_ctx->parent_is_trusted != -1 )
2175 {
2176 *parent_is_trusted = rs_ctx->parent_is_trusted;
2177 rs_ctx->parent_is_trusted = -1;
2178 }
2179#endif
2180
2181 while( 1 ) {
2182 search_list = *parent_is_trusted ? trust_ca : child->next;
2183
2184 ret = x509_crt_find_parent_in( child, search_list,
2185 parent, signature_is_good,
2186 *parent_is_trusted,
2187 path_cnt, self_cnt, rs_ctx );
2188
2189#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
2190 if( rs_ctx != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
2191 {
2192 /* save state */
2193 rs_ctx->parent_is_trusted = *parent_is_trusted;
2194 return( ret );
2195 }
2196#else
2197 (void) ret;
2198#endif
2199
2200 /* stop here if found or already in second iteration */
2201 if( *parent != NULL || *parent_is_trusted == 0 )
2202 break;
2203
2204 /* prepare second iteration */
2205 *parent_is_trusted = 0;
2206 }
2207
2208 /* extra precaution against mistakes in the caller */
2209 if( *parent == NULL )
2210 {
2211 *parent_is_trusted = 0;
2212 *signature_is_good = 0;
2213 }
2214
2215 return( 0 );
2216}
2217
2218/*
2219 * Check if an end-entity certificate is locally trusted
2220 *
2221 * Currently we require such certificates to be self-signed (actually only
2222 * check for self-issued as self-signatures are not checked)
2223 */
2224static int x509_crt_check_ee_locally_trusted(
2225 mbedtls_x509_crt *crt,
2226 mbedtls_x509_crt *trust_ca )
2227{
2229
2230 /* must be self-issued */
2231 if( x509_name_cmp( &crt->issuer, &crt->subject ) != 0 )
2232 return( -1 );
2233
2234 /* look for an exact match with trusted cert */
2235 for( cur = trust_ca; cur != NULL; cur = cur->next )
2236 {
2237 if( crt->raw.len == cur->raw.len &&
2238 memcmp( crt->raw.p, cur->raw.p, crt->raw.len ) == 0 )
2239 {
2240 return( 0 );
2241 }
2242 }
2243
2244 /* too bad */
2245 return( -1 );
2246}
2247
2248/*
2249 * Build and verify a certificate chain
2250 *
2251 * Given a peer-provided list of certificates EE, C1, ..., Cn and
2252 * a list of trusted certs R1, ... Rp, try to build and verify a chain
2253 * EE, Ci1, ... Ciq [, Rj]
2254 * such that every cert in the chain is a child of the next one,
2255 * jumping to a trusted root as early as possible.
2256 *
2257 * Verify that chain and return it with flags for all issues found.
2258 *
2259 * Special cases:
2260 * - EE == Rj -> return a one-element list containing it
2261 * - EE, Ci1, ..., Ciq cannot be continued with a trusted root
2262 * -> return that chain with NOT_TRUSTED set on Ciq
2263 *
2264 * Tests for (aspects of) this function should include at least:
2265 * - trusted EE
2266 * - EE -> trusted root
2267 * - EE -> intermediate CA -> trusted root
2268 * - if relevant: EE untrusted
2269 * - if relevant: EE -> intermediate, untrusted
2270 * with the aspect under test checked at each relevant level (EE, int, root).
2271 * For some aspects longer chains are required, but usually length 2 is
2272 * enough (but length 1 is not in general).
2273 *
2274 * Arguments:
2275 * - [in] crt: the cert list EE, C1, ..., Cn
2276 * - [in] trust_ca: the trusted list R1, ..., Rp
2277 * - [in] ca_crl, profile: as in verify_with_profile()
2278 * - [out] ver_chain: the built and verified chain
2279 * Only valid when return value is 0, may contain garbage otherwise!
2280 * Restart note: need not be the same when calling again to resume.
2281 * - [in-out] rs_ctx: context for restarting operations
2282 *
2283 * Return value:
2284 * - non-zero if the chain could not be fully built and examined
2285 * - 0 is the chain was successfully built and examined,
2286 * even if it was found to be invalid
2287 */
2288static int x509_crt_verify_chain(
2289 mbedtls_x509_crt *crt,
2290 mbedtls_x509_crt *trust_ca,
2291 mbedtls_x509_crl *ca_crl,
2295{
2296 /* Don't initialize any of those variables here, so that the compiler can
2297 * catch potential issues with jumping ahead when restarting */
2298 int ret;
2299 uint32_t *flags;
2303 int parent_is_trusted;
2304 int child_is_trusted;
2305 int signature_is_good;
2306 unsigned self_cnt;
2307
2308#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
2309 /* resume if we had an operation in progress */
2310 if( rs_ctx != NULL && rs_ctx->in_progress == x509_crt_rs_find_parent )
2311 {
2312 /* restore saved state */
2313 *ver_chain = rs_ctx->ver_chain; /* struct copy */
2314 self_cnt = rs_ctx->self_cnt;
2315
2316 /* restore derived state */
2317 cur = &ver_chain->items[ver_chain->len - 1];
2318 child = cur->crt;
2319 flags = &cur->flags;
2320
2321 goto find_parent;
2322 }
2323#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
2324
2325 child = crt;
2326 self_cnt = 0;
2327 parent_is_trusted = 0;
2328 child_is_trusted = 0;
2329
2330 while( 1 ) {
2331 /* Add certificate to the verification chain */
2332 cur = &ver_chain->items[ver_chain->len];
2333 cur->crt = child;
2334 cur->flags = 0;
2335 ver_chain->len++;
2336 flags = &cur->flags;
2337
2338 /* Check time-validity (all certificates) */
2339 if( mbedtls_x509_time_is_past( &child->valid_to ) )
2341
2342 if( mbedtls_x509_time_is_future( &child->valid_from ) )
2344
2345 /* Stop here for trusted roots (but not for trusted EE certs) */
2346 if( child_is_trusted )
2347 return( 0 );
2348
2349 /* Check signature algorithm: MD & PK algs */
2350 if( x509_profile_check_md_alg( profile, child->sig_md ) != 0 )
2352
2353 if( x509_profile_check_pk_alg( profile, child->sig_pk ) != 0 )
2355
2356 /* Special case: EE certs that are locally trusted */
2357 if( ver_chain->len == 1 &&
2358 x509_crt_check_ee_locally_trusted( child, trust_ca ) == 0 )
2359 {
2360 return( 0 );
2361 }
2362
2363#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
2364find_parent:
2365#endif
2366 /* Look for a parent in trusted CAs or up the chain */
2367 ret = x509_crt_find_parent( child, trust_ca, &parent,
2368 &parent_is_trusted, &signature_is_good,
2369 ver_chain->len - 1, self_cnt, rs_ctx );
2370
2371#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
2372 if( rs_ctx != NULL && ret == MBEDTLS_ERR_ECP_IN_PROGRESS )
2373 {
2374 /* save state */
2375 rs_ctx->in_progress = x509_crt_rs_find_parent;
2376 rs_ctx->self_cnt = self_cnt;
2377 rs_ctx->ver_chain = *ver_chain; /* struct copy */
2378
2379 return( ret );
2380 }
2381#else
2382 (void) ret;
2383#endif
2384
2385 /* No parent? We're done here */
2386 if( parent == NULL )
2387 {
2389 return( 0 );
2390 }
2391
2392 /* Count intermediate self-issued (not necessarily self-signed) certs.
2393 * These can occur with some strategies for key rollover, see [SIRO],
2394 * and should be excluded from max_pathlen checks. */
2395 if( ver_chain->len != 1 &&
2396 x509_name_cmp( &child->issuer, &child->subject ) == 0 )
2397 {
2398 self_cnt++;
2399 }
2400
2401 /* path_cnt is 0 for the first intermediate CA,
2402 * and if parent is trusted it's not an intermediate CA */
2403 if( ! parent_is_trusted &&
2405 {
2406 /* return immediately to avoid overflow the chain array */
2408 }
2409
2410 /* signature was checked while searching parent */
2411 if( ! signature_is_good )
2413
2414 /* check size of signing key */
2415 if( x509_profile_check_key( profile, &parent->pk ) != 0 )
2417
2418#if defined(MBEDTLS_X509_CRL_PARSE_C)
2419 /* Check trusted CA's CRL for the given crt */
2420 *flags |= x509_crt_verifycrl( child, parent, ca_crl, profile );
2421#else
2422 (void) ca_crl;
2423#endif
2424
2425 /* prepare for next iteration */
2426 child = parent;
2427 parent = NULL;
2428 child_is_trusted = parent_is_trusted;
2429 signature_is_good = 0;
2430 }
2431}
2432
2433/*
2434 * Check for CN match
2435 */
2436static int x509_crt_check_cn( const mbedtls_x509_buf *name,
2437 const char *cn, size_t cn_len )
2438{
2439 /* try exact match */
2440 if( name->len == cn_len &&
2441 x509_memcasecmp( cn, name->p, cn_len ) == 0 )
2442 {
2443 return( 0 );
2444 }
2445
2446 /* try wildcard match */
2447 if( x509_check_wildcard( cn, name ) == 0 )
2448 {
2449 return( 0 );
2450 }
2451
2452 return( -1 );
2453}
2454
2455/*
2456 * Verify the requested CN - only call this if cn is not NULL!
2457 */
2458static void x509_crt_verify_name( const mbedtls_x509_crt *crt,
2459 const char *cn,
2460 uint32_t *flags )
2461{
2462 const mbedtls_x509_name *name;
2464 size_t cn_len = strlen( cn );
2465
2467 {
2468 for( cur = &crt->subject_alt_names; cur != NULL; cur = cur->next )
2469 {
2470 if( x509_crt_check_cn( &cur->buf, cn, cn_len ) == 0 )
2471 break;
2472 }
2473
2474 if( cur == NULL )
2476 }
2477 else
2478 {
2479 for( name = &crt->subject; name != NULL; name = name->next )
2480 {
2481 if( MBEDTLS_OID_CMP( MBEDTLS_OID_AT_CN, &name->oid ) == 0 &&
2482 x509_crt_check_cn( &name->val, cn, cn_len ) == 0 )
2483 {
2484 break;
2485 }
2486 }
2487
2488 if( name == NULL )
2490 }
2491}
2492
2493/*
2494 * Merge the flags for all certs in the chain, after calling callback
2495 */
2496static int x509_crt_merge_flags_with_cb(
2497 uint32_t *flags,
2498 const mbedtls_x509_crt_verify_chain *ver_chain,
2499 int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
2500 void *p_vrfy )
2501{
2502 int ret;
2503 unsigned i;
2504 uint32_t cur_flags;
2506
2507 for( i = ver_chain->len; i != 0; --i )
2508 {
2509 cur = &ver_chain->items[i-1];
2510 cur_flags = cur->flags;
2511
2512 if( NULL != f_vrfy )
2513 if( ( ret = f_vrfy( p_vrfy, cur->crt, (int) i-1, &cur_flags ) ) != 0 )
2514 return( ret );
2515
2516 *flags |= cur_flags;
2517 }
2518
2519 return( 0 );
2520}
2521
2522/*
2523 * Verify the certificate validity (default profile, not restartable)
2524 */
2526 mbedtls_x509_crt *trust_ca,
2527 mbedtls_x509_crl *ca_crl,
2528 const char *cn, uint32_t *flags,
2529 int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
2530 void *p_vrfy )
2531{
2532 return( mbedtls_x509_crt_verify_restartable( crt, trust_ca, ca_crl,
2534 f_vrfy, p_vrfy, NULL ) );
2535}
2536
2537/*
2538 * Verify the certificate validity (user-chosen profile, not restartable)
2539 */
2541 mbedtls_x509_crt *trust_ca,
2542 mbedtls_x509_crl *ca_crl,
2544 const char *cn, uint32_t *flags,
2545 int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
2546 void *p_vrfy )
2547{
2548 return( mbedtls_x509_crt_verify_restartable( crt, trust_ca, ca_crl,
2549 profile, cn, flags, f_vrfy, p_vrfy, NULL ) );
2550}
2551
2552/*
2553 * Verify the certificate validity, with profile, restartable version
2554 *
2555 * This function:
2556 * - checks the requested CN (if any)
2557 * - checks the type and size of the EE cert's key,
2558 * as that isn't done as part of chain building/verification currently
2559 * - builds and verifies the chain
2560 * - then calls the callback and merges the flags
2561 */
2563 mbedtls_x509_crt *trust_ca,
2564 mbedtls_x509_crl *ca_crl,
2566 const char *cn, uint32_t *flags,
2567 int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *),
2568 void *p_vrfy,
2570{
2571 int ret;
2572 mbedtls_pk_type_t pk_type;
2574 uint32_t ee_flags;
2575
2576 *flags = 0;
2577 ee_flags = 0;
2578 x509_crt_verify_chain_reset( &ver_chain );
2579
2580 if( profile == NULL )
2581 {
2583 goto exit;
2584 }
2585
2586 /* check name if requested */
2587 if( cn != NULL )
2588 x509_crt_verify_name( crt, cn, &ee_flags );
2589
2590 /* Check the type and size of the key */
2591 pk_type = mbedtls_pk_get_type( &crt->pk );
2592
2593 if( x509_profile_check_pk_alg( profile, pk_type ) != 0 )
2594 ee_flags |= MBEDTLS_X509_BADCERT_BAD_PK;
2595
2596 if( x509_profile_check_key( profile, &crt->pk ) != 0 )
2597 ee_flags |= MBEDTLS_X509_BADCERT_BAD_KEY;
2598
2599 /* Check the chain */
2600 ret = x509_crt_verify_chain( crt, trust_ca, ca_crl, profile,
2601 &ver_chain, rs_ctx );
2602
2603 if( ret != 0 )
2604 goto exit;
2605
2606 /* Merge end-entity flags */
2607 ver_chain.items[0].flags |= ee_flags;
2608
2609 /* Build final flags, calling callback on the way if any */
2610 ret = x509_crt_merge_flags_with_cb( flags, &ver_chain, f_vrfy, p_vrfy );
2611
2612exit:
2613#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
2614 if( rs_ctx != NULL && ret != MBEDTLS_ERR_ECP_IN_PROGRESS )
2615 mbedtls_x509_crt_restart_free( rs_ctx );
2616#endif
2617
2618 /* prevent misuse of the vrfy callback - VERIFY_FAILED would be ignored by
2619 * the SSL module for authmode optional, but non-zero return from the
2620 * callback means a fatal error so it shouldn't be ignored */
2623
2624 if( ret != 0 )
2625 {
2626 *flags = (uint32_t) -1;
2627 return( ret );
2628 }
2629
2630 if( *flags != 0 )
2632
2633 return( 0 );
2634}
2635
2636/*
2637 * Initialize a certificate chain
2638 */
2640{
2641 memset( crt, 0, sizeof(mbedtls_x509_crt) );
2642}
2643
2644/*
2645 * Unallocate all certificate data
2646 */
2648{
2649 mbedtls_x509_crt *cert_cur = crt;
2650 mbedtls_x509_crt *cert_prv;
2651 mbedtls_x509_name *name_cur;
2652 mbedtls_x509_name *name_prv;
2653 mbedtls_x509_sequence *seq_cur;
2654 mbedtls_x509_sequence *seq_prv;
2655
2656 if( crt == NULL )
2657 return;
2658
2659 do
2660 {
2661 mbedtls_pk_free( &cert_cur->pk );
2662
2663#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
2664 mbedtls_free( cert_cur->sig_opts );
2665#endif
2666
2667 name_cur = cert_cur->issuer.next;
2668 while( name_cur != NULL )
2669 {
2670 name_prv = name_cur;
2671 name_cur = name_cur->next;
2672 mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
2673 mbedtls_free( name_prv );
2674 }
2675
2676 name_cur = cert_cur->subject.next;
2677 while( name_cur != NULL )
2678 {
2679 name_prv = name_cur;
2680 name_cur = name_cur->next;
2681 mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
2682 mbedtls_free( name_prv );
2683 }
2684
2685 seq_cur = cert_cur->ext_key_usage.next;
2686 while( seq_cur != NULL )
2687 {
2688 seq_prv = seq_cur;
2689 seq_cur = seq_cur->next;
2690 mbedtls_platform_zeroize( seq_prv,
2691 sizeof( mbedtls_x509_sequence ) );
2692 mbedtls_free( seq_prv );
2693 }
2694
2695 seq_cur = cert_cur->subject_alt_names.next;
2696 while( seq_cur != NULL )
2697 {
2698 seq_prv = seq_cur;
2699 seq_cur = seq_cur->next;
2700 mbedtls_platform_zeroize( seq_prv,
2701 sizeof( mbedtls_x509_sequence ) );
2702 mbedtls_free( seq_prv );
2703 }
2704
2705 if( cert_cur->raw.p != NULL )
2706 {
2707 mbedtls_platform_zeroize( cert_cur->raw.p, cert_cur->raw.len );
2708 mbedtls_free( cert_cur->raw.p );
2709 }
2710
2711 cert_cur = cert_cur->next;
2712 }
2713 while( cert_cur != NULL );
2714
2715 cert_cur = crt;
2716 do
2717 {
2718 cert_prv = cert_cur;
2719 cert_cur = cert_cur->next;
2720
2721 mbedtls_platform_zeroize( cert_prv, sizeof( mbedtls_x509_crt ) );
2722 if( cert_prv != crt )
2723 mbedtls_free( cert_prv );
2724 }
2725 while( cert_cur != NULL );
2726}
2727
2728#if defined(MBEDTLS_ECDSA_C) && defined(MBEDTLS_ECP_RESTARTABLE)
2729/*
2730 * Initialize a restart context
2731 */
2732void mbedtls_x509_crt_restart_init( mbedtls_x509_crt_restart_ctx *ctx )
2733{
2734 mbedtls_pk_restart_init( &ctx->pk );
2735
2736 ctx->parent = NULL;
2737 ctx->fallback_parent = NULL;
2738 ctx->fallback_signature_is_good = 0;
2739
2740 ctx->parent_is_trusted = -1;
2741
2742 ctx->in_progress = x509_crt_rs_none;
2743 ctx->self_cnt = 0;
2744 x509_crt_verify_chain_reset( &ctx->ver_chain );
2745}
2746
2747/*
2748 * Free the components of a restart context
2749 */
2750void mbedtls_x509_crt_restart_free( mbedtls_x509_crt_restart_ctx *ctx )
2751{
2752 if( ctx == NULL )
2753 return;
2754
2755 mbedtls_pk_restart_free( &ctx->pk );
2756 mbedtls_x509_crt_restart_init( ctx );
2757}
2758#endif /* MBEDTLS_ECDSA_C && MBEDTLS_ECP_RESTARTABLE */
2759
2760#endif /* MBEDTLS_X509_CRT_PARSE_C */
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define stat
Definition: acwin.h:99
unsigned int dir
Definition: maze.c:112
#define S_ISREG(mode)
Definition: various.h:17
#define NULL
Definition: types.h:112
UINT32 uint32_t
Definition: types.h:75
static const WCHAR ca[]
Definition: main.c:455
#define CP_ACP
Definition: compat.h:109
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define MAX_PATH
Definition: compat.h:34
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
#define lstrlenW
Definition: compat.h:750
static void cleanup(void)
Definition: main.c:1335
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:320
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502
BOOL WINAPI FindNextFileW(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:382
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
superblock * sb
Definition: btrfs.c:4261
r parent
Definition: btrfs.c:3010
#define MBEDTLS_ERR_ECP_IN_PROGRESS
Definition: ecp.h:87
mbedtls_ecp_group_id
Definition: ecp.h:103
@ MBEDTLS_ECP_DP_SECP384R1
Definition: ecp.h:108
@ MBEDTLS_ECP_DP_NONE
Definition: ecp.h:104
@ MBEDTLS_ECP_DP_SECP256K1
Definition: ecp.h:116
@ MBEDTLS_ECP_DP_BP512R1
Definition: ecp.h:112
@ MBEDTLS_ECP_DP_SECP521R1
Definition: ecp.h:109
@ MBEDTLS_ECP_DP_BP384R1
Definition: ecp.h:111
@ MBEDTLS_ECP_DP_BP256R1
Definition: ecp.h:110
@ MBEDTLS_ECP_DP_SECP256R1
Definition: ecp.h:107
FxCollectionEntry * cur
GLuint GLuint end
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLdouble n
Definition: glext.h:7729
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLbitfield flags
Definition: glext.h:7161
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLsizeiptr const GLvoid GLenum usage
Definition: glext.h:5919
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define MBEDTLS_ASN1_TAG_CLASS_MASK
Definition: asn1.h:127
size_t len
Definition: asn1.h:162
#define MBEDTLS_ASN1_OCTET_STRING
Definition: asn1.h:100
unsigned char * p
Definition: asn1.h:163
#define MBEDTLS_OID_CMP(oid_str, oid_buf)
Definition: asn1.h:143
#define MBEDTLS_ERR_ASN1_INVALID_LENGTH
Definition: asn1.h:78
#define MBEDTLS_ERR_ASN1_OUT_OF_DATA
Definition: asn1.h:76
struct mbedtls_asn1_named_data * next
Definition: asn1.h:195
#define MBEDTLS_ASN1_PRINTABLE_STRING
Definition: asn1.h:106
#define MBEDTLS_ASN1_SEQUENCE
Definition: asn1.h:104
mbedtls_asn1_buf buf
Definition: asn1.h:183
int mbedtls_asn1_get_int(unsigned char **p, const unsigned char *end, int *val)
Retrieve an integer ASN.1 tag and its value. Updates the pointer to immediately behind the full tag.
int mbedtls_asn1_get_sequence_of(unsigned char **p, const unsigned char *end, mbedtls_asn1_sequence *cur, int tag)
Parses and splits an ASN.1 "SEQUENCE OF <tag>" Updated the pointer to immediately behind the full seq...
#define MBEDTLS_ASN1_CONTEXT_SPECIFIC
Definition: asn1.h:115
#define MBEDTLS_ASN1_CONSTRUCTED
Definition: asn1.h:114
#define MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
Definition: asn1.h:77
#define MBEDTLS_ERR_ASN1_ALLOC_FAILED
Definition: asn1.h:81
struct mbedtls_asn1_sequence * next
Definition: asn1.h:184
#define MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
Definition: asn1.h:79
int mbedtls_asn1_get_len(unsigned char **p, const unsigned char *end, size_t *len)
Get the length of an ASN.1 element. Updates the pointer to immediately behind the length.
#define MBEDTLS_ASN1_OID
Definition: asn1.h:102
int mbedtls_asn1_get_bitstring(unsigned char **p, const unsigned char *end, mbedtls_asn1_bitstring *bs)
Retrieve a bitstring ASN.1 tag and its value. Updates the pointer to immediately behind the full tag.
int mbedtls_asn1_get_tag(unsigned char **p, const unsigned char *end, size_t *len, int tag)
Get the tag and length of the tag. Check for the requested tag. Updates the pointer to immediately be...
int mbedtls_asn1_get_bool(unsigned char **p, const unsigned char *end, int *val)
Retrieve a boolean ASN.1 tag and its value. Updates the pointer to immediately behind the full tag.
#define MBEDTLS_ASN1_UTF8_STRING
Definition: asn1.h:103
int mbedtls_x509_crt_parse_der(mbedtls_x509_crt *chain, const unsigned char *buf, size_t buflen)
Parse a single DER formatted certificate and add it to the chained list.
void mbedtls_x509_crt_init(mbedtls_x509_crt *crt)
Initialize a certificate (chain)
int mbedtls_x509_crt_parse(mbedtls_x509_crt *chain, const unsigned char *buf, size_t buflen)
Parse one DER-encoded or one or more concatenated PEM-encoded certificates and add them to the chaine...
mbedtls_x509_time valid_to
Definition: x509_crt.h:94
int mbedtls_x509_time_is_past(const mbedtls_x509_time *to)
Check a given mbedtls_x509_time against the system time and tell if it's in the past.
int mbedtls_x509_crt_check_key_usage(const mbedtls_x509_crt *crt, unsigned int usage)
Check usage of certificate against keyUsage extension.
#define MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING
Definition: x509.h:159
#define MBEDTLS_X509_BADCERT_NOT_TRUSTED
Definition: x509.h:116
int mbedtls_x509_time_is_future(const mbedtls_x509_time *from)
Check a given mbedtls_x509_time against the system time and tell if it's in the future.
#define MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA
Definition: x509.h:162
mbedtls_x509_buf sig_oid
Definition: x509_crt.h:85
#define MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA
Definition: x509.h:163
#define MBEDTLS_X509_BADCRL_BAD_PK
Definition: x509.h:131
#define MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE
Definition: x509.h:86
#define MBEDTLS_X509_FORMAT_PEM
Definition: x509.h:194
int mbedtls_x509_get_name(unsigned char **p, const unsigned char *end, mbedtls_x509_name *cur)
#define MBEDTLS_X509_BADCERT_SKIP_VERIFY
Definition: x509.h:120
mbedtls_x509_sequence subject_alt_names
Definition: x509_crt.h:101
#define MBEDTLS_X509_BADCERT_KEY_USAGE
Definition: x509.h:124
#define MBEDTLS_X509_KU_DIGITAL_SIGNATURE
Definition: x509.h:141
#define MBEDTLS_X509_KU_DECIPHER_ONLY
Definition: x509.h:149
int mbedtls_x509_crt_verify_restartable(mbedtls_x509_crt *crt, mbedtls_x509_crt *trust_ca, mbedtls_x509_crl *ca_crl, const mbedtls_x509_crt_profile *profile, const char *cn, uint32_t *flags, int(*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), void *p_vrfy, mbedtls_x509_crt_restart_ctx *rs_ctx)
Restartable version of mbedtls_crt_verify_with_profile()
#define MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT
Definition: x509.h:156
unsigned int key_usage
Definition: x509_crt.h:107
#define MBEDTLS_X509_BADCERT_BAD_MD
Definition: x509.h:127
#define MBEDTLS_X509_NS_CERT_TYPE_EMAIL
Definition: x509.h:158
mbedtls_x509_buf tbs
Definition: x509_crt.h:81
#define MBEDTLS_ERR_X509_INVALID_FORMAT
Definition: x509.h:88
#define MBEDTLS_X509_MAX_FILE_PATH_LEN
Definition: x509_crt.h:150
#define MBEDTLS_ERR_X509_FATAL_ERROR
Definition: x509.h:105
#define MBEDTLS_ERR_X509_INVALID_VERSION
Definition: x509.h:89
#define MBEDTLS_X509_MAX_VERIFY_CHAIN_SIZE
Definition: x509_crt.h:182
int mbedtls_x509_dn_gets(char *buf, size_t size, const mbedtls_x509_name *dn)
Store the certificate DN in printable form into buf; no more than size characters will be written.
mbedtls_x509_buf raw
Definition: x509_crt.h:80
mbedtls_x509_buf serial
Definition: x509_crt.h:84
mbedtls_md_type_t sig_md
Definition: x509_crt.h:114
#define MBEDTLS_X509_BADCERT_EXPIRED
Definition: x509.h:113
mbedtls_x509_time this_update
Definition: x509_crl.h:107
#define MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER
Definition: x509.h:157
mbedtls_pk_context pk
Definition: x509_crt.h:96
mbedtls_pk_type_t sig_pk
Definition: x509_crt.h:115
void * sig_opts
Definition: x509_crt.h:116
#define MBEDTLS_X509_KU_KEY_CERT_SIGN
Definition: x509.h:146
mbedtls_x509_buf v3_ext
Definition: x509_crt.h:100
mbedtls_x509_buf issuer_id
Definition: x509_crt.h:98
struct mbedtls_x509_crl * next
Definition: x509_crl.h:120
#define MBEDTLS_X509_BADCERT_CN_MISMATCH
Definition: x509.h:115
#define MBEDTLS_X509_BADCERT_OTHER
Definition: x509.h:121
mbedtls_x509_name subject
Definition: x509_crt.h:91
#define MBEDTLS_X509_NS_CERT_TYPE_SSL_CA
Definition: x509.h:161
mbedtls_md_type_t sig_md
Definition: x509_crl.h:116
#define MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE
Definition: x509.h:182
mbedtls_x509_time next_update
Definition: x509_crl.h:108
const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_next
#define MBEDTLS_X509_BADCERT_MISSING
Definition: x509.h:119
#define MBEDTLS_X509_SAFE_SNPRINTF
Definition: x509.h:349
mbedtls_pk_type_t sig_pk
Definition: x509_crl.h:117
int mbedtls_x509_get_sig_alg(const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params, mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg, void **sig_opts)
mbedtls_x509_buf sig
Definition: x509_crl.h:115
#define MBEDTLS_X509_BADCERT_BAD_PK
Definition: x509.h:128
#define MBEDTLS_X509_EXT_BASIC_CONSTRAINTS
Definition: x509.h:179
int mbedtls_x509_get_alg(unsigned char **p, const unsigned char *end, mbedtls_x509_buf *alg, mbedtls_x509_buf *params)
int mbedtls_x509_crt_verify(mbedtls_x509_crt *crt, mbedtls_x509_crt *trust_ca, mbedtls_x509_crl *ca_crl, const char *cn, uint32_t *flags, int(*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), void *p_vrfy)
Verify the certificate signature.
#define MBEDTLS_X509_KU_CRL_SIGN
Definition: x509.h:147
const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default
#define MBEDTLS_ERR_X509_INVALID_EXTENSIONS
Definition: x509.h:95
mbedtls_x509_crt_verify_chain_item items[MBEDTLS_X509_MAX_VERIFY_CHAIN_SIZE]
Definition: x509_crt.h:189
#define MBEDTLS_X509_BADCERT_NS_CERT_TYPE
Definition: x509.h:126
int mbedtls_x509_get_ext(unsigned char **p, const unsigned char *end, mbedtls_x509_buf *ext, int tag)
mbedtls_x509_time valid_from
Definition: x509_crt.h:93
mbedtls_x509_name issuer
Definition: x509_crl.h:105
#define MBEDTLS_X509_KU_NON_REPUDIATION
Definition: x509.h:142
void mbedtls_x509_crt_free(mbedtls_x509_crt *crt)
Unallocate all certificate data.
#define MBEDTLS_X509_EXT_KEY_USAGE
Definition: x509.h:173
mbedtls_x509_buf tbs
Definition: x509_crl.h:98
#define MBEDTLS_ERR_X509_UNKNOWN_VERSION
Definition: x509.h:96
#define MBEDTLS_X509_EXT_SUBJECT_ALT_NAME
Definition: x509.h:176
#define MBEDTLS_ERR_X509_BUFFER_TOO_SMALL
Definition: x509.h:104
#define MBEDTLS_X509_MAX_INTERMEDIATE_CA
Definition: x509.h:79
#define MBEDTLS_ERR_X509_CERT_VERIFY_FAILED
Definition: x509.h:99
int mbedtls_x509_key_size_helper(char *buf, size_t buf_size, const char *name)
int mbedtls_x509_crt_info(char *buf, size_t size, const char *prefix, const mbedtls_x509_crt *crt)
Returns an informational string about the certificate.
#define MBEDTLS_X509_KU_KEY_AGREEMENT
Definition: x509.h:145
#define MBEDTLS_X509_KU_ENCIPHER_ONLY
Definition: x509.h:148
#define MBEDTLS_X509_BADCRL_BAD_KEY
Definition: x509.h:132
mbedtls_x509_buf subject_raw
Definition: x509_crt.h:88
#define MBEDTLS_ERR_X509_INVALID_DATE
Definition: x509.h:93
#define MBEDTLS_X509_BADCERT_EXT_KEY_USAGE
Definition: x509.h:125
#define MBEDTLS_ERR_X509_SIG_MISMATCH
Definition: x509.h:98
int mbedtls_x509_sig_alg_gets(char *buf, size_t size, const mbedtls_x509_buf *sig_oid, mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg, const void *sig_opts)
#define MBEDTLS_X509_BADCERT_FUTURE
Definition: x509.h:122
mbedtls_x509_sequence ext_key_usage
Definition: x509_crt.h:109
struct mbedtls_x509_crt * next
Definition: x509_crt.h:118
#define MBEDTLS_ERR_X509_ALLOC_FAILED
Definition: x509.h:102
int mbedtls_x509_get_serial(unsigned char **p, const unsigned char *end, mbedtls_x509_buf *serial)
int mbedtls_x509_get_sig(unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig)
#define MBEDTLS_X509_BADCRL_NOT_TRUSTED
Definition: x509.h:117
int mbedtls_x509_crt_check_extended_key_usage(const mbedtls_x509_crt *crt, const char *usage_oid, size_t usage_len)
Check usage of certificate against extendedKeyUsage.
#define MBEDTLS_X509_FORMAT_DER
Definition: x509.h:193
#define MBEDTLS_X509_KU_DATA_ENCIPHERMENT
Definition: x509.h:144
#define MBEDTLS_X509_BADCRL_BAD_MD
Definition: x509.h:130
void * sig_opts
Definition: x509_crl.h:118
int mbedtls_x509_get_time(unsigned char **p, const unsigned char *end, mbedtls_x509_time *t)
#define MBEDTLS_X509_KU_KEY_ENCIPHERMENT
Definition: x509.h:143
#define MBEDTLS_ERR_X509_FILE_IO_ERROR
Definition: x509.h:103
#define MBEDTLS_X509_BADCRL_FUTURE
Definition: x509.h:123
mbedtls_x509_buf subject_id
Definition: x509_crt.h:99
unsigned char ns_cert_type
Definition: x509_crt.h:111
#define MBEDTLS_X509_EXT_NS_CERT_TYPE
Definition: x509.h:187
#define MBEDTLS_X509_BADCERT_REVOKED
Definition: x509.h:114
mbedtls_x509_name issuer
Definition: x509_crt.h:90
int mbedtls_x509_crt_verify_info(char *buf, size_t size, const char *prefix, uint32_t flags)
Returns an informational string about the verification status of a certificate.
#define MBEDTLS_X509_NS_CERT_TYPE_RESERVED
Definition: x509.h:160
mbedtls_x509_buf sig
Definition: x509_crt.h:113
#define MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT
Definition: x509.h:100
#define MBEDTLS_X509_BADCRL_EXPIRED
Definition: x509.h:118
#define MBEDTLS_X509_ID_FLAG(id)
Definition: x509_crt.h:126
#define MBEDTLS_ERR_X509_BAD_INPUT_DATA
Definition: x509.h:101
#define MBEDTLS_X509_BADCERT_BAD_KEY
Definition: x509.h:129
int mbedtls_x509_crt_verify_with_profile(mbedtls_x509_crt *crt, mbedtls_x509_crt *trust_ca, mbedtls_x509_crl *ca_crl, const mbedtls_x509_crt_profile *profile, const char *cn, uint32_t *flags, int(*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), void *p_vrfy)
Verify the certificate signature according to profile.
const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb
int mbedtls_x509_serial_gets(char *buf, size_t size, const mbedtls_x509_buf *serial)
Store the certificate serial in printable form into buf; no more than size characters will be written...
mbedtls_x509_buf issuer_raw
Definition: x509_crt.h:87
int __cdecl closedir(DIR *)
DIR *__cdecl opendir(const char *)
struct dirent *__cdecl readdir(DIR *)
#define INT_MAX
Definition: limits.h:40
const char * filename
Definition: ioapi.h:137
uint32_t entry
Definition: isohybrid.c:63
#define profile
Definition: kernel32.h:12
mbedtls_md_type_t
Supported message digests.
Definition: md.h:83
@ MBEDTLS_MD_SHA512
Definition: md.h:92
@ MBEDTLS_MD_SHA384
Definition: md.h:91
@ MBEDTLS_MD_NONE
Definition: md.h:84
@ MBEDTLS_MD_SHA256
Definition: md.h:90
@ MBEDTLS_MD_SHA224
Definition: md.h:89
@ MBEDTLS_MD_SHA1
Definition: md.h:88
int mbedtls_md(const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen, unsigned char *output)
This function calculates the message-digest of a buffer, with respect to a configurable message-diges...
#define MBEDTLS_MD_MAX_SIZE
Definition: md.h:97
unsigned char mbedtls_md_get_size(const mbedtls_md_info_t *md_info)
This function extracts the message-digest size from the message-digest information structure.
struct S1 s1
struct S2 s2
static struct msdos_boot_sector bs
Definition: mkdosfs.c:539
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
char string[160]
Definition: util.h:11
static BYTE cn[]
Definition: cert.c:2938
static const BYTE crl[]
Definition: message.c:864
static const WCHAR desc[]
Definition: protectdata.c:36
static HWND child
Definition: cursoricon.c:298
#define uint32_t
Definition: nsiface.idl:61
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
Object Identifier (OID) database.
int mbedtls_oid_get_extended_key_usage(const mbedtls_asn1_buf *oid, const char **desc)
Translate Extended Key Usage OID into description.
#define MBEDTLS_OID_ANY_EXTENDED_KEY_USAGE
Definition: oid.h:201
int mbedtls_oid_get_x509_ext_type(const mbedtls_asn1_buf *oid, int *ext_type)
Translate an X.509 extension OID into local values.
#define MBEDTLS_OID_AT_CN
Definition: oid.h:138
Privacy Enhanced Mail (PEM) decoding.
#define MBEDTLS_ERR_PEM_BAD_INPUT_DATA
Definition: pem.h:74
#define MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT
Definition: pem.h:66
int mbedtls_pk_parse_subpubkey(unsigned char **p, const unsigned char *end, mbedtls_pk_context *pk)
Parse a SubjectPublicKeyInfo DER structure.
int mbedtls_pk_can_do(const mbedtls_pk_context *ctx, mbedtls_pk_type_t type)
Tell if a context can do the operation given by type.
mbedtls_pk_type_t
Public key types.
Definition: pk.h:103
@ MBEDTLS_PK_NONE
Definition: pk.h:104
@ MBEDTLS_PK_ECDSA
Definition: pk.h:108
@ MBEDTLS_PK_RSASSA_PSS
Definition: pk.h:110
@ MBEDTLS_PK_RSA
Definition: pk.h:105
@ MBEDTLS_PK_ECKEY_DH
Definition: pk.h:107
@ MBEDTLS_PK_ECKEY
Definition: pk.h:106
static mbedtls_ecp_keypair * mbedtls_pk_ec(const mbedtls_pk_context pk)
Definition: pk.h:195
int mbedtls_pk_verify_ext(mbedtls_pk_type_t type, const void *options, mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, const unsigned char *hash, size_t hash_len, const unsigned char *sig, size_t sig_len)
Verify signature, with options. (Includes verification of the padding depending on type....
int mbedtls_pk_verify_restartable(mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, const unsigned char *hash, size_t hash_len, const unsigned char *sig, size_t sig_len, mbedtls_pk_restart_ctx *rs_ctx)
Restartable version of mbedtls_pk_verify()
mbedtls_pk_type_t mbedtls_pk_get_type(const mbedtls_pk_context *ctx)
Get the key type.
void mbedtls_pk_free(mbedtls_pk_context *ctx)
Free the components of a mbedtls_pk_context.
const char * mbedtls_pk_get_name(const mbedtls_pk_context *ctx)
Access the type name.
void mbedtls_platform_zeroize(void *buf, size_t len)
Securely zeroize a buffer.
Definition: platform_util.c:98
Common and shared functions used by multiple modules in the Mbed TLS library.
int n2
Definition: dwarfget.c:147
int n1
Definition: dwarfget.c:147
#define mbedtls_md_info_from_type
#define mbedtls_pk_get_bitlen
Configuration options (set of defines)
This file contains the definitions and functions of the Mbed TLS platform abstraction layer.
#define mbedtls_free
Definition: platform.h:168
#define mbedtls_snprintf
Definition: platform.h:254
#define mbedtls_calloc
Definition: platform.h:169
#define exit(n)
Definition: config.h:202
#define memset(x, y, z)
Definition: compat.h:39
CardRegion * from
Definition: spigame.cpp:19
Definition: dirent.h:40
Definition: inflate.c:139
Definition: fatfs.h:198
Definition: _hash_fun.h:40
mbedtls_ecp_group_id id
Definition: ecp.h:234
mbedtls_ecp_group grp
Definition: ecp.h:399
Public key container.
Definition: pk.h:156
Definition: x509_crl.h:78
Definition: name.c:39
Definition: stat.h:55
Definition: ecma_167.h:138
struct sock * chain
Definition: tcpcore.h:1
Threading abstraction layer.
#define MBEDTLS_ERR_THREADING_MUTEX_ERROR
Definition: threading.h:69
int ret
#define success(from, fromstr, to, tostr)
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define ERROR_NO_MORE_FILES
Definition: winerror.h:121
X.509 certificate parsing and writing.
__wchar_t WCHAR
Definition: xmlstorage.h:180