1 /* 2 * X.509 certificate writing 3 * 4 * Copyright The Mbed TLS Contributors 5 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 6 */ 7 /* 8 * References: 9 * - certificates: RFC 5280, updated by RFC 6818 10 * - CSRs: PKCS#10 v1.7 aka RFC 2986 11 * - attributes: PKCS#9 v2.0 aka RFC 2985 12 */ 13 14 #include "common.h" 15 16 #if defined(MBEDTLS_X509_CRT_WRITE_C) 17 18 #include "mbedtls/x509_crt.h" 19 #include "x509_internal.h" 20 #include "mbedtls/asn1write.h" 21 #include "mbedtls/error.h" 22 #include "mbedtls/oid.h" 23 #include "mbedtls/platform.h" 24 #include "mbedtls/platform_util.h" 25 #include "mbedtls/md.h" 26 27 #include <string.h> 28 #include <stdint.h> 29 30 #if defined(MBEDTLS_PEM_WRITE_C) 31 #include "mbedtls/pem.h" 32 #endif /* MBEDTLS_PEM_WRITE_C */ 33 34 #if defined(MBEDTLS_USE_PSA_CRYPTO) 35 #include "psa/crypto.h" 36 #include "psa_util_internal.h" 37 #include "mbedtls/psa_util.h" 38 #endif /* MBEDTLS_USE_PSA_CRYPTO */ 39 40 void mbedtls_x509write_crt_init(mbedtls_x509write_cert *ctx) 41 { 42 memset(ctx, 0, sizeof(mbedtls_x509write_cert)); 43 44 ctx->version = MBEDTLS_X509_CRT_VERSION_3; 45 } 46 47 void mbedtls_x509write_crt_free(mbedtls_x509write_cert *ctx) 48 { 49 if (ctx == NULL) { 50 return; 51 } 52 53 mbedtls_asn1_free_named_data_list(&ctx->subject); 54 mbedtls_asn1_free_named_data_list(&ctx->issuer); 55 mbedtls_asn1_free_named_data_list(&ctx->extensions); 56 57 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_x509write_cert)); 58 } 59 60 void mbedtls_x509write_crt_set_version(mbedtls_x509write_cert *ctx, 61 int version) 62 { 63 ctx->version = version; 64 } 65 66 void mbedtls_x509write_crt_set_md_alg(mbedtls_x509write_cert *ctx, 67 mbedtls_md_type_t md_alg) 68 { 69 ctx->md_alg = md_alg; 70 } 71 72 void mbedtls_x509write_crt_set_subject_key(mbedtls_x509write_cert *ctx, 73 mbedtls_pk_context *key) 74 { 75 ctx->subject_key = key; 76 } 77 78 void mbedtls_x509write_crt_set_issuer_key(mbedtls_x509write_cert *ctx, 79 mbedtls_pk_context *key) 80 { 81 ctx->issuer_key = key; 82 } 83 84 int mbedtls_x509write_crt_set_subject_name(mbedtls_x509write_cert *ctx, 85 const char *subject_name) 86 { 87 return mbedtls_x509_string_to_names(&ctx->subject, subject_name); 88 } 89 90 int mbedtls_x509write_crt_set_issuer_name(mbedtls_x509write_cert *ctx, 91 const char *issuer_name) 92 { 93 return mbedtls_x509_string_to_names(&ctx->issuer, issuer_name); 94 } 95 96 #if defined(MBEDTLS_BIGNUM_C) && !defined(MBEDTLS_DEPRECATED_REMOVED) 97 int mbedtls_x509write_crt_set_serial(mbedtls_x509write_cert *ctx, 98 const mbedtls_mpi *serial) 99 { 100 int ret; 101 size_t tmp_len; 102 103 /* Ensure that the MPI value fits into the buffer */ 104 tmp_len = mbedtls_mpi_size(serial); 105 if (tmp_len > MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN) { 106 return MBEDTLS_ERR_X509_BAD_INPUT_DATA; 107 } 108 109 ctx->serial_len = tmp_len; 110 111 ret = mbedtls_mpi_write_binary(serial, ctx->serial, tmp_len); 112 if (ret < 0) { 113 return ret; 114 } 115 116 return 0; 117 } 118 #endif // MBEDTLS_BIGNUM_C && !MBEDTLS_DEPRECATED_REMOVED 119 120 int mbedtls_x509write_crt_set_serial_raw(mbedtls_x509write_cert *ctx, 121 unsigned char *serial, size_t serial_len) 122 { 123 if (serial_len > MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN) { 124 return MBEDTLS_ERR_X509_BAD_INPUT_DATA; 125 } 126 127 ctx->serial_len = serial_len; 128 memcpy(ctx->serial, serial, serial_len); 129 130 return 0; 131 } 132 133 int mbedtls_x509write_crt_set_validity(mbedtls_x509write_cert *ctx, 134 const char *not_before, 135 const char *not_after) 136 { 137 if (strlen(not_before) != MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1 || 138 strlen(not_after) != MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1) { 139 return MBEDTLS_ERR_X509_BAD_INPUT_DATA; 140 } 141 strncpy(ctx->not_before, not_before, MBEDTLS_X509_RFC5280_UTC_TIME_LEN); 142 strncpy(ctx->not_after, not_after, MBEDTLS_X509_RFC5280_UTC_TIME_LEN); 143 ctx->not_before[MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1] = 'Z'; 144 ctx->not_after[MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1] = 'Z'; 145 146 return 0; 147 } 148 149 int mbedtls_x509write_crt_set_subject_alternative_name(mbedtls_x509write_cert *ctx, 150 const mbedtls_x509_san_list *san_list) 151 { 152 return mbedtls_x509_write_set_san_common(&ctx->extensions, san_list); 153 } 154 155 156 int mbedtls_x509write_crt_set_extension(mbedtls_x509write_cert *ctx, 157 const char *oid, size_t oid_len, 158 int critical, 159 const unsigned char *val, size_t val_len) 160 { 161 return mbedtls_x509_set_extension(&ctx->extensions, oid, oid_len, 162 critical, val, val_len); 163 } 164 165 int mbedtls_x509write_crt_set_basic_constraints(mbedtls_x509write_cert *ctx, 166 int is_ca, int max_pathlen) 167 { 168 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 169 unsigned char buf[9]; 170 unsigned char *c = buf + sizeof(buf); 171 size_t len = 0; 172 173 memset(buf, 0, sizeof(buf)); 174 175 if (is_ca && max_pathlen > 127) { 176 return MBEDTLS_ERR_X509_BAD_INPUT_DATA; 177 } 178 179 if (is_ca) { 180 if (max_pathlen >= 0) { 181 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_int(&c, buf, 182 max_pathlen)); 183 } 184 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_bool(&c, buf, 1)); 185 } 186 187 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); 188 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf, 189 MBEDTLS_ASN1_CONSTRUCTED | 190 MBEDTLS_ASN1_SEQUENCE)); 191 192 return 193 mbedtls_x509write_crt_set_extension(ctx, MBEDTLS_OID_BASIC_CONSTRAINTS, 194 MBEDTLS_OID_SIZE(MBEDTLS_OID_BASIC_CONSTRAINTS), 195 is_ca, buf + sizeof(buf) - len, len); 196 } 197 198 #if defined(MBEDTLS_MD_CAN_SHA1) 199 static int mbedtls_x509write_crt_set_key_identifier(mbedtls_x509write_cert *ctx, 200 int is_ca, 201 unsigned char tag) 202 { 203 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 204 unsigned char buf[MBEDTLS_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */ 205 unsigned char *c = buf + sizeof(buf); 206 size_t len = 0; 207 #if defined(MBEDTLS_USE_PSA_CRYPTO) 208 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 209 size_t hash_length; 210 #endif /* MBEDTLS_USE_PSA_CRYPTO */ 211 212 memset(buf, 0, sizeof(buf)); 213 MBEDTLS_ASN1_CHK_ADD(len, 214 mbedtls_pk_write_pubkey(&c, 215 buf, 216 is_ca ? 217 ctx->issuer_key : 218 ctx->subject_key)); 219 220 221 #if defined(MBEDTLS_USE_PSA_CRYPTO) 222 status = psa_hash_compute(PSA_ALG_SHA_1, 223 buf + sizeof(buf) - len, 224 len, 225 buf + sizeof(buf) - 20, 226 20, 227 &hash_length); 228 if (status != PSA_SUCCESS) { 229 return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; 230 } 231 #else 232 ret = mbedtls_md(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), 233 buf + sizeof(buf) - len, len, 234 buf + sizeof(buf) - 20); 235 if (ret != 0) { 236 return ret; 237 } 238 #endif /* MBEDTLS_USE_PSA_CRYPTO */ 239 240 c = buf + sizeof(buf) - 20; 241 len = 20; 242 243 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); 244 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf, tag)); 245 246 if (is_ca) { // writes AuthorityKeyIdentifier sequence 247 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); 248 MBEDTLS_ASN1_CHK_ADD(len, 249 mbedtls_asn1_write_tag(&c, 250 buf, 251 MBEDTLS_ASN1_CONSTRUCTED | 252 MBEDTLS_ASN1_SEQUENCE)); 253 } 254 255 if (is_ca) { 256 return mbedtls_x509write_crt_set_extension(ctx, 257 MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER, 258 MBEDTLS_OID_SIZE( 259 MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER), 260 0, buf + sizeof(buf) - len, len); 261 } else { 262 return mbedtls_x509write_crt_set_extension(ctx, 263 MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER, 264 MBEDTLS_OID_SIZE( 265 MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER), 266 0, buf + sizeof(buf) - len, len); 267 } 268 } 269 270 int mbedtls_x509write_crt_set_subject_key_identifier(mbedtls_x509write_cert *ctx) 271 { 272 return mbedtls_x509write_crt_set_key_identifier(ctx, 273 0, 274 MBEDTLS_ASN1_OCTET_STRING); 275 } 276 277 int mbedtls_x509write_crt_set_authority_key_identifier(mbedtls_x509write_cert *ctx) 278 { 279 return mbedtls_x509write_crt_set_key_identifier(ctx, 280 1, 281 (MBEDTLS_ASN1_CONTEXT_SPECIFIC | 0)); 282 } 283 #endif /* MBEDTLS_MD_CAN_SHA1 */ 284 285 int mbedtls_x509write_crt_set_key_usage(mbedtls_x509write_cert *ctx, 286 unsigned int key_usage) 287 { 288 unsigned char buf[5] = { 0 }, ku[2] = { 0 }; 289 unsigned char *c; 290 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 291 const unsigned int allowed_bits = MBEDTLS_X509_KU_DIGITAL_SIGNATURE | 292 MBEDTLS_X509_KU_NON_REPUDIATION | 293 MBEDTLS_X509_KU_KEY_ENCIPHERMENT | 294 MBEDTLS_X509_KU_DATA_ENCIPHERMENT | 295 MBEDTLS_X509_KU_KEY_AGREEMENT | 296 MBEDTLS_X509_KU_KEY_CERT_SIGN | 297 MBEDTLS_X509_KU_CRL_SIGN | 298 MBEDTLS_X509_KU_ENCIPHER_ONLY | 299 MBEDTLS_X509_KU_DECIPHER_ONLY; 300 301 /* Check that nothing other than the allowed flags is set */ 302 if ((key_usage & ~allowed_bits) != 0) { 303 return MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE; 304 } 305 306 c = buf + 5; 307 MBEDTLS_PUT_UINT16_LE(key_usage, ku, 0); 308 ret = mbedtls_asn1_write_named_bitstring(&c, buf, ku, 9); 309 310 if (ret < 0) { 311 return ret; 312 } else if (ret < 3 || ret > 5) { 313 return MBEDTLS_ERR_X509_INVALID_FORMAT; 314 } 315 316 ret = mbedtls_x509write_crt_set_extension(ctx, MBEDTLS_OID_KEY_USAGE, 317 MBEDTLS_OID_SIZE(MBEDTLS_OID_KEY_USAGE), 318 1, c, (size_t) ret); 319 if (ret != 0) { 320 return ret; 321 } 322 323 return 0; 324 } 325 326 int mbedtls_x509write_crt_set_ext_key_usage(mbedtls_x509write_cert *ctx, 327 const mbedtls_asn1_sequence *exts) 328 { 329 unsigned char buf[256]; 330 unsigned char *c = buf + sizeof(buf); 331 int ret; 332 size_t len = 0; 333 const mbedtls_asn1_sequence *last_ext = NULL; 334 const mbedtls_asn1_sequence *ext; 335 336 memset(buf, 0, sizeof(buf)); 337 338 /* We need at least one extension: SEQUENCE SIZE (1..MAX) OF KeyPurposeId */ 339 if (exts == NULL) { 340 return MBEDTLS_ERR_X509_BAD_INPUT_DATA; 341 } 342 343 /* Iterate over exts backwards, so we write them out in the requested order */ 344 while (last_ext != exts) { 345 for (ext = exts; ext->next != last_ext; ext = ext->next) { 346 } 347 if (ext->buf.tag != MBEDTLS_ASN1_OID) { 348 return MBEDTLS_ERR_X509_BAD_INPUT_DATA; 349 } 350 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(&c, buf, ext->buf.p, ext->buf.len)); 351 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, ext->buf.len)); 352 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf, MBEDTLS_ASN1_OID)); 353 last_ext = ext; 354 } 355 356 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); 357 MBEDTLS_ASN1_CHK_ADD(len, 358 mbedtls_asn1_write_tag(&c, buf, 359 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)); 360 361 return mbedtls_x509write_crt_set_extension(ctx, 362 MBEDTLS_OID_EXTENDED_KEY_USAGE, 363 MBEDTLS_OID_SIZE(MBEDTLS_OID_EXTENDED_KEY_USAGE), 364 1, c, len); 365 } 366 367 int mbedtls_x509write_crt_set_ns_cert_type(mbedtls_x509write_cert *ctx, 368 unsigned char ns_cert_type) 369 { 370 unsigned char buf[4] = { 0 }; 371 unsigned char *c; 372 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 373 374 c = buf + 4; 375 376 ret = mbedtls_asn1_write_named_bitstring(&c, buf, &ns_cert_type, 8); 377 if (ret < 3 || ret > 4) { 378 return ret; 379 } 380 381 ret = mbedtls_x509write_crt_set_extension(ctx, MBEDTLS_OID_NS_CERT_TYPE, 382 MBEDTLS_OID_SIZE(MBEDTLS_OID_NS_CERT_TYPE), 383 0, c, (size_t) ret); 384 if (ret != 0) { 385 return ret; 386 } 387 388 return 0; 389 } 390 391 static int x509_write_time(unsigned char **p, unsigned char *start, 392 const char *t, size_t size) 393 { 394 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 395 size_t len = 0; 396 397 /* 398 * write MBEDTLS_ASN1_UTC_TIME if year < 2050 (2 bytes shorter) 399 */ 400 if (t[0] < '2' || (t[0] == '2' && t[1] == '0' && t[2] < '5')) { 401 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(p, start, 402 (const unsigned char *) t + 2, 403 size - 2)); 404 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len)); 405 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, 406 MBEDTLS_ASN1_UTC_TIME)); 407 } else { 408 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(p, start, 409 (const unsigned char *) t, 410 size)); 411 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(p, start, len)); 412 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(p, start, 413 MBEDTLS_ASN1_GENERALIZED_TIME)); 414 } 415 416 return (int) len; 417 } 418 419 int mbedtls_x509write_crt_der(mbedtls_x509write_cert *ctx, 420 unsigned char *buf, size_t size, 421 int (*f_rng)(void *, unsigned char *, size_t), 422 void *p_rng) 423 { 424 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 425 const char *sig_oid; 426 size_t sig_oid_len = 0; 427 unsigned char *c, *c2; 428 unsigned char sig[MBEDTLS_PK_SIGNATURE_MAX_SIZE]; 429 size_t hash_length = 0; 430 unsigned char hash[MBEDTLS_MD_MAX_SIZE]; 431 #if defined(MBEDTLS_USE_PSA_CRYPTO) 432 psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; 433 psa_algorithm_t psa_algorithm; 434 #endif /* MBEDTLS_USE_PSA_CRYPTO */ 435 436 size_t sub_len = 0, pub_len = 0, sig_and_oid_len = 0, sig_len; 437 size_t len = 0; 438 mbedtls_pk_type_t pk_alg; 439 int write_sig_null_par; 440 441 /* 442 * Prepare data to be signed at the end of the target buffer 443 */ 444 c = buf + size; 445 446 /* Signature algorithm needed in TBS, and later for actual signature */ 447 448 /* There's no direct way of extracting a signature algorithm 449 * (represented as an element of mbedtls_pk_type_t) from a PK instance. */ 450 if (mbedtls_pk_can_do(ctx->issuer_key, MBEDTLS_PK_RSA)) { 451 pk_alg = MBEDTLS_PK_RSA; 452 } else if (mbedtls_pk_can_do(ctx->issuer_key, MBEDTLS_PK_ECDSA)) { 453 pk_alg = MBEDTLS_PK_ECDSA; 454 } else { 455 return MBEDTLS_ERR_X509_INVALID_ALG; 456 } 457 458 if ((ret = mbedtls_oid_get_oid_by_sig_alg(pk_alg, ctx->md_alg, 459 &sig_oid, &sig_oid_len)) != 0) { 460 return ret; 461 } 462 463 /* 464 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension 465 */ 466 467 /* Only for v3 */ 468 if (ctx->version == MBEDTLS_X509_CRT_VERSION_3) { 469 MBEDTLS_ASN1_CHK_ADD(len, 470 mbedtls_x509_write_extensions(&c, 471 buf, ctx->extensions)); 472 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); 473 MBEDTLS_ASN1_CHK_ADD(len, 474 mbedtls_asn1_write_tag(&c, buf, 475 MBEDTLS_ASN1_CONSTRUCTED | 476 MBEDTLS_ASN1_SEQUENCE)); 477 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); 478 MBEDTLS_ASN1_CHK_ADD(len, 479 mbedtls_asn1_write_tag(&c, buf, 480 MBEDTLS_ASN1_CONTEXT_SPECIFIC | 481 MBEDTLS_ASN1_CONSTRUCTED | 3)); 482 } 483 484 /* 485 * SubjectPublicKeyInfo 486 */ 487 MBEDTLS_ASN1_CHK_ADD(pub_len, 488 mbedtls_pk_write_pubkey_der(ctx->subject_key, 489 buf, (size_t) (c - buf))); 490 c -= pub_len; 491 len += pub_len; 492 493 /* 494 * Subject ::= Name 495 */ 496 MBEDTLS_ASN1_CHK_ADD(len, 497 mbedtls_x509_write_names(&c, buf, 498 ctx->subject)); 499 500 /* 501 * Validity ::= SEQUENCE { 502 * notBefore Time, 503 * notAfter Time } 504 */ 505 sub_len = 0; 506 507 MBEDTLS_ASN1_CHK_ADD(sub_len, 508 x509_write_time(&c, buf, ctx->not_after, 509 MBEDTLS_X509_RFC5280_UTC_TIME_LEN)); 510 511 MBEDTLS_ASN1_CHK_ADD(sub_len, 512 x509_write_time(&c, buf, ctx->not_before, 513 MBEDTLS_X509_RFC5280_UTC_TIME_LEN)); 514 515 len += sub_len; 516 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, sub_len)); 517 MBEDTLS_ASN1_CHK_ADD(len, 518 mbedtls_asn1_write_tag(&c, buf, 519 MBEDTLS_ASN1_CONSTRUCTED | 520 MBEDTLS_ASN1_SEQUENCE)); 521 522 /* 523 * Issuer ::= Name 524 */ 525 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_x509_write_names(&c, buf, 526 ctx->issuer)); 527 528 /* 529 * Signature ::= AlgorithmIdentifier 530 */ 531 if (pk_alg == MBEDTLS_PK_ECDSA) { 532 /* 533 * The AlgorithmIdentifier's parameters field must be absent for DSA/ECDSA signature 534 * algorithms, see https://www.rfc-editor.org/rfc/rfc5480#page-17 and 535 * https://www.rfc-editor.org/rfc/rfc5758#section-3. 536 */ 537 write_sig_null_par = 0; 538 } else { 539 write_sig_null_par = 1; 540 } 541 MBEDTLS_ASN1_CHK_ADD(len, 542 mbedtls_asn1_write_algorithm_identifier_ext(&c, buf, 543 sig_oid, strlen(sig_oid), 544 0, write_sig_null_par)); 545 546 /* 547 * Serial ::= INTEGER 548 * 549 * Written data is: 550 * - "ctx->serial_len" bytes for the raw serial buffer 551 * - if MSb of "serial" is 1, then prepend an extra 0x00 byte 552 * - 1 byte for the length 553 * - 1 byte for the TAG 554 */ 555 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(&c, buf, 556 ctx->serial, ctx->serial_len)); 557 if (*c & 0x80) { 558 if (c - buf < 1) { 559 return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL; 560 } 561 *(--c) = 0x0; 562 len++; 563 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, 564 ctx->serial_len + 1)); 565 } else { 566 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, 567 ctx->serial_len)); 568 } 569 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf, 570 MBEDTLS_ASN1_INTEGER)); 571 572 /* 573 * Version ::= INTEGER { v1(0), v2(1), v3(2) } 574 */ 575 576 /* Can be omitted for v1 */ 577 if (ctx->version != MBEDTLS_X509_CRT_VERSION_1) { 578 sub_len = 0; 579 MBEDTLS_ASN1_CHK_ADD(sub_len, 580 mbedtls_asn1_write_int(&c, buf, ctx->version)); 581 len += sub_len; 582 MBEDTLS_ASN1_CHK_ADD(len, 583 mbedtls_asn1_write_len(&c, buf, sub_len)); 584 MBEDTLS_ASN1_CHK_ADD(len, 585 mbedtls_asn1_write_tag(&c, buf, 586 MBEDTLS_ASN1_CONTEXT_SPECIFIC | 587 MBEDTLS_ASN1_CONSTRUCTED | 0)); 588 } 589 590 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); 591 MBEDTLS_ASN1_CHK_ADD(len, 592 mbedtls_asn1_write_tag(&c, buf, MBEDTLS_ASN1_CONSTRUCTED | 593 MBEDTLS_ASN1_SEQUENCE)); 594 595 /* 596 * Make signature 597 */ 598 599 /* Compute hash of CRT. */ 600 #if defined(MBEDTLS_USE_PSA_CRYPTO) 601 psa_algorithm = mbedtls_md_psa_alg_from_type(ctx->md_alg); 602 603 status = psa_hash_compute(psa_algorithm, 604 c, 605 len, 606 hash, 607 sizeof(hash), 608 &hash_length); 609 if (status != PSA_SUCCESS) { 610 return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; 611 } 612 #else 613 if ((ret = mbedtls_md(mbedtls_md_info_from_type(ctx->md_alg), c, 614 len, hash)) != 0) { 615 return ret; 616 } 617 #endif /* MBEDTLS_USE_PSA_CRYPTO */ 618 619 620 if ((ret = mbedtls_pk_sign(ctx->issuer_key, ctx->md_alg, 621 hash, hash_length, sig, sizeof(sig), &sig_len, 622 f_rng, p_rng)) != 0) { 623 return ret; 624 } 625 626 /* Move CRT to the front of the buffer to have space 627 * for the signature. */ 628 memmove(buf, c, len); 629 c = buf + len; 630 631 /* Add signature at the end of the buffer, 632 * making sure that it doesn't underflow 633 * into the CRT buffer. */ 634 c2 = buf + size; 635 MBEDTLS_ASN1_CHK_ADD(sig_and_oid_len, mbedtls_x509_write_sig(&c2, c, 636 sig_oid, sig_oid_len, 637 sig, sig_len, pk_alg)); 638 639 /* 640 * Memory layout after this step: 641 * 642 * buf c=buf+len c2 buf+size 643 * [CRT0,...,CRTn, UNUSED, ..., UNUSED, SIG0, ..., SIGm] 644 */ 645 646 /* Move raw CRT to just before the signature. */ 647 c = c2 - len; 648 memmove(c, buf, len); 649 650 len += sig_and_oid_len; 651 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); 652 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf, 653 MBEDTLS_ASN1_CONSTRUCTED | 654 MBEDTLS_ASN1_SEQUENCE)); 655 656 return (int) len; 657 } 658 659 #define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----\n" 660 #define PEM_END_CRT "-----END CERTIFICATE-----\n" 661 662 #if defined(MBEDTLS_PEM_WRITE_C) 663 int mbedtls_x509write_crt_pem(mbedtls_x509write_cert *crt, 664 unsigned char *buf, size_t size, 665 int (*f_rng)(void *, unsigned char *, size_t), 666 void *p_rng) 667 { 668 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 669 size_t olen; 670 671 if ((ret = mbedtls_x509write_crt_der(crt, buf, size, 672 f_rng, p_rng)) < 0) { 673 return ret; 674 } 675 676 if ((ret = mbedtls_pem_write_buffer(PEM_BEGIN_CRT, PEM_END_CRT, 677 buf + size - ret, ret, 678 buf, size, &olen)) != 0) { 679 return ret; 680 } 681 682 return 0; 683 } 684 #endif /* MBEDTLS_PEM_WRITE_C */ 685 686 #endif /* MBEDTLS_X509_CRT_WRITE_C */ 687