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