source: azure_iot_hub_mbedtls/trunk/mbedtls-2.16.1/library/x509.c@ 398

Last change on this file since 398 was 398, checked in by coas-nagasima, 5 years ago

mbedTLS版Azure IoT Hub接続サンプルのソースコードを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 28.0 KB
Line 
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 */
76int 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 */
107int 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 */
121int 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 */
142static 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 */
201int 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 */
344static 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 */
418int 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
471static 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
487static 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 */
524static 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 */
589int 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
619int 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 */
646int 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 */
695int 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 */
736int 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 */
798int 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 */
832int 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 */
877int 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 */
894static 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 */
921static 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
959int 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
969int 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
981int mbedtls_x509_time_is_past( const mbedtls_x509_time *to )
982{
983 ((void) to);
984 return( 0 );
985}
986
987int 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 */
1002int 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 */
Note: See TracBrowser for help on using the repository browser.