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