4
0
mirror of https://github.com/QuasarApp/openssl.git synced 2025-05-08 15:39:41 +00:00

Add the ability to ECX to import keys with only the private key

ECX keys can very easily crete the public key from the private key.
Therefore when we import ecx keys it is sufficent to just have the private
key.

Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/11635)
This commit is contained in:
Matt Caswell 2020-04-24 15:32:34 +01:00
parent a6f8a834ba
commit 969024b458
4 changed files with 44 additions and 32 deletions
crypto/ec
include/crypto
providers/implementations/keymgmt

@ -9,6 +9,8 @@
#include <openssl/core_names.h>
#include <openssl/params.h>
#include <openssl/ec.h>
#include <openssl/err.h>
#include "crypto/ecx.h"
#include "ecx_backend.h"
@ -18,10 +20,35 @@
* implementations alike.
*/
int ecx_public_from_private(ECX_KEY *key)
{
switch (key->type) {
case ECX_KEY_TYPE_X25519:
X25519_public_from_private(key->pubkey, key->privkey);
break;
case ECX_KEY_TYPE_ED25519:
if (!ED25519_public_from_private(key->libctx, key->pubkey, key->privkey)) {
ECerr(0, EC_R_FAILED_MAKING_PUBLIC_KEY);
return 0;
}
break;
case ECX_KEY_TYPE_X448:
X448_public_from_private(key->pubkey, key->privkey);
break;
case ECX_KEY_TYPE_ED448:
if (!ED448_public_from_private(key->libctx, key->pubkey, key->privkey)) {
ECerr(0, EC_R_FAILED_MAKING_PUBLIC_KEY);
return 0;
}
break;
}
return 1;
}
int ecx_key_fromdata(ECX_KEY *ecx, const OSSL_PARAM params[],
int include_private)
{
size_t privkeylen = 0, pubkeylen;
size_t privkeylen = 0, pubkeylen = 0;
const OSSL_PARAM *param_priv_key = NULL, *param_pub_key;
unsigned char *pubkey;
@ -32,11 +59,8 @@ int ecx_key_fromdata(ECX_KEY *ecx, const OSSL_PARAM params[],
if (include_private)
param_priv_key =
OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY);
/*
* If a private key is present then a public key must also be present.
* Alternatively we've just got a public key.
*/
if (param_pub_key == NULL)
if (param_pub_key == NULL && param_priv_key == NULL)
return 0;
if (param_priv_key != NULL
@ -46,15 +70,19 @@ int ecx_key_fromdata(ECX_KEY *ecx, const OSSL_PARAM params[],
return 0;
pubkey = ecx->pubkey;
if (!OSSL_PARAM_get_octet_string(param_pub_key,
(void **)&pubkey,
sizeof(ecx->pubkey), &pubkeylen))
if (param_pub_key != NULL
&& !OSSL_PARAM_get_octet_string(param_pub_key,
(void **)&pubkey,
sizeof(ecx->pubkey), &pubkeylen))
return 0;
if (pubkeylen != ecx->keylen
if ((param_pub_key != NULL && pubkeylen != ecx->keylen)
|| (param_priv_key != NULL && privkeylen != ecx->keylen))
return 0;
if (param_pub_key == NULL && !ecx_public_from_private(ecx))
return 0;
ecx->haspubkey = 1;
return 1;

@ -88,25 +88,9 @@ static int ecx_key_op(EVP_PKEY *pkey, int id, const X509_ALGOR *palg,
} else {
memcpy(privkey, p, KEYLENID(id));
}
switch (id) {
case EVP_PKEY_X25519:
X25519_public_from_private(pubkey, privkey);
break;
case EVP_PKEY_ED25519:
if (!ED25519_public_from_private(libctx, pubkey, privkey)) {
ECerr(EC_F_ECX_KEY_OP, EC_R_FAILED_MAKING_PUBLIC_KEY);
goto err;
}
break;
case EVP_PKEY_X448:
X448_public_from_private(pubkey, privkey);
break;
case EVP_PKEY_ED448:
if (!ED448_public_from_private(libctx, pubkey, privkey)) {
ECerr(EC_F_ECX_KEY_OP, EC_R_FAILED_MAKING_PUBLIC_KEY);
goto err;
}
break;
if (!ecx_public_from_private(key)) {
ECerr(EC_F_ECX_KEY_OP, EC_R_FAILED_MAKING_PUBLIC_KEY);
goto err;
}
}

@ -109,6 +109,7 @@ void X448_public_from_private(uint8_t out_public_value[56],
const uint8_t private_key[56]);
/* Backend support */
int ecx_public_from_private(ECX_KEY *key);
int ecx_key_fromdata(ECX_KEY *ecx, const OSSL_PARAM params[],
int include_private);

@ -113,12 +113,11 @@ static int ecx_import(void *keydata, int selection, const OSSL_PARAM params[])
if (key == NULL)
return 0;
if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) == 0)
if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
return 0;
include_private = ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0);
if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
ok = ok && ecx_key_fromdata(key, params, include_private);
ok = ok && ecx_key_fromdata(key, params, include_private);
return ok;
}