xref: /rk3399_ARM-atf/tools/cert_create/src/key.c (revision 5cc9bdd399717df95d4c51f3a97ccbf90d60a2dc)
16f971622SJuan Castillo /*
2ccbfd01dSManish V Badarkhe  * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
36f971622SJuan Castillo  *
482cb2c1aSdp-arm  * SPDX-License-Identifier: BSD-3-Clause
56f971622SJuan Castillo  */
66f971622SJuan Castillo 
7c512c89cSlaurenw-arm #include <assert.h>
86f971622SJuan Castillo #include <getopt.h>
96f971622SJuan Castillo #include <stdio.h>
106f971622SJuan Castillo #include <stdlib.h>
116f971622SJuan Castillo #include <string.h>
126f971622SJuan Castillo 
13616b3ce2SRobin van der Gracht /* Suppress OpenSSL engine deprecation warnings */
14616b3ce2SRobin van der Gracht #define OPENSSL_SUPPRESS_DEPRECATED
15616b3ce2SRobin van der Gracht 
166f971622SJuan Castillo #include <openssl/conf.h>
17616b3ce2SRobin van der Gracht #include <openssl/engine.h>
186f971622SJuan Castillo #include <openssl/evp.h>
196f971622SJuan Castillo #include <openssl/pem.h>
20*785c2c3eSGatien Chevallier #include <openssl/ssl.h>
216f971622SJuan Castillo 
226f971622SJuan Castillo #include "cert.h"
23ad2c1a9aSJuan Castillo #include "cmd_opt.h"
246f971622SJuan Castillo #include "debug.h"
256f971622SJuan Castillo #include "key.h"
266f971622SJuan Castillo #include "sha.h"
276f971622SJuan Castillo 
286f971622SJuan Castillo #define MAX_FILENAME_LEN		1024
296f971622SJuan Castillo 
30ccbfd01dSManish V Badarkhe cert_key_t *keys;
31b94bf967SPankaj Gupta unsigned int num_keys;
32b94bf967SPankaj Gupta 
33cf2dd17dSJuan Pablo Conde #if !USING_OPENSSL3
346f971622SJuan Castillo /*
35ccbf890eSJuan Castillo  * Create a new key container
366f971622SJuan Castillo  */
key_new(cert_key_t * key)37ccbfd01dSManish V Badarkhe int key_new(cert_key_t *key)
38ccbf890eSJuan Castillo {
39ccbf890eSJuan Castillo 	/* Create key pair container */
40ccbf890eSJuan Castillo 	key->key = EVP_PKEY_new();
41ccbf890eSJuan Castillo 	if (key->key == NULL) {
42ccbf890eSJuan Castillo 		return 0;
43ccbf890eSJuan Castillo 	}
44ccbf890eSJuan Castillo 
45ccbf890eSJuan Castillo 	return 1;
46ccbf890eSJuan Castillo }
47cf2dd17dSJuan Pablo Conde #endif
48ccbf890eSJuan Castillo 
key_create_rsa(cert_key_t * key,int key_bits)49ccbfd01dSManish V Badarkhe static int key_create_rsa(cert_key_t *key, int key_bits)
506f971622SJuan Castillo {
51cf2dd17dSJuan Pablo Conde #if USING_OPENSSL3
529bc52d33SJuan Pablo Conde 	EVP_PKEY *rsa = EVP_RSA_gen(key_bits);
53ccbf890eSJuan Castillo 	if (rsa == NULL) {
54742c4e14SMichalis Pappas 		printf("Cannot generate RSA key\n");
55ed2a76eaSJuan Castillo 		return 0;
56ed2a76eaSJuan Castillo 	}
579bc52d33SJuan Pablo Conde 	key->key = rsa;
589bc52d33SJuan Pablo Conde 	return 1;
59cf2dd17dSJuan Pablo Conde #else
60cf2dd17dSJuan Pablo Conde 	BIGNUM *e;
61cf2dd17dSJuan Pablo Conde 	RSA *rsa = NULL;
62cf2dd17dSJuan Pablo Conde 
63cf2dd17dSJuan Pablo Conde 	e = BN_new();
64cf2dd17dSJuan Pablo Conde 	if (e == NULL) {
65cf2dd17dSJuan Pablo Conde 		printf("Cannot create RSA exponent\n");
66cf2dd17dSJuan Pablo Conde 		return 0;
67cf2dd17dSJuan Pablo Conde 	}
68cf2dd17dSJuan Pablo Conde 
69cf2dd17dSJuan Pablo Conde 	if (!BN_set_word(e, RSA_F4)) {
70cf2dd17dSJuan Pablo Conde 		printf("Cannot assign RSA exponent\n");
71cf2dd17dSJuan Pablo Conde 		goto err2;
72cf2dd17dSJuan Pablo Conde 	}
73cf2dd17dSJuan Pablo Conde 
74cf2dd17dSJuan Pablo Conde 	rsa = RSA_new();
75cf2dd17dSJuan Pablo Conde 	if (rsa == NULL) {
76cf2dd17dSJuan Pablo Conde 		printf("Cannot create RSA key\n");
77cf2dd17dSJuan Pablo Conde 		goto err2;
78cf2dd17dSJuan Pablo Conde 	}
79cf2dd17dSJuan Pablo Conde 
80cf2dd17dSJuan Pablo Conde 	if (!RSA_generate_key_ex(rsa, key_bits, e, NULL)) {
81cf2dd17dSJuan Pablo Conde 		printf("Cannot generate RSA key\n");
82cf2dd17dSJuan Pablo Conde 		goto err;
83cf2dd17dSJuan Pablo Conde 	}
84cf2dd17dSJuan Pablo Conde 
85cf2dd17dSJuan Pablo Conde 	if (!EVP_PKEY_assign_RSA(key->key, rsa)) {
86cf2dd17dSJuan Pablo Conde 		printf("Cannot assign RSA key\n");
87cf2dd17dSJuan Pablo Conde 		goto err;
88cf2dd17dSJuan Pablo Conde 	}
89cf2dd17dSJuan Pablo Conde 
90cf2dd17dSJuan Pablo Conde 	BN_free(e);
91cf2dd17dSJuan Pablo Conde 	return 1;
92cf2dd17dSJuan Pablo Conde 
93cf2dd17dSJuan Pablo Conde err:
94cf2dd17dSJuan Pablo Conde 	RSA_free(rsa);
95cf2dd17dSJuan Pablo Conde err2:
96cf2dd17dSJuan Pablo Conde 	BN_free(e);
97cf2dd17dSJuan Pablo Conde 	return 0;
98cf2dd17dSJuan Pablo Conde #endif
999bc52d33SJuan Pablo Conde }
100ed2a76eaSJuan Castillo 
101ed2a76eaSJuan Castillo #ifndef OPENSSL_NO_EC
102cf2dd17dSJuan Pablo Conde #if USING_OPENSSL3
key_create_ecdsa(cert_key_t * key,int key_bits,const char * curve)103ccbfd01dSManish V Badarkhe static int key_create_ecdsa(cert_key_t *key, int key_bits, const char *curve)
104e78ba69eSLionel Debieve {
105e78ba69eSLionel Debieve 	EVP_PKEY *ec = EVP_EC_gen(curve);
106ccbf890eSJuan Castillo 	if (ec == NULL) {
107ccbf890eSJuan Castillo 		printf("Cannot generate EC key\n");
108ed2a76eaSJuan Castillo 		return 0;
109ed2a76eaSJuan Castillo 	}
110e78ba69eSLionel Debieve 
1119bc52d33SJuan Pablo Conde 	key->key = ec;
1129bc52d33SJuan Pablo Conde 	return 1;
113e78ba69eSLionel Debieve }
114e78ba69eSLionel Debieve 
key_create_ecdsa_nist(cert_key_t * key,int key_bits)115ccbfd01dSManish V Badarkhe static int key_create_ecdsa_nist(cert_key_t *key, int key_bits)
116e78ba69eSLionel Debieve {
117c512c89cSlaurenw-arm 	if (key_bits == 384) {
118c512c89cSlaurenw-arm 		return key_create_ecdsa(key, key_bits, "secp384r1");
119c512c89cSlaurenw-arm 	} else {
120c512c89cSlaurenw-arm 		assert(key_bits == 256);
121e78ba69eSLionel Debieve 		return key_create_ecdsa(key, key_bits, "prime256v1");
122e78ba69eSLionel Debieve 	}
123c512c89cSlaurenw-arm }
124e78ba69eSLionel Debieve 
key_create_ecdsa_brainpool_r(cert_key_t * key,int key_bits)125ccbfd01dSManish V Badarkhe static int key_create_ecdsa_brainpool_r(cert_key_t *key, int key_bits)
126e78ba69eSLionel Debieve {
127e78ba69eSLionel Debieve 	return key_create_ecdsa(key, key_bits, "brainpoolP256r1");
128e78ba69eSLionel Debieve }
129e78ba69eSLionel Debieve 
key_create_ecdsa_brainpool_t(cert_key_t * key,int key_bits)130ccbfd01dSManish V Badarkhe static int key_create_ecdsa_brainpool_t(cert_key_t *key, int key_bits)
131e78ba69eSLionel Debieve {
132e78ba69eSLionel Debieve 	return key_create_ecdsa(key, key_bits, "brainpoolP256t1");
133e78ba69eSLionel Debieve }
134cf2dd17dSJuan Pablo Conde #else
key_create_ecdsa(cert_key_t * key,int key_bits,const int curve_id)135ccbfd01dSManish V Badarkhe static int key_create_ecdsa(cert_key_t *key, int key_bits, const int curve_id)
136e78ba69eSLionel Debieve {
137cf2dd17dSJuan Pablo Conde 	EC_KEY *ec;
138cf2dd17dSJuan Pablo Conde 
139e78ba69eSLionel Debieve 	ec = EC_KEY_new_by_curve_name(curve_id);
140cf2dd17dSJuan Pablo Conde 	if (ec == NULL) {
141cf2dd17dSJuan Pablo Conde 		printf("Cannot create EC key\n");
142cf2dd17dSJuan Pablo Conde 		return 0;
143cf2dd17dSJuan Pablo Conde 	}
144cf2dd17dSJuan Pablo Conde 	if (!EC_KEY_generate_key(ec)) {
145cf2dd17dSJuan Pablo Conde 		printf("Cannot generate EC key\n");
146cf2dd17dSJuan Pablo Conde 		goto err;
147cf2dd17dSJuan Pablo Conde 	}
148cf2dd17dSJuan Pablo Conde 	EC_KEY_set_flags(ec, EC_PKEY_NO_PARAMETERS);
149cf2dd17dSJuan Pablo Conde 	EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE);
150cf2dd17dSJuan Pablo Conde 	if (!EVP_PKEY_assign_EC_KEY(key->key, ec)) {
151cf2dd17dSJuan Pablo Conde 		printf("Cannot assign EC key\n");
152cf2dd17dSJuan Pablo Conde 		goto err;
153cf2dd17dSJuan Pablo Conde 	}
154cf2dd17dSJuan Pablo Conde 
155cf2dd17dSJuan Pablo Conde 	return 1;
156cf2dd17dSJuan Pablo Conde 
157cf2dd17dSJuan Pablo Conde err:
158cf2dd17dSJuan Pablo Conde 	EC_KEY_free(ec);
159cf2dd17dSJuan Pablo Conde 	return 0;
1609bc52d33SJuan Pablo Conde }
161e78ba69eSLionel Debieve 
key_create_ecdsa_nist(cert_key_t * key,int key_bits)162ccbfd01dSManish V Badarkhe static int key_create_ecdsa_nist(cert_key_t *key, int key_bits)
163e78ba69eSLionel Debieve {
164c512c89cSlaurenw-arm 	if (key_bits == 384) {
165c512c89cSlaurenw-arm 		return key_create_ecdsa(key, key_bits, NID_secp384r1);
166c512c89cSlaurenw-arm 	} else {
167c512c89cSlaurenw-arm 		assert(key_bits == 256);
168e78ba69eSLionel Debieve 		return key_create_ecdsa(key, key_bits, NID_X9_62_prime256v1);
169e78ba69eSLionel Debieve 	}
170c512c89cSlaurenw-arm }
171e78ba69eSLionel Debieve 
172c0c280dfSDonald Chan #if OPENSSL_VERSION_NUMBER >= 0x10100000L
key_create_ecdsa_brainpool_r(cert_key_t * key,int key_bits)173ccbfd01dSManish V Badarkhe static int key_create_ecdsa_brainpool_r(cert_key_t *key, int key_bits)
174e78ba69eSLionel Debieve {
175e78ba69eSLionel Debieve 	return key_create_ecdsa(key, key_bits, NID_brainpoolP256r1);
176e78ba69eSLionel Debieve }
177e78ba69eSLionel Debieve 
key_create_ecdsa_brainpool_t(cert_key_t * key,int key_bits)178ccbfd01dSManish V Badarkhe static int key_create_ecdsa_brainpool_t(cert_key_t *key, int key_bits)
179e78ba69eSLionel Debieve {
180e78ba69eSLionel Debieve 	return key_create_ecdsa(key, key_bits, NID_brainpoolP256t1);
181e78ba69eSLionel Debieve }
182c0c280dfSDonald Chan #endif
183e78ba69eSLionel Debieve #endif /* USING_OPENSSL3 */
184ed2a76eaSJuan Castillo #endif /* OPENSSL_NO_EC */
185ed2a76eaSJuan Castillo 
186ccbfd01dSManish V Badarkhe typedef int (*key_create_fn_t)(cert_key_t *key, int key_bits);
187ed2a76eaSJuan Castillo static const key_create_fn_t key_create_fn[KEY_ALG_MAX_NUM] = {
188e78ba69eSLionel Debieve 	[KEY_ALG_RSA] = key_create_rsa,
189ed2a76eaSJuan Castillo #ifndef OPENSSL_NO_EC
190e78ba69eSLionel Debieve 	[KEY_ALG_ECDSA_NIST] = key_create_ecdsa_nist,
191c0c280dfSDonald Chan #if OPENSSL_VERSION_NUMBER >= 0x10100000L
192e78ba69eSLionel Debieve 	[KEY_ALG_ECDSA_BRAINPOOL_R] = key_create_ecdsa_brainpool_r,
193e78ba69eSLionel Debieve 	[KEY_ALG_ECDSA_BRAINPOOL_T] = key_create_ecdsa_brainpool_t,
194c0c280dfSDonald Chan #endif
195ed2a76eaSJuan Castillo #endif /* OPENSSL_NO_EC */
196ed2a76eaSJuan Castillo };
197ed2a76eaSJuan Castillo 
key_create(cert_key_t * key,int type,int key_bits)198ccbfd01dSManish V Badarkhe int key_create(cert_key_t *key, int type, int key_bits)
199ed2a76eaSJuan Castillo {
200ed2a76eaSJuan Castillo 	if (type >= KEY_ALG_MAX_NUM) {
201ed2a76eaSJuan Castillo 		printf("Invalid key type\n");
202ed2a76eaSJuan Castillo 		return 0;
203ed2a76eaSJuan Castillo 	}
204ed2a76eaSJuan Castillo 
205ed2a76eaSJuan Castillo 	if (key_create_fn[type]) {
206dfe0f4c2SJustin Chadwell 		return key_create_fn[type](key, key_bits);
207ed2a76eaSJuan Castillo 	}
208ccbf890eSJuan Castillo 
2096f971622SJuan Castillo 	return 0;
2106f971622SJuan Castillo }
2116f971622SJuan Castillo 
key_load_pkcs11(const char * uri)212616b3ce2SRobin van der Gracht static EVP_PKEY *key_load_pkcs11(const char *uri)
213616b3ce2SRobin van der Gracht {
214616b3ce2SRobin van der Gracht 	char *key_pass;
215616b3ce2SRobin van der Gracht 	EVP_PKEY *pkey;
216616b3ce2SRobin van der Gracht 	ENGINE *e;
217616b3ce2SRobin van der Gracht 
218*785c2c3eSGatien Chevallier #if !USING_OPENSSL3
219*785c2c3eSGatien Chevallier 	if (!OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG, NULL)) {
220*785c2c3eSGatien Chevallier 		fprintf(stderr, "Failed to init SSL\n");
221*785c2c3eSGatien Chevallier 		return NULL;
222*785c2c3eSGatien Chevallier 	}
223*785c2c3eSGatien Chevallier #endif
224*785c2c3eSGatien Chevallier 
225616b3ce2SRobin van der Gracht 	ENGINE_load_builtin_engines();
226616b3ce2SRobin van der Gracht 	e = ENGINE_by_id("pkcs11");
227616b3ce2SRobin van der Gracht 	if (!e) {
228616b3ce2SRobin van der Gracht 		fprintf(stderr, "Cannot Load PKCS#11 ENGINE\n");
229616b3ce2SRobin van der Gracht 		return NULL;
230616b3ce2SRobin van der Gracht 	}
231616b3ce2SRobin van der Gracht 
232616b3ce2SRobin van der Gracht 	if (!ENGINE_init(e)) {
233616b3ce2SRobin van der Gracht 		fprintf(stderr, "Cannot ENGINE_init\n");
234616b3ce2SRobin van der Gracht 		goto err;
235616b3ce2SRobin van der Gracht 	}
236616b3ce2SRobin van der Gracht 
237616b3ce2SRobin van der Gracht 	key_pass = getenv("PKCS11_PIN");
238616b3ce2SRobin van der Gracht 	if (key_pass) {
239616b3ce2SRobin van der Gracht 		if (!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0)) {
240616b3ce2SRobin van der Gracht 			fprintf(stderr, "Cannot Set PKCS#11 PIN\n");
241616b3ce2SRobin van der Gracht 			goto err;
242616b3ce2SRobin van der Gracht 		}
243616b3ce2SRobin van der Gracht 	}
244616b3ce2SRobin van der Gracht 
245616b3ce2SRobin van der Gracht 	pkey = ENGINE_load_private_key(e, uri, NULL, NULL);
246616b3ce2SRobin van der Gracht 	if (pkey)
247616b3ce2SRobin van der Gracht 		return pkey;
248616b3ce2SRobin van der Gracht err:
249616b3ce2SRobin van der Gracht 	ENGINE_free(e);
250616b3ce2SRobin van der Gracht 	return NULL;
251616b3ce2SRobin van der Gracht 
252616b3ce2SRobin van der Gracht }
253616b3ce2SRobin van der Gracht 
key_load(cert_key_t * key)254ccbfd01dSManish V Badarkhe unsigned int key_load(cert_key_t *key)
2556f971622SJuan Castillo {
256bb3b0c0bSSandrine Bailleux 	if (key->fn == NULL) {
257bb3b0c0bSSandrine Bailleux 		VERBOSE("Key not specified\n");
258bb3b0c0bSSandrine Bailleux 		return KEY_ERR_FILENAME;
259bb3b0c0bSSandrine Bailleux 	}
2606f971622SJuan Castillo 
261bb3b0c0bSSandrine Bailleux 	if (strncmp(key->fn, "pkcs11:", 7) == 0) {
262616b3ce2SRobin van der Gracht 		/* Load key through pkcs11 */
263616b3ce2SRobin van der Gracht 		key->key = key_load_pkcs11(key->fn);
264616b3ce2SRobin van der Gracht 	} else {
2656f971622SJuan Castillo 		/* Load key from file */
266bb3b0c0bSSandrine Bailleux 		FILE *fp = fopen(key->fn, "r");
267bb3b0c0bSSandrine Bailleux 		if (fp == NULL) {
268616b3ce2SRobin van der Gracht 			WARN("Cannot open file %s\n", key->fn);
269bb3b0c0bSSandrine Bailleux 			return KEY_ERR_OPEN;
2706f971622SJuan Castillo 		}
2716f971622SJuan Castillo 
272bb3b0c0bSSandrine Bailleux 		key->key = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
273bb3b0c0bSSandrine Bailleux 		fclose(fp);
274bb3b0c0bSSandrine Bailleux 	}
275bb3b0c0bSSandrine Bailleux 
276bb3b0c0bSSandrine Bailleux 	if (key->key == NULL) {
277bb3b0c0bSSandrine Bailleux 		ERROR("Cannot load key from %s\n", key->fn);
278bb3b0c0bSSandrine Bailleux 		return KEY_ERR_LOAD;
279bb3b0c0bSSandrine Bailleux 	}
280bb3b0c0bSSandrine Bailleux 
281bb3b0c0bSSandrine Bailleux 	return KEY_ERR_NONE;
2826f971622SJuan Castillo }
2836f971622SJuan Castillo 
key_store(cert_key_t * key)284ccbfd01dSManish V Badarkhe int key_store(cert_key_t *key)
2856f971622SJuan Castillo {
286c893c733SMasahiro Yamada 	FILE *fp;
2876f971622SJuan Castillo 
2886f971622SJuan Castillo 	if (key->fn) {
289616b3ce2SRobin van der Gracht 		if (!strncmp(key->fn, "pkcs11:", 7)) {
290616b3ce2SRobin van der Gracht 			ERROR("PKCS11 URI provided instead of a file");
291616b3ce2SRobin van der Gracht 			return 0;
292616b3ce2SRobin van der Gracht 		}
2936f971622SJuan Castillo 		fp = fopen(key->fn, "w");
2946f971622SJuan Castillo 		if (fp) {
2956f971622SJuan Castillo 			PEM_write_PrivateKey(fp, key->key,
2966f971622SJuan Castillo 					NULL, NULL, 0, NULL, NULL);
2976f971622SJuan Castillo 			fclose(fp);
2986f971622SJuan Castillo 			return 1;
2996f971622SJuan Castillo 		} else {
3006f971622SJuan Castillo 			ERROR("Cannot create file %s\n", key->fn);
3016f971622SJuan Castillo 		}
3026f971622SJuan Castillo 	} else {
3036f971622SJuan Castillo 		ERROR("Key filename not specified\n");
3046f971622SJuan Castillo 	}
3056f971622SJuan Castillo 
3066f971622SJuan Castillo 	return 0;
3076f971622SJuan Castillo }
308ad2c1a9aSJuan Castillo 
key_init(void)309ad2c1a9aSJuan Castillo int key_init(void)
310ad2c1a9aSJuan Castillo {
311159807e2SJuan Castillo 	cmd_opt_t cmd_opt;
312ccbfd01dSManish V Badarkhe 	cert_key_t *key;
313ad2c1a9aSJuan Castillo 	unsigned int i;
314ad2c1a9aSJuan Castillo 
315b94bf967SPankaj Gupta 	keys = malloc((num_def_keys * sizeof(def_keys[0]))
316b94bf967SPankaj Gupta #ifdef PDEF_KEYS
317b94bf967SPankaj Gupta 		      + (num_pdef_keys * sizeof(pdef_keys[0]))
318b94bf967SPankaj Gupta #endif
319b94bf967SPankaj Gupta 		      );
320b94bf967SPankaj Gupta 
321b94bf967SPankaj Gupta 	if (keys == NULL) {
322b94bf967SPankaj Gupta 		ERROR("%s:%d Failed to allocate memory.\n", __func__, __LINE__);
323b94bf967SPankaj Gupta 		return 1;
324b94bf967SPankaj Gupta 	}
325b94bf967SPankaj Gupta 
326b94bf967SPankaj Gupta 	memcpy(&keys[0], &def_keys[0], (num_def_keys * sizeof(def_keys[0])));
327b94bf967SPankaj Gupta #ifdef PDEF_KEYS
328b94bf967SPankaj Gupta 	memcpy(&keys[num_def_keys], &pdef_keys[0],
329b94bf967SPankaj Gupta 		(num_pdef_keys * sizeof(pdef_keys[0])));
330b94bf967SPankaj Gupta 
331b94bf967SPankaj Gupta 	num_keys = num_def_keys + num_pdef_keys;
332b94bf967SPankaj Gupta #else
333b94bf967SPankaj Gupta 	num_keys = num_def_keys;
334b94bf967SPankaj Gupta #endif
335b94bf967SPankaj Gupta 		   ;
336b94bf967SPankaj Gupta 
337ad2c1a9aSJuan Castillo 	for (i = 0; i < num_keys; i++) {
338ad2c1a9aSJuan Castillo 		key = &keys[i];
339ad2c1a9aSJuan Castillo 		if (key->opt != NULL) {
340159807e2SJuan Castillo 			cmd_opt.long_opt.name = key->opt;
341159807e2SJuan Castillo 			cmd_opt.long_opt.has_arg = required_argument;
342159807e2SJuan Castillo 			cmd_opt.long_opt.flag = NULL;
343159807e2SJuan Castillo 			cmd_opt.long_opt.val = CMD_OPT_KEY;
344159807e2SJuan Castillo 			cmd_opt.help_msg = key->help_msg;
345159807e2SJuan Castillo 			cmd_opt_add(&cmd_opt);
346ad2c1a9aSJuan Castillo 		}
347ad2c1a9aSJuan Castillo 	}
348ad2c1a9aSJuan Castillo 
349c893c733SMasahiro Yamada 	return 0;
350ad2c1a9aSJuan Castillo }
351ad2c1a9aSJuan Castillo 
key_get_by_opt(const char * opt)352ccbfd01dSManish V Badarkhe cert_key_t *key_get_by_opt(const char *opt)
353ad2c1a9aSJuan Castillo {
354ccbfd01dSManish V Badarkhe 	cert_key_t *key;
355ad2c1a9aSJuan Castillo 	unsigned int i;
356ad2c1a9aSJuan Castillo 
357ad2c1a9aSJuan Castillo 	/* Sequential search. This is not a performance concern since the number
358ad2c1a9aSJuan Castillo 	 * of keys is bounded and the code runs on a host machine */
359ad2c1a9aSJuan Castillo 	for (i = 0; i < num_keys; i++) {
360ad2c1a9aSJuan Castillo 		key = &keys[i];
361ad2c1a9aSJuan Castillo 		if (0 == strcmp(key->opt, opt)) {
362ad2c1a9aSJuan Castillo 			return key;
363ad2c1a9aSJuan Castillo 		}
364ad2c1a9aSJuan Castillo 	}
365ad2c1a9aSJuan Castillo 
366ad2c1a9aSJuan Castillo 	return NULL;
367ad2c1a9aSJuan Castillo }
368cf2dd17dSJuan Pablo Conde 
key_cleanup(void)369cf2dd17dSJuan Pablo Conde void key_cleanup(void)
370cf2dd17dSJuan Pablo Conde {
371cf2dd17dSJuan Pablo Conde 	unsigned int i;
372cf2dd17dSJuan Pablo Conde 
373cf2dd17dSJuan Pablo Conde 	for (i = 0; i < num_keys; i++) {
374cf2dd17dSJuan Pablo Conde 		EVP_PKEY_free(keys[i].key);
375cf2dd17dSJuan Pablo Conde 		if (keys[i].fn != NULL) {
376cf2dd17dSJuan Pablo Conde 			void *ptr = keys[i].fn;
377cf2dd17dSJuan Pablo Conde 
378cf2dd17dSJuan Pablo Conde 			free(ptr);
379cf2dd17dSJuan Pablo Conde 			keys[i].fn = NULL;
380cf2dd17dSJuan Pablo Conde 		}
381cf2dd17dSJuan Pablo Conde 	}
382cf2dd17dSJuan Pablo Conde 	free(keys);
383cf2dd17dSJuan Pablo Conde }
384cf2dd17dSJuan Pablo Conde 
385