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