2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-22 10:10:06 +00:00
bind/lib/dns/openssleddsa_link.c
Ondřej Surý 288f5a4b52 Various little fixes found by coccinelle
The coccinellery repository provides many little semantic patches to fix common
problems in the code.  The number of semantic patches in the coccinellery
repository is high and most of the semantic patches apply only for Linux, so it
doesn't make sense to run them on regular basis as the processing takes a lot of
time.

The list of issue found in BIND 9, by no means complete, includes:

- double assignment to a variable
- `continue` at the end of the loop
- double checks for `NULL`
- useless checks for `NULL` (cannot be `NULL`, because of earlier return)
- using `0` instead of `NULL`
- useless extra condition (`if (foo) return; if (!foo) { ...; }`)
- removing & in front of static functions passed as arguments
2019-10-01 16:48:55 +02:00

759 lines
18 KiB
C

/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
#if !USE_PKCS11
#if HAVE_OPENSSL_ED25519 || HAVE_OPENSSL_ED448
#include <stdbool.h>
#include <isc/mem.h>
#include <isc/safe.h>
#include <isc/result.h>
#include <isc/string.h>
#include <isc/util.h>
#include <dns/keyvalues.h>
#include <dst/result.h>
#include "dst_internal.h"
#include "dst_openssl.h"
#include "dst_parse.h"
#include <openssl/err.h>
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include "openssl_shim.h"
#define DST_RET(a) {ret = a; goto err;}
#if HAVE_OPENSSL_ED25519
#ifndef NID_ED25519
#error "Ed25519 group is not known (NID_ED25519)"
#endif
/* OpenSSL doesn't provide direct access to key values */
#define PUBPREFIXLEN 12
static const unsigned char ed25519_pub_prefix[] = {
0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65,
0x70, 0x03, 0x21, 0x00
};
static EVP_PKEY *pub_ed25519_to_ossl(const unsigned char *key)
{
unsigned char buf[PUBPREFIXLEN + DNS_KEY_ED25519SIZE];
const unsigned char *p;
memmove(buf, ed25519_pub_prefix, PUBPREFIXLEN);
memmove(buf + PUBPREFIXLEN, key, DNS_KEY_ED25519SIZE);
p = buf;
return (d2i_PUBKEY(NULL, &p, PUBPREFIXLEN + DNS_KEY_ED25519SIZE));
}
static isc_result_t pub_ed25519_from_ossl(EVP_PKEY *pkey,
unsigned char *key)
{
unsigned char buf[PUBPREFIXLEN + DNS_KEY_ED25519SIZE];
unsigned char *p;
int len;
len = i2d_PUBKEY(pkey, NULL);
if ((len <= DNS_KEY_ED25519SIZE) ||
(len > PUBPREFIXLEN + DNS_KEY_ED25519SIZE))
return (DST_R_OPENSSLFAILURE);
p = buf;
len = i2d_PUBKEY(pkey, &p);
if ((len <= DNS_KEY_ED25519SIZE) ||
(len > PUBPREFIXLEN + DNS_KEY_ED25519SIZE))
return (DST_R_OPENSSLFAILURE);
memmove(key, buf + len - DNS_KEY_ED25519SIZE, DNS_KEY_ED25519SIZE);
return (ISC_R_SUCCESS);
}
#define PRIVPREFIXLEN 16
static const unsigned char ed25519_priv_prefix[] = {
0x30, 0x2e, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06,
0x03, 0x2b, 0x65, 0x70, 0x04, 0x22, 0x04, 0x20
};
static EVP_PKEY *priv_ed25519_to_ossl(const unsigned char *key)
{
unsigned char buf[PRIVPREFIXLEN + DNS_KEY_ED25519SIZE];
const unsigned char *p;
memmove(buf, ed25519_priv_prefix, PRIVPREFIXLEN);
memmove(buf + PRIVPREFIXLEN, key, DNS_KEY_ED25519SIZE);
p = buf;
return (d2i_PrivateKey(NID_ED25519, NULL, &p,
PRIVPREFIXLEN + DNS_KEY_ED25519SIZE));
}
static isc_result_t priv_ed25519_from_ossl(EVP_PKEY *pkey,
unsigned char *key)
{
unsigned char buf[PRIVPREFIXLEN + DNS_KEY_ED25519SIZE];
unsigned char *p;
int len;
len = i2d_PrivateKey(pkey, NULL);
if ((len <= DNS_KEY_ED25519SIZE) ||
(len > PRIVPREFIXLEN + DNS_KEY_ED25519SIZE))
return (DST_R_OPENSSLFAILURE);
p = buf;
len = i2d_PrivateKey(pkey, &p);
if ((len <= DNS_KEY_ED25519SIZE) ||
(len > PRIVPREFIXLEN + DNS_KEY_ED25519SIZE))
return (DST_R_OPENSSLFAILURE);
memmove(key, buf + len - DNS_KEY_ED25519SIZE, DNS_KEY_ED25519SIZE);
return (ISC_R_SUCCESS);
}
#else /* HAVE_OPENSSL_ED25519 */
static EVP_PKEY *
pub_ed25519_to_ossl(const unsigned char *key)
{
UNUSED(key);
return (NULL);
}
static isc_result_t
pub_ed25519_from_ossl(EVP_PKEY *pkey, unsigned char *key)
{
UNUSED(pkey);
UNUSED(key);
return (ISC_R_NOTIMPLEMENTED);
}
static EVP_PKEY *
priv_ed25519_to_ossl(const unsigned char *key)
{
UNUSED(key);
return (NULL);
}
static isc_result_t
priv_ed25519_from_ossl(EVP_PKEY *pkey, unsigned char *key) {
UNUSED(pkey);
UNUSED(key);
return (ISC_R_NOTIMPLEMENTED);
}
#endif /* HAVE_OPENSSL_ED25519 */
#if HAVE_OPENSSL_ED448
#ifndef NID_ED448
#error "Ed448 group is not known (NID_ED448)"
#endif
static const unsigned char ed448_pub_prefix[] = {
0x30, 0x43, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65,
0x71, 0x03, 0x3a, 0x00
};
static EVP_PKEY *pub_ed448_to_ossl(const unsigned char *key)
{
unsigned char buf[PUBPREFIXLEN + DNS_KEY_ED448SIZE];
const unsigned char *p;
memmove(buf, ed448_pub_prefix, PUBPREFIXLEN);
memmove(buf + PUBPREFIXLEN, key, DNS_KEY_ED448SIZE);
p = buf;
return (d2i_PUBKEY(NULL, &p, PUBPREFIXLEN + DNS_KEY_ED448SIZE));
}
static isc_result_t pub_ed448_from_ossl(EVP_PKEY *pkey,
unsigned char *key)
{
unsigned char buf[PUBPREFIXLEN + DNS_KEY_ED448SIZE];
unsigned char *p;
int len;
len = i2d_PUBKEY(pkey, NULL);
if ((len <= DNS_KEY_ED448SIZE) ||
(len > PUBPREFIXLEN + DNS_KEY_ED448SIZE))
return (DST_R_OPENSSLFAILURE);
p = buf;
len = i2d_PUBKEY(pkey, &p);
if ((len <= DNS_KEY_ED448SIZE) ||
(len > PUBPREFIXLEN + DNS_KEY_ED448SIZE))
return (DST_R_OPENSSLFAILURE);
memmove(key, buf + len - DNS_KEY_ED448SIZE, DNS_KEY_ED448SIZE);
return (ISC_R_SUCCESS);
}
static const unsigned char ed448_priv_prefix[] = {
0x30, 0x47, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06,
0x03, 0x2b, 0x65, 0x71, 0x04, 0x3b, 0x04, 0x39
};
static EVP_PKEY *priv_ed448_to_ossl(const unsigned char *key)
{
unsigned char buf[PRIVPREFIXLEN + DNS_KEY_ED448SIZE];
const unsigned char *p;
memmove(buf, ed448_priv_prefix, PRIVPREFIXLEN);
memmove(buf + PRIVPREFIXLEN, key, DNS_KEY_ED448SIZE);
p = buf;
return (d2i_PrivateKey(NID_ED448, NULL, &p,
PRIVPREFIXLEN + DNS_KEY_ED448SIZE));
}
static isc_result_t priv_ed448_from_ossl(EVP_PKEY *pkey,
unsigned char *key)
{
unsigned char buf[PRIVPREFIXLEN + DNS_KEY_ED448SIZE];
unsigned char *p;
int len;
len = i2d_PrivateKey(pkey, NULL);
if ((len <= DNS_KEY_ED448SIZE) ||
(len > PRIVPREFIXLEN + DNS_KEY_ED448SIZE))
return (DST_R_OPENSSLFAILURE);
p = buf;
len = i2d_PrivateKey(pkey, &p);
if ((len <= DNS_KEY_ED448SIZE) ||
(len > PRIVPREFIXLEN + DNS_KEY_ED448SIZE))
return (DST_R_OPENSSLFAILURE);
memmove(key, buf + len - DNS_KEY_ED448SIZE, DNS_KEY_ED448SIZE);
return (ISC_R_SUCCESS);
}
#else /* HAVE_OPENSSL_ED448 */
static EVP_PKEY *
pub_ed448_to_ossl(const unsigned char *key)
{
UNUSED(key);
return (NULL);
}
static isc_result_t
pub_ed448_from_ossl(EVP_PKEY *pkey, unsigned char *key)
{
UNUSED(pkey);
UNUSED(key);
return (ISC_R_NOTIMPLEMENTED);
}
static EVP_PKEY *
priv_ed448_to_ossl(const unsigned char *key)
{
UNUSED(key);
return (NULL);
}
static isc_result_t
priv_ed448_from_ossl(EVP_PKEY *pkey, unsigned char *key) {
UNUSED(pkey);
UNUSED(key);
return (ISC_R_NOTIMPLEMENTED);
}
#endif /* HAVE_OPENSSL_ED448 */
static isc_result_t openssleddsa_todns(const dst_key_t *key,
isc_buffer_t *data);
static isc_result_t
openssleddsa_createctx(dst_key_t *key, dst_context_t *dctx) {
isc_buffer_t *buf = NULL;
isc_result_t result;
UNUSED(key);
REQUIRE(dctx->key->key_alg == DST_ALG_ED25519 ||
dctx->key->key_alg == DST_ALG_ED448);
result = isc_buffer_allocate(dctx->mctx, &buf, 64);
dctx->ctxdata.generic = buf;
return (result);
}
static void
openssleddsa_destroyctx(dst_context_t *dctx) {
isc_buffer_t *buf = (isc_buffer_t *) dctx->ctxdata.generic;
REQUIRE(dctx->key->key_alg == DST_ALG_ED25519 ||
dctx->key->key_alg == DST_ALG_ED448);
if (buf != NULL)
isc_buffer_free(&buf);
dctx->ctxdata.generic = NULL;
}
static isc_result_t
openssleddsa_adddata(dst_context_t *dctx, const isc_region_t *data) {
isc_buffer_t *buf = (isc_buffer_t *) dctx->ctxdata.generic;
isc_buffer_t *nbuf = NULL;
isc_region_t r;
unsigned int length;
isc_result_t result;
REQUIRE(dctx->key->key_alg == DST_ALG_ED25519 ||
dctx->key->key_alg == DST_ALG_ED448);
result = isc_buffer_copyregion(buf, data);
if (result == ISC_R_SUCCESS)
return (ISC_R_SUCCESS);
length = isc_buffer_length(buf) + data->length + 64;
result = isc_buffer_allocate(dctx->mctx, &nbuf, length);
if (result != ISC_R_SUCCESS)
return (result);
isc_buffer_usedregion(buf, &r);
(void) isc_buffer_copyregion(nbuf, &r);
(void) isc_buffer_copyregion(nbuf, data);
isc_buffer_free(&buf);
dctx->ctxdata.generic = nbuf;
return (ISC_R_SUCCESS);
}
static isc_result_t
openssleddsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
isc_result_t ret;
dst_key_t *key = dctx->key;
isc_region_t tbsreg;
isc_region_t sigreg;
EVP_PKEY *pkey = key->keydata.pkey;
EVP_MD_CTX* ctx = EVP_MD_CTX_new();
isc_buffer_t *buf = (isc_buffer_t *) dctx->ctxdata.generic;
size_t siglen;
REQUIRE(key->key_alg == DST_ALG_ED25519 ||
key->key_alg == DST_ALG_ED448);
if (ctx == NULL)
return (ISC_R_NOMEMORY);
if (key->key_alg == DST_ALG_ED25519)
siglen = DNS_SIG_ED25519SIZE;
else
siglen = DNS_SIG_ED448SIZE;
isc_buffer_availableregion(sig, &sigreg);
if (sigreg.length < (unsigned int) siglen)
DST_RET(ISC_R_NOSPACE);
isc_buffer_usedregion(buf, &tbsreg);
if (EVP_DigestSignInit(ctx, NULL, NULL, NULL, pkey) != 1) {
DST_RET(dst__openssl_toresult3(dctx->category,
"EVP_DigestSignInit",
ISC_R_FAILURE));
}
if (EVP_DigestSign(ctx, sigreg.base, &siglen,
tbsreg.base, tbsreg.length) != 1) {
DST_RET(dst__openssl_toresult3(dctx->category,
"EVP_DigestSign",
DST_R_SIGNFAILURE));
}
isc_buffer_add(sig, (unsigned int) siglen);
ret = ISC_R_SUCCESS;
err:
EVP_MD_CTX_free(ctx);
isc_buffer_free(&buf);
dctx->ctxdata.generic = NULL;
return (ret);
}
static isc_result_t
openssleddsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
isc_result_t ret;
dst_key_t *key = dctx->key;
int status;
isc_region_t tbsreg;
EVP_PKEY *pkey = key->keydata.pkey;
EVP_MD_CTX* ctx = EVP_MD_CTX_new();
isc_buffer_t *buf = (isc_buffer_t *) dctx->ctxdata.generic;
unsigned int siglen = 0;
REQUIRE(key->key_alg == DST_ALG_ED25519 ||
key->key_alg == DST_ALG_ED448);
if (ctx == NULL)
return (ISC_R_NOMEMORY);
#if HAVE_OPENSSL_ED25519
if (key->key_alg == DST_ALG_ED25519) {
siglen = DNS_SIG_ED25519SIZE;
}
#endif
#if HAVE_OPENSSL_ED448
if (key->key_alg == DST_ALG_ED448) {
siglen = DNS_SIG_ED448SIZE;
}
#endif
if (siglen == 0) {
return (ISC_R_NOTIMPLEMENTED);
}
if (sig->length != siglen)
return (DST_R_VERIFYFAILURE);
isc_buffer_usedregion(buf, &tbsreg);
if (EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, pkey) != 1) {
DST_RET(dst__openssl_toresult3(dctx->category,
"EVP_DigestVerifyInit",
ISC_R_FAILURE));
}
status = EVP_DigestVerify(ctx, sig->base, siglen,
tbsreg.base, tbsreg.length);
switch (status) {
case 1:
ret = ISC_R_SUCCESS;
break;
case 0:
ret = dst__openssl_toresult(DST_R_VERIFYFAILURE);
break;
default:
ret = dst__openssl_toresult3(dctx->category,
"EVP_DigestVerify",
DST_R_VERIFYFAILURE);
break;
}
err:
EVP_MD_CTX_free(ctx);
isc_buffer_free(&buf);
dctx->ctxdata.generic = NULL;
return (ret);
}
static bool
openssleddsa_compare(const dst_key_t *key1, const dst_key_t *key2) {
int status;
EVP_PKEY *pkey1 = key1->keydata.pkey;
EVP_PKEY *pkey2 = key2->keydata.pkey;
if (pkey1 == NULL && pkey2 == NULL)
return (true);
else if (pkey1 == NULL || pkey2 == NULL)
return (false);
status = EVP_PKEY_cmp(pkey1, pkey2);
if (status == 1)
return (true);
return (false);
}
static isc_result_t
openssleddsa_generate(dst_key_t *key, int unused, void (*callback)(int)) {
isc_result_t ret;
EVP_PKEY *pkey = NULL;
EVP_PKEY_CTX *ctx = NULL;
int nid = 0, status;
REQUIRE(key->key_alg == DST_ALG_ED25519 ||
key->key_alg == DST_ALG_ED448);
UNUSED(unused);
UNUSED(callback);
#if HAVE_OPENSSL_ED25519
if (key->key_alg == DST_ALG_ED25519) {
nid = NID_ED25519;
key->key_size = DNS_KEY_ED25519SIZE;
}
#endif
#if HAVE_OPENSSL_ED448
if (key->key_alg == DST_ALG_ED448) {
nid = NID_ED448;
key->key_size = DNS_KEY_ED448SIZE;
}
#endif
if (nid == 0) {
return (ISC_R_NOTIMPLEMENTED);
}
ctx = EVP_PKEY_CTX_new_id(nid, NULL);
if (ctx == NULL)
return (dst__openssl_toresult2("EVP_PKEY_CTX_new_id",
DST_R_OPENSSLFAILURE));
status = EVP_PKEY_keygen_init(ctx);
if (status != 1)
DST_RET (dst__openssl_toresult2("EVP_PKEY_keygen_init",
DST_R_OPENSSLFAILURE));
status = EVP_PKEY_keygen(ctx, &pkey);
if (status != 1)
DST_RET (dst__openssl_toresult2("EVP_PKEY_keygen",
DST_R_OPENSSLFAILURE));
key->keydata.pkey = pkey;
ret = ISC_R_SUCCESS;
err:
EVP_PKEY_CTX_free(ctx);
return (ret);
}
static bool
openssleddsa_isprivate(const dst_key_t *key) {
EVP_PKEY *pkey = key->keydata.pkey;
int len;
unsigned long err;
if (pkey == NULL)
return (false);
len = i2d_PrivateKey(pkey, NULL);
if (len > 0)
return (true);
/* can check if first error is EC_R_INVALID_PRIVATE_KEY */
while ((err = ERR_get_error()) != 0)
/**/;
return (false);
}
static void
openssleddsa_destroy(dst_key_t *key) {
EVP_PKEY *pkey = key->keydata.pkey;
EVP_PKEY_free(pkey);
key->keydata.pkey = NULL;
}
static isc_result_t
openssleddsa_todns(const dst_key_t *key, isc_buffer_t *data) {
EVP_PKEY *pkey = key->keydata.pkey;
isc_region_t r;
isc_result_t result;
REQUIRE(pkey != NULL);
pkey = key->keydata.pkey;
switch (key->key_alg) {
case DST_ALG_ED25519:
isc_buffer_availableregion(data, &r);
if (r.length < DNS_KEY_ED25519SIZE)
return (ISC_R_NOSPACE);
result = pub_ed25519_from_ossl(pkey, r.base);
if (result == ISC_R_SUCCESS)
isc_buffer_add(data, DNS_KEY_ED25519SIZE);
return (result);
case DST_ALG_ED448:
isc_buffer_availableregion(data, &r);
if (r.length < DNS_KEY_ED448SIZE)
return (ISC_R_NOSPACE);
result = pub_ed448_from_ossl(pkey, r.base);
if (result == ISC_R_SUCCESS)
isc_buffer_add(data, DNS_KEY_ED448SIZE);
return (result);
default:
INSIST(0);
ISC_UNREACHABLE();
}
}
static isc_result_t
openssleddsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
EVP_PKEY *pkey;
isc_region_t r;
unsigned int len;
REQUIRE(key->key_alg == DST_ALG_ED25519 ||
key->key_alg == DST_ALG_ED448);
isc_buffer_remainingregion(data, &r);
if (r.length == 0)
return (ISC_R_SUCCESS);
if (key->key_alg == DST_ALG_ED25519) {
len = DNS_KEY_ED25519SIZE;
if (r.length < len)
return (DST_R_INVALIDPUBLICKEY);
pkey = pub_ed25519_to_ossl(r.base);
} else {
len = DNS_KEY_ED448SIZE;
if (r.length < len)
return (DST_R_INVALIDPUBLICKEY);
pkey = pub_ed448_to_ossl(r.base);
}
if (pkey == NULL)
return (dst__openssl_toresult(ISC_R_FAILURE));
isc_buffer_forward(data, len);
key->keydata.pkey = pkey;
key->key_size = len;
return (ISC_R_SUCCESS);
}
static isc_result_t
openssleddsa_tofile(const dst_key_t *key, const char *directory) {
isc_result_t ret;
EVP_PKEY *pkey;
dst_private_t priv;
unsigned char *buf = NULL;
unsigned int len;
REQUIRE(key->key_alg == DST_ALG_ED25519 ||
key->key_alg == DST_ALG_ED448);
if (key->keydata.pkey == NULL)
return (DST_R_NULLKEY);
if (key->external) {
priv.nelements = 0;
return (dst__privstruct_writefile(key, &priv, directory));
}
pkey = key->keydata.pkey;
if (key->key_alg == DST_ALG_ED25519) {
len = DNS_KEY_ED25519SIZE;
buf = isc_mem_get(key->mctx, len);
priv.elements[0].tag = TAG_EDDSA_PRIVATEKEY;
priv.elements[0].length = len;
ret = priv_ed25519_from_ossl(pkey, buf);
if (ret != ISC_R_SUCCESS)
DST_RET (dst__openssl_toresult(ret));
priv.elements[0].data = buf;
priv.nelements = 1;
ret = dst__privstruct_writefile(key, &priv, directory);
} else {
len = DNS_KEY_ED448SIZE;
buf = isc_mem_get(key->mctx, len);
priv.elements[0].tag = TAG_EDDSA_PRIVATEKEY;
priv.elements[0].length = len;
ret = priv_ed448_from_ossl(pkey, buf);
if (ret != ISC_R_SUCCESS)
DST_RET (dst__openssl_toresult(ret));
priv.elements[0].data = buf;
priv.nelements = 1;
ret = dst__privstruct_writefile(key, &priv, directory);
}
err:
if (buf != NULL)
isc_mem_put(key->mctx, buf, len);
return (ret);
}
static isc_result_t
eddsa_check(EVP_PKEY *privkey, dst_key_t *pub)
{
EVP_PKEY *pkey;
if (pub == NULL)
return (ISC_R_SUCCESS);
pkey = pub->keydata.pkey;
if (pkey == NULL)
return (ISC_R_SUCCESS);
if (EVP_PKEY_cmp(privkey, pkey) == 1)
return (ISC_R_SUCCESS);
return (ISC_R_FAILURE);
}
static isc_result_t
openssleddsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
dst_private_t priv;
isc_result_t ret;
EVP_PKEY *pkey = NULL;
unsigned int len;
isc_mem_t *mctx = key->mctx;
REQUIRE(key->key_alg == DST_ALG_ED25519 ||
key->key_alg == DST_ALG_ED448);
/* read private key file */
ret = dst__privstruct_parse(key, DST_ALG_ED25519, lexer, mctx, &priv);
if (ret != ISC_R_SUCCESS)
goto err;
if (key->external) {
if (priv.nelements != 0)
DST_RET(DST_R_INVALIDPRIVATEKEY);
if (pub == NULL)
DST_RET(DST_R_INVALIDPRIVATEKEY);
key->keydata.pkey = pub->keydata.pkey;
pub->keydata.pkey = NULL;
dst__privstruct_free(&priv, mctx);
isc_safe_memwipe(&priv, sizeof(priv));
return (ISC_R_SUCCESS);
}
if (key->key_alg == DST_ALG_ED25519) {
len = DNS_KEY_ED25519SIZE;
if (priv.elements[0].length < len)
DST_RET(DST_R_INVALIDPRIVATEKEY);
pkey = priv_ed25519_to_ossl(priv.elements[0].data);
} else {
len = DNS_KEY_ED448SIZE;
if (priv.elements[0].length < len)
DST_RET(DST_R_INVALIDPRIVATEKEY);
pkey = priv_ed448_to_ossl(priv.elements[0].data);
}
if (pkey == NULL)
DST_RET (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
if (eddsa_check(pkey, pub) != ISC_R_SUCCESS) {
EVP_PKEY_free(pkey);
DST_RET(DST_R_INVALIDPRIVATEKEY);
}
key->keydata.pkey = pkey;
key->key_size = len;
ret = ISC_R_SUCCESS;
err:
dst__privstruct_free(&priv, mctx);
isc_safe_memwipe(&priv, sizeof(priv));
return (ret);
}
static dst_func_t openssleddsa_functions = {
openssleddsa_createctx,
NULL, /*%< createctx2 */
openssleddsa_destroyctx,
openssleddsa_adddata,
openssleddsa_sign,
openssleddsa_verify,
NULL, /*%< verify2 */
NULL, /*%< computesecret */
openssleddsa_compare,
NULL, /*%< paramcompare */
openssleddsa_generate,
openssleddsa_isprivate,
openssleddsa_destroy,
openssleddsa_todns,
openssleddsa_fromdns,
openssleddsa_tofile,
openssleddsa_parse,
NULL, /*%< cleanup */
NULL, /*%< fromlabel */
NULL, /*%< dump */
NULL, /*%< restore */
};
isc_result_t
dst__openssleddsa_init(dst_func_t **funcp) {
REQUIRE(funcp != NULL);
if (*funcp == NULL)
*funcp = &openssleddsa_functions;
return (ISC_R_SUCCESS);
}
#endif /* HAVE_OPENSSL_ED25519 || HAVE_OPENSSL_ED448 */
#endif /* !USE_PKCS11 */
/*! \file */