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