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