1 // SPDX-License-Identifier: Apache-2.0 2 /* 3 * X.509 certificate writing 4 * 5 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 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 * This file is part of mbed TLS (https://tls.mbed.org) 20 */ 21 /* 22 * References: 23 * - certificates: RFC 5280, updated by RFC 6818 24 * - CSRs: PKCS#10 v1.7 aka RFC 2986 25 * - attributes: PKCS#9 v2.0 aka RFC 2985 26 */ 27 28 #if !defined(MBEDTLS_CONFIG_FILE) 29 #include "mbedtls/config.h" 30 #else 31 #include MBEDTLS_CONFIG_FILE 32 #endif 33 34 #if defined(MBEDTLS_X509_CRT_WRITE_C) 35 36 #include "mbedtls/x509_crt.h" 37 #include "mbedtls/asn1write.h" 38 #include "mbedtls/error.h" 39 #include "mbedtls/oid.h" 40 #include "mbedtls/platform_util.h" 41 #include "mbedtls/sha1.h" 42 43 #include <string.h> 44 45 #if defined(MBEDTLS_PEM_WRITE_C) 46 #include "mbedtls/pem.h" 47 #endif /* MBEDTLS_PEM_WRITE_C */ 48 49 void mbedtls_x509write_crt_init( mbedtls_x509write_cert *ctx ) 50 { 51 memset( ctx, 0, sizeof( mbedtls_x509write_cert ) ); 52 53 mbedtls_mpi_init( &ctx->serial ); 54 ctx->version = MBEDTLS_X509_CRT_VERSION_3; 55 } 56 57 void mbedtls_x509write_crt_free( mbedtls_x509write_cert *ctx ) 58 { 59 mbedtls_mpi_free( &ctx->serial ); 60 61 mbedtls_asn1_free_named_data_list( &ctx->subject ); 62 mbedtls_asn1_free_named_data_list( &ctx->issuer ); 63 mbedtls_asn1_free_named_data_list( &ctx->extensions ); 64 65 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_x509write_cert ) ); 66 } 67 68 void mbedtls_x509write_crt_set_version( mbedtls_x509write_cert *ctx, 69 int version ) 70 { 71 ctx->version = version; 72 } 73 74 void mbedtls_x509write_crt_set_md_alg( mbedtls_x509write_cert *ctx, 75 mbedtls_md_type_t md_alg ) 76 { 77 ctx->md_alg = md_alg; 78 } 79 80 void mbedtls_x509write_crt_set_subject_key( mbedtls_x509write_cert *ctx, 81 mbedtls_pk_context *key ) 82 { 83 ctx->subject_key = key; 84 } 85 86 void mbedtls_x509write_crt_set_issuer_key( mbedtls_x509write_cert *ctx, 87 mbedtls_pk_context *key ) 88 { 89 ctx->issuer_key = key; 90 } 91 92 int mbedtls_x509write_crt_set_subject_name( mbedtls_x509write_cert *ctx, 93 const char *subject_name ) 94 { 95 return mbedtls_x509_string_to_names( &ctx->subject, subject_name ); 96 } 97 98 int mbedtls_x509write_crt_set_issuer_name( mbedtls_x509write_cert *ctx, 99 const char *issuer_name ) 100 { 101 return mbedtls_x509_string_to_names( &ctx->issuer, issuer_name ); 102 } 103 104 int mbedtls_x509write_crt_set_serial( mbedtls_x509write_cert *ctx, 105 const mbedtls_mpi *serial ) 106 { 107 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 108 109 if( ( ret = mbedtls_mpi_copy( &ctx->serial, serial ) ) != 0 ) 110 return( ret ); 111 112 return( 0 ); 113 } 114 115 int mbedtls_x509write_crt_set_validity( mbedtls_x509write_cert *ctx, 116 const char *not_before, 117 const char *not_after ) 118 { 119 if( strlen( not_before ) != MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1 || 120 strlen( not_after ) != MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1 ) 121 { 122 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); 123 } 124 strncpy( ctx->not_before, not_before, MBEDTLS_X509_RFC5280_UTC_TIME_LEN ); 125 strncpy( ctx->not_after , not_after , MBEDTLS_X509_RFC5280_UTC_TIME_LEN ); 126 ctx->not_before[MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1] = 'Z'; 127 ctx->not_after[MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1] = 'Z'; 128 129 return( 0 ); 130 } 131 132 int mbedtls_x509write_crt_set_extension( mbedtls_x509write_cert *ctx, 133 const char *oid, size_t oid_len, 134 int critical, 135 const unsigned char *val, size_t val_len ) 136 { 137 return( mbedtls_x509_set_extension( &ctx->extensions, oid, oid_len, 138 critical, val, val_len ) ); 139 } 140 141 int mbedtls_x509write_crt_set_basic_constraints( mbedtls_x509write_cert *ctx, 142 int is_ca, int max_pathlen ) 143 { 144 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 145 unsigned char buf[9]; 146 unsigned char *c = buf + sizeof(buf); 147 size_t len = 0; 148 149 memset( buf, 0, sizeof(buf) ); 150 151 if( is_ca && max_pathlen > 127 ) 152 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); 153 154 if( is_ca ) 155 { 156 if( max_pathlen >= 0 ) 157 { 158 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 159 max_pathlen ) ); 160 } 161 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_bool( &c, buf, 1 ) ); 162 } 163 164 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); 165 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, 166 MBEDTLS_ASN1_CONSTRUCTED | 167 MBEDTLS_ASN1_SEQUENCE ) ); 168 169 return( 170 mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_BASIC_CONSTRAINTS, 171 MBEDTLS_OID_SIZE( MBEDTLS_OID_BASIC_CONSTRAINTS ), 172 0, buf + sizeof(buf) - len, len ) ); 173 } 174 175 #if defined(MBEDTLS_SHA1_C) 176 int mbedtls_x509write_crt_set_subject_key_identifier( mbedtls_x509write_cert *ctx ) 177 { 178 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 179 unsigned char buf[MBEDTLS_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */ 180 unsigned char *c = buf + sizeof(buf); 181 size_t len = 0; 182 183 memset( buf, 0, sizeof(buf) ); 184 MBEDTLS_ASN1_CHK_ADD( len, 185 mbedtls_pk_write_pubkey( &c, buf, ctx->subject_key ) ); 186 187 ret = mbedtls_sha1_ret( buf + sizeof( buf ) - len, len, 188 buf + sizeof( buf ) - 20 ); 189 if( ret != 0 ) 190 return( ret ); 191 c = buf + sizeof( buf ) - 20; 192 len = 20; 193 194 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); 195 MBEDTLS_ASN1_CHK_ADD( len, 196 mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_OCTET_STRING ) ); 197 198 return mbedtls_x509write_crt_set_extension( ctx, 199 MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER, 200 MBEDTLS_OID_SIZE( MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER ), 201 0, buf + sizeof(buf) - len, len ); 202 } 203 204 int mbedtls_x509write_crt_set_authority_key_identifier( mbedtls_x509write_cert *ctx ) 205 { 206 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 207 unsigned char buf[MBEDTLS_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */ 208 unsigned char *c = buf + sizeof( buf ); 209 size_t len = 0; 210 211 memset( buf, 0, sizeof(buf) ); 212 MBEDTLS_ASN1_CHK_ADD( len, 213 mbedtls_pk_write_pubkey( &c, buf, ctx->issuer_key ) ); 214 215 ret = mbedtls_sha1_ret( buf + sizeof( buf ) - len, len, 216 buf + sizeof( buf ) - 20 ); 217 if( ret != 0 ) 218 return( ret ); 219 c = buf + sizeof( buf ) - 20; 220 len = 20; 221 222 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); 223 MBEDTLS_ASN1_CHK_ADD( len, 224 mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC | 0 ) ); 225 226 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); 227 MBEDTLS_ASN1_CHK_ADD( len, 228 mbedtls_asn1_write_tag( &c, buf, 229 MBEDTLS_ASN1_CONSTRUCTED | 230 MBEDTLS_ASN1_SEQUENCE ) ); 231 232 return mbedtls_x509write_crt_set_extension( 233 ctx, MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER, 234 MBEDTLS_OID_SIZE( MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER ), 235 0, buf + sizeof( buf ) - len, len ); 236 } 237 #endif /* MBEDTLS_SHA1_C */ 238 239 int mbedtls_x509write_crt_set_key_usage( mbedtls_x509write_cert *ctx, 240 unsigned int key_usage ) 241 { 242 unsigned char buf[5], ku[2]; 243 unsigned char *c; 244 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 245 const unsigned int allowed_bits = MBEDTLS_X509_KU_DIGITAL_SIGNATURE | 246 MBEDTLS_X509_KU_NON_REPUDIATION | 247 MBEDTLS_X509_KU_KEY_ENCIPHERMENT | 248 MBEDTLS_X509_KU_DATA_ENCIPHERMENT | 249 MBEDTLS_X509_KU_KEY_AGREEMENT | 250 MBEDTLS_X509_KU_KEY_CERT_SIGN | 251 MBEDTLS_X509_KU_CRL_SIGN | 252 MBEDTLS_X509_KU_ENCIPHER_ONLY | 253 MBEDTLS_X509_KU_DECIPHER_ONLY; 254 255 /* Check that nothing other than the allowed flags is set */ 256 if( ( key_usage & ~allowed_bits ) != 0 ) 257 return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE ); 258 259 c = buf + 5; 260 ku[0] = (unsigned char)( key_usage ); 261 ku[1] = (unsigned char)( key_usage >> 8 ); 262 ret = mbedtls_asn1_write_named_bitstring( &c, buf, ku, 9 ); 263 264 if( ret < 0 ) 265 return( ret ); 266 else if( ret < 3 || ret > 5 ) 267 return( MBEDTLS_ERR_X509_INVALID_FORMAT ); 268 269 ret = mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_KEY_USAGE, 270 MBEDTLS_OID_SIZE( MBEDTLS_OID_KEY_USAGE ), 271 1, c, (size_t)ret ); 272 if( ret != 0 ) 273 return( ret ); 274 275 return( 0 ); 276 } 277 278 int mbedtls_x509write_crt_set_ns_cert_type( mbedtls_x509write_cert *ctx, 279 unsigned char ns_cert_type ) 280 { 281 unsigned char buf[4]; 282 unsigned char *c; 283 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 284 285 c = buf + 4; 286 287 ret = mbedtls_asn1_write_named_bitstring( &c, buf, &ns_cert_type, 8 ); 288 if( ret < 3 || ret > 4 ) 289 return( ret ); 290 291 ret = mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_NS_CERT_TYPE, 292 MBEDTLS_OID_SIZE( MBEDTLS_OID_NS_CERT_TYPE ), 293 0, c, (size_t)ret ); 294 if( ret != 0 ) 295 return( ret ); 296 297 return( 0 ); 298 } 299 300 static int x509_write_time( unsigned char **p, unsigned char *start, 301 const char *t, size_t size ) 302 { 303 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 304 size_t len = 0; 305 306 /* 307 * write MBEDTLS_ASN1_UTC_TIME if year < 2050 (2 bytes shorter) 308 */ 309 if( t[0] == '2' && t[1] == '0' && t[2] < '5' ) 310 { 311 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, 312 (const unsigned char *) t + 2, 313 size - 2 ) ); 314 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 315 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, 316 MBEDTLS_ASN1_UTC_TIME ) ); 317 } 318 else 319 { 320 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, 321 (const unsigned char *) t, 322 size ) ); 323 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 324 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, 325 MBEDTLS_ASN1_GENERALIZED_TIME ) ); 326 } 327 328 return( (int) len ); 329 } 330 331 int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, 332 unsigned char *buf, size_t size, 333 int (*f_rng)(void *, unsigned char *, size_t), 334 void *p_rng ) 335 { 336 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 337 const char *sig_oid; 338 size_t sig_oid_len = 0; 339 unsigned char *c, *c2; 340 unsigned char hash[64]; 341 unsigned char sig[MBEDTLS_PK_SIGNATURE_MAX_SIZE]; 342 size_t sub_len = 0, pub_len = 0, sig_and_oid_len = 0, sig_len; 343 size_t len = 0; 344 mbedtls_pk_type_t pk_alg; 345 346 /* 347 * Prepare data to be signed at the end of the target buffer 348 */ 349 c = buf + size; 350 351 /* Signature algorithm needed in TBS, and later for actual signature */ 352 353 /* There's no direct way of extracting a signature algorithm 354 * (represented as an element of mbedtls_pk_type_t) from a PK instance. */ 355 if( mbedtls_pk_can_do( ctx->issuer_key, MBEDTLS_PK_RSA ) ) 356 pk_alg = MBEDTLS_PK_RSA; 357 else if( mbedtls_pk_can_do( ctx->issuer_key, MBEDTLS_PK_ECDSA ) ) 358 pk_alg = MBEDTLS_PK_ECDSA; 359 else 360 return( MBEDTLS_ERR_X509_INVALID_ALG ); 361 362 if( ( ret = mbedtls_oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg, 363 &sig_oid, &sig_oid_len ) ) != 0 ) 364 { 365 return( ret ); 366 } 367 368 /* 369 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension 370 */ 371 372 /* Only for v3 */ 373 if( ctx->version == MBEDTLS_X509_CRT_VERSION_3 ) 374 { 375 MBEDTLS_ASN1_CHK_ADD( len, 376 mbedtls_x509_write_extensions( &c, 377 buf, ctx->extensions ) ); 378 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); 379 MBEDTLS_ASN1_CHK_ADD( len, 380 mbedtls_asn1_write_tag( &c, buf, 381 MBEDTLS_ASN1_CONSTRUCTED | 382 MBEDTLS_ASN1_SEQUENCE ) ); 383 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); 384 MBEDTLS_ASN1_CHK_ADD( len, 385 mbedtls_asn1_write_tag( &c, buf, 386 MBEDTLS_ASN1_CONTEXT_SPECIFIC | 387 MBEDTLS_ASN1_CONSTRUCTED | 3 ) ); 388 } 389 390 /* 391 * SubjectPublicKeyInfo 392 */ 393 MBEDTLS_ASN1_CHK_ADD( pub_len, 394 mbedtls_pk_write_pubkey_der( ctx->subject_key, 395 buf, c - buf ) ); 396 c -= pub_len; 397 len += pub_len; 398 399 /* 400 * Subject ::= Name 401 */ 402 MBEDTLS_ASN1_CHK_ADD( len, 403 mbedtls_x509_write_names( &c, buf, 404 ctx->subject ) ); 405 406 /* 407 * Validity ::= SEQUENCE { 408 * notBefore Time, 409 * notAfter Time } 410 */ 411 sub_len = 0; 412 413 MBEDTLS_ASN1_CHK_ADD( sub_len, 414 x509_write_time( &c, buf, ctx->not_after, 415 MBEDTLS_X509_RFC5280_UTC_TIME_LEN ) ); 416 417 MBEDTLS_ASN1_CHK_ADD( sub_len, 418 x509_write_time( &c, buf, ctx->not_before, 419 MBEDTLS_X509_RFC5280_UTC_TIME_LEN ) ); 420 421 len += sub_len; 422 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, sub_len ) ); 423 MBEDTLS_ASN1_CHK_ADD( len, 424 mbedtls_asn1_write_tag( &c, buf, 425 MBEDTLS_ASN1_CONSTRUCTED | 426 MBEDTLS_ASN1_SEQUENCE ) ); 427 428 /* 429 * Issuer ::= Name 430 */ 431 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, buf, 432 ctx->issuer ) ); 433 434 /* 435 * Signature ::= AlgorithmIdentifier 436 */ 437 MBEDTLS_ASN1_CHK_ADD( len, 438 mbedtls_asn1_write_algorithm_identifier( &c, buf, 439 sig_oid, strlen( sig_oid ), 0 ) ); 440 441 /* 442 * Serial ::= INTEGER 443 */ 444 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, 445 &ctx->serial ) ); 446 447 /* 448 * Version ::= INTEGER { v1(0), v2(1), v3(2) } 449 */ 450 451 /* Can be omitted for v1 */ 452 if( ctx->version != MBEDTLS_X509_CRT_VERSION_1 ) 453 { 454 sub_len = 0; 455 MBEDTLS_ASN1_CHK_ADD( sub_len, 456 mbedtls_asn1_write_int( &c, buf, ctx->version ) ); 457 len += sub_len; 458 MBEDTLS_ASN1_CHK_ADD( len, 459 mbedtls_asn1_write_len( &c, buf, sub_len ) ); 460 MBEDTLS_ASN1_CHK_ADD( len, 461 mbedtls_asn1_write_tag( &c, buf, 462 MBEDTLS_ASN1_CONTEXT_SPECIFIC | 463 MBEDTLS_ASN1_CONSTRUCTED | 0 ) ); 464 } 465 466 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); 467 MBEDTLS_ASN1_CHK_ADD( len, 468 mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | 469 MBEDTLS_ASN1_SEQUENCE ) ); 470 471 /* 472 * Make signature 473 */ 474 475 /* Compute hash of CRT. */ 476 if( ( ret = mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, 477 len, hash ) ) != 0 ) 478 { 479 return( ret ); 480 } 481 482 if( ( ret = mbedtls_pk_sign( ctx->issuer_key, ctx->md_alg, 483 hash, 0, sig, &sig_len, 484 f_rng, p_rng ) ) != 0 ) 485 { 486 return( ret ); 487 } 488 489 /* Move CRT to the front of the buffer to have space 490 * for the signature. */ 491 memmove( buf, c, len ); 492 c = buf + len; 493 494 /* Add signature at the end of the buffer, 495 * making sure that it doesn't underflow 496 * into the CRT buffer. */ 497 c2 = buf + size; 498 MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, mbedtls_x509_write_sig( &c2, c, 499 sig_oid, sig_oid_len, sig, sig_len ) ); 500 501 /* 502 * Memory layout after this step: 503 * 504 * buf c=buf+len c2 buf+size 505 * [CRT0,...,CRTn, UNUSED, ..., UNUSED, SIG0, ..., SIGm] 506 */ 507 508 /* Move raw CRT to just before the signature. */ 509 c = c2 - len; 510 memmove( c, buf, len ); 511 512 len += sig_and_oid_len; 513 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); 514 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, 515 MBEDTLS_ASN1_CONSTRUCTED | 516 MBEDTLS_ASN1_SEQUENCE ) ); 517 518 return( (int) len ); 519 } 520 521 #define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----\n" 522 #define PEM_END_CRT "-----END CERTIFICATE-----\n" 523 524 #if defined(MBEDTLS_PEM_WRITE_C) 525 int mbedtls_x509write_crt_pem( mbedtls_x509write_cert *crt, 526 unsigned char *buf, size_t size, 527 int (*f_rng)(void *, unsigned char *, size_t), 528 void *p_rng ) 529 { 530 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 531 size_t olen; 532 533 if( ( ret = mbedtls_x509write_crt_der( crt, buf, size, 534 f_rng, p_rng ) ) < 0 ) 535 { 536 return( ret ); 537 } 538 539 if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_CRT, PEM_END_CRT, 540 buf + size - ret, ret, 541 buf, size, &olen ) ) != 0 ) 542 { 543 return( ret ); 544 } 545 546 return( 0 ); 547 } 548 #endif /* MBEDTLS_PEM_WRITE_C */ 549 550 #endif /* MBEDTLS_X509_CRT_WRITE_C */ 551