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