• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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