diff options
author | Shane Lontis <shane.lontis@oracle.com> | 2020-01-29 20:32:32 +1000 |
---|---|---|
committer | Shane Lontis <shane.lontis@oracle.com> | 2020-01-29 20:32:32 +1000 |
commit | 12603de634fe628488066d1f3f2c720ca20d6df9 (patch) | |
tree | a7345e533ae5811eeb682a7cf8d02c6a8008b6f6 /crypto/evp | |
parent | a76ce2862bc6ae2cf8a749c8747d371041fc42d1 (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.info | 3 | ||||
-rw-r--r-- | crypto/evp/evp_local.h | 4 | ||||
-rw-r--r-- | crypto/evp/keymgmt_lib.c | 23 | ||||
-rw-r--r-- | crypto/evp/keymgmt_meth.c | 24 | ||||
-rw-r--r-- | crypto/evp/pmeth_check.c | 158 | ||||
-rw-r--r-- | crypto/evp/pmeth_gn.c | 71 | ||||
-rw-r--r-- | crypto/evp/pmeth_lib.c | 1 |
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; |