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