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