}
int evp_keymgmt_validate(const EVP_KEYMGMT *keymgmt, void *keydata,
- int selection)
+ int selection, int checktype)
{
/* We assume valid if the implementation doesn't have a function */
if (keymgmt->validate == NULL)
return 1;
- return keymgmt->validate(keydata, selection);
+ return keymgmt->validate(keydata, selection, checktype);
}
int evp_keymgmt_match(const EVP_KEYMGMT *keymgmt,
* 0 False
* -1 Unsupported (use legacy path)
*/
-static int try_provided_check(EVP_PKEY_CTX *ctx, int selection)
+static int try_provided_check(EVP_PKEY_CTX *ctx, int selection, int checktype)
{
EVP_KEYMGMT *keymgmt;
void *keydata;
return 0;
}
- return evp_keymgmt_validate(keymgmt, keydata, selection);
+ return evp_keymgmt_validate(keymgmt, keydata, selection, checktype);
}
int EVP_PKEY_public_check(EVP_PKEY_CTX *ctx)
return 0;
}
- if ((ok = try_provided_check(ctx, OSSL_KEYMGMT_SELECT_PUBLIC_KEY)) != -1)
+ if ((ok = try_provided_check(ctx, OSSL_KEYMGMT_SELECT_PUBLIC_KEY,
+ OSSL_KEYMGMT_VALIDATE_FULL_CHECK)) != -1)
return ok;
if (pkey->type == EVP_PKEY_NONE)
return -2;
}
-int EVP_PKEY_param_check(EVP_PKEY_CTX *ctx)
+static int evp_pkey_param_check_combined(EVP_PKEY_CTX *ctx, int checktype)
{
EVP_PKEY *pkey = ctx->pkey;
int ok;
}
if ((ok = try_provided_check(ctx,
- OSSL_KEYMGMT_SELECT_ALL_PARAMETERS)) != -1)
+ OSSL_KEYMGMT_SELECT_ALL_PARAMETERS,
+ checktype)) != -1)
return ok;
if (pkey->type == EVP_PKEY_NONE)
return -2;
}
+int EVP_PKEY_param_check(EVP_PKEY_CTX *ctx)
+{
+ return evp_pkey_param_check_combined(ctx, OSSL_KEYMGMT_VALIDATE_FULL_CHECK);
+}
+
+int EVP_PKEY_param_check_quick(EVP_PKEY_CTX *ctx)
+{
+ return evp_pkey_param_check_combined(ctx, OSSL_KEYMGMT_VALIDATE_QUICK_CHECK);
+}
+
int EVP_PKEY_private_check(EVP_PKEY_CTX *ctx)
{
EVP_PKEY *pkey = ctx->pkey;
return 0;
}
- if ((ok = try_provided_check(ctx, OSSL_KEYMGMT_SELECT_PRIVATE_KEY)) != -1)
+ if ((ok = try_provided_check(ctx, OSSL_KEYMGMT_SELECT_PRIVATE_KEY,
+ OSSL_KEYMGMT_VALIDATE_FULL_CHECK)) != -1)
return ok;
/* not supported for legacy keys */
return 0;
}
- if ((ok = try_provided_check(ctx, OSSL_KEYMGMT_SELECT_KEYPAIR)) != -1)
+ if ((ok = try_provided_check(ctx, OSSL_KEYMGMT_SELECT_KEYPAIR,
+ OSSL_KEYMGMT_VALIDATE_FULL_CHECK)) != -1)
return ok;
/* not supported for legacy keys */
return 0;
}
- if ((ok = try_provided_check(ctx, OSSL_KEYMGMT_SELECT_KEYPAIR)) != -1)
+ if ((ok = try_provided_check(ctx, OSSL_KEYMGMT_SELECT_KEYPAIR,
+ OSSL_KEYMGMT_VALIDATE_FULL_CHECK)) != -1)
return ok;
if (pkey->type == EVP_PKEY_NONE)
int OSSL_FUNC_keymgmt_copy(void *keydata_to, const void *keydata_from, int selection);
/* Key object validation */
- int OSSL_FUNC_keymgmt_validate(const void *keydata, int selection);
+ int OSSL_FUNC_keymgmt_validate(const void *keydata, int selection, int checktype);
=head1 DESCRIPTION
For example, the combination of B<OSSL_KEYMGMT_SELECT_PRIVATE_KEY> and
B<OSSL_KEYMGMT_SELECT_PUBLIC_KEY> (or B<OSSL_KEYMGMT_SELECT_KEYPAIR>
for short) is expected to check that the pairwise consistency of
-I<keydata> is valid.
+I<keydata> is valid. The I<checktype> parameter controls what type of check is
+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.
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
int evp_keymgmt_has(const EVP_KEYMGMT *keymgmt, void *keyddata, int selection);
int evp_keymgmt_validate(const EVP_KEYMGMT *keymgmt, void *keydata,
- int selection);
+ int selection, int checktype);
int evp_keymgmt_match(const EVP_KEYMGMT *keymgmt,
const void *keydata1, const void *keydata2,
int selection);
# define OSSL_KEYMGMT_SELECT_ALL \
( OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS )
+# define OSSL_KEYMGMT_VALIDATE_FULL_CHECK 0
+# define OSSL_KEYMGMT_VALIDATE_QUICK_CHECK 1
+
/* Basic key object creation */
# define OSSL_FUNC_KEYMGMT_NEW 1
OSSL_CORE_MAKE_FUNC(void *, keymgmt_new, (void *provctx))
/* Key checks - validation */
# define OSSL_FUNC_KEYMGMT_VALIDATE 22
-OSSL_CORE_MAKE_FUNC(int, keymgmt_validate, (const void *keydata, int selection))
+OSSL_CORE_MAKE_FUNC(int, keymgmt_validate, (const void *keydata, int selection,
+ int checktype))
/* Key checks - matching */
# define OSSL_FUNC_KEYMGMT_MATCH 23
int EVP_PKEY_check(EVP_PKEY_CTX *ctx);
int EVP_PKEY_public_check(EVP_PKEY_CTX *ctx);
int EVP_PKEY_param_check(EVP_PKEY_CTX *ctx);
+int EVP_PKEY_param_check_quick(EVP_PKEY_CTX *ctx);
int EVP_PKEY_private_check(EVP_PKEY_CTX *ctx);
int EVP_PKEY_pairwise_check(EVP_PKEY_CTX *ctx);
return dh_check_priv_key(dh, priv_key, &status);;
}
-static int dh_validate(const void *keydata, int selection)
+static int dh_validate(const void *keydata, int selection, int checktype)
{
const DH *dh = keydata;
int ok = 0;
if ((selection & DH_POSSIBLE_SELECTIONS) != 0)
ok = 1;
- if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
- ok = ok && DH_check_ex(dh);
+ if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) {
+ /*
+ * Both of these functions check parameters. DH_check_params_ex()
+ * performs a lightweight check (e.g. it does not check that p is a
+ * safe prime)
+ */
+ if (checktype == OSSL_KEYMGMT_VALIDATE_QUICK_CHECK)
+ ok = ok && DH_check_params_ex(dh);
+ else
+ ok = ok && DH_check_ex(dh);
+ }
if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
ok = ok && dh_validate_public(dh);
return dsa_check_priv_key(dsa, priv_key, &status);
}
-static int dsa_validate(const void *keydata, int selection)
+static int dsa_validate(const void *keydata, int selection, int checktype)
{
const DSA *dsa = keydata;
int ok = 0;
}
static
-int sm2_validate(const void *keydata, int selection)
+int sm2_validate(const void *keydata, int selection, int checktype)
{
const EC_KEY *eck = keydata;
int ok = 0;
#endif
static
-int ec_validate(const void *keydata, int selection)
+int ec_validate(const void *keydata, int selection, int checktype)
{
const EC_KEY *eck = keydata;
int ok = 0;
return ok;
}
-static int x25519_validate(const void *keydata, int selection)
+static int x25519_validate(const void *keydata, int selection, int checktype)
{
return ecx_validate(keydata, selection, ECX_KEY_TYPE_X25519, X25519_KEYLEN);
}
-static int x448_validate(const void *keydata, int selection)
+static int x448_validate(const void *keydata, int selection, int checktype)
{
return ecx_validate(keydata, selection, ECX_KEY_TYPE_X448, X448_KEYLEN);
}
-static int ed25519_validate(const void *keydata, int selection)
+static int ed25519_validate(const void *keydata, int selection, int checktype)
{
return ecx_validate(keydata, selection, ECX_KEY_TYPE_ED25519, ED25519_KEYLEN);
}
-static int ed448_validate(const void *keydata, int selection)
+static int ed448_validate(const void *keydata, int selection, int checktype)
{
return ecx_validate(keydata, selection, ECX_KEY_TYPE_ED448, ED448_KEYLEN);
}
return rsa_params;
}
-static int rsa_validate(const void *keydata, int selection)
+static int rsa_validate(const void *keydata, int selection, int checktype)
{
const RSA *rsa = keydata;
int ok = 0;
EVP_PKEY_CTX_free(pctx);
pctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, peer_tmp, s->ctx->propq);
if (pctx == NULL
- || EVP_PKEY_param_check(pctx) != 1
+ /*
+ * EVP_PKEY_param_check() will verify that the DH params are using
+ * a safe prime. In this context, because we're using ephemeral DH,
+ * we're ok with it not being a safe prime.
+ * EVP_PKEY_param_check_quick() skips the safe prime check.
+ */
+ || EVP_PKEY_param_check_quick(pctx) != 1
|| EVP_PKEY_public_check(pctx) != 1) {
SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_DH_VALUE);
goto err;
EVP_PKEY_get_params ? 3_0_0 EXIST::FUNCTION:
EVP_PKEY_fromdata_init ? 3_0_0 EXIST::FUNCTION:
EVP_PKEY_fromdata_settable ? 3_0_0 EXIST::FUNCTION:
+EVP_PKEY_param_check_quick ? 3_0_0 EXIST::FUNCTION: