xref: /netbsd-src/external/mpl/bind/dist/lib/dns/openssl_link.c (revision bcda20f65a8566e103791ec395f7f499ef322704)
1*bcda20f6Schristos /*	$NetBSD: openssl_link.c,v 1.12 2025/01/26 16:25:23 christos Exp $	*/
2d68c78b8Schristos 
3d68c78b8Schristos /*
48596601aSchristos  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
58596601aSchristos  *
68596601aSchristos  * SPDX-License-Identifier: MPL-2.0 AND ISC
7d68c78b8Schristos  *
8d68c78b8Schristos  * This Source Code Form is subject to the terms of the Mozilla Public
9d68c78b8Schristos  * License, v. 2.0. If a copy of the MPL was not distributed with this
10fce770bdSchristos  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
11d68c78b8Schristos  *
12d68c78b8Schristos  * See the COPYRIGHT file distributed with this work for additional
13d68c78b8Schristos  * information regarding copyright ownership.
148596601aSchristos  */
158596601aSchristos 
168596601aSchristos /*
178596601aSchristos  * Copyright (C) Network Associates, Inc.
18d68c78b8Schristos  *
19d68c78b8Schristos  * Permission to use, copy, modify, and/or distribute this software for any
20d68c78b8Schristos  * purpose with or without fee is hereby granted, provided that the above
21d68c78b8Schristos  * copyright notice and this permission notice appear in all copies.
22d68c78b8Schristos  *
23d68c78b8Schristos  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
24d68c78b8Schristos  * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
25d68c78b8Schristos  * WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE
26d68c78b8Schristos  * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
27d68c78b8Schristos  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
28d68c78b8Schristos  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
29d68c78b8Schristos  * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
30d68c78b8Schristos  */
31d68c78b8Schristos 
32*bcda20f6Schristos #include <isc/fips.h>
33d68c78b8Schristos #include <isc/mem.h>
34d68c78b8Schristos #include <isc/mutex.h>
35d68c78b8Schristos #include <isc/mutexblock.h>
36bb5aa156Schristos #include <isc/result.h>
37d68c78b8Schristos #include <isc/string.h>
38d68c78b8Schristos #include <isc/thread.h>
39bb5aa156Schristos #include <isc/tls.h>
40d68c78b8Schristos #include <isc/util.h>
41d68c78b8Schristos 
42d68c78b8Schristos #include <dns/log.h>
43d68c78b8Schristos 
44d68c78b8Schristos #include "dst_internal.h"
45d68c78b8Schristos #include "dst_openssl.h"
46d68c78b8Schristos 
47bb5aa156Schristos #if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000
48d68c78b8Schristos #include <openssl/engine.h>
49bb5aa156Schristos #endif /* if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000 */
50*bcda20f6Schristos #if OPENSSL_VERSION_NUMBER >= 0x30000000L
51*bcda20f6Schristos #include <openssl/core_names.h>
52*bcda20f6Schristos #include <openssl/store.h>
53*bcda20f6Schristos #endif
54d68c78b8Schristos 
55bb5aa156Schristos #include "openssl_shim.h"
56bb5aa156Schristos 
57*bcda20f6Schristos #define DST_RET(a)        \
58*bcda20f6Schristos 	{                 \
59*bcda20f6Schristos 		ret = a;  \
60*bcda20f6Schristos 		goto err; \
61*bcda20f6Schristos 	}
62*bcda20f6Schristos 
63bb5aa156Schristos #if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000
64*bcda20f6Schristos static ENGINE *global_engine = NULL;
65bb5aa156Schristos #endif /* if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000 */
66d68c78b8Schristos 
67d4a20c3eSchristos static void
68d4a20c3eSchristos enable_fips_mode(void) {
69*bcda20f6Schristos #if defined(ENABLE_FIPS_MODE)
70*bcda20f6Schristos 	if (isc_fips_mode()) {
71d4a20c3eSchristos 		/*
72d4a20c3eSchristos 		 * FIPS mode is already enabled.
73d4a20c3eSchristos 		 */
74d4a20c3eSchristos 		return;
75d68c78b8Schristos 	}
76d68c78b8Schristos 
77*bcda20f6Schristos 	if (isc_fips_set_mode(1) != ISC_R_SUCCESS) {
78d4a20c3eSchristos 		dst__openssl_toresult2("FIPS_mode_set", DST_R_OPENSSLFAILURE);
79dff692fcSchristos 		exit(EXIT_FAILURE);
80d68c78b8Schristos 	}
81*bcda20f6Schristos #endif
82d68c78b8Schristos }
83d68c78b8Schristos 
84d68c78b8Schristos isc_result_t
8599a1c298Schristos dst__openssl_init(const char *engine) {
86d4a20c3eSchristos 	enable_fips_mode();
87d4a20c3eSchristos 
885606745fSchristos 	if (engine != NULL && *engine == '\0') {
89d68c78b8Schristos 		engine = NULL;
905606745fSchristos 	}
91d68c78b8Schristos 
92*bcda20f6Schristos 	if (engine == NULL) {
93*bcda20f6Schristos 		return ISC_R_SUCCESS;
94*bcda20f6Schristos 	}
95*bcda20f6Schristos 
96*bcda20f6Schristos #if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000
97*bcda20f6Schristos 	global_engine = ENGINE_by_id(engine);
98*bcda20f6Schristos 	if (global_engine == NULL) {
99d68c78b8Schristos 		goto cleanup_rm;
100d68c78b8Schristos 	}
101*bcda20f6Schristos 	if (!ENGINE_init(global_engine)) {
102bb5aa156Schristos 		goto cleanup_rm;
103bb5aa156Schristos 	}
104d68c78b8Schristos 	/* This will init the engine. */
105*bcda20f6Schristos 	if (!ENGINE_set_default(global_engine, ENGINE_METHOD_ALL)) {
106bb5aa156Schristos 		goto cleanup_init;
107d68c78b8Schristos 	}
108*bcda20f6Schristos 	return ISC_R_SUCCESS;
109bb5aa156Schristos cleanup_init:
110*bcda20f6Schristos 	ENGINE_finish(global_engine);
111d68c78b8Schristos cleanup_rm:
112*bcda20f6Schristos 	if (global_engine != NULL) {
113*bcda20f6Schristos 		ENGINE_free(global_engine);
1145606745fSchristos 	}
115bb5aa156Schristos 	ERR_clear_error();
116*bcda20f6Schristos 	global_engine = NULL;
117bb5aa156Schristos #endif /* if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000 */
118*bcda20f6Schristos 	return DST_R_NOENGINE;
119d68c78b8Schristos }
120d68c78b8Schristos 
121d68c78b8Schristos void
122d68c78b8Schristos dst__openssl_destroy(void) {
123bb5aa156Schristos #if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000
124*bcda20f6Schristos 	if (global_engine != NULL) {
125*bcda20f6Schristos 		ENGINE_finish(global_engine);
126*bcda20f6Schristos 		ENGINE_free(global_engine);
1275606745fSchristos 	}
128*bcda20f6Schristos 	global_engine = NULL;
129bb5aa156Schristos #endif /* if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000 */
130d68c78b8Schristos }
131d68c78b8Schristos 
132d68c78b8Schristos static isc_result_t
133d68c78b8Schristos toresult(isc_result_t fallback) {
134d68c78b8Schristos 	isc_result_t result = fallback;
135d4a20c3eSchristos 	unsigned long err = ERR_peek_error();
136d4a20c3eSchristos #if defined(ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED)
137d68c78b8Schristos 	int lib = ERR_GET_LIB(err);
1385606745fSchristos #endif /* if defined(ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED) */
139d68c78b8Schristos 	int reason = ERR_GET_REASON(err);
140d68c78b8Schristos 
141d68c78b8Schristos 	switch (reason) {
142d68c78b8Schristos 	/*
143d68c78b8Schristos 	 * ERR_* errors are globally unique; others
144d68c78b8Schristos 	 * are unique per sublibrary
145d68c78b8Schristos 	 */
146d68c78b8Schristos 	case ERR_R_MALLOC_FAILURE:
147d68c78b8Schristos 		result = ISC_R_NOMEMORY;
148d68c78b8Schristos 		break;
149d68c78b8Schristos 	default:
150d4a20c3eSchristos #if defined(ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED)
151d68c78b8Schristos 		if (lib == ERR_R_ECDSA_LIB &&
152903adeddSchristos 		    reason == ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED)
153903adeddSchristos 		{
154d68c78b8Schristos 			result = ISC_R_NOENTROPY;
155d68c78b8Schristos 			break;
156d68c78b8Schristos 		}
1575606745fSchristos #endif /* if defined(ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED) */
158d68c78b8Schristos 		break;
159d68c78b8Schristos 	}
160d68c78b8Schristos 
161*bcda20f6Schristos 	return result;
162d68c78b8Schristos }
163d68c78b8Schristos 
164d68c78b8Schristos isc_result_t
165d68c78b8Schristos dst__openssl_toresult(isc_result_t fallback) {
166d68c78b8Schristos 	isc_result_t result;
167d68c78b8Schristos 
168d68c78b8Schristos 	result = toresult(fallback);
169d68c78b8Schristos 
170d68c78b8Schristos 	ERR_clear_error();
171*bcda20f6Schristos 	return result;
172d68c78b8Schristos }
173d68c78b8Schristos 
174d68c78b8Schristos isc_result_t
175*bcda20f6Schristos dst___openssl_toresult2(const char *funcname, isc_result_t fallback,
176*bcda20f6Schristos 			const char *file, int line) {
177*bcda20f6Schristos 	return dst___openssl_toresult3(DNS_LOGCATEGORY_GENERAL, funcname,
178*bcda20f6Schristos 				       fallback, file, line);
179d68c78b8Schristos }
180d68c78b8Schristos 
181d68c78b8Schristos isc_result_t
182*bcda20f6Schristos dst___openssl_toresult3(isc_logcategory_t *category, const char *funcname,
183*bcda20f6Schristos 			isc_result_t fallback, const char *file, int line) {
184d68c78b8Schristos 	isc_result_t result;
185d68c78b8Schristos 	unsigned long err;
186*bcda20f6Schristos 	const char *func, *data;
187*bcda20f6Schristos 	int flags;
188d68c78b8Schristos 	char buf[256];
189d68c78b8Schristos 
190d68c78b8Schristos 	result = toresult(fallback);
191d68c78b8Schristos 
1925606745fSchristos 	isc_log_write(dns_lctx, category, DNS_LOGMODULE_CRYPTO, ISC_LOG_WARNING,
193*bcda20f6Schristos 		      "%s (%s:%d) failed (%s)", funcname, file, line,
194*bcda20f6Schristos 		      isc_result_totext(result));
195d68c78b8Schristos 
1965606745fSchristos 	if (result == ISC_R_NOMEMORY) {
197d68c78b8Schristos 		goto done;
1985606745fSchristos 	}
199d68c78b8Schristos 
200d68c78b8Schristos 	for (;;) {
201bb5aa156Schristos 		err = ERR_get_error_all(&file, &line, &func, &data, &flags);
2025606745fSchristos 		if (err == 0U) {
203d68c78b8Schristos 			goto done;
2045606745fSchristos 		}
205d68c78b8Schristos 		ERR_error_string_n(err, buf, sizeof(buf));
2065606745fSchristos 		isc_log_write(dns_lctx, category, DNS_LOGMODULE_CRYPTO,
2075606745fSchristos 			      ISC_LOG_INFO, "%s:%s:%d:%s", buf, file, line,
208d4a20c3eSchristos 			      ((flags & ERR_TXT_STRING) != 0) ? data : "");
209d68c78b8Schristos 	}
210d68c78b8Schristos 
211d68c78b8Schristos done:
212d68c78b8Schristos 	ERR_clear_error();
213*bcda20f6Schristos 	return result;
214d68c78b8Schristos }
215d68c78b8Schristos 
216bb5aa156Schristos #if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000
217d68c78b8Schristos ENGINE *
218d68c78b8Schristos dst__openssl_getengine(const char *engine) {
2195606745fSchristos 	if (engine == NULL) {
220*bcda20f6Schristos 		return NULL;
221d68c78b8Schristos 	}
222*bcda20f6Schristos 	if (global_engine == NULL) {
223*bcda20f6Schristos 		return NULL;
2245606745fSchristos 	}
225*bcda20f6Schristos 	if (strcmp(engine, ENGINE_get_id(global_engine)) == 0) {
226*bcda20f6Schristos 		return global_engine;
2275606745fSchristos 	}
228*bcda20f6Schristos 	return NULL;
2295606745fSchristos }
230bb5aa156Schristos #endif /* if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000 */
231d68c78b8Schristos 
232*bcda20f6Schristos static isc_result_t
233*bcda20f6Schristos dst__openssl_fromlabel_engine(int key_base_id, const char *engine,
234*bcda20f6Schristos 			      const char *label, const char *pin,
235*bcda20f6Schristos 			      EVP_PKEY **ppub, EVP_PKEY **ppriv) {
236*bcda20f6Schristos #if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000
237*bcda20f6Schristos 	isc_result_t ret = ISC_R_SUCCESS;
238*bcda20f6Schristos 	ENGINE *e = NULL;
239*bcda20f6Schristos 
240*bcda20f6Schristos 	UNUSED(pin);
241*bcda20f6Schristos 
242*bcda20f6Schristos 	e = dst__openssl_getengine(engine);
243*bcda20f6Schristos 	if (e == NULL) {
244*bcda20f6Schristos 		DST_RET(dst__openssl_toresult(DST_R_NOENGINE));
245*bcda20f6Schristos 	}
246*bcda20f6Schristos 
247*bcda20f6Schristos 	*ppub = ENGINE_load_public_key(e, label, NULL, NULL);
248*bcda20f6Schristos 	if (*ppub == NULL) {
249*bcda20f6Schristos 		DST_RET(dst__openssl_toresult2("ENGINE_load_public_key",
250*bcda20f6Schristos 					       DST_R_OPENSSLFAILURE));
251*bcda20f6Schristos 	}
252*bcda20f6Schristos 	if (EVP_PKEY_base_id(*ppub) != key_base_id) {
253*bcda20f6Schristos 		DST_RET(DST_R_BADKEYTYPE);
254*bcda20f6Schristos 	}
255*bcda20f6Schristos 
256*bcda20f6Schristos 	*ppriv = ENGINE_load_private_key(e, label, NULL, NULL);
257*bcda20f6Schristos 	if (*ppriv == NULL) {
258*bcda20f6Schristos 		DST_RET(dst__openssl_toresult2("ENGINE_load_private_key",
259*bcda20f6Schristos 					       DST_R_OPENSSLFAILURE));
260*bcda20f6Schristos 	}
261*bcda20f6Schristos 	if (EVP_PKEY_base_id(*ppriv) != key_base_id) {
262*bcda20f6Schristos 		DST_RET(DST_R_BADKEYTYPE);
263*bcda20f6Schristos 	}
264*bcda20f6Schristos err:
265*bcda20f6Schristos 	return ret;
266*bcda20f6Schristos #else  /* if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000 */
267*bcda20f6Schristos 	UNUSED(key_base_id);
268*bcda20f6Schristos 	UNUSED(engine);
269*bcda20f6Schristos 	UNUSED(label);
270*bcda20f6Schristos 	UNUSED(pin);
271*bcda20f6Schristos 	UNUSED(ppub);
272*bcda20f6Schristos 	UNUSED(ppriv);
273*bcda20f6Schristos 	return DST_R_NOENGINE;
274*bcda20f6Schristos #endif /* if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000 */
275*bcda20f6Schristos }
276*bcda20f6Schristos 
277*bcda20f6Schristos static isc_result_t
278*bcda20f6Schristos dst__openssl_fromlabel_provider(int key_base_id, const char *label,
279*bcda20f6Schristos 				const char *pin, EVP_PKEY **ppub,
280*bcda20f6Schristos 				EVP_PKEY **ppriv) {
281*bcda20f6Schristos #if OPENSSL_VERSION_NUMBER >= 0x30000000L
282*bcda20f6Schristos 	isc_result_t ret = DST_R_OPENSSLFAILURE;
283*bcda20f6Schristos 	OSSL_STORE_CTX *ctx = NULL;
284*bcda20f6Schristos 
285*bcda20f6Schristos 	UNUSED(pin);
286*bcda20f6Schristos 
287*bcda20f6Schristos 	ctx = OSSL_STORE_open(label, NULL, NULL, NULL, NULL);
288*bcda20f6Schristos 	if (!ctx) {
289*bcda20f6Schristos 		DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
290*bcda20f6Schristos 	}
291*bcda20f6Schristos 
292*bcda20f6Schristos 	while (!OSSL_STORE_eof(ctx)) {
293*bcda20f6Schristos 		OSSL_STORE_INFO *info = OSSL_STORE_load(ctx);
294*bcda20f6Schristos 		if (info == NULL) {
295*bcda20f6Schristos 			continue;
296*bcda20f6Schristos 		}
297*bcda20f6Schristos 		switch (OSSL_STORE_INFO_get_type(info)) {
298*bcda20f6Schristos 		case OSSL_STORE_INFO_PKEY:
299*bcda20f6Schristos 			if (*ppriv != NULL) {
300*bcda20f6Schristos 				OSSL_STORE_INFO_free(info);
301*bcda20f6Schristos 				DST_RET(DST_R_INVALIDPRIVATEKEY);
302*bcda20f6Schristos 			}
303*bcda20f6Schristos 			*ppriv = OSSL_STORE_INFO_get1_PKEY(info);
304*bcda20f6Schristos 			if (EVP_PKEY_get_base_id(*ppriv) != key_base_id) {
305*bcda20f6Schristos 				OSSL_STORE_INFO_free(info);
306*bcda20f6Schristos 				DST_RET(DST_R_BADKEYTYPE);
307*bcda20f6Schristos 			}
308*bcda20f6Schristos 			break;
309*bcda20f6Schristos 		case OSSL_STORE_INFO_PUBKEY:
310*bcda20f6Schristos 			if (*ppub != NULL) {
311*bcda20f6Schristos 				OSSL_STORE_INFO_free(info);
312*bcda20f6Schristos 				DST_RET(DST_R_INVALIDPUBLICKEY);
313*bcda20f6Schristos 			}
314*bcda20f6Schristos 			*ppub = OSSL_STORE_INFO_get1_PUBKEY(info);
315*bcda20f6Schristos 			if (EVP_PKEY_get_base_id(*ppub) != key_base_id) {
316*bcda20f6Schristos 				OSSL_STORE_INFO_free(info);
317*bcda20f6Schristos 				DST_RET(DST_R_BADKEYTYPE);
318*bcda20f6Schristos 			}
319*bcda20f6Schristos 			break;
320*bcda20f6Schristos 		}
321*bcda20f6Schristos 		OSSL_STORE_INFO_free(info);
322*bcda20f6Schristos 	}
323*bcda20f6Schristos 	if (*ppriv != NULL && *ppub != NULL) {
324*bcda20f6Schristos 		ret = ISC_R_SUCCESS;
325*bcda20f6Schristos 	}
326*bcda20f6Schristos err:
327*bcda20f6Schristos 	OSSL_STORE_close(ctx);
328*bcda20f6Schristos 	return ret;
329*bcda20f6Schristos #else
330*bcda20f6Schristos 	UNUSED(key_base_id);
331*bcda20f6Schristos 	UNUSED(label);
332*bcda20f6Schristos 	UNUSED(pin);
333*bcda20f6Schristos 	UNUSED(ppub);
334*bcda20f6Schristos 	UNUSED(ppriv);
335*bcda20f6Schristos 	return DST_R_OPENSSLFAILURE;
336*bcda20f6Schristos #endif
337*bcda20f6Schristos }
338*bcda20f6Schristos 
339*bcda20f6Schristos isc_result_t
340*bcda20f6Schristos dst__openssl_fromlabel(int key_base_id, const char *engine, const char *label,
341*bcda20f6Schristos 		       const char *pin, EVP_PKEY **ppub, EVP_PKEY **ppriv) {
342*bcda20f6Schristos 	if (engine == NULL) {
343*bcda20f6Schristos 		return dst__openssl_fromlabel_provider(key_base_id, label, pin,
344*bcda20f6Schristos 						       ppub, ppriv);
345*bcda20f6Schristos 	}
346*bcda20f6Schristos 
347*bcda20f6Schristos 	if (*ppub != NULL) {
348*bcda20f6Schristos 		EVP_PKEY_free(*ppub);
349*bcda20f6Schristos 		*ppub = NULL;
350*bcda20f6Schristos 	}
351*bcda20f6Schristos 
352*bcda20f6Schristos 	if (*ppriv != NULL) {
353*bcda20f6Schristos 		EVP_PKEY_free(*ppriv);
354*bcda20f6Schristos 		*ppriv = NULL;
355*bcda20f6Schristos 	}
356*bcda20f6Schristos 
357*bcda20f6Schristos 	return dst__openssl_fromlabel_engine(key_base_id, engine, label, pin,
358*bcda20f6Schristos 					     ppub, ppriv);
359*bcda20f6Schristos }
360*bcda20f6Schristos 
361*bcda20f6Schristos bool
362*bcda20f6Schristos dst__openssl_keypair_compare(const dst_key_t *key1, const dst_key_t *key2) {
363*bcda20f6Schristos 	EVP_PKEY *pkey1 = key1->keydata.pkeypair.pub;
364*bcda20f6Schristos 	EVP_PKEY *pkey2 = key2->keydata.pkeypair.pub;
365*bcda20f6Schristos 
366*bcda20f6Schristos 	if (pkey1 == pkey2) {
367*bcda20f6Schristos 		return true;
368*bcda20f6Schristos 	} else if (pkey1 == NULL || pkey2 == NULL) {
369*bcda20f6Schristos 		return false;
370*bcda20f6Schristos 	}
371*bcda20f6Schristos 
372*bcda20f6Schristos 	/* `EVP_PKEY_eq` checks only the public components and parameters. */
373*bcda20f6Schristos 	if (EVP_PKEY_eq(pkey1, pkey2) != 1) {
374*bcda20f6Schristos 		return false;
375*bcda20f6Schristos 	}
376*bcda20f6Schristos 	/* The private key presence must be same for keys to match. */
377*bcda20f6Schristos 	if ((key1->keydata.pkeypair.priv != NULL) !=
378*bcda20f6Schristos 	    (key2->keydata.pkeypair.priv != NULL))
379*bcda20f6Schristos 	{
380*bcda20f6Schristos 		return false;
381*bcda20f6Schristos 	}
382*bcda20f6Schristos 	return true;
383*bcda20f6Schristos }
384*bcda20f6Schristos 
385*bcda20f6Schristos bool
386*bcda20f6Schristos dst__openssl_keypair_isprivate(const dst_key_t *key) {
387*bcda20f6Schristos 	return key->keydata.pkeypair.priv != NULL;
388*bcda20f6Schristos }
389*bcda20f6Schristos 
390*bcda20f6Schristos void
391*bcda20f6Schristos dst__openssl_keypair_destroy(dst_key_t *key) {
392*bcda20f6Schristos 	if (key->keydata.pkeypair.priv != key->keydata.pkeypair.pub) {
393*bcda20f6Schristos 		EVP_PKEY_free(key->keydata.pkeypair.priv);
394*bcda20f6Schristos 	}
395*bcda20f6Schristos 	EVP_PKEY_free(key->keydata.pkeypair.pub);
396*bcda20f6Schristos 	key->keydata.pkeypair.pub = NULL;
397*bcda20f6Schristos 	key->keydata.pkeypair.priv = NULL;
398*bcda20f6Schristos }
399*bcda20f6Schristos 
400d68c78b8Schristos /*! \file */
401