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