1 /*
2  *  X.509 Certificate Signing Request (CSR) parsing
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_CSR_PARSE_C)
21 
22 #include "mbedtls/x509_csr.h"
23 #include "x509_internal.h"
24 #include "mbedtls/error.h"
25 #include "mbedtls/oid.h"
26 #include "mbedtls/platform_util.h"
27 
28 #include <string.h>
29 
30 #if defined(MBEDTLS_PEM_PARSE_C)
31 #include "mbedtls/pem.h"
32 #endif
33 
34 #include "mbedtls/platform.h"
35 
36 #if defined(MBEDTLS_FS_IO) || defined(EFIX64) || defined(EFI32)
37 #include <stdio.h>
38 #endif
39 
40 /*
41  *  Version  ::=  INTEGER  {  v1(0)  }
42  */
x509_csr_get_version(unsigned char ** p,const unsigned char * end,int * ver)43 static int x509_csr_get_version(unsigned char **p,
44                                 const unsigned char *end,
45                                 int *ver)
46 {
47     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
48 
49     if ((ret = mbedtls_asn1_get_int(p, end, ver)) != 0) {
50         if (ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
51             *ver = 0;
52             return 0;
53         }
54 
55         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_VERSION, ret);
56     }
57 
58     return 0;
59 }
60 
61 /*
62  * Parse CSR extension requests in DER format
63  */
x509_csr_parse_extensions(mbedtls_x509_csr * csr,unsigned char ** p,const unsigned char * end,mbedtls_x509_csr_ext_cb_t cb,void * p_ctx)64 static int x509_csr_parse_extensions(mbedtls_x509_csr *csr,
65                                      unsigned char **p, const unsigned char *end,
66                                      mbedtls_x509_csr_ext_cb_t cb,
67                                      void *p_ctx)
68 {
69     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
70     size_t len;
71     unsigned char *end_ext_data, *end_ext_octet;
72 
73     while (*p < end) {
74         mbedtls_x509_buf extn_oid = { 0, 0, NULL };
75         int is_critical = 0; /* DEFAULT FALSE */
76         int ext_type = 0;
77 
78         /* Read sequence tag */
79         if ((ret = mbedtls_asn1_get_tag(p, end, &len,
80                                         MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
81             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
82         }
83 
84         end_ext_data = *p + len;
85 
86         /* Get extension ID */
87         if ((ret = mbedtls_asn1_get_tag(p, end_ext_data, &extn_oid.len,
88                                         MBEDTLS_ASN1_OID)) != 0) {
89             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
90         }
91 
92         extn_oid.tag = MBEDTLS_ASN1_OID;
93         extn_oid.p = *p;
94         *p += extn_oid.len;
95 
96         /* Get optional critical */
97         if ((ret = mbedtls_asn1_get_bool(p, end_ext_data, &is_critical)) != 0 &&
98             (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)) {
99             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
100         }
101 
102         /* Data should be octet string type */
103         if ((ret = mbedtls_asn1_get_tag(p, end_ext_data, &len,
104                                         MBEDTLS_ASN1_OCTET_STRING)) != 0) {
105             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
106         }
107 
108         end_ext_octet = *p + len;
109 
110         if (end_ext_octet != end_ext_data) {
111             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
112                                      MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
113         }
114 
115         /*
116          * Detect supported extensions and skip unsupported extensions
117          */
118         ret = mbedtls_oid_get_x509_ext_type(&extn_oid, &ext_type);
119 
120         if (ret != 0) {
121             /* Give the callback (if any) a chance to handle the extension */
122             if (cb != NULL) {
123                 ret = cb(p_ctx, csr, &extn_oid, is_critical, *p, end_ext_octet);
124                 if (ret != 0 && is_critical) {
125                     return ret;
126                 }
127                 *p = end_ext_octet;
128                 continue;
129             }
130 
131             /* No parser found, skip extension */
132             *p = end_ext_octet;
133 
134             if (is_critical) {
135                 /* Data is marked as critical: fail */
136                 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
137                                          MBEDTLS_ERR_ASN1_UNEXPECTED_TAG);
138             }
139             continue;
140         }
141 
142         /* Forbid repeated extensions */
143         if ((csr->ext_types & ext_type) != 0) {
144             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
145                                      MBEDTLS_ERR_ASN1_INVALID_DATA);
146         }
147 
148         csr->ext_types |= ext_type;
149 
150         switch (ext_type) {
151             case MBEDTLS_X509_EXT_KEY_USAGE:
152                 /* Parse key usage */
153                 if ((ret = mbedtls_x509_get_key_usage(p, end_ext_data,
154                                                       &csr->key_usage)) != 0) {
155                     return ret;
156                 }
157                 break;
158 
159             case MBEDTLS_X509_EXT_SUBJECT_ALT_NAME:
160                 /* Parse subject alt name */
161                 if ((ret = mbedtls_x509_get_subject_alt_name(p, end_ext_data,
162                                                              &csr->subject_alt_names)) != 0) {
163                     return ret;
164                 }
165                 break;
166 
167             case MBEDTLS_X509_EXT_NS_CERT_TYPE:
168                 /* Parse netscape certificate type */
169                 if ((ret = mbedtls_x509_get_ns_cert_type(p, end_ext_data,
170                                                          &csr->ns_cert_type)) != 0) {
171                     return ret;
172                 }
173                 break;
174             default:
175                 /*
176                  * If this is a non-critical extension, which the oid layer
177                  * supports, but there isn't an x509 parser for it,
178                  * skip the extension.
179                  */
180                 if (is_critical) {
181                     return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
182                 } else {
183                     *p = end_ext_octet;
184                 }
185         }
186     }
187 
188     if (*p != end) {
189         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
190                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
191     }
192 
193     return 0;
194 }
195 
196 /*
197  * Parse CSR attributes in DER format
198  */
x509_csr_parse_attributes(mbedtls_x509_csr * csr,const unsigned char * start,const unsigned char * end,mbedtls_x509_csr_ext_cb_t cb,void * p_ctx)199 static int x509_csr_parse_attributes(mbedtls_x509_csr *csr,
200                                      const unsigned char *start, const unsigned char *end,
201                                      mbedtls_x509_csr_ext_cb_t cb,
202                                      void *p_ctx)
203 {
204     int ret;
205     size_t len;
206     unsigned char *end_attr_data;
207     unsigned char **p = (unsigned char **) &start;
208 
209     while (*p < end) {
210         mbedtls_x509_buf attr_oid = { 0, 0, NULL };
211 
212         if ((ret = mbedtls_asn1_get_tag(p, end, &len,
213                                         MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
214             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
215         }
216         end_attr_data = *p + len;
217 
218         /* Get attribute ID */
219         if ((ret = mbedtls_asn1_get_tag(p, end_attr_data, &attr_oid.len,
220                                         MBEDTLS_ASN1_OID)) != 0) {
221             return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
222         }
223 
224         attr_oid.tag = MBEDTLS_ASN1_OID;
225         attr_oid.p = *p;
226         *p += attr_oid.len;
227 
228         /* Check that this is an extension-request attribute */
229         if (MBEDTLS_OID_CMP(MBEDTLS_OID_PKCS9_CSR_EXT_REQ, &attr_oid) == 0) {
230             if ((ret = mbedtls_asn1_get_tag(p, end, &len,
231                                             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET)) != 0) {
232                 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
233             }
234 
235             if ((ret = mbedtls_asn1_get_tag(p, end, &len,
236                                             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) !=
237                 0) {
238                 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS, ret);
239             }
240 
241             if ((ret = x509_csr_parse_extensions(csr, p, *p + len, cb, p_ctx)) != 0) {
242                 return ret;
243             }
244 
245             if (*p != end_attr_data) {
246                 return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
247                                          MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
248             }
249         }
250 
251         *p = end_attr_data;
252     }
253 
254     if (*p != end) {
255         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_EXTENSIONS,
256                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
257     }
258 
259     return 0;
260 }
261 
262 /*
263  * Parse a CSR in DER format
264  */
mbedtls_x509_csr_parse_der_internal(mbedtls_x509_csr * csr,const unsigned char * buf,size_t buflen,mbedtls_x509_csr_ext_cb_t cb,void * p_ctx)265 static int mbedtls_x509_csr_parse_der_internal(mbedtls_x509_csr *csr,
266                                                const unsigned char *buf, size_t buflen,
267                                                mbedtls_x509_csr_ext_cb_t cb,
268                                                void *p_ctx)
269 {
270     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
271     size_t len;
272     unsigned char *p, *end;
273     mbedtls_x509_buf sig_params;
274 
275     memset(&sig_params, 0, sizeof(mbedtls_x509_buf));
276 
277     /*
278      * Check for valid input
279      */
280     if (csr == NULL || buf == NULL || buflen == 0) {
281         return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
282     }
283 
284     mbedtls_x509_csr_init(csr);
285 
286     /*
287      * first copy the raw DER data
288      */
289     p = mbedtls_calloc(1, len = buflen);
290 
291     if (p == NULL) {
292         return MBEDTLS_ERR_X509_ALLOC_FAILED;
293     }
294 
295     memcpy(p, buf, buflen);
296 
297     csr->raw.p = p;
298     csr->raw.len = len;
299     end = p + len;
300 
301     /*
302      *  CertificationRequest ::= SEQUENCE {
303      *       certificationRequestInfo CertificationRequestInfo,
304      *       signatureAlgorithm AlgorithmIdentifier,
305      *       signature          BIT STRING
306      *  }
307      */
308     if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
309                                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
310         mbedtls_x509_csr_free(csr);
311         return MBEDTLS_ERR_X509_INVALID_FORMAT;
312     }
313 
314     if (len != (size_t) (end - p)) {
315         mbedtls_x509_csr_free(csr);
316         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT,
317                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
318     }
319 
320     /*
321      *  CertificationRequestInfo ::= SEQUENCE {
322      */
323     csr->cri.p = p;
324 
325     if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
326                                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
327         mbedtls_x509_csr_free(csr);
328         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret);
329     }
330 
331     end = p + len;
332     csr->cri.len = (size_t) (end - csr->cri.p);
333 
334     /*
335      *  Version  ::=  INTEGER {  v1(0) }
336      */
337     if ((ret = x509_csr_get_version(&p, end, &csr->version)) != 0) {
338         mbedtls_x509_csr_free(csr);
339         return ret;
340     }
341 
342     if (csr->version != 0) {
343         mbedtls_x509_csr_free(csr);
344         return MBEDTLS_ERR_X509_UNKNOWN_VERSION;
345     }
346 
347     csr->version++;
348 
349     /*
350      *  subject               Name
351      */
352     csr->subject_raw.p = p;
353 
354     if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
355                                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)) != 0) {
356         mbedtls_x509_csr_free(csr);
357         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret);
358     }
359 
360     if ((ret = mbedtls_x509_get_name(&p, p + len, &csr->subject)) != 0) {
361         mbedtls_x509_csr_free(csr);
362         return ret;
363     }
364 
365     csr->subject_raw.len = (size_t) (p - csr->subject_raw.p);
366 
367     /*
368      *  subjectPKInfo SubjectPublicKeyInfo
369      */
370     if ((ret = mbedtls_pk_parse_subpubkey(&p, end, &csr->pk)) != 0) {
371         mbedtls_x509_csr_free(csr);
372         return ret;
373     }
374 
375     /*
376      *  attributes    [0] Attributes
377      *
378      *  The list of possible attributes is open-ended, though RFC 2985
379      *  (PKCS#9) defines a few in section 5.4. We currently don't support any,
380      *  so we just ignore them. This is a safe thing to do as the worst thing
381      *  that could happen is that we issue a certificate that does not match
382      *  the requester's expectations - this cannot cause a violation of our
383      *  signature policies.
384      */
385     if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
386                                     MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC)) !=
387         0) {
388         mbedtls_x509_csr_free(csr);
389         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT, ret);
390     }
391 
392     if ((ret = x509_csr_parse_attributes(csr, p, p + len, cb, p_ctx)) != 0) {
393         mbedtls_x509_csr_free(csr);
394         return ret;
395     }
396 
397     p += len;
398 
399     end = csr->raw.p + csr->raw.len;
400 
401     /*
402      *  signatureAlgorithm   AlgorithmIdentifier,
403      *  signature            BIT STRING
404      */
405     if ((ret = mbedtls_x509_get_alg(&p, end, &csr->sig_oid, &sig_params)) != 0) {
406         mbedtls_x509_csr_free(csr);
407         return ret;
408     }
409 
410     if ((ret = mbedtls_x509_get_sig_alg(&csr->sig_oid, &sig_params,
411                                         &csr->sig_md, &csr->sig_pk,
412                                         &csr->sig_opts)) != 0) {
413         mbedtls_x509_csr_free(csr);
414         return MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG;
415     }
416 
417     if ((ret = mbedtls_x509_get_sig(&p, end, &csr->sig)) != 0) {
418         mbedtls_x509_csr_free(csr);
419         return ret;
420     }
421 
422     if (p != end) {
423         mbedtls_x509_csr_free(csr);
424         return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_X509_INVALID_FORMAT,
425                                  MBEDTLS_ERR_ASN1_LENGTH_MISMATCH);
426     }
427 
428     return 0;
429 }
430 
431 /*
432  * Parse a CSR in DER format
433  */
mbedtls_x509_csr_parse_der(mbedtls_x509_csr * csr,const unsigned char * buf,size_t buflen)434 int mbedtls_x509_csr_parse_der(mbedtls_x509_csr *csr,
435                                const unsigned char *buf, size_t buflen)
436 {
437     return mbedtls_x509_csr_parse_der_internal(csr, buf, buflen, NULL, NULL);
438 }
439 
440 /*
441  * Parse a CSR in DER format with callback for unknown extensions
442  */
mbedtls_x509_csr_parse_der_with_ext_cb(mbedtls_x509_csr * csr,const unsigned char * buf,size_t buflen,mbedtls_x509_csr_ext_cb_t cb,void * p_ctx)443 int mbedtls_x509_csr_parse_der_with_ext_cb(mbedtls_x509_csr *csr,
444                                            const unsigned char *buf, size_t buflen,
445                                            mbedtls_x509_csr_ext_cb_t cb,
446                                            void *p_ctx)
447 {
448     return mbedtls_x509_csr_parse_der_internal(csr, buf, buflen, cb, p_ctx);
449 }
450 
451 /*
452  * Parse a CSR, allowing for PEM or raw DER encoding
453  */
mbedtls_x509_csr_parse(mbedtls_x509_csr * csr,const unsigned char * buf,size_t buflen)454 int mbedtls_x509_csr_parse(mbedtls_x509_csr *csr, const unsigned char *buf, size_t buflen)
455 {
456 #if defined(MBEDTLS_PEM_PARSE_C)
457     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
458     size_t use_len;
459     mbedtls_pem_context pem;
460 #endif
461 
462     /*
463      * Check for valid input
464      */
465     if (csr == NULL || buf == NULL || buflen == 0) {
466         return MBEDTLS_ERR_X509_BAD_INPUT_DATA;
467     }
468 
469 #if defined(MBEDTLS_PEM_PARSE_C)
470     /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
471     if (buf[buflen - 1] == '\0') {
472         mbedtls_pem_init(&pem);
473         ret = mbedtls_pem_read_buffer(&pem,
474                                       "-----BEGIN CERTIFICATE REQUEST-----",
475                                       "-----END CERTIFICATE REQUEST-----",
476                                       buf, NULL, 0, &use_len);
477         if (ret == MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) {
478             ret = mbedtls_pem_read_buffer(&pem,
479                                           "-----BEGIN NEW CERTIFICATE REQUEST-----",
480                                           "-----END NEW CERTIFICATE REQUEST-----",
481                                           buf, NULL, 0, &use_len);
482         }
483 
484         if (ret == 0) {
485             /*
486              * Was PEM encoded, parse the result
487              */
488             ret = mbedtls_x509_csr_parse_der(csr, pem.buf, pem.buflen);
489         }
490 
491         mbedtls_pem_free(&pem);
492         if (ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) {
493             return ret;
494         }
495     }
496 #endif /* MBEDTLS_PEM_PARSE_C */
497     return mbedtls_x509_csr_parse_der(csr, buf, buflen);
498 }
499 
500 #if defined(MBEDTLS_FS_IO)
501 /*
502  * Load a CSR into the structure
503  */
mbedtls_x509_csr_parse_file(mbedtls_x509_csr * csr,const char * path)504 int mbedtls_x509_csr_parse_file(mbedtls_x509_csr *csr, const char *path)
505 {
506     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
507     size_t n;
508     unsigned char *buf;
509 
510     if ((ret = mbedtls_pk_load_file(path, &buf, &n)) != 0) {
511         return ret;
512     }
513 
514     ret = mbedtls_x509_csr_parse(csr, buf, n);
515 
516     mbedtls_zeroize_and_free(buf, n);
517 
518     return ret;
519 }
520 #endif /* MBEDTLS_FS_IO */
521 
522 #if !defined(MBEDTLS_X509_REMOVE_INFO)
523 #define BEFORE_COLON    14
524 #define BC              "14"
525 /*
526  * Return an informational string about the CSR.
527  */
mbedtls_x509_csr_info(char * buf,size_t size,const char * prefix,const mbedtls_x509_csr * csr)528 int mbedtls_x509_csr_info(char *buf, size_t size, const char *prefix,
529                           const mbedtls_x509_csr *csr)
530 {
531     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
532     size_t n;
533     char *p;
534     char key_size_str[BEFORE_COLON];
535 
536     p = buf;
537     n = size;
538 
539     ret = mbedtls_snprintf(p, n, "%sCSR version   : %d",
540                            prefix, csr->version);
541     MBEDTLS_X509_SAFE_SNPRINTF;
542 
543     ret = mbedtls_snprintf(p, n, "\n%ssubject name  : ", prefix);
544     MBEDTLS_X509_SAFE_SNPRINTF;
545     ret = mbedtls_x509_dn_gets(p, n, &csr->subject);
546     MBEDTLS_X509_SAFE_SNPRINTF;
547 
548     ret = mbedtls_snprintf(p, n, "\n%ssigned using  : ", prefix);
549     MBEDTLS_X509_SAFE_SNPRINTF;
550 
551     ret = mbedtls_x509_sig_alg_gets(p, n, &csr->sig_oid, csr->sig_pk, csr->sig_md,
552                                     csr->sig_opts);
553     MBEDTLS_X509_SAFE_SNPRINTF;
554 
555     if ((ret = mbedtls_x509_key_size_helper(key_size_str, BEFORE_COLON,
556                                             mbedtls_pk_get_name(&csr->pk))) != 0) {
557         return ret;
558     }
559 
560     ret = mbedtls_snprintf(p, n, "\n%s%-" BC "s: %d bits\n", prefix, key_size_str,
561                            (int) mbedtls_pk_get_bitlen(&csr->pk));
562     MBEDTLS_X509_SAFE_SNPRINTF;
563 
564     /*
565      * Optional extensions
566      */
567 
568     if (csr->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME) {
569         ret = mbedtls_snprintf(p, n, "\n%ssubject alt name  :", prefix);
570         MBEDTLS_X509_SAFE_SNPRINTF;
571 
572         if ((ret = mbedtls_x509_info_subject_alt_name(&p, &n,
573                                                       &csr->subject_alt_names,
574                                                       prefix)) != 0) {
575             return ret;
576         }
577     }
578 
579     if (csr->ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE) {
580         ret = mbedtls_snprintf(p, n, "\n%scert. type        : ", prefix);
581         MBEDTLS_X509_SAFE_SNPRINTF;
582 
583         if ((ret = mbedtls_x509_info_cert_type(&p, &n, csr->ns_cert_type)) != 0) {
584             return ret;
585         }
586     }
587 
588     if (csr->ext_types & MBEDTLS_X509_EXT_KEY_USAGE) {
589         ret = mbedtls_snprintf(p, n, "\n%skey usage         : ", prefix);
590         MBEDTLS_X509_SAFE_SNPRINTF;
591 
592         if ((ret = mbedtls_x509_info_key_usage(&p, &n, csr->key_usage)) != 0) {
593             return ret;
594         }
595     }
596 
597     if (csr->ext_types != 0) {
598         ret = mbedtls_snprintf(p, n, "\n");
599         MBEDTLS_X509_SAFE_SNPRINTF;
600     }
601 
602     return (int) (size - n);
603 }
604 #endif /* MBEDTLS_X509_REMOVE_INFO */
605 
606 /*
607  * Initialize a CSR
608  */
mbedtls_x509_csr_init(mbedtls_x509_csr * csr)609 void mbedtls_x509_csr_init(mbedtls_x509_csr *csr)
610 {
611     memset(csr, 0, sizeof(mbedtls_x509_csr));
612 }
613 
614 /*
615  * Unallocate all CSR data
616  */
mbedtls_x509_csr_free(mbedtls_x509_csr * csr)617 void mbedtls_x509_csr_free(mbedtls_x509_csr *csr)
618 {
619     if (csr == NULL) {
620         return;
621     }
622 
623     mbedtls_pk_free(&csr->pk);
624 
625 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
626     mbedtls_free(csr->sig_opts);
627 #endif
628 
629     mbedtls_asn1_free_named_data_list_shallow(csr->subject.next);
630     mbedtls_asn1_sequence_free(csr->subject_alt_names.next);
631 
632     if (csr->raw.p != NULL) {
633         mbedtls_zeroize_and_free(csr->raw.p, csr->raw.len);
634     }
635 
636     mbedtls_platform_zeroize(csr, sizeof(mbedtls_x509_csr));
637 }
638 
639 #endif /* MBEDTLS_X509_CSR_PARSE_C */
640