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