1 /* 2 * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <getopt.h> 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <string.h> 12 13 /* Suppress OpenSSL engine deprecation warnings */ 14 #define OPENSSL_SUPPRESS_DEPRECATED 15 16 #include <openssl/conf.h> 17 #include <openssl/engine.h> 18 #include <openssl/evp.h> 19 #include <openssl/pem.h> 20 #include <openssl/ssl.h> 21 22 #include "cert.h" 23 #include "cmd_opt.h" 24 #include "debug.h" 25 #include "key.h" 26 #include "sha.h" 27 28 #define MAX_FILENAME_LEN 1024 29 30 cert_key_t *keys; 31 unsigned int num_keys; 32 33 #if !USING_OPENSSL3 34 /* 35 * Create a new key container 36 */ 37 int key_new(cert_key_t *key) 38 { 39 /* Create key pair container */ 40 key->key = EVP_PKEY_new(); 41 if (key->key == NULL) { 42 return 0; 43 } 44 45 return 1; 46 } 47 #endif 48 49 static int key_create_rsa(cert_key_t *key, int key_bits) 50 { 51 #if USING_OPENSSL3 52 EVP_PKEY *rsa = EVP_RSA_gen(key_bits); 53 if (rsa == NULL) { 54 printf("Cannot generate RSA key\n"); 55 return 0; 56 } 57 key->key = rsa; 58 return 1; 59 #else 60 BIGNUM *e; 61 RSA *rsa = NULL; 62 63 e = BN_new(); 64 if (e == NULL) { 65 printf("Cannot create RSA exponent\n"); 66 return 0; 67 } 68 69 if (!BN_set_word(e, RSA_F4)) { 70 printf("Cannot assign RSA exponent\n"); 71 goto err2; 72 } 73 74 rsa = RSA_new(); 75 if (rsa == NULL) { 76 printf("Cannot create RSA key\n"); 77 goto err2; 78 } 79 80 if (!RSA_generate_key_ex(rsa, key_bits, e, NULL)) { 81 printf("Cannot generate RSA key\n"); 82 goto err; 83 } 84 85 if (!EVP_PKEY_assign_RSA(key->key, rsa)) { 86 printf("Cannot assign RSA key\n"); 87 goto err; 88 } 89 90 BN_free(e); 91 return 1; 92 93 err: 94 RSA_free(rsa); 95 err2: 96 BN_free(e); 97 return 0; 98 #endif 99 } 100 101 #ifndef OPENSSL_NO_EC 102 #if USING_OPENSSL3 103 static int key_create_ecdsa(cert_key_t *key, int key_bits, const char *curve) 104 { 105 EVP_PKEY *ec = EVP_EC_gen(curve); 106 if (ec == NULL) { 107 printf("Cannot generate EC key\n"); 108 return 0; 109 } 110 111 key->key = ec; 112 return 1; 113 } 114 115 static int key_create_ecdsa_nist(cert_key_t *key, int key_bits) 116 { 117 if (key_bits == 384) { 118 return key_create_ecdsa(key, key_bits, "secp384r1"); 119 } else { 120 assert(key_bits == 256); 121 return key_create_ecdsa(key, key_bits, "prime256v1"); 122 } 123 } 124 125 static int key_create_ecdsa_brainpool_r(cert_key_t *key, int key_bits) 126 { 127 return key_create_ecdsa(key, key_bits, "brainpoolP256r1"); 128 } 129 130 static int key_create_ecdsa_brainpool_t(cert_key_t *key, int key_bits) 131 { 132 return key_create_ecdsa(key, key_bits, "brainpoolP256t1"); 133 } 134 #else 135 static int key_create_ecdsa(cert_key_t *key, int key_bits, const int curve_id) 136 { 137 EC_KEY *ec; 138 139 ec = EC_KEY_new_by_curve_name(curve_id); 140 if (ec == NULL) { 141 printf("Cannot create EC key\n"); 142 return 0; 143 } 144 if (!EC_KEY_generate_key(ec)) { 145 printf("Cannot generate EC key\n"); 146 goto err; 147 } 148 EC_KEY_set_flags(ec, EC_PKEY_NO_PARAMETERS); 149 EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE); 150 if (!EVP_PKEY_assign_EC_KEY(key->key, ec)) { 151 printf("Cannot assign EC key\n"); 152 goto err; 153 } 154 155 return 1; 156 157 err: 158 EC_KEY_free(ec); 159 return 0; 160 } 161 162 static int key_create_ecdsa_nist(cert_key_t *key, int key_bits) 163 { 164 if (key_bits == 384) { 165 return key_create_ecdsa(key, key_bits, NID_secp384r1); 166 } else { 167 assert(key_bits == 256); 168 return key_create_ecdsa(key, key_bits, NID_X9_62_prime256v1); 169 } 170 } 171 172 #if OPENSSL_VERSION_NUMBER >= 0x10100000L 173 static int key_create_ecdsa_brainpool_r(cert_key_t *key, int key_bits) 174 { 175 return key_create_ecdsa(key, key_bits, NID_brainpoolP256r1); 176 } 177 178 static int key_create_ecdsa_brainpool_t(cert_key_t *key, int key_bits) 179 { 180 return key_create_ecdsa(key, key_bits, NID_brainpoolP256t1); 181 } 182 #endif 183 #endif /* USING_OPENSSL3 */ 184 #endif /* OPENSSL_NO_EC */ 185 186 typedef int (*key_create_fn_t)(cert_key_t *key, int key_bits); 187 static const key_create_fn_t key_create_fn[KEY_ALG_MAX_NUM] = { 188 [KEY_ALG_RSA] = key_create_rsa, 189 #ifndef OPENSSL_NO_EC 190 [KEY_ALG_ECDSA_NIST] = key_create_ecdsa_nist, 191 #if OPENSSL_VERSION_NUMBER >= 0x10100000L 192 [KEY_ALG_ECDSA_BRAINPOOL_R] = key_create_ecdsa_brainpool_r, 193 [KEY_ALG_ECDSA_BRAINPOOL_T] = key_create_ecdsa_brainpool_t, 194 #endif 195 #endif /* OPENSSL_NO_EC */ 196 }; 197 198 int key_create(cert_key_t *key, int type, int key_bits) 199 { 200 if (type >= KEY_ALG_MAX_NUM) { 201 printf("Invalid key type\n"); 202 return 0; 203 } 204 205 if (key_create_fn[type]) { 206 return key_create_fn[type](key, key_bits); 207 } 208 209 return 0; 210 } 211 212 static EVP_PKEY *key_load_pkcs11(const char *uri) 213 { 214 char *key_pass; 215 EVP_PKEY *pkey; 216 ENGINE *e; 217 218 #if !USING_OPENSSL3 219 if (!OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL)) { 220 fprintf(stderr, "Failed to init SSL\n"); 221 return NULL; 222 } 223 #endif 224 225 ENGINE_load_builtin_engines(); 226 e = ENGINE_by_id("pkcs11"); 227 if (!e) { 228 fprintf(stderr, "Cannot Load PKCS#11 ENGINE\n"); 229 return NULL; 230 } 231 232 if (!ENGINE_init(e)) { 233 fprintf(stderr, "Cannot ENGINE_init\n"); 234 goto err; 235 } 236 237 key_pass = getenv("PKCS11_PIN"); 238 if (key_pass) { 239 if (!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0)) { 240 fprintf(stderr, "Cannot Set PKCS#11 PIN\n"); 241 goto err; 242 } 243 } 244 245 pkey = ENGINE_load_private_key(e, uri, NULL, NULL); 246 if (pkey) 247 return pkey; 248 err: 249 ENGINE_free(e); 250 return NULL; 251 252 } 253 254 unsigned int key_load(cert_key_t *key) 255 { 256 if (key->fn == NULL) { 257 VERBOSE("Key not specified\n"); 258 return KEY_ERR_FILENAME; 259 } 260 261 if (strncmp(key->fn, "pkcs11:", 7) == 0) { 262 /* Load key through pkcs11 */ 263 key->key = key_load_pkcs11(key->fn); 264 } else { 265 /* Load key from file */ 266 FILE *fp = fopen(key->fn, "r"); 267 if (fp == NULL) { 268 WARN("Cannot open file %s\n", key->fn); 269 return KEY_ERR_OPEN; 270 } 271 272 key->key = PEM_read_PrivateKey(fp, NULL, NULL, NULL); 273 fclose(fp); 274 } 275 276 if (key->key == NULL) { 277 ERROR("Cannot load key from %s\n", key->fn); 278 return KEY_ERR_LOAD; 279 } 280 281 return KEY_ERR_NONE; 282 } 283 284 int key_store(cert_key_t *key) 285 { 286 FILE *fp; 287 288 if (key->fn) { 289 if (!strncmp(key->fn, "pkcs11:", 7)) { 290 ERROR("PKCS11 URI provided instead of a file"); 291 return 0; 292 } 293 fp = fopen(key->fn, "w"); 294 if (fp) { 295 PEM_write_PrivateKey(fp, key->key, 296 NULL, NULL, 0, NULL, NULL); 297 fclose(fp); 298 return 1; 299 } else { 300 ERROR("Cannot create file %s\n", key->fn); 301 } 302 } else { 303 ERROR("Key filename not specified\n"); 304 } 305 306 return 0; 307 } 308 309 int key_init(void) 310 { 311 cmd_opt_t cmd_opt; 312 cert_key_t *key; 313 unsigned int i; 314 315 keys = malloc((num_def_keys * sizeof(def_keys[0])) 316 #ifdef PDEF_KEYS 317 + (num_pdef_keys * sizeof(pdef_keys[0])) 318 #endif 319 ); 320 321 if (keys == NULL) { 322 ERROR("%s:%d Failed to allocate memory.\n", __func__, __LINE__); 323 return 1; 324 } 325 326 memcpy(&keys[0], &def_keys[0], (num_def_keys * sizeof(def_keys[0]))); 327 #ifdef PDEF_KEYS 328 memcpy(&keys[num_def_keys], &pdef_keys[0], 329 (num_pdef_keys * sizeof(pdef_keys[0]))); 330 331 num_keys = num_def_keys + num_pdef_keys; 332 #else 333 num_keys = num_def_keys; 334 #endif 335 ; 336 337 for (i = 0; i < num_keys; i++) { 338 key = &keys[i]; 339 if (key->opt != NULL) { 340 cmd_opt.long_opt.name = key->opt; 341 cmd_opt.long_opt.has_arg = required_argument; 342 cmd_opt.long_opt.flag = NULL; 343 cmd_opt.long_opt.val = CMD_OPT_KEY; 344 cmd_opt.help_msg = key->help_msg; 345 cmd_opt_add(&cmd_opt); 346 } 347 } 348 349 return 0; 350 } 351 352 cert_key_t *key_get_by_opt(const char *opt) 353 { 354 cert_key_t *key; 355 unsigned int i; 356 357 /* Sequential search. This is not a performance concern since the number 358 * of keys is bounded and the code runs on a host machine */ 359 for (i = 0; i < num_keys; i++) { 360 key = &keys[i]; 361 if (0 == strcmp(key->opt, opt)) { 362 return key; 363 } 364 } 365 366 return NULL; 367 } 368 369 void key_cleanup(void) 370 { 371 unsigned int i; 372 373 for (i = 0; i < num_keys; i++) { 374 EVP_PKEY_free(keys[i].key); 375 if (keys[i].fn != NULL) { 376 void *ptr = keys[i].fn; 377 378 free(ptr); 379 keys[i].fn = NULL; 380 } 381 } 382 free(keys); 383 } 384 385