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 /*
8 * The ITU-T X.509 standard defines a certificate format for PKI.
9 *
10 * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
11 * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
12 * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
13 *
14 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
15 * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
16 */
17
18 #include "common.h"
19
20 #if defined(MBEDTLS_X509_USE_C)
21
22 #include "x509_internal.h"
23 #include "mbedtls/asn1.h"
24 #include "mbedtls/error.h"
25 #include "mbedtls/oid.h"
26
27 #include <stdio.h>
28 #include <string.h>
29
30 #if defined(MBEDTLS_PEM_PARSE_C)
31 #include "mbedtls/pem.h"
32 #endif
33
34 #include "mbedtls/asn1write.h"
35
36 #include "mbedtls/platform.h"
37
38 #if defined(MBEDTLS_HAVE_TIME)
39 #include "mbedtls/platform_time.h"
40 #endif
41 #if defined(MBEDTLS_HAVE_TIME_DATE)
42 #include "mbedtls/platform_util.h"
43 #include <time.h>
44 #endif
45
46 #define CHECK(code) \
47 do { \
48 if ((ret = (code)) != 0) { \
49 return ret; \
50 } \
51 } while (0)
52
53 #define CHECK_RANGE(min, max, val) \
54 do { \
55 if ((val) < (min) || (val) > (max)) { \
56 return ret; \
57 } \
58 } while (0)
59
60 /*
61 * CertificateSerialNumber ::= INTEGER
62 */
mbedtls_x509_get_serial(unsigned char ** p,const unsigned char * end,mbedtls_x509_buf * serial)63 int mbedtls_x509_get_serial(unsigned char **p, const unsigned char *end,
64 mbedtls_x509_buf *serial)
65 {
66 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
67
68 if ((end - *p) < 1) {
69 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_SERIAL,
70 MBEDTLS_ERR_ASN1_OUT_OF_DATA);
71 }
72
73 if (**p != (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_PRIMITIVE | 2) &&
74 **p != MBEDTLS_ASN1_INTEGER) {
75 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_SERIAL,
76 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
77 }
78
79 serial->tag = *(*p)++;
80
81 if ((ret = mbedtls_asn1_get_len(p, end, &serial->len)) != 0) {
82 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_SERIAL, ret);
83 }
84
85 serial->p = *p;
86 *p += serial->len;
87
88 return 0;
89 }
90
91 /* Get an algorithm identifier without parameters (eg for signatures)
92 *
93 * AlgorithmIdentifier ::= SEQUENCE {
94 * algorithm OBJECT IDENTIFIER,
95 * parameters ANY DEFINED BY algorithm OPTIONAL }
96 */
mbedtls_x509_get_alg_null(unsigned char ** p,const unsigned char * end,mbedtls_x509_buf * alg)97 int mbedtls_x509_get_alg_null(unsigned char **p, const unsigned char *end,
98 mbedtls_x509_buf *alg)
99 {
100 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
101
102 if ((ret = mbedtls_asn1_get_alg_null(p, end, alg)) != 0) {
103 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
104 }
105
106 return 0;
107 }
108
109 /*
110 * Parse an algorithm identifier with (optional) parameters
111 */
mbedtls_x509_get_alg(unsigned char ** p,const unsigned char * end,mbedtls_x509_buf * alg,mbedtls_x509_buf * params)112 int mbedtls_x509_get_alg(unsigned char **p, const unsigned char *end,
113 mbedtls_x509_buf *alg, mbedtls_x509_buf *params)
114 {
115 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
116
117 if ((ret = mbedtls_asn1_get_alg(p, end, alg, params)) != 0) {
118 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
119 }
120
121 return 0;
122 }
123
124 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
125 /*
126 * Convert md type to string
127 */
128 #if !defined(MBEDTLS_X509_REMOVE_INFO) && defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
129
md_type_to_string(mbedtls_md_type_t md_alg)130 static inline const char *md_type_to_string(mbedtls_md_type_t md_alg)
131 {
132 switch (md_alg) {
133 #if defined(MBEDTLS_MD_CAN_MD5)
134 case MBEDTLS_MD_MD5:
135 return "MD5";
136 #endif
137 #if defined(MBEDTLS_MD_CAN_SHA1)
138 case MBEDTLS_MD_SHA1:
139 return "SHA1";
140 #endif
141 #if defined(MBEDTLS_MD_CAN_SHA224)
142 case MBEDTLS_MD_SHA224:
143 return "SHA224";
144 #endif
145 #if defined(MBEDTLS_MD_CAN_SHA256)
146 case MBEDTLS_MD_SHA256:
147 return "SHA256";
148 #endif
149 #if defined(MBEDTLS_MD_CAN_SHA384)
150 case MBEDTLS_MD_SHA384:
151 return "SHA384";
152 #endif
153 #if defined(MBEDTLS_MD_CAN_SHA512)
154 case MBEDTLS_MD_SHA512:
155 return "SHA512";
156 #endif
157 #if defined(MBEDTLS_MD_CAN_RIPEMD160)
158 case MBEDTLS_MD_RIPEMD160:
159 return "RIPEMD160";
160 #endif
161 case MBEDTLS_MD_NONE:
162 return NULL;
163 default:
164 return NULL;
165 }
166 }
167
168 #endif /* !defined(MBEDTLS_X509_REMOVE_INFO) && defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) */
169 /*
170 * HashAlgorithm ::= AlgorithmIdentifier
171 *
172 * AlgorithmIdentifier ::= SEQUENCE {
173 * algorithm OBJECT IDENTIFIER,
174 * parameters ANY DEFINED BY algorithm OPTIONAL }
175 *
176 * For HashAlgorithm, parameters MUST be NULL or absent.
177 */
x509_get_hash_alg(const mbedtls_x509_buf * alg,mbedtls_md_type_t * md_alg)178 static int x509_get_hash_alg(const mbedtls_x509_buf *alg, mbedtls_md_type_t *md_alg)
179 {
180 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
181 unsigned char *p;
182 const unsigned char *end;
183 mbedtls_x509_buf md_oid;
184 size_t len;
185
186 /* Make sure we got a SEQUENCE and setup bounds */
187 if (alg->tag != (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) {
188 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
189 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
190 }
191
192 p = alg->p;
193 end = p + alg->len;
194
195 if (p >= end) {
196 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
197 MBEDTLS_ERR_ASN1_OUT_OF_DATA);
198 }
199
200 /* Parse md_oid */
201 md_oid.tag = *p;
202
203 if ((ret = mbedtls_asn1_get_tag(&p, end, &md_oid.len, MBEDTLS_ASN1_OID)) != 0) {
204 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
205 }
206
207 md_oid.p = p;
208 p += md_oid.len;
209
210 /* Get md_alg from md_oid */
211 if ((ret = mbedtls_oid_get_md_alg(&md_oid, md_alg)) != 0) {
212 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
213 }
214
215 /* Make sure params is absent of NULL */
216 if (p == end) {
217 return 0;
218 }
219
220 if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_NULL)) != 0 || len != 0) {
221 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
222 }
223
224 if (p != end) {
225 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
226 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
227 }
228
229 return 0;
230 }
231
232 /*
233 * RSASSA-PSS-params ::= SEQUENCE {
234 * hashAlgorithm [0] HashAlgorithm DEFAULT sha1Identifier,
235 * maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1Identifier,
236 * saltLength [2] INTEGER DEFAULT 20,
237 * trailerField [3] INTEGER DEFAULT 1 }
238 * -- Note that the tags in this Sequence are explicit.
239 *
240 * RFC 4055 (which defines use of RSASSA-PSS in PKIX) states that the value
241 * of trailerField MUST be 1, and PKCS#1 v2.2 doesn't even define any other
242 * option. Enforce this at parsing time.
243 */
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)244 int mbedtls_x509_get_rsassa_pss_params(const mbedtls_x509_buf *params,
245 mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md,
246 int *salt_len)
247 {
248 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
249 unsigned char *p;
250 const unsigned char *end, *end2;
251 size_t len;
252 mbedtls_x509_buf alg_id, alg_params;
253
254 /* First set everything to defaults */
255 *md_alg = MBEDTLS_MD_SHA1;
256 *mgf_md = MBEDTLS_MD_SHA1;
257 *salt_len = 20;
258
259 /* Make sure params is a SEQUENCE and setup bounds */
260 if (params->tag != (MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) {
261 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
262 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
263 }
264
265 p = (unsigned char *) params->p;
266 end = p + params->len;
267
268 if (p == end) {
269 return 0;
270 }
271
272 /*
273 * HashAlgorithm
274 */
275 if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
276 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED |
277 0)) == 0) {
278 end2 = p + len;
279
280 /* HashAlgorithm ::= AlgorithmIdentifier (without parameters) */
281 if ((ret = mbedtls_x509_get_alg_null(&p, end2, &alg_id)) != 0) {
282 return ret;
283 }
284
285 if ((ret = mbedtls_oid_get_md_alg(&alg_id, md_alg)) != 0) {
286 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
287 }
288
289 if (p != end2) {
290 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
291 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
292 }
293 } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
294 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
295 }
296
297 if (p == end) {
298 return 0;
299 }
300
301 /*
302 * MaskGenAlgorithm
303 */
304 if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
305 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED |
306 1)) == 0) {
307 end2 = p + len;
308
309 /* MaskGenAlgorithm ::= AlgorithmIdentifier (params = HashAlgorithm) */
310 if ((ret = mbedtls_x509_get_alg(&p, end2, &alg_id, &alg_params)) != 0) {
311 return ret;
312 }
313
314 /* Only MFG1 is recognised for now */
315 if (MBEDTLS_OID_CMP(MBEDTLS_OID_MGF1, &alg_id) != 0) {
316 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE,
317 MBEDTLS_ERR_OID_NOT_FOUND);
318 }
319
320 /* Parse HashAlgorithm */
321 if ((ret = x509_get_hash_alg(&alg_params, mgf_md)) != 0) {
322 return ret;
323 }
324
325 if (p != end2) {
326 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
327 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
328 }
329 } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
330 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
331 }
332
333 if (p == end) {
334 return 0;
335 }
336
337 /*
338 * salt_len
339 */
340 if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
341 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED |
342 2)) == 0) {
343 end2 = p + len;
344
345 if ((ret = mbedtls_asn1_get_int(&p, end2, salt_len)) != 0) {
346 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
347 }
348
349 if (p != end2) {
350 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
351 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
352 }
353 } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
354 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
355 }
356
357 if (p == end) {
358 return 0;
359 }
360
361 /*
362 * trailer_field (if present, must be 1)
363 */
364 if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
365 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED |
366 3)) == 0) {
367 int trailer_field;
368
369 end2 = p + len;
370
371 if ((ret = mbedtls_asn1_get_int(&p, end2, &trailer_field)) != 0) {
372 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
373 }
374
375 if (p != end2) {
376 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
377 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
378 }
379
380 if (trailer_field != 1) {
381 return MBEDTLS_ERR_X509_INVALID_ALG;
382 }
383 } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
384 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG, ret);
385 }
386
387 if (p != end) {
388 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_ALG,
389 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
390 }
391
392 return 0;
393 }
394 #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
395
396 /*
397 * AttributeTypeAndValue ::= SEQUENCE {
398 * type AttributeType,
399 * value AttributeValue }
400 *
401 * AttributeType ::= OBJECT IDENTIFIER
402 *
403 * AttributeValue ::= ANY DEFINED BY AttributeType
404 */
x509_get_attr_type_value(unsigned char ** p,const unsigned char * end,mbedtls_x509_name * cur)405 static int x509_get_attr_type_value(unsigned char **p,
406 const unsigned char *end,
407 mbedtls_x509_name *cur)
408 {
409 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
410 size_t len;
411 mbedtls_x509_buf *oid;
412 mbedtls_x509_buf *val;
413
414 if ((ret = mbedtls_asn1_get_tag(p, end, &len,
415 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
416 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME, ret);
417 }
418
419 end = *p + len;
420
421 if ((end - *p) < 1) {
422 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME,
423 MBEDTLS_ERR_ASN1_OUT_OF_DATA);
424 }
425
426 oid = &cur->oid;
427 oid->tag = **p;
428
429 if ((ret = mbedtls_asn1_get_tag(p, end, &oid->len, MBEDTLS_ASN1_OID)) != 0) {
430 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME, ret);
431 }
432
433 oid->p = *p;
434 *p += oid->len;
435
436 if ((end - *p) < 1) {
437 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME,
438 MBEDTLS_ERR_ASN1_OUT_OF_DATA);
439 }
440
441 if (**p != MBEDTLS_ASN1_BMP_STRING && **p != MBEDTLS_ASN1_UTF8_STRING &&
442 **p != MBEDTLS_ASN1_T61_STRING && **p != MBEDTLS_ASN1_PRINTABLE_STRING &&
443 **p != MBEDTLS_ASN1_IA5_STRING && **p != MBEDTLS_ASN1_UNIVERSAL_STRING &&
444 **p != MBEDTLS_ASN1_BIT_STRING) {
445 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME,
446 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
447 }
448
449 val = &cur->val;
450 val->tag = *(*p)++;
451
452 if ((ret = mbedtls_asn1_get_len(p, end, &val->len)) != 0) {
453 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME, ret);
454 }
455
456 val->p = *p;
457 *p += val->len;
458
459 if (*p != end) {
460 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME,
461 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
462 }
463
464 cur->next = NULL;
465
466 return 0;
467 }
468
469 /*
470 * Name ::= CHOICE { -- only one possibility for now --
471 * rdnSequence RDNSequence }
472 *
473 * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
474 *
475 * RelativeDistinguishedName ::=
476 * SET OF AttributeTypeAndValue
477 *
478 * AttributeTypeAndValue ::= SEQUENCE {
479 * type AttributeType,
480 * value AttributeValue }
481 *
482 * AttributeType ::= OBJECT IDENTIFIER
483 *
484 * AttributeValue ::= ANY DEFINED BY AttributeType
485 *
486 * The data structure is optimized for the common case where each RDN has only
487 * one element, which is represented as a list of AttributeTypeAndValue.
488 * For the general case we still use a flat list, but we mark elements of the
489 * same set so that they are "merged" together in the functions that consume
490 * this list, eg mbedtls_x509_dn_gets().
491 *
492 * On success, this function may allocate a linked list starting at cur->next
493 * that must later be free'd by the caller using mbedtls_free(). In error
494 * cases, this function frees all allocated memory internally and the caller
495 * has no freeing responsibilities.
496 */
mbedtls_x509_get_name(unsigned char ** p,const unsigned char * end,mbedtls_x509_name * cur)497 int mbedtls_x509_get_name(unsigned char **p, const unsigned char *end,
498 mbedtls_x509_name *cur)
499 {
500 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
501 size_t set_len;
502 const unsigned char *end_set;
503 mbedtls_x509_name *head = cur;
504
505 /* don't use recursion, we'd risk stack overflow if not optimized */
506 while (1) {
507 /*
508 * parse SET
509 */
510 if ((ret = mbedtls_asn1_get_tag(p, end, &set_len,
511 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET)) != 0) {
512 ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_NAME, ret);
513 goto error;
514 }
515
516 end_set = *p + set_len;
517
518 while (1) {
519 if ((ret = x509_get_attr_type_value(p, end_set, cur)) != 0) {
520 goto error;
521 }
522
523 if (*p == end_set) {
524 break;
525 }
526
527 /* Mark this item as being no the only one in a set */
528 cur->next_merged = 1;
529
530 cur->next = mbedtls_calloc(1, sizeof(mbedtls_x509_name));
531
532 if (cur->next == NULL) {
533 ret = MBEDTLS_ERR_X509_ALLOC_FAILED;
534 goto error;
535 }
536
537 cur = cur->next;
538 }
539
540 /*
541 * continue until end of SEQUENCE is reached
542 */
543 if (*p == end) {
544 return 0;
545 }
546
547 cur->next = mbedtls_calloc(1, sizeof(mbedtls_x509_name));
548
549 if (cur->next == NULL) {
550 ret = MBEDTLS_ERR_X509_ALLOC_FAILED;
551 goto error;
552 }
553
554 cur = cur->next;
555 }
556
557 error:
558 /* Skip the first element as we did not allocate it */
559 mbedtls_asn1_free_named_data_list_shallow(head->next);
560 head->next = NULL;
561
562 return ret;
563 }
564
x509_date_is_valid(const mbedtls_x509_time * t)565 static int x509_date_is_valid(const mbedtls_x509_time *t)
566 {
567 unsigned int month_days;
568 unsigned int year;
569 switch (t->mon) {
570 case 1: case 3: case 5: case 7: case 8: case 10: case 12:
571 month_days = 31;
572 break;
573 case 4: case 6: case 9: case 11:
574 month_days = 30;
575 break;
576 case 2:
577 year = (unsigned int) t->year;
578 month_days = ((year & 3) || (!(year % 100)
579 && (year % 400)))
580 ? 28 : 29;
581 break;
582 default:
583 return MBEDTLS_ERR_X509_INVALID_DATE;
584 }
585
586 if ((unsigned int) (t->day - 1) >= month_days || /* (1 - days in month) */
587 /* (unsigned int) (t->mon - 1) >= 12 || */ /* (1 - 12) checked above */
588 (unsigned int) t->year > 9999 || /* (0 - 9999) */
589 (unsigned int) t->hour > 23 || /* (0 - 23) */
590 (unsigned int) t->min > 59 || /* (0 - 59) */
591 (unsigned int) t->sec > 59) { /* (0 - 59) */
592 return MBEDTLS_ERR_X509_INVALID_DATE;
593 }
594
595 return 0;
596 }
597
x509_parse2_int(const unsigned char * p)598 static int x509_parse2_int(const unsigned char *p)
599 {
600 uint32_t d1 = p[0] - '0';
601 uint32_t d2 = p[1] - '0';
602 return (d1 < 10 && d2 < 10) ? (int) (d1 * 10 + d2) : -1;
603 }
604
605 /*
606 * Parse an ASN1_UTC_TIME (yearlen=2) or ASN1_GENERALIZED_TIME (yearlen=4)
607 * field.
608 */
x509_parse_time(const unsigned char * p,mbedtls_x509_time * tm,size_t yearlen)609 static int x509_parse_time(const unsigned char *p, mbedtls_x509_time *tm,
610 size_t yearlen)
611 {
612 int x;
613
614 /*
615 * Parse year, month, day, hour, minute, second
616 */
617 tm->year = x509_parse2_int(p);
618 if (tm->year < 0) {
619 return MBEDTLS_ERR_X509_INVALID_DATE;
620 }
621
622 if (4 == yearlen) {
623 x = tm->year * 100;
624 p += 2;
625 tm->year = x509_parse2_int(p);
626 if (tm->year < 0) {
627 return MBEDTLS_ERR_X509_INVALID_DATE;
628 }
629 } else {
630 x = (tm->year < 50) ? 2000 : 1900;
631 }
632 tm->year += x;
633
634 tm->mon = x509_parse2_int(p + 2);
635 tm->day = x509_parse2_int(p + 4);
636 tm->hour = x509_parse2_int(p + 6);
637 tm->min = x509_parse2_int(p + 8);
638 tm->sec = x509_parse2_int(p + 10);
639
640 return x509_date_is_valid(tm);
641 }
642
643 /*
644 * Time ::= CHOICE {
645 * utcTime UTCTime,
646 * generalTime GeneralizedTime }
647 */
mbedtls_x509_get_time(unsigned char ** p,const unsigned char * end,mbedtls_x509_time * tm)648 int mbedtls_x509_get_time(unsigned char **p, const unsigned char *end,
649 mbedtls_x509_time *tm)
650 {
651 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
652 size_t len, year_len;
653 unsigned char tag;
654
655 if ((end - *p) < 1) {
656 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_DATE,
657 MBEDTLS_ERR_ASN1_OUT_OF_DATA);
658 }
659
660 tag = **p;
661
662 if (tag == MBEDTLS_ASN1_UTC_TIME) {
663 year_len = 2;
664 } else if (tag == MBEDTLS_ASN1_GENERALIZED_TIME) {
665 year_len = 4;
666 } else {
667 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_DATE,
668 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
669 }
670
671 (*p)++;
672 ret = mbedtls_asn1_get_len(p, end, &len);
673
674 if (ret != 0) {
675 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_DATE, ret);
676 }
677
678 /* len is 12 or 14 depending on year_len, plus optional trailing 'Z' */
679 if (len != year_len + 10 &&
680 !(len == year_len + 11 && (*p)[(len - 1)] == 'Z')) {
681 return MBEDTLS_ERR_X509_INVALID_DATE;
682 }
683
684 (*p) += len;
685 return x509_parse_time(*p - len, tm, year_len);
686 }
687
mbedtls_x509_get_sig(unsigned char ** p,const unsigned char * end,mbedtls_x509_buf * sig)688 int mbedtls_x509_get_sig(unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig)
689 {
690 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
691 size_t len;
692 int tag_type;
693
694 if ((end - *p) < 1) {
695 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_SIGNATURE,
696 MBEDTLS_ERR_ASN1_OUT_OF_DATA);
697 }
698
699 tag_type = **p;
700
701 if ((ret = mbedtls_asn1_get_bitstring_null(p, end, &len)) != 0) {
702 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_SIGNATURE, ret);
703 }
704
705 sig->tag = tag_type;
706 sig->len = len;
707 sig->p = *p;
708
709 *p += len;
710
711 return 0;
712 }
713
714 /*
715 * Get signature algorithm from alg OID and optional parameters
716 */
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)717 int mbedtls_x509_get_sig_alg(const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params,
718 mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg,
719 void **sig_opts)
720 {
721 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
722
723 if (*sig_opts != NULL) {
724 return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
725 }
726
727 if ((ret = mbedtls_oid_get_sig_alg(sig_oid, md_alg, pk_alg)) != 0) {
728 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG, ret);
729 }
730
731 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
732 if (*pk_alg == MBEDTLS_PK_RSASSA_PSS) {
733 mbedtls_pk_rsassa_pss_options *pss_opts;
734
735 pss_opts = mbedtls_calloc(1, sizeof(mbedtls_pk_rsassa_pss_options));
736 if (pss_opts == NULL) {
737 return MBEDTLS_ERR_X509_ALLOC_FAILED;
738 }
739
740 ret = mbedtls_x509_get_rsassa_pss_params(sig_params,
741 md_alg,
742 &pss_opts->mgf1_hash_id,
743 &pss_opts->expected_salt_len);
744 if (ret != 0) {
745 mbedtls_free(pss_opts);
746 return ret;
747 }
748
749 *sig_opts = (void *) pss_opts;
750 } else
751 #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
752 {
753 /* Make sure parameters are absent or NULL */
754 if ((sig_params->tag != MBEDTLS_ASN1_NULL && sig_params->tag != 0) ||
755 sig_params->len != 0) {
756 return MBEDTLS_ERR_X509_INVALID_ALG;
757 }
758 }
759
760 return 0;
761 }
762
763 /*
764 * X.509 Extensions (No parsing of extensions, pointer should
765 * be either manually updated or extensions should be parsed!)
766 */
mbedtls_x509_get_ext(unsigned char ** p,const unsigned char * end,mbedtls_x509_buf * ext,int tag)767 int mbedtls_x509_get_ext(unsigned char **p, const unsigned char *end,
768 mbedtls_x509_buf *ext, int tag)
769 {
770 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
771 size_t len;
772
773 /* Extension structure use EXPLICIT tagging. That is, the actual
774 * `Extensions` structure is wrapped by a tag-length pair using
775 * the respective context-specific tag. */
776 ret = mbedtls_asn1_get_tag(p, end, &ext->len,
777 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag);
778 if (ret != 0) {
779 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
780 }
781
782 ext->tag = MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag;
783 ext->p = *p;
784 end = *p + ext->len;
785
786 /*
787 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
788 */
789 if ((ret = mbedtls_asn1_get_tag(p, end, &len,
790 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
791 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
792 }
793
794 if (end != *p + len) {
795 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
796 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
797 }
798
799 return 0;
800 }
801
nibble_to_hex_digit(int i)802 static char nibble_to_hex_digit(int i)
803 {
804 return (i < 10) ? (i + '0') : (i - 10 + 'A');
805 }
806
807 /*
808 * Store the name in printable form into buf; no more
809 * than size characters will be written
810 */
mbedtls_x509_dn_gets(char * buf,size_t size,const mbedtls_x509_name * dn)811 int mbedtls_x509_dn_gets(char *buf, size_t size, const mbedtls_x509_name *dn)
812 {
813 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
814 size_t i, j, n, asn1_len_size, asn1_tag_size, asn1_tag_len_buf_start;
815 /* 6 is enough as our asn1 write functions only write one byte for the tag and at most five bytes for the length*/
816 unsigned char asn1_tag_len_buf[6];
817 unsigned char *asn1_len_p;
818 unsigned char c, merge = 0;
819 const mbedtls_x509_name *name;
820 const char *short_name = NULL;
821 char lowbits, highbits;
822 char s[MBEDTLS_X509_MAX_DN_NAME_SIZE], *p;
823 int print_hexstring;
824
825 memset(s, 0, sizeof(s));
826
827 name = dn;
828 p = buf;
829 n = size;
830
831 while (name != NULL) {
832 if (!name->oid.p) {
833 name = name->next;
834 continue;
835 }
836
837 if (name != dn) {
838 ret = mbedtls_snprintf(p, n, merge ? " + " : ", ");
839 MBEDTLS_X509_SAFE_SNPRINTF;
840 }
841
842 print_hexstring = (name->val.tag != MBEDTLS_ASN1_UTF8_STRING) &&
843 (name->val.tag != MBEDTLS_ASN1_PRINTABLE_STRING) &&
844 (name->val.tag != MBEDTLS_ASN1_IA5_STRING);
845
846 if ((ret = mbedtls_oid_get_attr_short_name(&name->oid, &short_name)) == 0) {
847 ret = mbedtls_snprintf(p, n, "%s=", short_name);
848 } else {
849 if ((ret = mbedtls_oid_get_numeric_string(p, n, &name->oid)) > 0) {
850 n -= ret;
851 p += ret;
852 ret = mbedtls_snprintf(p, n, "=");
853 print_hexstring = 1;
854 } else if (ret == MBEDTLS_ERR_OID_BUF_TOO_SMALL) {
855 return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
856 } else {
857 ret = mbedtls_snprintf(p, n, "\?\?=");
858 }
859 }
860 MBEDTLS_X509_SAFE_SNPRINTF;
861
862 if (print_hexstring) {
863 s[0] = '#';
864
865 asn1_len_p = asn1_tag_len_buf + sizeof(asn1_tag_len_buf);
866 if ((ret = mbedtls_asn1_write_len(&asn1_len_p, asn1_tag_len_buf, name->val.len)) < 0) {
867 return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
868 }
869 asn1_len_size = ret;
870 if ((ret = mbedtls_asn1_write_tag(&asn1_len_p, asn1_tag_len_buf, name->val.tag)) < 0) {
871 return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
872 }
873 asn1_tag_size = ret;
874 asn1_tag_len_buf_start = sizeof(asn1_tag_len_buf) - asn1_len_size - asn1_tag_size;
875 for (i = 0, j = 1; i < asn1_len_size + asn1_tag_size; i++) {
876 if (j + 1 >= sizeof(s) - 1) {
877 return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
878 }
879 c = asn1_tag_len_buf[asn1_tag_len_buf_start+i];
880 lowbits = (c & 0x0F);
881 highbits = c >> 4;
882 s[j++] = nibble_to_hex_digit(highbits);
883 s[j++] = nibble_to_hex_digit(lowbits);
884 }
885 for (i = 0; i < name->val.len; i++) {
886 if (j + 1 >= sizeof(s) - 1) {
887 return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
888 }
889 c = name->val.p[i];
890 lowbits = (c & 0x0F);
891 highbits = c >> 4;
892 s[j++] = nibble_to_hex_digit(highbits);
893 s[j++] = nibble_to_hex_digit(lowbits);
894 }
895 } else {
896 for (i = 0, j = 0; i < name->val.len; i++, j++) {
897 if (j >= sizeof(s) - 1) {
898 return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
899 }
900
901 c = name->val.p[i];
902 // Special characters requiring escaping, RFC 4514 Section 2.4
903 if (c == '\0') {
904 return MBEDTLS_ERR_X509_INVALID_NAME;
905 } else {
906 if (strchr(",=+<>;\"\\", c) ||
907 ((i == 0) && strchr("# ", c)) ||
908 ((i == name->val.len-1) && (c == ' '))) {
909 if (j + 1 >= sizeof(s) - 1) {
910 return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
911 }
912 s[j++] = '\\';
913 }
914 }
915 if (c < 32 || c >= 127) {
916 if (j + 3 >= sizeof(s) - 1) {
917 return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
918 }
919 s[j++] = '\\';
920 lowbits = (c & 0x0F);
921 highbits = c >> 4;
922 s[j++] = nibble_to_hex_digit(highbits);
923 s[j] = nibble_to_hex_digit(lowbits);
924 } else {
925 s[j] = c;
926 }
927 }
928 }
929 s[j] = '\0';
930 ret = mbedtls_snprintf(p, n, "%s", s);
931 MBEDTLS_X509_SAFE_SNPRINTF;
932
933 merge = name->next_merged;
934 name = name->next;
935 }
936
937 return (int) (size - n);
938 }
939
940 /*
941 * Store the serial in printable form into buf; no more
942 * than size characters will be written
943 */
mbedtls_x509_serial_gets(char * buf,size_t size,const mbedtls_x509_buf * serial)944 int mbedtls_x509_serial_gets(char *buf, size_t size, const mbedtls_x509_buf *serial)
945 {
946 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
947 size_t i, n, nr;
948 char *p;
949
950 p = buf;
951 n = size;
952
953 nr = (serial->len <= 32)
954 ? serial->len : 28;
955
956 for (i = 0; i < nr; i++) {
957 if (i == 0 && nr > 1 && serial->p[i] == 0x0) {
958 continue;
959 }
960
961 ret = mbedtls_snprintf(p, n, "%02X%s",
962 serial->p[i], (i < nr - 1) ? ":" : "");
963 MBEDTLS_X509_SAFE_SNPRINTF;
964 }
965
966 if (nr != serial->len) {
967 ret = mbedtls_snprintf(p, n, "....");
968 MBEDTLS_X509_SAFE_SNPRINTF;
969 }
970
971 return (int) (size - n);
972 }
973
974 #if !defined(MBEDTLS_X509_REMOVE_INFO)
975 /*
976 * Helper for writing signature algorithms
977 */
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)978 int mbedtls_x509_sig_alg_gets(char *buf, size_t size, const mbedtls_x509_buf *sig_oid,
979 mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg,
980 const void *sig_opts)
981 {
982 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
983 char *p = buf;
984 size_t n = size;
985 const char *desc = NULL;
986
987 ret = mbedtls_oid_get_sig_alg_desc(sig_oid, &desc);
988 if (ret != 0) {
989 ret = mbedtls_snprintf(p, n, "???");
990 } else {
991 ret = mbedtls_snprintf(p, n, "%s", desc);
992 }
993 MBEDTLS_X509_SAFE_SNPRINTF;
994
995 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
996 if (pk_alg == MBEDTLS_PK_RSASSA_PSS) {
997 const mbedtls_pk_rsassa_pss_options *pss_opts;
998
999 pss_opts = (const mbedtls_pk_rsassa_pss_options *) sig_opts;
1000
1001 const char *name = md_type_to_string(md_alg);
1002 const char *mgf_name = md_type_to_string(pss_opts->mgf1_hash_id);
1003
1004 ret = mbedtls_snprintf(p, n, " (%s, MGF1-%s, 0x%02X)",
1005 name ? name : "???",
1006 mgf_name ? mgf_name : "???",
1007 (unsigned int) pss_opts->expected_salt_len);
1008 MBEDTLS_X509_SAFE_SNPRINTF;
1009 }
1010 #else
1011 ((void) pk_alg);
1012 ((void) md_alg);
1013 ((void) sig_opts);
1014 #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
1015
1016 return (int) (size - n);
1017 }
1018 #endif /* MBEDTLS_X509_REMOVE_INFO */
1019
1020 /*
1021 * Helper for writing "RSA key size", "EC key size", etc
1022 */
mbedtls_x509_key_size_helper(char * buf,size_t buf_size,const char * name)1023 int mbedtls_x509_key_size_helper(char *buf, size_t buf_size, const char *name)
1024 {
1025 char *p = buf;
1026 size_t n = buf_size;
1027 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1028
1029 ret = mbedtls_snprintf(p, n, "%s key size", name);
1030 MBEDTLS_X509_SAFE_SNPRINTF;
1031
1032 return 0;
1033 }
1034
mbedtls_x509_time_cmp(const mbedtls_x509_time * t1,const mbedtls_x509_time * t2)1035 int mbedtls_x509_time_cmp(const mbedtls_x509_time *t1,
1036 const mbedtls_x509_time *t2)
1037 {
1038 int x;
1039
1040 x = (((t1->year << 9) | (t1->mon << 5) | (t1->day)) -
1041 ((t2->year << 9) | (t2->mon << 5) | (t2->day)));
1042 if (x != 0) {
1043 return x;
1044 }
1045
1046 x = (((t1->hour << 12) | (t1->min << 6) | (t1->sec)) -
1047 ((t2->hour << 12) | (t2->min << 6) | (t2->sec)));
1048 return x;
1049 }
1050
1051 #if defined(MBEDTLS_HAVE_TIME_DATE)
mbedtls_x509_time_gmtime(mbedtls_time_t tt,mbedtls_x509_time * now)1052 int mbedtls_x509_time_gmtime(mbedtls_time_t tt, mbedtls_x509_time *now)
1053 {
1054 struct tm tm;
1055
1056 if (mbedtls_platform_gmtime_r(&tt, &tm) == NULL) {
1057 return -1;
1058 }
1059
1060 now->year = tm.tm_year + 1900;
1061 now->mon = tm.tm_mon + 1;
1062 now->day = tm.tm_mday;
1063 now->hour = tm.tm_hour;
1064 now->min = tm.tm_min;
1065 now->sec = tm.tm_sec;
1066 return 0;
1067 }
1068
x509_get_current_time(mbedtls_x509_time * now)1069 static int x509_get_current_time(mbedtls_x509_time *now)
1070 {
1071 return mbedtls_x509_time_gmtime(mbedtls_time(NULL), now);
1072 }
1073
mbedtls_x509_time_is_past(const mbedtls_x509_time * to)1074 int mbedtls_x509_time_is_past(const mbedtls_x509_time *to)
1075 {
1076 mbedtls_x509_time now;
1077
1078 if (x509_get_current_time(&now) != 0) {
1079 return 1;
1080 }
1081
1082 return mbedtls_x509_time_cmp(to, &now) < 0;
1083 }
1084
mbedtls_x509_time_is_future(const mbedtls_x509_time * from)1085 int mbedtls_x509_time_is_future(const mbedtls_x509_time *from)
1086 {
1087 mbedtls_x509_time now;
1088
1089 if (x509_get_current_time(&now) != 0) {
1090 return 1;
1091 }
1092
1093 return mbedtls_x509_time_cmp(from, &now) > 0;
1094 }
1095
1096 #else /* MBEDTLS_HAVE_TIME_DATE */
1097
mbedtls_x509_time_is_past(const mbedtls_x509_time * to)1098 int mbedtls_x509_time_is_past(const mbedtls_x509_time *to)
1099 {
1100 ((void) to);
1101 return 0;
1102 }
1103
mbedtls_x509_time_is_future(const mbedtls_x509_time * from)1104 int mbedtls_x509_time_is_future(const mbedtls_x509_time *from)
1105 {
1106 ((void) from);
1107 return 0;
1108 }
1109 #endif /* MBEDTLS_HAVE_TIME_DATE */
1110
1111 /* Common functions for parsing CRT and CSR. */
1112 #if defined(MBEDTLS_X509_CRT_PARSE_C) || defined(MBEDTLS_X509_CSR_PARSE_C)
1113 /*
1114 * OtherName ::= SEQUENCE {
1115 * type-id OBJECT IDENTIFIER,
1116 * value [0] EXPLICIT ANY DEFINED BY type-id }
1117 *
1118 * HardwareModuleName ::= SEQUENCE {
1119 * hwType OBJECT IDENTIFIER,
1120 * hwSerialNum OCTET STRING }
1121 *
1122 * NOTE: we currently only parse and use otherName of type HwModuleName,
1123 * as defined in RFC 4108.
1124 */
x509_get_other_name(const mbedtls_x509_buf * subject_alt_name,mbedtls_x509_san_other_name * other_name)1125 static int x509_get_other_name(const mbedtls_x509_buf *subject_alt_name,
1126 mbedtls_x509_san_other_name *other_name)
1127 {
1128 int ret = 0;
1129 size_t len;
1130 unsigned char *p = subject_alt_name->p;
1131 const unsigned char *end = p + subject_alt_name->len;
1132 mbedtls_x509_buf cur_oid;
1133
1134 if ((subject_alt_name->tag &
1135 (MBEDTLS_ASN1_TAG_CLASS_MASK | MBEDTLS_ASN1_TAG_VALUE_MASK)) !=
1136 (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_OTHER_NAME)) {
1137 /*
1138 * The given subject alternative name is not of type "othername".
1139 */
1140 return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
1141 }
1142
1143 if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
1144 MBEDTLS_ASN1_OID)) != 0) {
1145 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
1146 }
1147
1148 cur_oid.tag = MBEDTLS_ASN1_OID;
1149 cur_oid.p = p;
1150 cur_oid.len = len;
1151
1152 /*
1153 * Only HwModuleName is currently supported.
1154 */
1155 if (MBEDTLS_OID_CMP(MBEDTLS_OID_ON_HW_MODULE_NAME, &cur_oid) != 0) {
1156 return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
1157 }
1158 other_name->type_id = cur_oid;
1159
1160 p += len;
1161 if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
1162 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC)) !=
1163 0) {
1164 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
1165 }
1166
1167 if (end != p + len) {
1168 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
1169 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
1170 }
1171
1172 if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
1173 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
1174 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
1175 }
1176
1177 if (end != p + len) {
1178 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
1179 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
1180 }
1181
1182 if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OID)) != 0) {
1183 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
1184 }
1185
1186 other_name->value.hardware_module_name.oid.tag = MBEDTLS_ASN1_OID;
1187 other_name->value.hardware_module_name.oid.p = p;
1188 other_name->value.hardware_module_name.oid.len = len;
1189
1190 p += len;
1191 if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
1192 MBEDTLS_ASN1_OCTET_STRING)) != 0) {
1193 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
1194 }
1195
1196 other_name->value.hardware_module_name.val.tag = MBEDTLS_ASN1_OCTET_STRING;
1197 other_name->value.hardware_module_name.val.p = p;
1198 other_name->value.hardware_module_name.val.len = len;
1199 p += len;
1200 if (p != end) {
1201 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
1202 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
1203 }
1204 return 0;
1205 }
1206
1207 /* Check mbedtls_x509_get_subject_alt_name for detailed description.
1208 *
1209 * In some cases while parsing subject alternative names the sequence tag is optional
1210 * (e.g. CertSerialNumber). This function is designed to handle such case.
1211 */
mbedtls_x509_get_subject_alt_name_ext(unsigned char ** p,const unsigned char * end,mbedtls_x509_sequence * subject_alt_name)1212 int mbedtls_x509_get_subject_alt_name_ext(unsigned char **p,
1213 const unsigned char *end,
1214 mbedtls_x509_sequence *subject_alt_name)
1215 {
1216 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1217 size_t tag_len;
1218 mbedtls_asn1_sequence *cur = subject_alt_name;
1219
1220 while (*p < end) {
1221 mbedtls_x509_subject_alternative_name tmp_san_name;
1222 mbedtls_x509_buf tmp_san_buf;
1223 memset(&tmp_san_name, 0, sizeof(tmp_san_name));
1224
1225 tmp_san_buf.tag = **p;
1226 (*p)++;
1227
1228 if ((ret = mbedtls_asn1_get_len(p, end, &tag_len)) != 0) {
1229 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
1230 }
1231
1232 tmp_san_buf.p = *p;
1233 tmp_san_buf.len = tag_len;
1234
1235 if ((tmp_san_buf.tag & MBEDTLS_ASN1_TAG_CLASS_MASK) !=
1236 MBEDTLS_ASN1_CONTEXT_SPECIFIC) {
1237 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
1238 MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
1239 }
1240
1241 /*
1242 * Check that the SAN is structured correctly by parsing it.
1243 * The SAN structure is discarded afterwards.
1244 */
1245 ret = mbedtls_x509_parse_subject_alt_name(&tmp_san_buf, &tmp_san_name);
1246 /*
1247 * In case the extension is malformed, return an error,
1248 * and clear the allocated sequences.
1249 */
1250 if (ret != 0 && ret != MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) {
1251 mbedtls_asn1_sequence_free(subject_alt_name->next);
1252 subject_alt_name->next = NULL;
1253 return ret;
1254 }
1255
1256 mbedtls_x509_free_subject_alt_name(&tmp_san_name);
1257 /* Allocate and assign next pointer */
1258 if (cur->buf.p != NULL) {
1259 if (cur->next != NULL) {
1260 return MBEDTLS_ERR_X509_INVALID_EXTENSIONS;
1261 }
1262
1263 cur->next = mbedtls_calloc(1, sizeof(mbedtls_asn1_sequence));
1264
1265 if (cur->next == NULL) {
1266 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
1267 MBEDTLS_ERR_ASN1_ALLOC_FAILED);
1268 }
1269
1270 cur = cur->next;
1271 }
1272
1273 cur->buf = tmp_san_buf;
1274 *p += tmp_san_buf.len;
1275 }
1276
1277 /* Set final sequence entry's next pointer to NULL */
1278 cur->next = NULL;
1279
1280 if (*p != end) {
1281 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
1282 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
1283 }
1284
1285 return 0;
1286 }
1287
1288 /*
1289 * SubjectAltName ::= GeneralNames
1290 *
1291 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
1292 *
1293 * GeneralName ::= CHOICE {
1294 * otherName [0] OtherName,
1295 * rfc822Name [1] IA5String,
1296 * dNSName [2] IA5String,
1297 * x400Address [3] ORAddress,
1298 * directoryName [4] Name,
1299 * ediPartyName [5] EDIPartyName,
1300 * uniformResourceIdentifier [6] IA5String,
1301 * iPAddress [7] OCTET STRING,
1302 * registeredID [8] OBJECT IDENTIFIER }
1303 *
1304 * OtherName ::= SEQUENCE {
1305 * type-id OBJECT IDENTIFIER,
1306 * value [0] EXPLICIT ANY DEFINED BY type-id }
1307 *
1308 * EDIPartyName ::= SEQUENCE {
1309 * nameAssigner [0] DirectoryString OPTIONAL,
1310 * partyName [1] DirectoryString }
1311 *
1312 * We list all types, but use the following GeneralName types from RFC 5280:
1313 * "dnsName", "uniformResourceIdentifier" and "hardware_module_name"
1314 * of type "otherName", as defined in RFC 4108.
1315 */
mbedtls_x509_get_subject_alt_name(unsigned char ** p,const unsigned char * end,mbedtls_x509_sequence * subject_alt_name)1316 int mbedtls_x509_get_subject_alt_name(unsigned char **p,
1317 const unsigned char *end,
1318 mbedtls_x509_sequence *subject_alt_name)
1319 {
1320 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1321 size_t len;
1322
1323 /* Get main sequence tag */
1324 if ((ret = mbedtls_asn1_get_tag(p, end, &len,
1325 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
1326 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
1327 }
1328
1329 if (*p + len != end) {
1330 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
1331 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
1332 }
1333
1334 return mbedtls_x509_get_subject_alt_name_ext(p, end, subject_alt_name);
1335 }
1336
mbedtls_x509_get_ns_cert_type(unsigned char ** p,const unsigned char * end,unsigned char * ns_cert_type)1337 int mbedtls_x509_get_ns_cert_type(unsigned char **p,
1338 const unsigned char *end,
1339 unsigned char *ns_cert_type)
1340 {
1341 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1342 mbedtls_x509_bitstring bs = { 0, 0, NULL };
1343
1344 if ((ret = mbedtls_asn1_get_bitstring(p, end, &bs)) != 0) {
1345 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
1346 }
1347
1348 /* A bitstring with no flags set is still technically valid, as it will mean
1349 that the certificate has no designated purpose at the time of creation. */
1350 if (bs.len == 0) {
1351 *ns_cert_type = 0;
1352 return 0;
1353 }
1354
1355 if (bs.len != 1) {
1356 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
1357 MBEDTLS_ERR_ASN1_INVALID_LENGTH);
1358 }
1359
1360 /* Get actual bitstring */
1361 *ns_cert_type = *bs.p;
1362 return 0;
1363 }
1364
mbedtls_x509_get_key_usage(unsigned char ** p,const unsigned char * end,unsigned int * key_usage)1365 int mbedtls_x509_get_key_usage(unsigned char **p,
1366 const unsigned char *end,
1367 unsigned int *key_usage)
1368 {
1369 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1370 size_t i;
1371 mbedtls_x509_bitstring bs = { 0, 0, NULL };
1372
1373 if ((ret = mbedtls_asn1_get_bitstring(p, end, &bs)) != 0) {
1374 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
1375 }
1376
1377 /* A bitstring with no flags set is still technically valid, as it will mean
1378 that the certificate has no designated purpose at the time of creation. */
1379 if (bs.len == 0) {
1380 *key_usage = 0;
1381 return 0;
1382 }
1383
1384 /* Get actual bitstring */
1385 *key_usage = 0;
1386 for (i = 0; i < bs.len && i < sizeof(unsigned int); i++) {
1387 *key_usage |= (unsigned int) bs.p[i] << (8*i);
1388 }
1389
1390 return 0;
1391 }
1392
mbedtls_x509_parse_subject_alt_name(const mbedtls_x509_buf * san_buf,mbedtls_x509_subject_alternative_name * san)1393 int mbedtls_x509_parse_subject_alt_name(const mbedtls_x509_buf *san_buf,
1394 mbedtls_x509_subject_alternative_name *san)
1395 {
1396 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1397 switch (san_buf->tag &
1398 (MBEDTLS_ASN1_TAG_CLASS_MASK |
1399 MBEDTLS_ASN1_TAG_VALUE_MASK)) {
1400 /*
1401 * otherName
1402 */
1403 case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_OTHER_NAME):
1404 {
1405 mbedtls_x509_san_other_name other_name;
1406
1407 ret = x509_get_other_name(san_buf, &other_name);
1408 if (ret != 0) {
1409 return ret;
1410 }
1411
1412 memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name));
1413 san->type = MBEDTLS_X509_SAN_OTHER_NAME;
1414 memcpy(&san->san.other_name,
1415 &other_name, sizeof(other_name));
1416
1417 }
1418 break;
1419 /*
1420 * uniformResourceIdentifier
1421 */
1422 case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER):
1423 {
1424 memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name));
1425 san->type = MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER;
1426
1427 memcpy(&san->san.unstructured_name,
1428 san_buf, sizeof(*san_buf));
1429
1430 }
1431 break;
1432 /*
1433 * dNSName
1434 */
1435 case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_DNS_NAME):
1436 {
1437 memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name));
1438 san->type = MBEDTLS_X509_SAN_DNS_NAME;
1439
1440 memcpy(&san->san.unstructured_name,
1441 san_buf, sizeof(*san_buf));
1442 }
1443 break;
1444 /*
1445 * IP address
1446 */
1447 case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_IP_ADDRESS):
1448 {
1449 memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name));
1450 san->type = MBEDTLS_X509_SAN_IP_ADDRESS;
1451 // Only IPv6 (16 bytes) and IPv4 (4 bytes) types are supported
1452 if (san_buf->len == 4 || san_buf->len == 16) {
1453 memcpy(&san->san.unstructured_name,
1454 san_buf, sizeof(*san_buf));
1455 } else {
1456 return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
1457 }
1458 }
1459 break;
1460 /*
1461 * rfc822Name
1462 */
1463 case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_RFC822_NAME):
1464 {
1465 memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name));
1466 san->type = MBEDTLS_X509_SAN_RFC822_NAME;
1467 memcpy(&san->san.unstructured_name, san_buf, sizeof(*san_buf));
1468 }
1469 break;
1470 /*
1471 * directoryName
1472 */
1473 case (MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_X509_SAN_DIRECTORY_NAME):
1474 {
1475 size_t name_len;
1476 unsigned char *p = san_buf->p;
1477 memset(san, 0, sizeof(mbedtls_x509_subject_alternative_name));
1478 san->type = MBEDTLS_X509_SAN_DIRECTORY_NAME;
1479
1480 ret = mbedtls_asn1_get_tag(&p, p + san_buf->len, &name_len,
1481 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
1482
1483 if (ret != 0) {
1484 return ret;
1485 }
1486
1487 if ((ret = mbedtls_x509_get_name(&p, p + name_len,
1488 &san->san.directory_name)) != 0) {
1489 return ret;
1490 }
1491 }
1492 break;
1493 /*
1494 * Type not supported
1495 */
1496 default:
1497 return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
1498 }
1499 return 0;
1500 }
1501
mbedtls_x509_free_subject_alt_name(mbedtls_x509_subject_alternative_name * san)1502 void mbedtls_x509_free_subject_alt_name(mbedtls_x509_subject_alternative_name *san)
1503 {
1504 if (san->type == MBEDTLS_X509_SAN_DIRECTORY_NAME) {
1505 mbedtls_asn1_free_named_data_list_shallow(san->san.directory_name.next);
1506 }
1507 }
1508
1509 #if !defined(MBEDTLS_X509_REMOVE_INFO)
mbedtls_x509_info_subject_alt_name(char ** buf,size_t * size,const mbedtls_x509_sequence * subject_alt_name,const char * prefix)1510 int mbedtls_x509_info_subject_alt_name(char **buf, size_t *size,
1511 const mbedtls_x509_sequence
1512 *subject_alt_name,
1513 const char *prefix)
1514 {
1515 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1516 size_t i;
1517 size_t n = *size;
1518 char *p = *buf;
1519 const mbedtls_x509_sequence *cur = subject_alt_name;
1520 mbedtls_x509_subject_alternative_name san;
1521 int parse_ret;
1522
1523 while (cur != NULL) {
1524 memset(&san, 0, sizeof(san));
1525 parse_ret = mbedtls_x509_parse_subject_alt_name(&cur->buf, &san);
1526 if (parse_ret != 0) {
1527 if (parse_ret == MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) {
1528 ret = mbedtls_snprintf(p, n, "\n%s <unsupported>", prefix);
1529 MBEDTLS_X509_SAFE_SNPRINTF;
1530 } else {
1531 ret = mbedtls_snprintf(p, n, "\n%s <malformed>", prefix);
1532 MBEDTLS_X509_SAFE_SNPRINTF;
1533 }
1534 cur = cur->next;
1535 continue;
1536 }
1537
1538 switch (san.type) {
1539 /*
1540 * otherName
1541 */
1542 case MBEDTLS_X509_SAN_OTHER_NAME:
1543 {
1544 mbedtls_x509_san_other_name *other_name = &san.san.other_name;
1545
1546 ret = mbedtls_snprintf(p, n, "\n%s otherName :", prefix);
1547 MBEDTLS_X509_SAFE_SNPRINTF;
1548
1549 if (MBEDTLS_OID_CMP(MBEDTLS_OID_ON_HW_MODULE_NAME,
1550 &other_name->type_id) == 0) {
1551 ret = mbedtls_snprintf(p, n, "\n%s hardware module name :", prefix);
1552 MBEDTLS_X509_SAFE_SNPRINTF;
1553 ret =
1554 mbedtls_snprintf(p, n, "\n%s hardware type : ", prefix);
1555 MBEDTLS_X509_SAFE_SNPRINTF;
1556
1557 ret = mbedtls_oid_get_numeric_string(p,
1558 n,
1559 &other_name->value.hardware_module_name.oid);
1560 MBEDTLS_X509_SAFE_SNPRINTF;
1561
1562 ret =
1563 mbedtls_snprintf(p, n, "\n%s hardware serial number : ", prefix);
1564 MBEDTLS_X509_SAFE_SNPRINTF;
1565
1566 for (i = 0; i < other_name->value.hardware_module_name.val.len; i++) {
1567 ret = mbedtls_snprintf(p,
1568 n,
1569 "%02X",
1570 other_name->value.hardware_module_name.val.p[i]);
1571 MBEDTLS_X509_SAFE_SNPRINTF;
1572 }
1573 }/* MBEDTLS_OID_ON_HW_MODULE_NAME */
1574 }
1575 break;
1576 /*
1577 * uniformResourceIdentifier
1578 */
1579 case MBEDTLS_X509_SAN_UNIFORM_RESOURCE_IDENTIFIER:
1580 {
1581 ret = mbedtls_snprintf(p, n, "\n%s uniformResourceIdentifier : ", prefix);
1582 MBEDTLS_X509_SAFE_SNPRINTF;
1583 if (san.san.unstructured_name.len >= n) {
1584 if (n > 0) {
1585 *p = '\0';
1586 }
1587 return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
1588 }
1589
1590 memcpy(p, san.san.unstructured_name.p, san.san.unstructured_name.len);
1591 p += san.san.unstructured_name.len;
1592 n -= san.san.unstructured_name.len;
1593 }
1594 break;
1595 /*
1596 * dNSName
1597 * RFC822 Name
1598 */
1599 case MBEDTLS_X509_SAN_DNS_NAME:
1600 case MBEDTLS_X509_SAN_RFC822_NAME:
1601 {
1602 const char *dns_name = "dNSName";
1603 const char *rfc822_name = "rfc822Name";
1604
1605 ret = mbedtls_snprintf(p, n,
1606 "\n%s %s : ",
1607 prefix,
1608 san.type ==
1609 MBEDTLS_X509_SAN_DNS_NAME ? dns_name : rfc822_name);
1610 MBEDTLS_X509_SAFE_SNPRINTF;
1611 if (san.san.unstructured_name.len >= n) {
1612 if (n > 0) {
1613 *p = '\0';
1614 }
1615 return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
1616 }
1617
1618 memcpy(p, san.san.unstructured_name.p, san.san.unstructured_name.len);
1619 p += san.san.unstructured_name.len;
1620 n -= san.san.unstructured_name.len;
1621 }
1622 break;
1623 /*
1624 * iPAddress
1625 */
1626 case MBEDTLS_X509_SAN_IP_ADDRESS:
1627 {
1628 ret = mbedtls_snprintf(p, n, "\n%s %s : ",
1629 prefix, "iPAddress");
1630 MBEDTLS_X509_SAFE_SNPRINTF;
1631 if (san.san.unstructured_name.len >= n) {
1632 if (n > 0) {
1633 *p = '\0';
1634 }
1635 return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL;
1636 }
1637
1638 unsigned char *ip = san.san.unstructured_name.p;
1639 // Only IPv6 (16 bytes) and IPv4 (4 bytes) types are supported
1640 if (san.san.unstructured_name.len == 4) {
1641 ret = mbedtls_snprintf(p, n, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]);
1642 MBEDTLS_X509_SAFE_SNPRINTF;
1643 } else if (san.san.unstructured_name.len == 16) {
1644 ret = mbedtls_snprintf(p, n,
1645 "%X%X:%X%X:%X%X:%X%X:%X%X:%X%X:%X%X:%X%X",
1646 ip[0], ip[1], ip[2], ip[3], ip[4], ip[5], ip[6],
1647 ip[7], ip[8], ip[9], ip[10], ip[11], ip[12], ip[13],
1648 ip[14], ip[15]);
1649 MBEDTLS_X509_SAFE_SNPRINTF;
1650 } else {
1651 if (n > 0) {
1652 *p = '\0';
1653 }
1654 return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
1655 }
1656 }
1657 break;
1658 /*
1659 * directoryName
1660 */
1661 case MBEDTLS_X509_SAN_DIRECTORY_NAME:
1662 {
1663 ret = mbedtls_snprintf(p, n, "\n%s directoryName : ", prefix);
1664 if (ret < 0 || (size_t) ret >= n) {
1665 mbedtls_x509_free_subject_alt_name(&san);
1666 }
1667
1668 MBEDTLS_X509_SAFE_SNPRINTF;
1669 ret = mbedtls_x509_dn_gets(p, n, &san.san.directory_name);
1670
1671 if (ret < 0) {
1672 mbedtls_x509_free_subject_alt_name(&san);
1673 if (n > 0) {
1674 *p = '\0';
1675 }
1676 return ret;
1677 }
1678
1679 p += ret;
1680 n -= ret;
1681 }
1682 break;
1683 /*
1684 * Type not supported, skip item.
1685 */
1686 default:
1687 ret = mbedtls_snprintf(p, n, "\n%s <unsupported>", prefix);
1688 MBEDTLS_X509_SAFE_SNPRINTF;
1689 break;
1690 }
1691
1692 /* So far memory is freed only in the case of directoryName
1693 * parsing succeeding, as mbedtls_x509_get_name allocates memory. */
1694 mbedtls_x509_free_subject_alt_name(&san);
1695 cur = cur->next;
1696 }
1697
1698 *p = '\0';
1699
1700 *size = n;
1701 *buf = p;
1702
1703 return 0;
1704 }
1705
1706 #define PRINT_ITEM(i) \
1707 do { \
1708 ret = mbedtls_snprintf(p, n, "%s" i, sep); \
1709 MBEDTLS_X509_SAFE_SNPRINTF; \
1710 sep = ", "; \
1711 } while (0)
1712
1713 #define CERT_TYPE(type, name) \
1714 do { \
1715 if (ns_cert_type & (type)) { \
1716 PRINT_ITEM(name); \
1717 } \
1718 } while (0)
1719
mbedtls_x509_info_cert_type(char ** buf,size_t * size,unsigned char ns_cert_type)1720 int mbedtls_x509_info_cert_type(char **buf, size_t *size,
1721 unsigned char ns_cert_type)
1722 {
1723 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1724 size_t n = *size;
1725 char *p = *buf;
1726 const char *sep = "";
1727
1728 CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT, "SSL Client");
1729 CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER, "SSL Server");
1730 CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_EMAIL, "Email");
1731 CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING, "Object Signing");
1732 CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_RESERVED, "Reserved");
1733 CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_SSL_CA, "SSL CA");
1734 CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA, "Email CA");
1735 CERT_TYPE(MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA, "Object Signing CA");
1736
1737 *size = n;
1738 *buf = p;
1739
1740 return 0;
1741 }
1742
1743 #define KEY_USAGE(code, name) \
1744 do { \
1745 if ((key_usage) & (code)) { \
1746 PRINT_ITEM(name); \
1747 } \
1748 } while (0)
1749
mbedtls_x509_info_key_usage(char ** buf,size_t * size,unsigned int key_usage)1750 int mbedtls_x509_info_key_usage(char **buf, size_t *size,
1751 unsigned int key_usage)
1752 {
1753 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1754 size_t n = *size;
1755 char *p = *buf;
1756 const char *sep = "";
1757
1758 KEY_USAGE(MBEDTLS_X509_KU_DIGITAL_SIGNATURE, "Digital Signature");
1759 KEY_USAGE(MBEDTLS_X509_KU_NON_REPUDIATION, "Non Repudiation");
1760 KEY_USAGE(MBEDTLS_X509_KU_KEY_ENCIPHERMENT, "Key Encipherment");
1761 KEY_USAGE(MBEDTLS_X509_KU_DATA_ENCIPHERMENT, "Data Encipherment");
1762 KEY_USAGE(MBEDTLS_X509_KU_KEY_AGREEMENT, "Key Agreement");
1763 KEY_USAGE(MBEDTLS_X509_KU_KEY_CERT_SIGN, "Key Cert Sign");
1764 KEY_USAGE(MBEDTLS_X509_KU_CRL_SIGN, "CRL Sign");
1765 KEY_USAGE(MBEDTLS_X509_KU_ENCIPHER_ONLY, "Encipher Only");
1766 KEY_USAGE(MBEDTLS_X509_KU_DECIPHER_ONLY, "Decipher Only");
1767
1768 *size = n;
1769 *buf = p;
1770
1771 return 0;
1772 }
1773 #endif /* MBEDTLS_X509_REMOVE_INFO */
1774 #endif /* MBEDTLS_X509_CRT_PARSE_C || MBEDTLS_X509_CSR_PARSE_C */
1775 #endif /* MBEDTLS_X509_USE_C */
1776