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