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