mirror of
https://github.com/openssl/openssl.git
synced 2025-03-19 19:50:42 +08:00
Make EVP_PKEY_missing_parameters work properly on provided RSA keys
This requires changing semantics of the keymgmt_has() function a little in the sense that it now returns 1 if the selection has no meaning for the key type. It was already doing so for ECX keys for example. The keymgmt_validate function semantics is changed similarly to allow passing validation on the same selection that the key returns 1 for. Fixes #14509 Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/14511)
This commit is contained in:
parent
e08993eab6
commit
9a48544058
@ -294,7 +294,10 @@ OSSL_FUNC_keymgmt_has() should check whether the given I<keydata> contains the s
|
||||
of data indicated by the I<selector>. A combination of several
|
||||
selector bits must consider all those subsets, not just one. An
|
||||
implementation is, however, free to consider an empty subset of data
|
||||
to still be a valid subset.
|
||||
to still be a valid subset. For algorithms where some selection is
|
||||
not meaningful such as B<OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS> for
|
||||
RSA keys the function should just return 1 as the selected subset
|
||||
is not really missing in the key.
|
||||
|
||||
OSSL_FUNC_keymgmt_validate() should check if the I<keydata> contains valid
|
||||
data subsets indicated by I<selection>. Some combined selections of
|
||||
@ -307,7 +310,10 @@ performed on the subset of data. Two types of check are defined:
|
||||
B<OSSL_KEYMGMT_VALIDATE_FULL_CHECK> and B<OSSL_KEYMGMT_VALIDATE_QUICK_CHECK>.
|
||||
The interpretation of how much checking is performed in a full check versus a
|
||||
quick check is key type specific. Some providers may have no distinction
|
||||
between a full check and a quick check.
|
||||
between a full check and a quick check. For algorithms where some selection is
|
||||
not meaningful such as B<OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS> for
|
||||
RSA keys the function should just return 1 as there is nothing to validate for
|
||||
that selection.
|
||||
|
||||
OSSL_FUNC_keymgmt_match() should check if the data subset indicated by
|
||||
I<selection> in I<keydata1> and I<keydata2> match. It is assumed that
|
||||
|
@ -128,19 +128,19 @@ static void dh_freedata(void *keydata)
|
||||
static int dh_has(const void *keydata, int selection)
|
||||
{
|
||||
const DH *dh = keydata;
|
||||
int ok = 0;
|
||||
int ok = 1;
|
||||
|
||||
if (ossl_prov_is_running() && dh != NULL) {
|
||||
if ((selection & DH_POSSIBLE_SELECTIONS) != 0)
|
||||
ok = 1;
|
||||
if (!ossl_prov_is_running() || dh == NULL)
|
||||
return 0;
|
||||
if ((selection & DH_POSSIBLE_SELECTIONS) == 0)
|
||||
return 1; /* the selection is not missing */
|
||||
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
|
||||
ok = ok && (DH_get0_pub_key(dh) != NULL);
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
|
||||
ok = ok && (DH_get0_priv_key(dh) != NULL);
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
|
||||
ok = ok && (DH_get0_p(dh) != NULL && DH_get0_g(dh) != NULL);
|
||||
}
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
|
||||
ok = ok && (DH_get0_pub_key(dh) != NULL);
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
|
||||
ok = ok && (DH_get0_priv_key(dh) != NULL);
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
|
||||
ok = ok && (DH_get0_p(dh) != NULL && DH_get0_g(dh) != NULL);
|
||||
return ok;
|
||||
}
|
||||
|
||||
@ -376,13 +376,13 @@ static int dh_validate_private(const DH *dh)
|
||||
static int dh_validate(const void *keydata, int selection, int checktype)
|
||||
{
|
||||
const DH *dh = keydata;
|
||||
int ok = 0;
|
||||
int ok = 1;
|
||||
|
||||
if (!ossl_prov_is_running())
|
||||
return 0;
|
||||
|
||||
if ((selection & DH_POSSIBLE_SELECTIONS) != 0)
|
||||
ok = 1;
|
||||
if ((selection & DH_POSSIBLE_SELECTIONS) == 0)
|
||||
return 1; /* nothing to validate */
|
||||
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) {
|
||||
/*
|
||||
|
@ -128,19 +128,19 @@ static void dsa_freedata(void *keydata)
|
||||
static int dsa_has(const void *keydata, int selection)
|
||||
{
|
||||
const DSA *dsa = keydata;
|
||||
int ok = 0;
|
||||
int ok = 1;
|
||||
|
||||
if (ossl_prov_is_running() && dsa != NULL) {
|
||||
if ((selection & DSA_POSSIBLE_SELECTIONS) != 0)
|
||||
ok = 1;
|
||||
if (!ossl_prov_is_running() || dsa == NULL)
|
||||
return 0;
|
||||
if ((selection & DSA_POSSIBLE_SELECTIONS) == 0)
|
||||
return 1; /* the selection is not missing */
|
||||
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
|
||||
ok = ok && (DSA_get0_pub_key(dsa) != NULL);
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
|
||||
ok = ok && (DSA_get0_priv_key(dsa) != NULL);
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
|
||||
ok = ok && (DSA_get0_p(dsa) != NULL && DSA_get0_g(dsa) != NULL);
|
||||
}
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
|
||||
ok = ok && (DSA_get0_pub_key(dsa) != NULL);
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
|
||||
ok = ok && (DSA_get0_priv_key(dsa) != NULL);
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
|
||||
ok = ok && (DSA_get0_p(dsa) != NULL && DSA_get0_g(dsa) != NULL);
|
||||
return ok;
|
||||
}
|
||||
|
||||
@ -341,13 +341,13 @@ static int dsa_validate_private(const DSA *dsa)
|
||||
static int dsa_validate(const void *keydata, int selection, int checktype)
|
||||
{
|
||||
const DSA *dsa = keydata;
|
||||
int ok = 0;
|
||||
int ok = 1;
|
||||
|
||||
if (!ossl_prov_is_running())
|
||||
return 0;
|
||||
|
||||
if ((selection & DSA_POSSIBLE_SELECTIONS) != 0)
|
||||
ok = 1;
|
||||
if ((selection & DSA_POSSIBLE_SELECTIONS) == 0)
|
||||
return 1; /* nothing to validate */
|
||||
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
|
||||
ok = ok && dsa_validate_domparams(dsa, checktype);
|
||||
|
@ -281,24 +281,24 @@ static
|
||||
int ec_has(const void *keydata, int selection)
|
||||
{
|
||||
const EC_KEY *ec = keydata;
|
||||
int ok = 0;
|
||||
int ok = 1;
|
||||
|
||||
if (ossl_prov_is_running() && ec != NULL) {
|
||||
if ((selection & EC_POSSIBLE_SELECTIONS) != 0)
|
||||
ok = 1;
|
||||
if (!ossl_prov_is_running() || ec == NULL)
|
||||
return 0;
|
||||
if ((selection & EC_POSSIBLE_SELECTIONS) == 0)
|
||||
return 1; /* the selection is not missing */
|
||||
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
|
||||
ok = ok && (EC_KEY_get0_public_key(ec) != NULL);
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
|
||||
ok = ok && (EC_KEY_get0_private_key(ec) != NULL);
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
|
||||
ok = ok && (EC_KEY_get0_group(ec) != NULL);
|
||||
/*
|
||||
* We consider OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS to always be
|
||||
* available, so no extra check is needed other than the previous one
|
||||
* against EC_POSSIBLE_SELECTIONS.
|
||||
*/
|
||||
}
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
|
||||
ok = ok && (EC_KEY_get0_public_key(ec) != NULL);
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
|
||||
ok = ok && (EC_KEY_get0_private_key(ec) != NULL);
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
|
||||
ok = ok && (EC_KEY_get0_group(ec) != NULL);
|
||||
/*
|
||||
* We consider OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS to always be
|
||||
* available, so no extra check is needed other than the previous one
|
||||
* against EC_POSSIBLE_SELECTIONS.
|
||||
*/
|
||||
return ok;
|
||||
}
|
||||
|
||||
@ -841,7 +841,7 @@ static
|
||||
int sm2_validate(const void *keydata, int selection, int checktype)
|
||||
{
|
||||
const EC_KEY *eck = keydata;
|
||||
int ok = 0;
|
||||
int ok = 1;
|
||||
BN_CTX *ctx = NULL;
|
||||
|
||||
if (!ossl_prov_is_running())
|
||||
@ -851,8 +851,8 @@ int sm2_validate(const void *keydata, int selection, int checktype)
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
|
||||
if ((selection & EC_POSSIBLE_SELECTIONS) != 0)
|
||||
ok = 1;
|
||||
if ((selection & EC_POSSIBLE_SELECTIONS) == 0)
|
||||
return 1; /* nothing to validate */
|
||||
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
|
||||
ok = ok && EC_GROUP_check(EC_KEY_get0_group(eck), ctx);
|
||||
@ -880,7 +880,7 @@ static
|
||||
int ec_validate(const void *keydata, int selection, int checktype)
|
||||
{
|
||||
const EC_KEY *eck = keydata;
|
||||
int ok = 0;
|
||||
int ok = 1;
|
||||
BN_CTX *ctx = NULL;
|
||||
|
||||
if (!ossl_prov_is_running())
|
||||
@ -890,8 +890,8 @@ int ec_validate(const void *keydata, int selection, int checktype)
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
|
||||
if ((selection & EC_POSSIBLE_SELECTIONS) != 0)
|
||||
ok = 1;
|
||||
if ((selection & EC_POSSIBLE_SELECTIONS) == 0)
|
||||
return 1; /* nothing to validate */
|
||||
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) {
|
||||
int flags = EC_KEY_get_flags(eck);
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <openssl/core_names.h>
|
||||
#include <openssl/params.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/proverr.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rand.h>
|
||||
#include "internal/param_build_set.h"
|
||||
@ -71,6 +72,8 @@ static OSSL_FUNC_keymgmt_import_types_fn ecx_imexport_types;
|
||||
static OSSL_FUNC_keymgmt_export_fn ecx_export;
|
||||
static OSSL_FUNC_keymgmt_export_types_fn ecx_imexport_types;
|
||||
|
||||
#define ECX_POSSIBLE_SELECTIONS (OSSL_KEYMGMT_SELECT_KEYPAIR)
|
||||
|
||||
struct ecx_gen_ctx {
|
||||
OSSL_LIB_CTX *libctx;
|
||||
char *propq;
|
||||
@ -718,21 +721,18 @@ static int ecx_key_pairwise_check(const ECX_KEY *ecx, int type)
|
||||
static int ecx_validate(const void *keydata, int selection, int type, size_t keylen)
|
||||
{
|
||||
const ECX_KEY *ecx = keydata;
|
||||
int ok = 0;
|
||||
int ok = keylen == ecx->keylen;
|
||||
|
||||
if (!ossl_prov_is_running())
|
||||
return 0;
|
||||
|
||||
assert(keylen == ecx->keylen);
|
||||
if ((selection & ECX_POSSIBLE_SELECTIONS) == 0)
|
||||
return 1; /* nothing to validate */
|
||||
|
||||
/*
|
||||
* ECX keys have no parameters. But if EVP_PKEY_param_check() is called then
|
||||
* we should return true.
|
||||
*/
|
||||
if ((selection & (OSSL_KEYMGMT_SELECT_KEYPAIR
|
||||
| OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS
|
||||
| OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS)) != 0)
|
||||
ok = 1;
|
||||
if (!ok) {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_ALGORITHM_MISMATCH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
|
||||
ok = ok && ecx->haspubkey;
|
||||
|
@ -93,7 +93,7 @@ static void kdf_freedata(void *kdfdata)
|
||||
|
||||
static int kdf_has(const void *keydata, int selection)
|
||||
{
|
||||
return 0;
|
||||
return 1; /* nothing is missing */
|
||||
}
|
||||
|
||||
const OSSL_DISPATCH ossl_kdf_keymgmt_functions[] = {
|
||||
|
@ -112,22 +112,22 @@ static void rsa_freedata(void *keydata)
|
||||
static int rsa_has(const void *keydata, int selection)
|
||||
{
|
||||
const RSA *rsa = keydata;
|
||||
int ok = 0;
|
||||
int ok = 1;
|
||||
|
||||
if (rsa != NULL && ossl_prov_is_running()) {
|
||||
if ((selection & RSA_POSSIBLE_SELECTIONS) != 0)
|
||||
ok = 1;
|
||||
if (rsa == NULL || !ossl_prov_is_running())
|
||||
return 0;
|
||||
if ((selection & RSA_POSSIBLE_SELECTIONS) == 0)
|
||||
return 1; /* the selection is not missing */
|
||||
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0)
|
||||
/* This will change with OAEP */
|
||||
ok = ok && (RSA_test_flags(rsa, RSA_FLAG_TYPE_RSASSAPSS) != 0);
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
|
||||
ok = ok && (RSA_get0_e(rsa) != NULL);
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
|
||||
ok = ok && (RSA_get0_n(rsa) != NULL);
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
|
||||
ok = ok && (RSA_get0_d(rsa) != NULL);
|
||||
}
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0)
|
||||
/* This will change with OAEP */
|
||||
ok = ok && (RSA_test_flags(rsa, RSA_FLAG_TYPE_RSASSAPSS) != 0);
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
|
||||
ok = ok && (RSA_get0_e(rsa) != NULL);
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
|
||||
ok = ok && (RSA_get0_n(rsa) != NULL);
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
|
||||
ok = ok && (RSA_get0_d(rsa) != NULL);
|
||||
return ok;
|
||||
}
|
||||
|
||||
@ -187,6 +187,9 @@ static int rsa_export(void *keydata, int selection,
|
||||
if (!ossl_prov_is_running() || rsa == NULL)
|
||||
return 0;
|
||||
|
||||
if ((selection & RSA_POSSIBLE_SELECTIONS) == 0)
|
||||
return 0;
|
||||
|
||||
tmpl = OSSL_PARAM_BLD_new();
|
||||
if (tmpl == NULL)
|
||||
return 0;
|
||||
@ -358,24 +361,13 @@ static const OSSL_PARAM *rsa_gettable_params(void *provctx)
|
||||
static int rsa_validate(const void *keydata, int selection, int checktype)
|
||||
{
|
||||
const RSA *rsa = keydata;
|
||||
int ok = 0;
|
||||
int ok = 1;
|
||||
|
||||
if (!ossl_prov_is_running())
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Although an RSA key has no domain parameters, validating them should
|
||||
* return true.
|
||||
*
|
||||
* RSA_POSSIBLE_SELECTIONS already includes
|
||||
* OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS. We explicitly add
|
||||
* OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS here as well for completeness. In
|
||||
* practice this makes little difference since EVP_PKEY_param_check() always
|
||||
* checks the combination of "other" and "domain" parameters anyway.
|
||||
*/
|
||||
if ((selection & (RSA_POSSIBLE_SELECTIONS
|
||||
| OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS)) != 0)
|
||||
ok = 1;
|
||||
if ((selection & RSA_POSSIBLE_SELECTIONS) == 0)
|
||||
return 1; /* nothing to validate */
|
||||
|
||||
/* If the whole key is selected, we do a pairwise validation */
|
||||
if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR)
|
||||
|
@ -344,7 +344,8 @@ static int test_fromdata_rsa(void)
|
||||
fromdata_params))
|
||||
|| !TEST_int_eq(EVP_PKEY_bits(pk), 32)
|
||||
|| !TEST_int_eq(EVP_PKEY_security_bits(pk), 8)
|
||||
|| !TEST_int_eq(EVP_PKEY_size(pk), 4))
|
||||
|| !TEST_int_eq(EVP_PKEY_size(pk), 4)
|
||||
|| !TEST_false(EVP_PKEY_missing_parameters(pk)))
|
||||
goto err;
|
||||
|
||||
if (!TEST_ptr(key_ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pk, "")))
|
||||
@ -509,7 +510,8 @@ static int test_fromdata_dh_named_group(void)
|
||||
fromdata_params))
|
||||
|| !TEST_int_eq(EVP_PKEY_bits(pk), 2048)
|
||||
|| !TEST_int_eq(EVP_PKEY_security_bits(pk), 112)
|
||||
|| !TEST_int_eq(EVP_PKEY_size(pk), 256))
|
||||
|| !TEST_int_eq(EVP_PKEY_size(pk), 256)
|
||||
|| !TEST_false(EVP_PKEY_missing_parameters(pk)))
|
||||
goto err;
|
||||
|
||||
if (!TEST_true(EVP_PKEY_get_utf8_string_param(pk, OSSL_PKEY_PARAM_GROUP_NAME,
|
||||
@ -654,7 +656,8 @@ static int test_fromdata_dh_fips186_4(void)
|
||||
fromdata_params))
|
||||
|| !TEST_int_eq(EVP_PKEY_bits(pk), 2048)
|
||||
|| !TEST_int_eq(EVP_PKEY_security_bits(pk), 112)
|
||||
|| !TEST_int_eq(EVP_PKEY_size(pk), 256))
|
||||
|| !TEST_int_eq(EVP_PKEY_size(pk), 256)
|
||||
|| !TEST_false(EVP_PKEY_missing_parameters(pk)))
|
||||
goto err;
|
||||
|
||||
if (!TEST_true(EVP_PKEY_get_utf8_string_param(pk, OSSL_PKEY_PARAM_GROUP_NAME,
|
||||
@ -926,7 +929,8 @@ static int test_fromdata_ecx(int tst)
|
||||
fromdata_params))
|
||||
|| !TEST_int_eq(EVP_PKEY_bits(pk), bits)
|
||||
|| !TEST_int_eq(EVP_PKEY_security_bits(pk), security_bits)
|
||||
|| !TEST_int_eq(EVP_PKEY_size(pk), size))
|
||||
|| !TEST_int_eq(EVP_PKEY_size(pk), size)
|
||||
|| !TEST_false(EVP_PKEY_missing_parameters(pk)))
|
||||
goto err;
|
||||
|
||||
if (!TEST_ptr(ctx2 = EVP_PKEY_CTX_new_from_pkey(NULL, pk, NULL)))
|
||||
@ -1039,7 +1043,8 @@ static int test_fromdata_ec(void)
|
||||
fromdata_params))
|
||||
|| !TEST_int_eq(EVP_PKEY_bits(pk), 256)
|
||||
|| !TEST_int_eq(EVP_PKEY_security_bits(pk), 128)
|
||||
|| !TEST_int_eq(EVP_PKEY_size(pk), 2 + 35 * 2))
|
||||
|| !TEST_int_eq(EVP_PKEY_size(pk), 2 + 35 * 2)
|
||||
|| !TEST_false(EVP_PKEY_missing_parameters(pk)))
|
||||
goto err;
|
||||
|
||||
if (!TEST_ptr(copy_pk = EVP_PKEY_new())
|
||||
@ -1298,7 +1303,8 @@ static int test_fromdata_dsa_fips186_4(void)
|
||||
fromdata_params))
|
||||
|| !TEST_int_eq(EVP_PKEY_bits(pk), 2048)
|
||||
|| !TEST_int_eq(EVP_PKEY_security_bits(pk), 112)
|
||||
|| !TEST_int_eq(EVP_PKEY_size(pk), 2 + 2 * (3 + sizeof(q_data))))
|
||||
|| !TEST_int_eq(EVP_PKEY_size(pk), 2 + 2 * (3 + sizeof(q_data)))
|
||||
|| !TEST_false(EVP_PKEY_missing_parameters(pk)))
|
||||
goto err;
|
||||
|
||||
if (!TEST_false(EVP_PKEY_get_utf8_string_param(pk, OSSL_PKEY_PARAM_GROUP_NAME,
|
||||
|
Loading…
x
Reference in New Issue
Block a user