1 /* 2 * X.509 Certificate Signing Request writing 3 * 4 * Copyright The Mbed TLS Contributors 5 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 6 * 7 * This file is provided under the Apache License 2.0, or the 8 * GNU General Public License v2.0 or later. 9 * 10 * ********** 11 * Apache License 2.0: 12 * 13 * Licensed under the Apache License, Version 2.0 (the "License"); you may 14 * not use this file except in compliance with the License. 15 * You may obtain a copy of the License at 16 * 17 * http://www.apache.org/licenses/LICENSE-2.0 18 * 19 * Unless required by applicable law or agreed to in writing, software 20 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 21 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 * See the License for the specific language governing permissions and 23 * limitations under the License. 24 * 25 * ********** 26 * 27 * ********** 28 * GNU General Public License v2.0 or later: 29 * 30 * This program is free software; you can redistribute it and/or modify 31 * it under the terms of the GNU General Public License as published by 32 * the Free Software Foundation; either version 2 of the License, or 33 * (at your option) any later version. 34 * 35 * This program is distributed in the hope that it will be useful, 36 * but WITHOUT ANY WARRANTY; without even the implied warranty of 37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 38 * GNU General Public License for more details. 39 * 40 * You should have received a copy of the GNU General Public License along 41 * with this program; if not, write to the Free Software Foundation, Inc., 42 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 43 * 44 * ********** 45 */ 46 /* 47 * References: 48 * - CSRs: PKCS#10 v1.7 aka RFC 2986 49 * - attributes: PKCS#9 v2.0 aka RFC 2985 50 */ 51 52 #if !defined(MBEDTLS_CONFIG_FILE) 53 #include "mbedtls/config.h" 54 #else 55 #include MBEDTLS_CONFIG_FILE 56 #endif 57 58 #if defined(MBEDTLS_X509_CSR_WRITE_C) 59 60 #include "mbedtls/x509_csr.h" 61 #include "mbedtls/oid.h" 62 #include "mbedtls/asn1write.h" 63 #include "mbedtls/platform_util.h" 64 65 #include <string.h> 66 #include <stdlib.h> 67 68 #if defined(MBEDTLS_PEM_WRITE_C) 69 #include "mbedtls/pem.h" 70 #endif 71 72 /* 73 * For the currently used signature algorithms the buffer to store any signature 74 * must be at least of size MAX(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE) 75 */ 76 #if MBEDTLS_ECDSA_MAX_LEN > MBEDTLS_MPI_MAX_SIZE 77 #define SIGNATURE_MAX_SIZE MBEDTLS_ECDSA_MAX_LEN 78 #else 79 #define SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE 80 #endif 81 82 #if defined(MBEDTLS_PLATFORM_C) 83 #include "mbedtls/platform.h" 84 #else 85 #include <stdlib.h> 86 #define mbedtls_calloc calloc 87 #define mbedtls_free free 88 #endif 89 90 void mbedtls_x509write_csr_init( mbedtls_x509write_csr *ctx ) 91 { 92 memset( ctx, 0, sizeof( mbedtls_x509write_csr ) ); 93 } 94 95 void mbedtls_x509write_csr_free( mbedtls_x509write_csr *ctx ) 96 { 97 mbedtls_asn1_free_named_data_list( &ctx->subject ); 98 mbedtls_asn1_free_named_data_list( &ctx->extensions ); 99 100 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_x509write_csr ) ); 101 } 102 103 void mbedtls_x509write_csr_set_md_alg( mbedtls_x509write_csr *ctx, mbedtls_md_type_t md_alg ) 104 { 105 ctx->md_alg = md_alg; 106 } 107 108 void mbedtls_x509write_csr_set_key( mbedtls_x509write_csr *ctx, mbedtls_pk_context *key ) 109 { 110 ctx->key = key; 111 } 112 113 int mbedtls_x509write_csr_set_subject_name( mbedtls_x509write_csr *ctx, 114 const char *subject_name ) 115 { 116 return mbedtls_x509_string_to_names( &ctx->subject, subject_name ); 117 } 118 119 int mbedtls_x509write_csr_set_extension( mbedtls_x509write_csr *ctx, 120 const char *oid, size_t oid_len, 121 const unsigned char *val, size_t val_len ) 122 { 123 return mbedtls_x509_set_extension( &ctx->extensions, oid, oid_len, 124 0, val, val_len ); 125 } 126 127 static size_t csr_get_unused_bits_for_named_bitstring( unsigned char bitstring, 128 size_t bit_offset ) 129 { 130 size_t unused_bits; 131 132 /* Count the unused bits removing trailing 0s */ 133 for( unused_bits = bit_offset; unused_bits < 8; unused_bits++ ) 134 if( ( ( bitstring >> unused_bits ) & 0x1 ) != 0 ) 135 break; 136 137 return( unused_bits ); 138 } 139 140 int mbedtls_x509write_csr_set_key_usage( mbedtls_x509write_csr *ctx, unsigned char key_usage ) 141 { 142 unsigned char buf[4]; 143 unsigned char *c; 144 size_t unused_bits; 145 int ret; 146 147 c = buf + 4; 148 149 unused_bits = csr_get_unused_bits_for_named_bitstring( key_usage, 0 ); 150 ret = mbedtls_asn1_write_bitstring( &c, buf, &key_usage, 8 - unused_bits ); 151 152 if( ret < 0 ) 153 return( ret ); 154 else if( ret < 3 || ret > 4 ) 155 return( MBEDTLS_ERR_X509_INVALID_FORMAT ); 156 157 ret = mbedtls_x509write_csr_set_extension( ctx, MBEDTLS_OID_KEY_USAGE, 158 MBEDTLS_OID_SIZE( MBEDTLS_OID_KEY_USAGE ), 159 c, (size_t)ret ); 160 if( ret != 0 ) 161 return( ret ); 162 163 return( 0 ); 164 } 165 166 int mbedtls_x509write_csr_set_ns_cert_type( mbedtls_x509write_csr *ctx, 167 unsigned char ns_cert_type ) 168 { 169 unsigned char buf[4]; 170 unsigned char *c; 171 size_t unused_bits; 172 int ret; 173 174 c = buf + 4; 175 176 unused_bits = csr_get_unused_bits_for_named_bitstring( ns_cert_type, 0 ); 177 ret = mbedtls_asn1_write_bitstring( &c, 178 buf, 179 &ns_cert_type, 180 8 - unused_bits ); 181 182 if( ret < 0 ) 183 return( ret ); 184 else if( ret < 3 || ret > 4 ) 185 return( ret ); 186 187 ret = mbedtls_x509write_csr_set_extension( ctx, MBEDTLS_OID_NS_CERT_TYPE, 188 MBEDTLS_OID_SIZE( MBEDTLS_OID_NS_CERT_TYPE ), 189 c, (size_t)ret ); 190 if( ret != 0 ) 191 return( ret ); 192 193 return( 0 ); 194 } 195 196 static int x509write_csr_der_internal( mbedtls_x509write_csr *ctx, 197 unsigned char *buf, 198 size_t size, 199 unsigned char *sig, 200 int (*f_rng)(void *, unsigned char *, size_t), 201 void *p_rng ) 202 { 203 int ret; 204 const char *sig_oid; 205 size_t sig_oid_len = 0; 206 unsigned char *c, *c2; 207 unsigned char hash[64]; 208 size_t pub_len = 0, sig_and_oid_len = 0, sig_len; 209 size_t len = 0; 210 mbedtls_pk_type_t pk_alg; 211 212 /* Write the CSR backwards starting from the end of buf */ 213 c = buf + size; 214 215 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_extensions( &c, buf, 216 ctx->extensions ) ); 217 218 if( len ) 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( 223 &c, buf, 224 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); 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( 229 &c, buf, 230 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET ) ); 231 232 MBEDTLS_ASN1_CHK_ADD( len, 233 mbedtls_asn1_write_oid( 234 &c, buf, MBEDTLS_OID_PKCS9_CSR_EXT_REQ, 235 MBEDTLS_OID_SIZE( MBEDTLS_OID_PKCS9_CSR_EXT_REQ ) ) ); 236 237 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); 238 MBEDTLS_ASN1_CHK_ADD( len, 239 mbedtls_asn1_write_tag( 240 &c, buf, 241 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); 242 } 243 244 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); 245 MBEDTLS_ASN1_CHK_ADD( len, 246 mbedtls_asn1_write_tag( 247 &c, buf, 248 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ); 249 250 MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_pk_write_pubkey_der( ctx->key, 251 buf, c - buf ) ); 252 c -= pub_len; 253 len += pub_len; 254 255 /* 256 * Subject ::= Name 257 */ 258 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, buf, 259 ctx->subject ) ); 260 261 /* 262 * Version ::= INTEGER { v1(0), v2(1), v3(2) } 263 */ 264 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 0 ) ); 265 266 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); 267 MBEDTLS_ASN1_CHK_ADD( len, 268 mbedtls_asn1_write_tag( 269 &c, buf, 270 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); 271 272 /* 273 * Sign the written CSR data into the sig buffer 274 * Note: hash errors can happen only after an internal error 275 */ 276 ret = mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, len, hash ); 277 if( ret != 0 ) 278 return( ret ); 279 280 if( ( ret = mbedtls_pk_sign( ctx->key, ctx->md_alg, hash, 0, sig, &sig_len, 281 f_rng, p_rng ) ) != 0 ) 282 { 283 return( ret ); 284 } 285 286 if( mbedtls_pk_can_do( ctx->key, MBEDTLS_PK_RSA ) ) 287 pk_alg = MBEDTLS_PK_RSA; 288 else if( mbedtls_pk_can_do( ctx->key, MBEDTLS_PK_ECDSA ) ) 289 pk_alg = MBEDTLS_PK_ECDSA; 290 else 291 return( MBEDTLS_ERR_X509_INVALID_ALG ); 292 293 if( ( ret = mbedtls_oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg, 294 &sig_oid, &sig_oid_len ) ) != 0 ) 295 { 296 return( ret ); 297 } 298 299 /* 300 * Move the written CSR data to the start of buf to create space for 301 * writing the signature into buf. 302 */ 303 memmove( buf, c, len ); 304 305 /* 306 * Write sig and its OID into buf backwards from the end of buf. 307 * Note: mbedtls_x509_write_sig will check for c2 - ( buf + len ) < sig_len 308 * and return MBEDTLS_ERR_ASN1_BUF_TOO_SMALL if needed. 309 */ 310 c2 = buf + size; 311 MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, 312 mbedtls_x509_write_sig( &c2, buf + len, sig_oid, sig_oid_len, 313 sig, sig_len ) ); 314 315 /* 316 * Compact the space between the CSR data and signature by moving the 317 * CSR data to the start of the signature. 318 */ 319 c2 -= len; 320 memmove( c2, buf, len ); 321 322 /* ASN encode the total size and tag the CSR data with it. */ 323 len += sig_and_oid_len; 324 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c2, buf, len ) ); 325 MBEDTLS_ASN1_CHK_ADD( len, 326 mbedtls_asn1_write_tag( 327 &c2, buf, 328 MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); 329 330 /* Zero the unused bytes at the start of buf */ 331 memset( buf, 0, c2 - buf); 332 333 return( (int) len ); 334 } 335 336 int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf, 337 size_t size, 338 int (*f_rng)(void *, unsigned char *, size_t), 339 void *p_rng ) 340 { 341 int ret; 342 unsigned char *sig; 343 344 if( ( sig = mbedtls_calloc( 1, SIGNATURE_MAX_SIZE ) ) == NULL ) 345 { 346 return( MBEDTLS_ERR_X509_ALLOC_FAILED ); 347 } 348 349 ret = x509write_csr_der_internal( ctx, buf, size, sig, f_rng, p_rng ); 350 351 mbedtls_free( sig ); 352 353 return( ret ); 354 } 355 356 #define PEM_BEGIN_CSR "-----BEGIN CERTIFICATE REQUEST-----\n" 357 #define PEM_END_CSR "-----END CERTIFICATE REQUEST-----\n" 358 359 #if defined(MBEDTLS_PEM_WRITE_C) 360 int mbedtls_x509write_csr_pem( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size, 361 int (*f_rng)(void *, unsigned char *, size_t), 362 void *p_rng ) 363 { 364 int ret; 365 unsigned char output_buf[4096]; 366 size_t olen = 0; 367 368 if( ( ret = mbedtls_x509write_csr_der( ctx, output_buf, sizeof(output_buf), 369 f_rng, p_rng ) ) < 0 ) 370 { 371 return( ret ); 372 } 373 374 if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_CSR, PEM_END_CSR, 375 output_buf + sizeof(output_buf) - ret, 376 ret, buf, size, &olen ) ) != 0 ) 377 { 378 return( ret ); 379 } 380 381 return( 0 ); 382 } 383 #endif /* MBEDTLS_PEM_WRITE_C */ 384 385 #endif /* MBEDTLS_X509_CSR_WRITE_C */ 386