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