summaryrefslogtreecommitdiffstats
path: root/crypto/evp
diff options
context:
space:
mode:
authorShane Lontis <shane.lontis@oracle.com>2020-01-29 20:32:32 +1000
committerShane Lontis <shane.lontis@oracle.com>2020-01-29 20:32:32 +1000
commit12603de634fe628488066d1f3f2c720ca20d6df9 (patch)
treea7345e533ae5811eeb682a7cf8d02c6a8008b6f6 /crypto/evp
parenta76ce2862bc6ae2cf8a749c8747d371041fc42d1 (diff)
Add RSA key validation to default provider
Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/10780)
Diffstat (limited to 'crypto/evp')
-rw-r--r--crypto/evp/build.info3
-rw-r--r--crypto/evp/evp_local.h4
-rw-r--r--crypto/evp/keymgmt_lib.c23
-rw-r--r--crypto/evp/keymgmt_meth.c24
-rw-r--r--crypto/evp/pmeth_check.c158
-rw-r--r--crypto/evp/pmeth_gn.c71
-rw-r--r--crypto/evp/pmeth_lib.c1
7 files changed, 211 insertions, 73 deletions
diff --git a/crypto/evp/build.info b/crypto/evp/build.info
index d3ebac9f4e..7972706f86 100644
--- a/crypto/evp/build.info
+++ b/crypto/evp/build.info
@@ -1,7 +1,8 @@
LIBS=../../libcrypto
$COMMON=digest.c evp_enc.c evp_lib.c evp_fetch.c cmeth_lib.c evp_utils.c \
mac_lib.c mac_meth.c keymgmt_meth.c keymgmt_lib.c kdf_lib.c kdf_meth.c \
- m_sigver.c pmeth_lib.c signature.c p_lib.c pmeth_gn.c exchange.c
+ m_sigver.c pmeth_lib.c signature.c p_lib.c pmeth_gn.c exchange.c \
+ pmeth_check.c
SOURCE[../../libcrypto]=$COMMON\
encode.c evp_key.c evp_cnf.c \
diff --git a/crypto/evp/evp_local.h b/crypto/evp/evp_local.h
index 894fdf996e..5f34aaeb23 100644
--- a/crypto/evp/evp_local.h
+++ b/crypto/evp/evp_local.h
@@ -82,6 +82,7 @@ struct evp_keymgmt_st {
OSSL_OP_keymgmt_exportdomparam_types_fn *exportdomparam_types;
OSSL_OP_keymgmt_get_domparam_params_fn *get_domparam_params;
OSSL_OP_keymgmt_gettable_domparam_params_fn *gettable_domparam_params;
+ OSSL_OP_keymgmt_validate_domparams_fn *validatedomparams;
/* Key routines */
OSSL_OP_keymgmt_importkey_fn *importkey;
@@ -95,6 +96,9 @@ struct evp_keymgmt_st {
OSSL_OP_keymgmt_gettable_key_params_fn *gettable_key_params;
OSSL_OP_keymgmt_query_operation_name_fn *query_operation_name;
+ OSSL_OP_keymgmt_validate_public_fn *validatepublic;
+ OSSL_OP_keymgmt_validate_private_fn *validateprivate;
+ OSSL_OP_keymgmt_validate_pairwise_fn *validatepairwise;
} /* EVP_KEYMGMT */ ;
struct keymgmt_data_st {
diff --git a/crypto/evp/keymgmt_lib.c b/crypto/evp/keymgmt_lib.c
index 53610d3ef8..1f4b4a104f 100644
--- a/crypto/evp/keymgmt_lib.c
+++ b/crypto/evp/keymgmt_lib.c
@@ -342,3 +342,26 @@ const OSSL_PARAM *evp_keymgmt_gettable_key_params(const EVP_KEYMGMT *keymgmt)
return NULL;
return keymgmt->gettable_key_params();
}
+
+int evp_keymgmt_validate_domparams(const EVP_KEYMGMT *keymgmt, void *provkey)
+{
+ /* if domainparams are not supported - then pass */
+ if (keymgmt->validatedomparams == NULL)
+ return 1;
+ return keymgmt->validatedomparams(provkey);
+}
+
+int evp_keymgmt_validate_public(const EVP_KEYMGMT *keymgmt, void *provkey)
+{
+ return keymgmt->validatepublic(provkey);
+}
+
+int evp_keymgmt_validate_private(const EVP_KEYMGMT *keymgmt, void *provkey)
+{
+ return keymgmt->validateprivate(provkey);
+}
+
+int evp_keymgmt_validate_pairwise(const EVP_KEYMGMT *keymgmt, void *provkey)
+{
+ return keymgmt->validatepairwise(provkey);
+}
diff --git a/crypto/evp/keymgmt_meth.c b/crypto/evp/keymgmt_meth.c
index ae1f10e6b3..e9e7f89744 100644
--- a/crypto/evp/keymgmt_meth.c
+++ b/crypto/evp/keymgmt_meth.c
@@ -144,6 +144,30 @@ static void *keymgmt_from_dispatch(int name_id,
keymgmt->query_operation_name =
OSSL_get_OP_keymgmt_query_operation_name(fns);
break;
+ case OSSL_FUNC_KEYMGMT_VALIDATE_DOMPARAMS:
+ if (keymgmt->validatedomparams != NULL)
+ break;
+ keymgmt->validatedomparams =
+ OSSL_get_OP_keymgmt_validate_domparams(fns);
+ break;
+ case OSSL_FUNC_KEYMGMT_VALIDATE_PUBLIC:
+ if (keymgmt->validatepublic != NULL)
+ break;
+ keymgmt->validatepublic =
+ OSSL_get_OP_keymgmt_validate_public(fns);
+ break;
+ case OSSL_FUNC_KEYMGMT_VALIDATE_PRIVATE:
+ if (keymgmt->validateprivate != NULL)
+ break;
+ keymgmt->validateprivate =
+ OSSL_get_OP_keymgmt_validate_private(fns);
+ break;
+ case OSSL_FUNC_KEYMGMT_VALIDATE_PAIRWISE:
+ if (keymgmt->validatepairwise != NULL)
+ break;
+ keymgmt->validatepairwise =
+ OSSL_get_OP_keymgmt_validate_pairwise(fns);
+ break;
}
}
/*
diff --git a/crypto/evp/pmeth_check.c b/crypto/evp/pmeth_check.c
new file mode 100644
index 0000000000..19f200a3ce
--- /dev/null
+++ b/crypto/evp/pmeth_check.c
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "internal/cryptlib.h"
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include "crypto/bn.h"
+#include "crypto/asn1.h"
+#include "crypto/evp.h"
+#include "evp_local.h"
+
+int EVP_PKEY_public_check(EVP_PKEY_CTX *ctx)
+{
+ EVP_PKEY *pkey = ctx->pkey;
+ void *key;
+ EVP_KEYMGMT *keymgmt;
+
+ if (pkey == NULL) {
+ EVPerr(EVP_F_EVP_PKEY_PUBLIC_CHECK, EVP_R_NO_KEY_SET);
+ return 0;
+ }
+
+ keymgmt = pkey->pkeys[0].keymgmt;
+ key = pkey->pkeys[0].provdata;
+
+ if (key != NULL && keymgmt != NULL)
+ return evp_keymgmt_validate_public(keymgmt, key);
+
+ /* legacy */
+ /* call customized public key check function first */
+ if (ctx->pmeth->public_check != NULL)
+ return ctx->pmeth->public_check(pkey);
+
+ /* use default public key check function in ameth */
+ if (pkey->ameth == NULL || pkey->ameth->pkey_public_check == NULL) {
+ EVPerr(EVP_F_EVP_PKEY_PUBLIC_CHECK,
+ EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return -2;
+ }
+
+ return pkey->ameth->pkey_public_check(pkey);
+}
+
+int EVP_PKEY_param_check(EVP_PKEY_CTX *ctx)
+{
+ EVP_PKEY *pkey = ctx->pkey;
+ void *key;
+ EVP_KEYMGMT *keymgmt;
+
+ if (pkey == NULL) {
+ EVPerr(EVP_F_EVP_PKEY_PARAM_CHECK, EVP_R_NO_KEY_SET);
+ return 0;
+ }
+
+ keymgmt = pkey->pkeys[0].keymgmt;
+ key = pkey->pkeys[0].provdata;
+
+ if (key != NULL && keymgmt != NULL)
+ return evp_keymgmt_validate_domparams(keymgmt, key);
+
+ /* call customized param check function first */
+ if (ctx->pmeth->param_check != NULL)
+ return ctx->pmeth->param_check(pkey);
+
+ /* legacy */
+ /* use default param check function in ameth */
+ if (pkey->ameth == NULL || pkey->ameth->pkey_param_check == NULL) {
+ EVPerr(EVP_F_EVP_PKEY_PARAM_CHECK,
+ EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return -2;
+ }
+
+ return pkey->ameth->pkey_param_check(pkey);
+}
+
+int EVP_PKEY_private_check(EVP_PKEY_CTX *ctx)
+{
+ EVP_PKEY *pkey = ctx->pkey;
+ void *key;
+ EVP_KEYMGMT *keymgmt;
+
+ if (pkey == NULL) {
+ EVPerr(0, EVP_R_NO_KEY_SET);
+ return 0;
+ }
+
+ keymgmt = pkey->pkeys[0].keymgmt;
+ key = pkey->pkeys[0].provdata;
+
+ if (key != NULL && keymgmt != NULL)
+ return evp_keymgmt_validate_private(keymgmt, key);
+ /* not supported for legacy keys */
+ return -2;
+}
+
+int EVP_PKEY_pairwise_check(EVP_PKEY_CTX *ctx)
+{
+ EVP_PKEY *pkey = ctx->pkey;
+ void *key;
+ EVP_KEYMGMT *keymgmt;
+
+ if (pkey == NULL) {
+ EVPerr(0, EVP_R_NO_KEY_SET);
+ return 0;
+ }
+
+ keymgmt = pkey->pkeys[0].keymgmt;
+ key = pkey->pkeys[0].provdata;
+
+ if (key != NULL && keymgmt != NULL)
+ return evp_keymgmt_validate_pairwise(keymgmt, key);
+ /* not supported for legacy keys */
+ return -2;
+}
+
+int EVP_PKEY_check(EVP_PKEY_CTX *ctx)
+{
+ EVP_PKEY *pkey = ctx->pkey;
+ void *key;
+ EVP_KEYMGMT *keymgmt;
+
+ if (pkey == NULL) {
+ EVPerr(EVP_F_EVP_PKEY_CHECK, EVP_R_NO_KEY_SET);
+ return 0;
+ }
+
+ keymgmt = pkey->pkeys[0].keymgmt;
+ key = pkey->pkeys[0].provdata;
+
+ if (key != NULL && keymgmt != NULL) {
+ return evp_keymgmt_validate_domparams(keymgmt, key)
+ && evp_keymgmt_validate_public(keymgmt, key)
+ && evp_keymgmt_validate_private(keymgmt, key)
+ && evp_keymgmt_validate_pairwise(keymgmt, key);
+ }
+ /* legacy */
+ /* call customized check function first */
+ if (ctx->pmeth->check != NULL)
+ return ctx->pmeth->check(pkey);
+
+ /* use default check function in ameth */
+ if (pkey->ameth == NULL || pkey->ameth->pkey_check == NULL) {
+ EVPerr(EVP_F_EVP_PKEY_CHECK,
+ EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return -2;
+ }
+
+ return pkey->ameth->pkey_check(pkey);
+}
+
diff --git a/crypto/evp/pmeth_gn.c b/crypto/evp/pmeth_gn.c
index 14c5fd4b99..a093337e62 100644
--- a/crypto/evp/pmeth_gn.c
+++ b/crypto/evp/pmeth_gn.c
@@ -171,75 +171,6 @@ EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e,
return mac_key;
}
-int EVP_PKEY_check(EVP_PKEY_CTX *ctx)
-{
- EVP_PKEY *pkey = ctx->pkey;
-
- if (pkey == NULL) {
- EVPerr(EVP_F_EVP_PKEY_CHECK, EVP_R_NO_KEY_SET);
- return 0;
- }
-
- /* call customized check function first */
- if (ctx->pmeth->check != NULL)
- return ctx->pmeth->check(pkey);
-
- /* use default check function in ameth */
- if (pkey->ameth == NULL || pkey->ameth->pkey_check == NULL) {
- EVPerr(EVP_F_EVP_PKEY_CHECK,
- EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
- return -2;
- }
-
- return pkey->ameth->pkey_check(pkey);
-}
-
-int EVP_PKEY_public_check(EVP_PKEY_CTX *ctx)
-{
- EVP_PKEY *pkey = ctx->pkey;
-
- if (pkey == NULL) {
- EVPerr(EVP_F_EVP_PKEY_PUBLIC_CHECK, EVP_R_NO_KEY_SET);
- return 0;
- }
-
- /* call customized public key check function first */
- if (ctx->pmeth->public_check != NULL)
- return ctx->pmeth->public_check(pkey);
-
- /* use default public key check function in ameth */
- if (pkey->ameth == NULL || pkey->ameth->pkey_public_check == NULL) {
- EVPerr(EVP_F_EVP_PKEY_PUBLIC_CHECK,
- EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
- return -2;
- }
-
- return pkey->ameth->pkey_public_check(pkey);
-}
-
-int EVP_PKEY_param_check(EVP_PKEY_CTX *ctx)
-{
- EVP_PKEY *pkey = ctx->pkey;
-
- if (pkey == NULL) {
- EVPerr(EVP_F_EVP_PKEY_PARAM_CHECK, EVP_R_NO_KEY_SET);
- return 0;
- }
-
- /* call customized param check function first */
- if (ctx->pmeth->param_check != NULL)
- return ctx->pmeth->param_check(pkey);
-
- /* use default param check function in ameth */
- if (pkey->ameth == NULL || pkey->ameth->pkey_param_check == NULL) {
- EVPerr(EVP_F_EVP_PKEY_PARAM_CHECK,
- EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
- return -2;
- }
-
- return pkey->ameth->pkey_param_check(pkey);
-}
-
#endif /* FIPS_MODE */
/*- All methods below can also be used in FIPS_MODE */
@@ -327,5 +258,3 @@ const OSSL_PARAM *EVP_PKEY_key_fromdata_settable(EVP_PKEY_CTX *ctx)
return evp_keymgmt_importdomparam_types(ctx->keymgmt);
return NULL;
}
-
-
diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c
index 03d6ab4da4..dda9358c4e 100644
--- a/crypto/evp/pmeth_lib.c
+++ b/crypto/evp/pmeth_lib.c
@@ -379,7 +379,6 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e)
return int_ctx_new(NULL, NULL, e, NULL, NULL, id);
}
-
EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx)
{
EVP_PKEY_CTX *rctx;