xref: /optee_os/lib/libmbedtls/mbedtls/library/x509.c (revision 11fa71b9ddb429088f325cfda430183003ccd1db)
1 // SPDX-License-Identifier: Apache-2.0
2 /*
3  *  X.509 common functions for parsing and verification
4  *
5  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
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_USE_C)
39 
40 #include "mbedtls/x509.h"
41 #include "mbedtls/asn1.h"
42 #include "mbedtls/error.h"
43 #include "mbedtls/oid.h"
44 
45 #include <stdio.h>
46 #include <string.h>
47 
48 #if defined(MBEDTLS_PEM_PARSE_C)
49 #include "mbedtls/pem.h"
50 #endif
51 
52 #if defined(MBEDTLS_PLATFORM_C)
53 #include "mbedtls/platform.h"
54 #else
55 #include <stdio.h>
56 #include <stdlib.h>
57 #define mbedtls_free      free
58 #define mbedtls_calloc    calloc
59 #define mbedtls_printf    printf
60 #define mbedtls_snprintf  snprintf
61 #endif
62 
63 #if defined(MBEDTLS_HAVE_TIME)
64 #include "mbedtls/platform_time.h"
65 #endif
66 #if defined(MBEDTLS_HAVE_TIME_DATE)
67 #include "mbedtls/platform_util.h"
68 #include <time.h>
69 #endif
70 
71 #define CHECK(code) if( ( ret = ( code ) ) != 0 ){ return( ret ); }
72 #define CHECK_RANGE(min, max, val)                      \
73     do                                                  \
74     {                                                   \
75         if( ( val ) < ( min ) || ( val ) > ( max ) )    \
76         {                                               \
77             return( ret );                              \
78         }                                               \
79     } while( 0 )
80 
81 /*
82  *  CertificateSerialNumber  ::=  INTEGER
83  */
84 int mbedtls_x509_get_serial( unsigned char **p, const unsigned char *end,
85                      mbedtls_x509_buf *serial )
86 {
87     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
88 
89     if( ( end - *p ) < 1 )
90         return( MBEDTLS_ERR_X509_INVALID_SERIAL +
91                 MBEDTLS_ERR_ASN1_OUT_OF_DATA );
92 
93     if( **p != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_PRIMITIVE | 2 ) &&
94         **p !=   MBEDTLS_ASN1_INTEGER )
95         return( MBEDTLS_ERR_X509_INVALID_SERIAL +
96                 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
97 
98     serial->tag = *(*p)++;
99 
100     if( ( ret = mbedtls_asn1_get_len( p, end, &serial->len ) ) != 0 )
101         return( MBEDTLS_ERR_X509_INVALID_SERIAL + ret );
102 
103     serial->p = *p;
104     *p += serial->len;
105 
106     return( 0 );
107 }
108 
109 /* Get an algorithm identifier without parameters (eg for signatures)
110  *
111  *  AlgorithmIdentifier  ::=  SEQUENCE  {
112  *       algorithm               OBJECT IDENTIFIER,
113  *       parameters              ANY DEFINED BY algorithm OPTIONAL  }
114  */
115 int mbedtls_x509_get_alg_null( unsigned char **p, const unsigned char *end,
116                        mbedtls_x509_buf *alg )
117 {
118     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
119 
120     if( ( ret = mbedtls_asn1_get_alg_null( p, end, alg ) ) != 0 )
121         return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
122 
123     return( 0 );
124 }
125 
126 /*
127  * Parse an algorithm identifier with (optional) parameters
128  */
129 int mbedtls_x509_get_alg( unsigned char **p, const unsigned char *end,
130                   mbedtls_x509_buf *alg, mbedtls_x509_buf *params )
131 {
132     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
133 
134     if( ( ret = mbedtls_asn1_get_alg( p, end, alg, params ) ) != 0 )
135         return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
136 
137     return( 0 );
138 }
139 
140 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
141 /*
142  * HashAlgorithm ::= AlgorithmIdentifier
143  *
144  * AlgorithmIdentifier  ::=  SEQUENCE  {
145  *      algorithm               OBJECT IDENTIFIER,
146  *      parameters              ANY DEFINED BY algorithm OPTIONAL  }
147  *
148  * For HashAlgorithm, parameters MUST be NULL or absent.
149  */
150 static int x509_get_hash_alg( const mbedtls_x509_buf *alg, mbedtls_md_type_t *md_alg )
151 {
152     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
153     unsigned char *p;
154     const unsigned char *end;
155     mbedtls_x509_buf md_oid;
156     size_t len;
157 
158     /* Make sure we got a SEQUENCE and setup bounds */
159     if( alg->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
160         return( MBEDTLS_ERR_X509_INVALID_ALG +
161                 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
162 
163     p = (unsigned char *) alg->p;
164     end = p + alg->len;
165 
166     if( p >= end )
167         return( MBEDTLS_ERR_X509_INVALID_ALG +
168                 MBEDTLS_ERR_ASN1_OUT_OF_DATA );
169 
170     /* Parse md_oid */
171     md_oid.tag = *p;
172 
173     if( ( ret = mbedtls_asn1_get_tag( &p, end, &md_oid.len, MBEDTLS_ASN1_OID ) ) != 0 )
174         return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
175 
176     md_oid.p = p;
177     p += md_oid.len;
178 
179     /* Get md_alg from md_oid */
180     if( ( ret = mbedtls_oid_get_md_alg( &md_oid, md_alg ) ) != 0 )
181         return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
182 
183     /* Make sure params is absent of NULL */
184     if( p == end )
185         return( 0 );
186 
187     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_NULL ) ) != 0 || len != 0 )
188         return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
189 
190     if( p != end )
191         return( MBEDTLS_ERR_X509_INVALID_ALG +
192                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
193 
194     return( 0 );
195 }
196 
197 /*
198  *    RSASSA-PSS-params  ::=  SEQUENCE  {
199  *       hashAlgorithm     [0] HashAlgorithm DEFAULT sha1Identifier,
200  *       maskGenAlgorithm  [1] MaskGenAlgorithm DEFAULT mgf1SHA1Identifier,
201  *       saltLength        [2] INTEGER DEFAULT 20,
202  *       trailerField      [3] INTEGER DEFAULT 1  }
203  *    -- Note that the tags in this Sequence are explicit.
204  *
205  * RFC 4055 (which defines use of RSASSA-PSS in PKIX) states that the value
206  * of trailerField MUST be 1, and PKCS#1 v2.2 doesn't even define any other
207  * option. Enfore this at parsing time.
208  */
209 int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params,
210                                 mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md,
211                                 int *salt_len )
212 {
213     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
214     unsigned char *p;
215     const unsigned char *end, *end2;
216     size_t len;
217     mbedtls_x509_buf alg_id, alg_params;
218 
219     /* First set everything to defaults */
220     *md_alg = MBEDTLS_MD_SHA1;
221     *mgf_md = MBEDTLS_MD_SHA1;
222     *salt_len = 20;
223 
224     /* Make sure params is a SEQUENCE and setup bounds */
225     if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) )
226         return( MBEDTLS_ERR_X509_INVALID_ALG +
227                 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
228 
229     p = (unsigned char *) params->p;
230     end = p + params->len;
231 
232     if( p == end )
233         return( 0 );
234 
235     /*
236      * HashAlgorithm
237      */
238     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
239                     MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) == 0 )
240     {
241         end2 = p + len;
242 
243         /* HashAlgorithm ::= AlgorithmIdentifier (without parameters) */
244         if( ( ret = mbedtls_x509_get_alg_null( &p, end2, &alg_id ) ) != 0 )
245             return( ret );
246 
247         if( ( ret = mbedtls_oid_get_md_alg( &alg_id, md_alg ) ) != 0 )
248             return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
249 
250         if( p != end2 )
251             return( MBEDTLS_ERR_X509_INVALID_ALG +
252                     MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
253     }
254     else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
255         return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
256 
257     if( p == end )
258         return( 0 );
259 
260     /*
261      * MaskGenAlgorithm
262      */
263     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
264                     MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) ) == 0 )
265     {
266         end2 = p + len;
267 
268         /* MaskGenAlgorithm ::= AlgorithmIdentifier (params = HashAlgorithm) */
269         if( ( ret = mbedtls_x509_get_alg( &p, end2, &alg_id, &alg_params ) ) != 0 )
270             return( ret );
271 
272         /* Only MFG1 is recognised for now */
273         if( MBEDTLS_OID_CMP( MBEDTLS_OID_MGF1, &alg_id ) != 0 )
274             return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE +
275                     MBEDTLS_ERR_OID_NOT_FOUND );
276 
277         /* Parse HashAlgorithm */
278         if( ( ret = x509_get_hash_alg( &alg_params, mgf_md ) ) != 0 )
279             return( ret );
280 
281         if( p != end2 )
282             return( MBEDTLS_ERR_X509_INVALID_ALG +
283                     MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
284     }
285     else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
286         return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
287 
288     if( p == end )
289         return( 0 );
290 
291     /*
292      * salt_len
293      */
294     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
295                     MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 2 ) ) == 0 )
296     {
297         end2 = p + len;
298 
299         if( ( ret = mbedtls_asn1_get_int( &p, end2, salt_len ) ) != 0 )
300             return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
301 
302         if( p != end2 )
303             return( MBEDTLS_ERR_X509_INVALID_ALG +
304                     MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
305     }
306     else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
307         return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
308 
309     if( p == end )
310         return( 0 );
311 
312     /*
313      * trailer_field (if present, must be 1)
314      */
315     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
316                     MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 3 ) ) == 0 )
317     {
318         int trailer_field;
319 
320         end2 = p + len;
321 
322         if( ( ret = mbedtls_asn1_get_int( &p, end2, &trailer_field ) ) != 0 )
323             return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
324 
325         if( p != end2 )
326             return( MBEDTLS_ERR_X509_INVALID_ALG +
327                     MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
328 
329         if( trailer_field != 1 )
330             return( MBEDTLS_ERR_X509_INVALID_ALG );
331     }
332     else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
333         return( MBEDTLS_ERR_X509_INVALID_ALG + ret );
334 
335     if( p != end )
336         return( MBEDTLS_ERR_X509_INVALID_ALG +
337                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
338 
339     return( 0 );
340 }
341 #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
342 
343 /*
344  *  AttributeTypeAndValue ::= SEQUENCE {
345  *    type     AttributeType,
346  *    value    AttributeValue }
347  *
348  *  AttributeType ::= OBJECT IDENTIFIER
349  *
350  *  AttributeValue ::= ANY DEFINED BY AttributeType
351  */
352 static int x509_get_attr_type_value( unsigned char **p,
353                                      const unsigned char *end,
354                                      mbedtls_x509_name *cur )
355 {
356     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
357     size_t len;
358     mbedtls_x509_buf *oid;
359     mbedtls_x509_buf *val;
360 
361     if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
362             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
363         return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
364 
365     end = *p + len;
366 
367     if( ( end - *p ) < 1 )
368         return( MBEDTLS_ERR_X509_INVALID_NAME +
369                 MBEDTLS_ERR_ASN1_OUT_OF_DATA );
370 
371     oid = &cur->oid;
372     oid->tag = **p;
373 
374     if( ( ret = mbedtls_asn1_get_tag( p, end, &oid->len, MBEDTLS_ASN1_OID ) ) != 0 )
375         return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
376 
377     oid->p = *p;
378     *p += oid->len;
379 
380     if( ( end - *p ) < 1 )
381         return( MBEDTLS_ERR_X509_INVALID_NAME +
382                 MBEDTLS_ERR_ASN1_OUT_OF_DATA );
383 
384     if( **p != MBEDTLS_ASN1_BMP_STRING && **p != MBEDTLS_ASN1_UTF8_STRING      &&
385         **p != MBEDTLS_ASN1_T61_STRING && **p != MBEDTLS_ASN1_PRINTABLE_STRING &&
386         **p != MBEDTLS_ASN1_IA5_STRING && **p != MBEDTLS_ASN1_UNIVERSAL_STRING &&
387         **p != MBEDTLS_ASN1_BIT_STRING )
388         return( MBEDTLS_ERR_X509_INVALID_NAME +
389                 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
390 
391     val = &cur->val;
392     val->tag = *(*p)++;
393 
394     if( ( ret = mbedtls_asn1_get_len( p, end, &val->len ) ) != 0 )
395         return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
396 
397     val->p = *p;
398     *p += val->len;
399 
400     if( *p != end )
401     {
402         return( MBEDTLS_ERR_X509_INVALID_NAME +
403                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
404     }
405 
406     cur->next = NULL;
407 
408     return( 0 );
409 }
410 
411 /*
412  *  Name ::= CHOICE { -- only one possibility for now --
413  *       rdnSequence  RDNSequence }
414  *
415  *  RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
416  *
417  *  RelativeDistinguishedName ::=
418  *    SET OF AttributeTypeAndValue
419  *
420  *  AttributeTypeAndValue ::= SEQUENCE {
421  *    type     AttributeType,
422  *    value    AttributeValue }
423  *
424  *  AttributeType ::= OBJECT IDENTIFIER
425  *
426  *  AttributeValue ::= ANY DEFINED BY AttributeType
427  *
428  * The data structure is optimized for the common case where each RDN has only
429  * one element, which is represented as a list of AttributeTypeAndValue.
430  * For the general case we still use a flat list, but we mark elements of the
431  * same set so that they are "merged" together in the functions that consume
432  * this list, eg mbedtls_x509_dn_gets().
433  */
434 int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end,
435                    mbedtls_x509_name *cur )
436 {
437     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
438     size_t set_len;
439     const unsigned char *end_set;
440 
441     /* don't use recursion, we'd risk stack overflow if not optimized */
442     while( 1 )
443     {
444         /*
445          * parse SET
446          */
447         if( ( ret = mbedtls_asn1_get_tag( p, end, &set_len,
448                 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET ) ) != 0 )
449             return( MBEDTLS_ERR_X509_INVALID_NAME + ret );
450 
451         end_set  = *p + set_len;
452 
453         while( 1 )
454         {
455             if( ( ret = x509_get_attr_type_value( p, end_set, cur ) ) != 0 )
456                 return( ret );
457 
458             if( *p == end_set )
459                 break;
460 
461             /* Mark this item as being no the only one in a set */
462             cur->next_merged = 1;
463 
464             cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) );
465 
466             if( cur->next == NULL )
467                 return( MBEDTLS_ERR_X509_ALLOC_FAILED );
468 
469             cur = cur->next;
470         }
471 
472         /*
473          * continue until end of SEQUENCE is reached
474          */
475         if( *p == end )
476             return( 0 );
477 
478         cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) );
479 
480         if( cur->next == NULL )
481             return( MBEDTLS_ERR_X509_ALLOC_FAILED );
482 
483         cur = cur->next;
484     }
485 }
486 
487 static int x509_parse_int( unsigned char **p, size_t n, int *res )
488 {
489     *res = 0;
490 
491     for( ; n > 0; --n )
492     {
493         if( ( **p < '0') || ( **p > '9' ) )
494             return ( MBEDTLS_ERR_X509_INVALID_DATE );
495 
496         *res *= 10;
497         *res += ( *(*p)++ - '0' );
498     }
499 
500     return( 0 );
501 }
502 
503 static int x509_date_is_valid(const mbedtls_x509_time *t )
504 {
505     int ret = MBEDTLS_ERR_X509_INVALID_DATE;
506     int month_len;
507 
508     CHECK_RANGE( 0, 9999, t->year );
509     CHECK_RANGE( 0, 23,   t->hour );
510     CHECK_RANGE( 0, 59,   t->min  );
511     CHECK_RANGE( 0, 59,   t->sec  );
512 
513     switch( t->mon )
514     {
515         case 1: case 3: case 5: case 7: case 8: case 10: case 12:
516             month_len = 31;
517             break;
518         case 4: case 6: case 9: case 11:
519             month_len = 30;
520             break;
521         case 2:
522             if( ( !( t->year % 4 ) && t->year % 100 ) ||
523                 !( t->year % 400 ) )
524                 month_len = 29;
525             else
526                 month_len = 28;
527             break;
528         default:
529             return( ret );
530     }
531     CHECK_RANGE( 1, month_len, t->day );
532 
533     return( 0 );
534 }
535 
536 /*
537  * Parse an ASN1_UTC_TIME (yearlen=2) or ASN1_GENERALIZED_TIME (yearlen=4)
538  * field.
539  */
540 static int x509_parse_time( unsigned char **p, size_t len, size_t yearlen,
541                             mbedtls_x509_time *tm )
542 {
543     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
544 
545     /*
546      * Minimum length is 10 or 12 depending on yearlen
547      */
548     if ( len < yearlen + 8 )
549         return ( MBEDTLS_ERR_X509_INVALID_DATE );
550     len -= yearlen + 8;
551 
552     /*
553      * Parse year, month, day, hour, minute
554      */
555     CHECK( x509_parse_int( p, yearlen, &tm->year ) );
556     if ( 2 == yearlen )
557     {
558         if ( tm->year < 50 )
559             tm->year += 100;
560 
561         tm->year += 1900;
562     }
563 
564     CHECK( x509_parse_int( p, 2, &tm->mon ) );
565     CHECK( x509_parse_int( p, 2, &tm->day ) );
566     CHECK( x509_parse_int( p, 2, &tm->hour ) );
567     CHECK( x509_parse_int( p, 2, &tm->min ) );
568 
569     /*
570      * Parse seconds if present
571      */
572     if ( len >= 2 )
573     {
574         CHECK( x509_parse_int( p, 2, &tm->sec ) );
575         len -= 2;
576     }
577     else
578         return ( MBEDTLS_ERR_X509_INVALID_DATE );
579 
580     /*
581      * Parse trailing 'Z' if present
582      */
583     if ( 1 == len && 'Z' == **p )
584     {
585         (*p)++;
586         len--;
587     }
588 
589     /*
590      * We should have parsed all characters at this point
591      */
592     if ( 0 != len )
593         return ( MBEDTLS_ERR_X509_INVALID_DATE );
594 
595     CHECK( x509_date_is_valid( tm ) );
596 
597     return ( 0 );
598 }
599 
600 /*
601  *  Time ::= CHOICE {
602  *       utcTime        UTCTime,
603  *       generalTime    GeneralizedTime }
604  */
605 int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end,
606                            mbedtls_x509_time *tm )
607 {
608     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
609     size_t len, year_len;
610     unsigned char tag;
611 
612     if( ( end - *p ) < 1 )
613         return( MBEDTLS_ERR_X509_INVALID_DATE +
614                 MBEDTLS_ERR_ASN1_OUT_OF_DATA );
615 
616     tag = **p;
617 
618     if( tag == MBEDTLS_ASN1_UTC_TIME )
619         year_len = 2;
620     else if( tag == MBEDTLS_ASN1_GENERALIZED_TIME )
621         year_len = 4;
622     else
623         return( MBEDTLS_ERR_X509_INVALID_DATE +
624                 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG );
625 
626     (*p)++;
627     ret = mbedtls_asn1_get_len( p, end, &len );
628 
629     if( ret != 0 )
630         return( MBEDTLS_ERR_X509_INVALID_DATE + ret );
631 
632     return x509_parse_time( p, len, year_len, tm );
633 }
634 
635 int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig )
636 {
637     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
638     size_t len;
639     int tag_type;
640 
641     if( ( end - *p ) < 1 )
642         return( MBEDTLS_ERR_X509_INVALID_SIGNATURE +
643                 MBEDTLS_ERR_ASN1_OUT_OF_DATA );
644 
645     tag_type = **p;
646 
647     if( ( ret = mbedtls_asn1_get_bitstring_null( p, end, &len ) ) != 0 )
648         return( MBEDTLS_ERR_X509_INVALID_SIGNATURE + ret );
649 
650     sig->tag = tag_type;
651     sig->len = len;
652     sig->p = *p;
653 
654     *p += len;
655 
656     return( 0 );
657 }
658 
659 /*
660  * Get signature algorithm from alg OID and optional parameters
661  */
662 int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params,
663                       mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg,
664                       void **sig_opts )
665 {
666     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
667 
668     if( *sig_opts != NULL )
669         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
670 
671     if( ( ret = mbedtls_oid_get_sig_alg( sig_oid, md_alg, pk_alg ) ) != 0 )
672         return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + ret );
673 
674 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
675     if( *pk_alg == MBEDTLS_PK_RSASSA_PSS )
676     {
677         mbedtls_pk_rsassa_pss_options *pss_opts;
678 
679         pss_opts = mbedtls_calloc( 1, sizeof( mbedtls_pk_rsassa_pss_options ) );
680         if( pss_opts == NULL )
681             return( MBEDTLS_ERR_X509_ALLOC_FAILED );
682 
683         ret = mbedtls_x509_get_rsassa_pss_params( sig_params,
684                                           md_alg,
685                                           &pss_opts->mgf1_hash_id,
686                                           &pss_opts->expected_salt_len );
687         if( ret != 0 )
688         {
689             mbedtls_free( pss_opts );
690             return( ret );
691         }
692 
693         *sig_opts = (void *) pss_opts;
694     }
695     else
696 #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
697     {
698         /* Make sure parameters are absent or NULL */
699         if( ( sig_params->tag != MBEDTLS_ASN1_NULL && sig_params->tag != 0 ) ||
700               sig_params->len != 0 )
701         return( MBEDTLS_ERR_X509_INVALID_ALG );
702     }
703 
704     return( 0 );
705 }
706 
707 /*
708  * X.509 Extensions (No parsing of extensions, pointer should
709  * be either manually updated or extensions should be parsed!)
710  */
711 int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end,
712                           mbedtls_x509_buf *ext, int tag )
713 {
714     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
715     size_t len;
716 
717     /* Extension structure use EXPLICIT tagging. That is, the actual
718      * `Extensions` structure is wrapped by a tag-length pair using
719      * the respective context-specific tag. */
720     ret = mbedtls_asn1_get_tag( p, end, &ext->len,
721               MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag );
722     if( ret != 0 )
723         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
724 
725     ext->tag = MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag;
726     ext->p   = *p;
727     end      = *p + ext->len;
728 
729     /*
730      * Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
731      */
732     if( ( ret = mbedtls_asn1_get_tag( p, end, &len,
733             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
734         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
735 
736     if( end != *p + len )
737         return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
738                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH );
739 
740     return( 0 );
741 }
742 
743 /*
744  * Store the name in printable form into buf; no more
745  * than size characters will be written
746  */
747 int mbedtls_x509_dn_gets( char *buf, size_t size, const mbedtls_x509_name *dn )
748 {
749     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
750     size_t i, n;
751     unsigned char c, merge = 0;
752     const mbedtls_x509_name *name;
753     const char *short_name = NULL;
754     char s[MBEDTLS_X509_MAX_DN_NAME_SIZE], *p;
755 
756     memset( s, 0, sizeof( s ) );
757 
758     name = dn;
759     p = buf;
760     n = size;
761 
762     while( name != NULL )
763     {
764         if( !name->oid.p )
765         {
766             name = name->next;
767             continue;
768         }
769 
770         if( name != dn )
771         {
772             ret = mbedtls_snprintf( p, n, merge ? " + " : ", " );
773             MBEDTLS_X509_SAFE_SNPRINTF;
774         }
775 
776         ret = mbedtls_oid_get_attr_short_name( &name->oid, &short_name );
777 
778         if( ret == 0 )
779             ret = mbedtls_snprintf( p, n, "%s=", short_name );
780         else
781             ret = mbedtls_snprintf( p, n, "\?\?=" );
782         MBEDTLS_X509_SAFE_SNPRINTF;
783 
784         for( i = 0; i < name->val.len; i++ )
785         {
786             if( i >= sizeof( s ) - 1 )
787                 break;
788 
789             c = name->val.p[i];
790             if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
791                  s[i] = '?';
792             else s[i] = c;
793         }
794         s[i] = '\0';
795         ret = mbedtls_snprintf( p, n, "%s", s );
796         MBEDTLS_X509_SAFE_SNPRINTF;
797 
798         merge = name->next_merged;
799         name = name->next;
800     }
801 
802     return( (int) ( size - n ) );
803 }
804 
805 /*
806  * Store the serial in printable form into buf; no more
807  * than size characters will be written
808  */
809 int mbedtls_x509_serial_gets( char *buf, size_t size, const mbedtls_x509_buf *serial )
810 {
811     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
812     size_t i, n, nr;
813     char *p;
814 
815     p = buf;
816     n = size;
817 
818     nr = ( serial->len <= 32 )
819         ? serial->len  : 28;
820 
821     for( i = 0; i < nr; i++ )
822     {
823         if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
824             continue;
825 
826         ret = mbedtls_snprintf( p, n, "%02X%s",
827                 serial->p[i], ( i < nr - 1 ) ? ":" : "" );
828         MBEDTLS_X509_SAFE_SNPRINTF;
829     }
830 
831     if( nr != serial->len )
832     {
833         ret = mbedtls_snprintf( p, n, "...." );
834         MBEDTLS_X509_SAFE_SNPRINTF;
835     }
836 
837     return( (int) ( size - n ) );
838 }
839 
840 /*
841  * Helper for writing signature algorithms
842  */
843 int mbedtls_x509_sig_alg_gets( char *buf, size_t size, const mbedtls_x509_buf *sig_oid,
844                        mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg,
845                        const void *sig_opts )
846 {
847     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
848     char *p = buf;
849     size_t n = size;
850     const char *desc = NULL;
851 
852     ret = mbedtls_oid_get_sig_alg_desc( sig_oid, &desc );
853     if( ret != 0 )
854         ret = mbedtls_snprintf( p, n, "???"  );
855     else
856         ret = mbedtls_snprintf( p, n, "%s", desc );
857     MBEDTLS_X509_SAFE_SNPRINTF;
858 
859 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
860     if( pk_alg == MBEDTLS_PK_RSASSA_PSS )
861     {
862         const mbedtls_pk_rsassa_pss_options *pss_opts;
863         const mbedtls_md_info_t *md_info, *mgf_md_info;
864 
865         pss_opts = (const mbedtls_pk_rsassa_pss_options *) sig_opts;
866 
867         md_info = mbedtls_md_info_from_type( md_alg );
868         mgf_md_info = mbedtls_md_info_from_type( pss_opts->mgf1_hash_id );
869 
870         ret = mbedtls_snprintf( p, n, " (%s, MGF1-%s, 0x%02X)",
871                               md_info ? mbedtls_md_get_name( md_info ) : "???",
872                               mgf_md_info ? mbedtls_md_get_name( mgf_md_info ) : "???",
873                               pss_opts->expected_salt_len );
874         MBEDTLS_X509_SAFE_SNPRINTF;
875     }
876 #else
877     ((void) pk_alg);
878     ((void) md_alg);
879     ((void) sig_opts);
880 #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
881 
882     return( (int)( size - n ) );
883 }
884 
885 /*
886  * Helper for writing "RSA key size", "EC key size", etc
887  */
888 int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char *name )
889 {
890     char *p = buf;
891     size_t n = buf_size;
892     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
893 
894     ret = mbedtls_snprintf( p, n, "%s key size", name );
895     MBEDTLS_X509_SAFE_SNPRINTF;
896 
897     return( 0 );
898 }
899 
900 #if defined(MBEDTLS_HAVE_TIME_DATE)
901 /*
902  * Set the time structure to the current time.
903  * Return 0 on success, non-zero on failure.
904  */
905 static int x509_get_current_time( mbedtls_x509_time *now )
906 {
907     struct tm *lt, tm_buf;
908     mbedtls_time_t tt;
909     int ret = 0;
910 
911     tt = mbedtls_time( NULL );
912     lt = mbedtls_platform_gmtime_r( &tt, &tm_buf );
913 
914     if( lt == NULL )
915         ret = -1;
916     else
917     {
918         now->year = lt->tm_year + 1900;
919         now->mon  = lt->tm_mon  + 1;
920         now->day  = lt->tm_mday;
921         now->hour = lt->tm_hour;
922         now->min  = lt->tm_min;
923         now->sec  = lt->tm_sec;
924     }
925 
926     return( ret );
927 }
928 
929 /*
930  * Return 0 if before <= after, 1 otherwise
931  */
932 static int x509_check_time( const mbedtls_x509_time *before, const mbedtls_x509_time *after )
933 {
934     if( before->year  > after->year )
935         return( 1 );
936 
937     if( before->year == after->year &&
938         before->mon   > after->mon )
939         return( 1 );
940 
941     if( before->year == after->year &&
942         before->mon  == after->mon  &&
943         before->day   > after->day )
944         return( 1 );
945 
946     if( before->year == after->year &&
947         before->mon  == after->mon  &&
948         before->day  == after->day  &&
949         before->hour  > after->hour )
950         return( 1 );
951 
952     if( before->year == after->year &&
953         before->mon  == after->mon  &&
954         before->day  == after->day  &&
955         before->hour == after->hour &&
956         before->min   > after->min  )
957         return( 1 );
958 
959     if( before->year == after->year &&
960         before->mon  == after->mon  &&
961         before->day  == after->day  &&
962         before->hour == after->hour &&
963         before->min  == after->min  &&
964         before->sec   > after->sec  )
965         return( 1 );
966 
967     return( 0 );
968 }
969 
970 int mbedtls_x509_time_is_past( const mbedtls_x509_time *to )
971 {
972     mbedtls_x509_time now;
973 
974     if( x509_get_current_time( &now ) != 0 )
975         return( 1 );
976 
977     return( x509_check_time( &now, to ) );
978 }
979 
980 int mbedtls_x509_time_is_future( const mbedtls_x509_time *from )
981 {
982     mbedtls_x509_time now;
983 
984     if( x509_get_current_time( &now ) != 0 )
985         return( 1 );
986 
987     return( x509_check_time( from, &now ) );
988 }
989 
990 #else  /* MBEDTLS_HAVE_TIME_DATE */
991 
992 int mbedtls_x509_time_is_past( const mbedtls_x509_time *to )
993 {
994     ((void) to);
995     return( 0 );
996 }
997 
998 int mbedtls_x509_time_is_future( const mbedtls_x509_time *from )
999 {
1000     ((void) from);
1001     return( 0 );
1002 }
1003 #endif /* MBEDTLS_HAVE_TIME_DATE */
1004 
1005 #if defined(MBEDTLS_SELF_TEST)
1006 
1007 #include "mbedtls/x509_crt.h"
1008 #include "mbedtls/certs.h"
1009 
1010 /*
1011  * Checkup routine
1012  */
1013 int mbedtls_x509_self_test( int verbose )
1014 {
1015     int ret = 0;
1016 #if defined(MBEDTLS_CERTS_C) && defined(MBEDTLS_SHA256_C)
1017     uint32_t flags;
1018     mbedtls_x509_crt cacert;
1019     mbedtls_x509_crt clicert;
1020 
1021     if( verbose != 0 )
1022         mbedtls_printf( "  X.509 certificate load: " );
1023 
1024     mbedtls_x509_crt_init( &cacert );
1025     mbedtls_x509_crt_init( &clicert );
1026 
1027     ret = mbedtls_x509_crt_parse( &clicert, (const unsigned char *) mbedtls_test_cli_crt,
1028                            mbedtls_test_cli_crt_len );
1029     if( ret != 0 )
1030     {
1031         if( verbose != 0 )
1032             mbedtls_printf( "failed\n" );
1033 
1034         goto cleanup;
1035     }
1036 
1037     ret = mbedtls_x509_crt_parse( &cacert, (const unsigned char *) mbedtls_test_ca_crt,
1038                           mbedtls_test_ca_crt_len );
1039     if( ret != 0 )
1040     {
1041         if( verbose != 0 )
1042             mbedtls_printf( "failed\n" );
1043 
1044         goto cleanup;
1045     }
1046 
1047     if( verbose != 0 )
1048         mbedtls_printf( "passed\n  X.509 signature verify: ");
1049 
1050     ret = mbedtls_x509_crt_verify( &clicert, &cacert, NULL, NULL, &flags, NULL, NULL );
1051     if( ret != 0 )
1052     {
1053         if( verbose != 0 )
1054             mbedtls_printf( "failed\n" );
1055 
1056         goto cleanup;
1057     }
1058 
1059     if( verbose != 0 )
1060         mbedtls_printf( "passed\n\n");
1061 
1062 cleanup:
1063     mbedtls_x509_crt_free( &cacert  );
1064     mbedtls_x509_crt_free( &clicert );
1065 #else
1066     ((void) verbose);
1067 #endif /* MBEDTLS_CERTS_C && MBEDTLS_SHA256_C */
1068     return( ret );
1069 }
1070 
1071 #endif /* MBEDTLS_SELF_TEST */
1072 
1073 #endif /* MBEDTLS_X509_USE_C */
1074