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 ku[0] = (unsigned char)( key_usage ); 255 ku[1] = (unsigned char)( key_usage >> 8 ); 256 ret = mbedtls_asn1_write_named_bitstring( &c, buf, ku, 9 ); 257 258 if( ret < 0 ) 259 return( ret ); 260 else if( ret < 3 || ret > 5 ) 261 return( MBEDTLS_ERR_X509_INVALID_FORMAT ); 262 263 ret = mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_KEY_USAGE, 264 MBEDTLS_OID_SIZE( MBEDTLS_OID_KEY_USAGE ), 265 1, c, (size_t)ret ); 266 if( ret != 0 ) 267 return( ret ); 268 269 return( 0 ); 270 } 271 272 int mbedtls_x509write_crt_set_ns_cert_type( mbedtls_x509write_cert *ctx, 273 unsigned char ns_cert_type ) 274 { 275 unsigned char buf[4] = {0}; 276 unsigned char *c; 277 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 278 279 c = buf + 4; 280 281 ret = mbedtls_asn1_write_named_bitstring( &c, buf, &ns_cert_type, 8 ); 282 if( ret < 3 || ret > 4 ) 283 return( ret ); 284 285 ret = mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_NS_CERT_TYPE, 286 MBEDTLS_OID_SIZE( MBEDTLS_OID_NS_CERT_TYPE ), 287 0, c, (size_t)ret ); 288 if( ret != 0 ) 289 return( ret ); 290 291 return( 0 ); 292 } 293 294 static int x509_write_time( unsigned char **p, unsigned char *start, 295 const char *t, size_t size ) 296 { 297 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 298 size_t len = 0; 299 300 /* 301 * write MBEDTLS_ASN1_UTC_TIME if year < 2050 (2 bytes shorter) 302 */ 303 if( t[0] == '2' && t[1] == '0' && t[2] < '5' ) 304 { 305 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, 306 (const unsigned char *) t + 2, 307 size - 2 ) ); 308 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 309 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, 310 MBEDTLS_ASN1_UTC_TIME ) ); 311 } 312 else 313 { 314 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, 315 (const unsigned char *) t, 316 size ) ); 317 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 318 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, 319 MBEDTLS_ASN1_GENERALIZED_TIME ) ); 320 } 321 322 return( (int) len ); 323 } 324 325 int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, 326 unsigned char *buf, size_t size, 327 int (*f_rng)(void *, unsigned char *, size_t), 328 void *p_rng ) 329 { 330 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 331 const char *sig_oid; 332 size_t sig_oid_len = 0; 333 unsigned char *c, *c2; 334 unsigned char hash[64]; 335 unsigned char sig[MBEDTLS_PK_SIGNATURE_MAX_SIZE]; 336 size_t sub_len = 0, pub_len = 0, sig_and_oid_len = 0, sig_len; 337 size_t len = 0; 338 mbedtls_pk_type_t pk_alg; 339 340 /* 341 * Prepare data to be signed at the end of the target buffer 342 */ 343 c = buf + size; 344 345 /* Signature algorithm needed in TBS, and later for actual signature */ 346 347 /* There's no direct way of extracting a signature algorithm 348 * (represented as an element of mbedtls_pk_type_t) from a PK instance. */ 349 if( mbedtls_pk_can_do( ctx->issuer_key, MBEDTLS_PK_RSA ) ) 350 pk_alg = MBEDTLS_PK_RSA; 351 else if( mbedtls_pk_can_do( ctx->issuer_key, MBEDTLS_PK_ECDSA ) ) 352 pk_alg = MBEDTLS_PK_ECDSA; 353 else 354 return( MBEDTLS_ERR_X509_INVALID_ALG ); 355 356 if( ( ret = mbedtls_oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg, 357 &sig_oid, &sig_oid_len ) ) != 0 ) 358 { 359 return( ret ); 360 } 361 362 /* 363 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension 364 */ 365 366 /* Only for v3 */ 367 if( ctx->version == MBEDTLS_X509_CRT_VERSION_3 ) 368 { 369 MBEDTLS_ASN1_CHK_ADD( len, 370 mbedtls_x509_write_extensions( &c, 371 buf, ctx->extensions ) ); 372 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); 373 MBEDTLS_ASN1_CHK_ADD( len, 374 mbedtls_asn1_write_tag( &c, buf, 375 MBEDTLS_ASN1_CONSTRUCTED | 376 MBEDTLS_ASN1_SEQUENCE ) ); 377 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); 378 MBEDTLS_ASN1_CHK_ADD( len, 379 mbedtls_asn1_write_tag( &c, buf, 380 MBEDTLS_ASN1_CONTEXT_SPECIFIC | 381 MBEDTLS_ASN1_CONSTRUCTED | 3 ) ); 382 } 383 384 /* 385 * SubjectPublicKeyInfo 386 */ 387 MBEDTLS_ASN1_CHK_ADD( pub_len, 388 mbedtls_pk_write_pubkey_der( ctx->subject_key, 389 buf, c - buf ) ); 390 c -= pub_len; 391 len += pub_len; 392 393 /* 394 * Subject ::= Name 395 */ 396 MBEDTLS_ASN1_CHK_ADD( len, 397 mbedtls_x509_write_names( &c, buf, 398 ctx->subject ) ); 399 400 /* 401 * Validity ::= SEQUENCE { 402 * notBefore Time, 403 * notAfter Time } 404 */ 405 sub_len = 0; 406 407 MBEDTLS_ASN1_CHK_ADD( sub_len, 408 x509_write_time( &c, buf, ctx->not_after, 409 MBEDTLS_X509_RFC5280_UTC_TIME_LEN ) ); 410 411 MBEDTLS_ASN1_CHK_ADD( sub_len, 412 x509_write_time( &c, buf, ctx->not_before, 413 MBEDTLS_X509_RFC5280_UTC_TIME_LEN ) ); 414 415 len += sub_len; 416 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, sub_len ) ); 417 MBEDTLS_ASN1_CHK_ADD( len, 418 mbedtls_asn1_write_tag( &c, buf, 419 MBEDTLS_ASN1_CONSTRUCTED | 420 MBEDTLS_ASN1_SEQUENCE ) ); 421 422 /* 423 * Issuer ::= Name 424 */ 425 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, buf, 426 ctx->issuer ) ); 427 428 /* 429 * Signature ::= AlgorithmIdentifier 430 */ 431 MBEDTLS_ASN1_CHK_ADD( len, 432 mbedtls_asn1_write_algorithm_identifier( &c, buf, 433 sig_oid, strlen( sig_oid ), 0 ) ); 434 435 /* 436 * Serial ::= INTEGER 437 */ 438 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, 439 &ctx->serial ) ); 440 441 /* 442 * Version ::= INTEGER { v1(0), v2(1), v3(2) } 443 */ 444 445 /* Can be omitted for v1 */ 446 if( ctx->version != MBEDTLS_X509_CRT_VERSION_1 ) 447 { 448 sub_len = 0; 449 MBEDTLS_ASN1_CHK_ADD( sub_len, 450 mbedtls_asn1_write_int( &c, buf, ctx->version ) ); 451 len += sub_len; 452 MBEDTLS_ASN1_CHK_ADD( len, 453 mbedtls_asn1_write_len( &c, buf, sub_len ) ); 454 MBEDTLS_ASN1_CHK_ADD( len, 455 mbedtls_asn1_write_tag( &c, buf, 456 MBEDTLS_ASN1_CONTEXT_SPECIFIC | 457 MBEDTLS_ASN1_CONSTRUCTED | 0 ) ); 458 } 459 460 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); 461 MBEDTLS_ASN1_CHK_ADD( len, 462 mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | 463 MBEDTLS_ASN1_SEQUENCE ) ); 464 465 /* 466 * Make signature 467 */ 468 469 /* Compute hash of CRT. */ 470 if( ( ret = mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, 471 len, hash ) ) != 0 ) 472 { 473 return( ret ); 474 } 475 476 if( ( ret = mbedtls_pk_sign( ctx->issuer_key, ctx->md_alg, 477 hash, 0, sig, &sig_len, 478 f_rng, p_rng ) ) != 0 ) 479 { 480 return( ret ); 481 } 482 483 /* Move CRT to the front of the buffer to have space 484 * for the signature. */ 485 memmove( buf, c, len ); 486 c = buf + len; 487 488 /* Add signature at the end of the buffer, 489 * making sure that it doesn't underflow 490 * into the CRT buffer. */ 491 c2 = buf + size; 492 MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, mbedtls_x509_write_sig( &c2, c, 493 sig_oid, sig_oid_len, sig, sig_len ) ); 494 495 /* 496 * Memory layout after this step: 497 * 498 * buf c=buf+len c2 buf+size 499 * [CRT0,...,CRTn, UNUSED, ..., UNUSED, SIG0, ..., SIGm] 500 */ 501 502 /* Move raw CRT to just before the signature. */ 503 c = c2 - len; 504 memmove( c, buf, len ); 505 506 len += sig_and_oid_len; 507 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); 508 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, 509 MBEDTLS_ASN1_CONSTRUCTED | 510 MBEDTLS_ASN1_SEQUENCE ) ); 511 512 return( (int) len ); 513 } 514 515 #define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----\n" 516 #define PEM_END_CRT "-----END CERTIFICATE-----\n" 517 518 #if defined(MBEDTLS_PEM_WRITE_C) 519 int mbedtls_x509write_crt_pem( mbedtls_x509write_cert *crt, 520 unsigned char *buf, size_t size, 521 int (*f_rng)(void *, unsigned char *, size_t), 522 void *p_rng ) 523 { 524 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 525 size_t olen; 526 527 if( ( ret = mbedtls_x509write_crt_der( crt, buf, size, 528 f_rng, p_rng ) ) < 0 ) 529 { 530 return( ret ); 531 } 532 533 if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_CRT, PEM_END_CRT, 534 buf + size - ret, ret, 535 buf, size, &olen ) ) != 0 ) 536 { 537 return( ret ); 538 } 539 540 return( 0 ); 541 } 542 #endif /* MBEDTLS_PEM_WRITE_C */ 543 544 #endif /* MBEDTLS_X509_CRT_WRITE_C */ 545