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 */ 43static 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 */ 64static 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 */ 199static 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 */ 265static 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 */ 434int 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 */ 443int 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 */ 454int 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 */ 504int 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 */ 528int 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 */ 609void 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 */ 617void 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