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 
171 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
key_create_ecdsa_brainpool_r(key_t * key,int key_bits)172 static int key_create_ecdsa_brainpool_r(key_t *key, int key_bits)
173 {
174 	return key_create_ecdsa(key, key_bits, NID_brainpoolP256r1);
175 }
176 
key_create_ecdsa_brainpool_t(key_t * key,int key_bits)177 static int key_create_ecdsa_brainpool_t(key_t *key, int key_bits)
178 {
179 	return key_create_ecdsa(key, key_bits, NID_brainpoolP256t1);
180 }
181 #endif
182 #endif /* USING_OPENSSL3 */
183 #endif /* OPENSSL_NO_EC */
184 
185 typedef int (*key_create_fn_t)(key_t *key, int key_bits);
186 static const key_create_fn_t key_create_fn[KEY_ALG_MAX_NUM] = {
187 	[KEY_ALG_RSA] = key_create_rsa,
188 #ifndef OPENSSL_NO_EC
189 	[KEY_ALG_ECDSA_NIST] = key_create_ecdsa_nist,
190 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
191 	[KEY_ALG_ECDSA_BRAINPOOL_R] = key_create_ecdsa_brainpool_r,
192 	[KEY_ALG_ECDSA_BRAINPOOL_T] = key_create_ecdsa_brainpool_t,
193 #endif
194 #endif /* OPENSSL_NO_EC */
195 };
196 
key_create(key_t * key,int type,int key_bits)197 int key_create(key_t *key, int type, int key_bits)
198 {
199 	if (type >= KEY_ALG_MAX_NUM) {
200 		printf("Invalid key type\n");
201 		return 0;
202 	}
203 
204 	if (key_create_fn[type]) {
205 		return key_create_fn[type](key, key_bits);
206 	}
207 
208 	return 0;
209 }
210 
key_load_pkcs11(const char * uri)211 static EVP_PKEY *key_load_pkcs11(const char *uri)
212 {
213 	char *key_pass;
214 	EVP_PKEY *pkey;
215 	ENGINE *e;
216 
217 	ENGINE_load_builtin_engines();
218 	e = ENGINE_by_id("pkcs11");
219 	if (!e) {
220 		fprintf(stderr, "Cannot Load PKCS#11 ENGINE\n");
221 		return NULL;
222 	}
223 
224 	if (!ENGINE_init(e)) {
225 		fprintf(stderr, "Cannot ENGINE_init\n");
226 		goto err;
227 	}
228 
229 	key_pass = getenv("PKCS11_PIN");
230 	if (key_pass) {
231 		if (!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0)) {
232 			fprintf(stderr, "Cannot Set PKCS#11 PIN\n");
233 			goto err;
234 		}
235 	}
236 
237 	pkey = ENGINE_load_private_key(e, uri, NULL, NULL);
238 	if (pkey)
239 		return pkey;
240 err:
241 	ENGINE_free(e);
242 	return NULL;
243 
244 }
245 
key_load(key_t * key)246 unsigned int key_load(key_t *key)
247 {
248 	if (key->fn == NULL) {
249 		VERBOSE("Key not specified\n");
250 		return KEY_ERR_FILENAME;
251 	}
252 
253 	if (strncmp(key->fn, "pkcs11:", 7) == 0) {
254 		/* Load key through pkcs11 */
255 		key->key = key_load_pkcs11(key->fn);
256 	} else {
257 		/* Load key from file */
258 		FILE *fp = fopen(key->fn, "r");
259 		if (fp == NULL) {
260 			WARN("Cannot open file %s\n", key->fn);
261 			return KEY_ERR_OPEN;
262 		}
263 
264 		key->key = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
265 		fclose(fp);
266 	}
267 
268 	if (key->key == NULL) {
269 		ERROR("Cannot load key from %s\n", key->fn);
270 		return KEY_ERR_LOAD;
271 	}
272 
273 	return KEY_ERR_NONE;
274 }
275 
key_store(key_t * key)276 int key_store(key_t *key)
277 {
278 	FILE *fp;
279 
280 	if (key->fn) {
281 		if (!strncmp(key->fn, "pkcs11:", 7)) {
282 			ERROR("PKCS11 URI provided instead of a file");
283 			return 0;
284 		}
285 		fp = fopen(key->fn, "w");
286 		if (fp) {
287 			PEM_write_PrivateKey(fp, key->key,
288 					NULL, NULL, 0, NULL, NULL);
289 			fclose(fp);
290 			return 1;
291 		} else {
292 			ERROR("Cannot create file %s\n", key->fn);
293 		}
294 	} else {
295 		ERROR("Key filename not specified\n");
296 	}
297 
298 	return 0;
299 }
300 
key_init(void)301 int key_init(void)
302 {
303 	cmd_opt_t cmd_opt;
304 	key_t *key;
305 	unsigned int i;
306 
307 	keys = malloc((num_def_keys * sizeof(def_keys[0]))
308 #ifdef PDEF_KEYS
309 		      + (num_pdef_keys * sizeof(pdef_keys[0]))
310 #endif
311 		      );
312 
313 	if (keys == NULL) {
314 		ERROR("%s:%d Failed to allocate memory.\n", __func__, __LINE__);
315 		return 1;
316 	}
317 
318 	memcpy(&keys[0], &def_keys[0], (num_def_keys * sizeof(def_keys[0])));
319 #ifdef PDEF_KEYS
320 	memcpy(&keys[num_def_keys], &pdef_keys[0],
321 		(num_pdef_keys * sizeof(pdef_keys[0])));
322 
323 	num_keys = num_def_keys + num_pdef_keys;
324 #else
325 	num_keys = num_def_keys;
326 #endif
327 		   ;
328 
329 	for (i = 0; i < num_keys; i++) {
330 		key = &keys[i];
331 		if (key->opt != NULL) {
332 			cmd_opt.long_opt.name = key->opt;
333 			cmd_opt.long_opt.has_arg = required_argument;
334 			cmd_opt.long_opt.flag = NULL;
335 			cmd_opt.long_opt.val = CMD_OPT_KEY;
336 			cmd_opt.help_msg = key->help_msg;
337 			cmd_opt_add(&cmd_opt);
338 		}
339 	}
340 
341 	return 0;
342 }
343 
key_get_by_opt(const char * opt)344 key_t *key_get_by_opt(const char *opt)
345 {
346 	key_t *key;
347 	unsigned int i;
348 
349 	/* Sequential search. This is not a performance concern since the number
350 	 * of keys is bounded and the code runs on a host machine */
351 	for (i = 0; i < num_keys; i++) {
352 		key = &keys[i];
353 		if (0 == strcmp(key->opt, opt)) {
354 			return key;
355 		}
356 	}
357 
358 	return NULL;
359 }
360 
key_cleanup(void)361 void key_cleanup(void)
362 {
363 	unsigned int i;
364 
365 	for (i = 0; i < num_keys; i++) {
366 		EVP_PKEY_free(keys[i].key);
367 		if (keys[i].fn != NULL) {
368 			void *ptr = keys[i].fn;
369 
370 			free(ptr);
371 			keys[i].fn = NULL;
372 		}
373 	}
374 	free(keys);
375 }
376 
377