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