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