1 /* 2 * X.509 certificate writing 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 * References: 21 * - certificates: RFC 5280, updated by RFC 6818 22 * - CSRs: PKCS#10 v1.7 aka RFC 2986 23 * - attributes: PKCS#9 v2.0 aka RFC 2985 24 */ 25 26 #include "common.h" 27 28 #if defined(MBEDTLS_X509_CRT_WRITE_C) 29 30 #include "mbedtls/x509_crt.h" 31 #include "mbedtls/asn1write.h" 32 #include "mbedtls/error.h" 33 #include "mbedtls/oid.h" 34 #include "mbedtls/platform_util.h" 35 #include "mbedtls/md.h" 36 37 #include <string.h> 38 39 #if defined(MBEDTLS_PEM_WRITE_C) 40 #include "mbedtls/pem.h" 41 #endif /* MBEDTLS_PEM_WRITE_C */ 42 43 #if defined(MBEDTLS_USE_PSA_CRYPTO) 44 #include "psa/crypto.h" 45 #include "mbedtls/psa_util.h" 46 #endif /* MBEDTLS_USE_PSA_CRYPTO */ 47 48 #include "hash_info.h" 49 #include "mbedtls/legacy_or_psa.h" 50 51 void mbedtls_x509write_crt_init(mbedtls_x509write_cert *ctx) 52 { 53 memset(ctx, 0, sizeof(mbedtls_x509write_cert)); 54 55 ctx->version = MBEDTLS_X509_CRT_VERSION_3; 56 } 57 58 void mbedtls_x509write_crt_free(mbedtls_x509write_cert *ctx) 59 { 60 mbedtls_asn1_free_named_data_list(&ctx->subject); 61 mbedtls_asn1_free_named_data_list(&ctx->issuer); 62 mbedtls_asn1_free_named_data_list(&ctx->extensions); 63 64 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_x509write_cert)); 65 } 66 67 void mbedtls_x509write_crt_set_version(mbedtls_x509write_cert *ctx, 68 int version) 69 { 70 ctx->version = version; 71 } 72 73 void mbedtls_x509write_crt_set_md_alg(mbedtls_x509write_cert *ctx, 74 mbedtls_md_type_t md_alg) 75 { 76 ctx->md_alg = md_alg; 77 } 78 79 void mbedtls_x509write_crt_set_subject_key(mbedtls_x509write_cert *ctx, 80 mbedtls_pk_context *key) 81 { 82 ctx->subject_key = key; 83 } 84 85 void mbedtls_x509write_crt_set_issuer_key(mbedtls_x509write_cert *ctx, 86 mbedtls_pk_context *key) 87 { 88 ctx->issuer_key = key; 89 } 90 91 int mbedtls_x509write_crt_set_subject_name(mbedtls_x509write_cert *ctx, 92 const char *subject_name) 93 { 94 return mbedtls_x509_string_to_names(&ctx->subject, subject_name); 95 } 96 97 int mbedtls_x509write_crt_set_issuer_name(mbedtls_x509write_cert *ctx, 98 const char *issuer_name) 99 { 100 return mbedtls_x509_string_to_names(&ctx->issuer, issuer_name); 101 } 102 103 #if defined(MBEDTLS_BIGNUM_C) && !defined(MBEDTLS_DEPRECATED_REMOVED) 104 int mbedtls_x509write_crt_set_serial(mbedtls_x509write_cert *ctx, 105 const mbedtls_mpi *serial) 106 { 107 int ret; 108 size_t tmp_len; 109 110 /* Ensure that the MPI value fits into the buffer */ 111 tmp_len = mbedtls_mpi_size(serial); 112 if (tmp_len > MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN) { 113 return MBEDTLS_ERR_X509_BAD_INPUT_DATA; 114 } 115 116 ctx->serial_len = tmp_len; 117 118 ret = mbedtls_mpi_write_binary(serial, ctx->serial, tmp_len); 119 if (ret < 0) { 120 return ret; 121 } 122 123 return 0; 124 } 125 #endif // MBEDTLS_BIGNUM_C && !MBEDTLS_DEPRECATED_REMOVED 126 127 int mbedtls_x509write_crt_set_serial_raw(mbedtls_x509write_cert *ctx, 128 unsigned char *serial, size_t serial_len) 129 { 130 if (serial_len > MBEDTLS_X509_RFC5280_MAX_SERIAL_LEN) { 131 return MBEDTLS_ERR_X509_BAD_INPUT_DATA; 132 } 133 134 ctx->serial_len = serial_len; 135 memcpy(ctx->serial, serial, serial_len); 136 137 return 0; 138 } 139 140 int mbedtls_x509write_crt_set_validity(mbedtls_x509write_cert *ctx, 141 const char *not_before, 142 const char *not_after) 143 { 144 if (strlen(not_before) != MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1 || 145 strlen(not_after) != MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1) { 146 return MBEDTLS_ERR_X509_BAD_INPUT_DATA; 147 } 148 strncpy(ctx->not_before, not_before, MBEDTLS_X509_RFC5280_UTC_TIME_LEN); 149 strncpy(ctx->not_after, not_after, MBEDTLS_X509_RFC5280_UTC_TIME_LEN); 150 ctx->not_before[MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1] = 'Z'; 151 ctx->not_after[MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1] = 'Z'; 152 153 return 0; 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_HAS_ALG_SHA_1_VIA_MD_OR_PSA_BASED_ON_USE_PSA) 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_HAS_ALG_SHA_1_VIA_MD_OR_PSA_BASED_ON_USE_PSA */ 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_HASH_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 440 /* 441 * Prepare data to be signed at the end of the target buffer 442 */ 443 c = buf + size; 444 445 /* Signature algorithm needed in TBS, and later for actual signature */ 446 447 /* There's no direct way of extracting a signature algorithm 448 * (represented as an element of mbedtls_pk_type_t) from a PK instance. */ 449 if (mbedtls_pk_can_do(ctx->issuer_key, MBEDTLS_PK_RSA)) { 450 pk_alg = MBEDTLS_PK_RSA; 451 } else if (mbedtls_pk_can_do(ctx->issuer_key, MBEDTLS_PK_ECDSA)) { 452 pk_alg = MBEDTLS_PK_ECDSA; 453 } else { 454 return MBEDTLS_ERR_X509_INVALID_ALG; 455 } 456 457 if ((ret = mbedtls_oid_get_oid_by_sig_alg(pk_alg, ctx->md_alg, 458 &sig_oid, &sig_oid_len)) != 0) { 459 return ret; 460 } 461 462 /* 463 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension 464 */ 465 466 /* Only for v3 */ 467 if (ctx->version == MBEDTLS_X509_CRT_VERSION_3) { 468 MBEDTLS_ASN1_CHK_ADD(len, 469 mbedtls_x509_write_extensions(&c, 470 buf, ctx->extensions)); 471 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); 472 MBEDTLS_ASN1_CHK_ADD(len, 473 mbedtls_asn1_write_tag(&c, buf, 474 MBEDTLS_ASN1_CONSTRUCTED | 475 MBEDTLS_ASN1_SEQUENCE)); 476 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); 477 MBEDTLS_ASN1_CHK_ADD(len, 478 mbedtls_asn1_write_tag(&c, buf, 479 MBEDTLS_ASN1_CONTEXT_SPECIFIC | 480 MBEDTLS_ASN1_CONSTRUCTED | 3)); 481 } 482 483 /* 484 * SubjectPublicKeyInfo 485 */ 486 MBEDTLS_ASN1_CHK_ADD(pub_len, 487 mbedtls_pk_write_pubkey_der(ctx->subject_key, 488 buf, c - buf)); 489 c -= pub_len; 490 len += pub_len; 491 492 /* 493 * Subject ::= Name 494 */ 495 MBEDTLS_ASN1_CHK_ADD(len, 496 mbedtls_x509_write_names(&c, buf, 497 ctx->subject)); 498 499 /* 500 * Validity ::= SEQUENCE { 501 * notBefore Time, 502 * notAfter Time } 503 */ 504 sub_len = 0; 505 506 MBEDTLS_ASN1_CHK_ADD(sub_len, 507 x509_write_time(&c, buf, ctx->not_after, 508 MBEDTLS_X509_RFC5280_UTC_TIME_LEN)); 509 510 MBEDTLS_ASN1_CHK_ADD(sub_len, 511 x509_write_time(&c, buf, ctx->not_before, 512 MBEDTLS_X509_RFC5280_UTC_TIME_LEN)); 513 514 len += sub_len; 515 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, sub_len)); 516 MBEDTLS_ASN1_CHK_ADD(len, 517 mbedtls_asn1_write_tag(&c, buf, 518 MBEDTLS_ASN1_CONSTRUCTED | 519 MBEDTLS_ASN1_SEQUENCE)); 520 521 /* 522 * Issuer ::= Name 523 */ 524 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_x509_write_names(&c, buf, 525 ctx->issuer)); 526 527 /* 528 * Signature ::= AlgorithmIdentifier 529 */ 530 MBEDTLS_ASN1_CHK_ADD(len, 531 mbedtls_asn1_write_algorithm_identifier(&c, buf, 532 sig_oid, strlen(sig_oid), 0)); 533 534 /* 535 * Serial ::= INTEGER 536 * 537 * Written data is: 538 * - "ctx->serial_len" bytes for the raw serial buffer 539 * - if MSb of "serial" is 1, then prepend an extra 0x00 byte 540 * - 1 byte for the length 541 * - 1 byte for the TAG 542 */ 543 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_raw_buffer(&c, buf, 544 ctx->serial, ctx->serial_len)); 545 if (*c & 0x80) { 546 if (c - buf < 1) { 547 return MBEDTLS_ERR_X509_BUFFER_TOO_SMALL; 548 } 549 *(--c) = 0x0; 550 len++; 551 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, 552 ctx->serial_len + 1)); 553 } else { 554 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, 555 ctx->serial_len)); 556 } 557 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf, 558 MBEDTLS_ASN1_INTEGER)); 559 560 /* 561 * Version ::= INTEGER { v1(0), v2(1), v3(2) } 562 */ 563 564 /* Can be omitted for v1 */ 565 if (ctx->version != MBEDTLS_X509_CRT_VERSION_1) { 566 sub_len = 0; 567 MBEDTLS_ASN1_CHK_ADD(sub_len, 568 mbedtls_asn1_write_int(&c, buf, ctx->version)); 569 len += sub_len; 570 MBEDTLS_ASN1_CHK_ADD(len, 571 mbedtls_asn1_write_len(&c, buf, sub_len)); 572 MBEDTLS_ASN1_CHK_ADD(len, 573 mbedtls_asn1_write_tag(&c, buf, 574 MBEDTLS_ASN1_CONTEXT_SPECIFIC | 575 MBEDTLS_ASN1_CONSTRUCTED | 0)); 576 } 577 578 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); 579 MBEDTLS_ASN1_CHK_ADD(len, 580 mbedtls_asn1_write_tag(&c, buf, MBEDTLS_ASN1_CONSTRUCTED | 581 MBEDTLS_ASN1_SEQUENCE)); 582 583 /* 584 * Make signature 585 */ 586 587 /* Compute hash of CRT. */ 588 #if defined(MBEDTLS_USE_PSA_CRYPTO) 589 psa_algorithm = mbedtls_hash_info_psa_from_md(ctx->md_alg); 590 591 status = psa_hash_compute(psa_algorithm, 592 c, 593 len, 594 hash, 595 sizeof(hash), 596 &hash_length); 597 if (status != PSA_SUCCESS) { 598 return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; 599 } 600 #else 601 if ((ret = mbedtls_md(mbedtls_md_info_from_type(ctx->md_alg), c, 602 len, hash)) != 0) { 603 return ret; 604 } 605 #endif /* MBEDTLS_USE_PSA_CRYPTO */ 606 607 608 if ((ret = mbedtls_pk_sign(ctx->issuer_key, ctx->md_alg, 609 hash, hash_length, sig, sizeof(sig), &sig_len, 610 f_rng, p_rng)) != 0) { 611 return ret; 612 } 613 614 /* Move CRT to the front of the buffer to have space 615 * for the signature. */ 616 memmove(buf, c, len); 617 c = buf + len; 618 619 /* Add signature at the end of the buffer, 620 * making sure that it doesn't underflow 621 * into the CRT buffer. */ 622 c2 = buf + size; 623 MBEDTLS_ASN1_CHK_ADD(sig_and_oid_len, mbedtls_x509_write_sig(&c2, c, 624 sig_oid, sig_oid_len, sig, 625 sig_len)); 626 627 /* 628 * Memory layout after this step: 629 * 630 * buf c=buf+len c2 buf+size 631 * [CRT0,...,CRTn, UNUSED, ..., UNUSED, SIG0, ..., SIGm] 632 */ 633 634 /* Move raw CRT to just before the signature. */ 635 c = c2 - len; 636 memmove(c, buf, len); 637 638 len += sig_and_oid_len; 639 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_len(&c, buf, len)); 640 MBEDTLS_ASN1_CHK_ADD(len, mbedtls_asn1_write_tag(&c, buf, 641 MBEDTLS_ASN1_CONSTRUCTED | 642 MBEDTLS_ASN1_SEQUENCE)); 643 644 return (int) len; 645 } 646 647 #define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----\n" 648 #define PEM_END_CRT "-----END CERTIFICATE-----\n" 649 650 #if defined(MBEDTLS_PEM_WRITE_C) 651 int mbedtls_x509write_crt_pem(mbedtls_x509write_cert *crt, 652 unsigned char *buf, size_t size, 653 int (*f_rng)(void *, unsigned char *, size_t), 654 void *p_rng) 655 { 656 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 657 size_t olen; 658 659 if ((ret = mbedtls_x509write_crt_der(crt, buf, size, 660 f_rng, p_rng)) < 0) { 661 return ret; 662 } 663 664 if ((ret = mbedtls_pem_write_buffer(PEM_BEGIN_CRT, PEM_END_CRT, 665 buf + size - ret, ret, 666 buf, size, &olen)) != 0) { 667 return ret; 668 } 669 670 return 0; 671 } 672 #endif /* MBEDTLS_PEM_WRITE_C */ 673 674 #endif /* MBEDTLS_X509_CRT_WRITE_C */ 675