diff options
author | Paul Yang <yang.yang@baishancloud.com> | 2017-09-04 22:02:59 +0800 |
---|---|---|
committer | Richard Levitte <levitte@openssl.org> | 2017-09-13 20:38:14 +0200 |
commit | 2aee35d37d5161a2efc4d57953a4a7b234b6ea4c (patch) | |
tree | 396369a86192ce41ecda126ad46fb0bbc8eae593 /crypto | |
parent | c061daaaed5ef05cd8cf0b8159d717be02fd451d (diff) |
Support key check in EVP interface
A new method is added to EVP_PKEY_METH as:
int (*check) (EVP_PKEY_CTX *ctx);
and to EVP_PKEY_ASN1_METHOD as:
int (*pkey_check) (EVP_PKEY_CTX *ctx);
This is used to check the validity of a specific key.
The order of calls is:
EVP_PKEY_check -> pmeth.check -> ameth.pkey_check.
Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/4337)
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/ec/ec_ameth.c | 19 | ||||
-rw-r--r-- | crypto/err/openssl.txt | 1 | ||||
-rw-r--r-- | crypto/evp/evp_err.c | 1 | ||||
-rw-r--r-- | crypto/evp/pmeth_gn.c | 24 | ||||
-rw-r--r-- | crypto/evp/pmeth_lib.c | 15 | ||||
-rw-r--r-- | crypto/include/internal/asn1_int.h | 2 | ||||
-rw-r--r-- | crypto/include/internal/evp_int.h | 1 | ||||
-rw-r--r-- | crypto/rsa/rsa_ameth.c | 10 |
8 files changed, 71 insertions, 2 deletions
diff --git a/crypto/ec/ec_ameth.c b/crypto/ec/ec_ameth.c index b66adf2bbc..ecf1a0207d 100644 --- a/crypto/ec/ec_ameth.c +++ b/crypto/ec/ec_ameth.c @@ -520,6 +520,19 @@ static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) } +static int ec_pkey_check(const EVP_PKEY *pkey) +{ + EC_KEY *eckey = pkey->pkey.ec; + + /* stay consistent to what EVP_PKEY_check demands */ + if (eckey->priv_key == NULL) { + ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_MISSING_PRIVATE_KEY); + return 0; + } + + return EC_KEY_check_key(eckey); +} + const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = { EVP_PKEY_EC, EVP_PKEY_EC, @@ -551,7 +564,11 @@ const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = { int_ec_free, ec_pkey_ctrl, old_ec_priv_decode, - old_ec_priv_encode + old_ec_priv_encode, + + 0, 0, 0, + + ec_pkey_check }; int EC_KEY_print(BIO *bp, const EC_KEY *x, int off) diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index 253e0ab29c..b05d4599af 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -661,6 +661,7 @@ EVP_F_EVP_PBE_CIPHERINIT:116:EVP_PBE_CipherInit EVP_F_EVP_PBE_SCRYPT:181:EVP_PBE_scrypt EVP_F_EVP_PKCS82PKEY:111:EVP_PKCS82PKEY EVP_F_EVP_PKEY2PKCS8:113:EVP_PKEY2PKCS8 +EVP_F_EVP_PKEY_CHECK:186:EVP_PKEY_check EVP_F_EVP_PKEY_COPY_PARAMETERS:103:EVP_PKEY_copy_parameters EVP_F_EVP_PKEY_CTX_CTRL:137:EVP_PKEY_CTX_ctrl EVP_F_EVP_PKEY_CTX_CTRL_STR:150:EVP_PKEY_CTX_ctrl_str diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c index c8161965d8..cc32a3bfde 100644 --- a/crypto/evp/evp_err.c +++ b/crypto/evp/evp_err.c @@ -55,6 +55,7 @@ static const ERR_STRING_DATA EVP_str_functs[] = { {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PBE_SCRYPT, 0), "EVP_PBE_scrypt"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKCS82PKEY, 0), "EVP_PKCS82PKEY"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY2PKCS8, 0), "EVP_PKEY2PKCS8"}, + {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CHECK, 0), "EVP_PKEY_check"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_COPY_PARAMETERS, 0), "EVP_PKEY_copy_parameters"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_CTX_CTRL, 0), "EVP_PKEY_CTX_ctrl"}, diff --git a/crypto/evp/pmeth_gn.c b/crypto/evp/pmeth_gn.c index 6adc3a9c19..1a927a8320 100644 --- a/crypto/evp/pmeth_gn.c +++ b/crypto/evp/pmeth_gn.c @@ -13,6 +13,7 @@ #include <openssl/objects.h> #include <openssl/evp.h> #include "internal/bn_int.h" +#include "internal/asn1_int.h" #include "internal/evp_int.h" int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx) @@ -167,3 +168,26 @@ EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, EVP_PKEY_CTX_free(mac_ctx); 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); +} diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c index 71ec099440..c62bd81da4 100644 --- a/crypto/evp/pmeth_lib.c +++ b/crypto/evp/pmeth_lib.c @@ -219,6 +219,8 @@ void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src) dst->ctrl = src->ctrl; dst->ctrl_str = src->ctrl_str; + + dst->check = src->check; } void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth) @@ -603,6 +605,12 @@ void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth, pmeth->ctrl_str = ctrl_str; } +void EVP_PKEY_meth_set_check(EVP_PKEY_METHOD *pmeth, + int (*check) (EVP_PKEY *pkey)) +{ + pmeth->check = check; +} + void EVP_PKEY_meth_get_init(EVP_PKEY_METHOD *pmeth, int (**pinit) (EVP_PKEY_CTX *ctx)) { @@ -769,3 +777,10 @@ void EVP_PKEY_meth_get_ctrl(EVP_PKEY_METHOD *pmeth, if (pctrl_str) *pctrl_str = pmeth->ctrl_str; } + +void EVP_PKEY_meth_get_check(EVP_PKEY_METHOD *pmeth, + int (**pcheck) (EVP_PKEY *pkey)) +{ + if (*pcheck) + *pcheck = pmeth->check; +} diff --git a/crypto/include/internal/asn1_int.h b/crypto/include/internal/asn1_int.h index 8ff919c8fa..d8b6f45bd8 100644 --- a/crypto/include/internal/asn1_int.h +++ b/crypto/include/internal/asn1_int.h @@ -54,6 +54,8 @@ struct evp_pkey_asn1_method_st { ASN1_BIT_STRING *sig); int (*siginf_set) (X509_SIG_INFO *siginf, const X509_ALGOR *alg, const ASN1_STRING *sig); + /* Check */ + int (*pkey_check) (const EVP_PKEY *pk); } /* EVP_PKEY_ASN1_METHOD */ ; DEFINE_STACK_OF_CONST(EVP_PKEY_ASN1_METHOD) diff --git a/crypto/include/internal/evp_int.h b/crypto/include/internal/evp_int.h index be1b9be926..b9558a60d4 100644 --- a/crypto/include/internal/evp_int.h +++ b/crypto/include/internal/evp_int.h @@ -75,6 +75,7 @@ struct evp_pkey_method_st { int (*digestverify) (EVP_MD_CTX *ctx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbslen); + int (*check) (EVP_PKEY *pkey); } /* EVP_PKEY_METHOD */ ; DEFINE_STACK_OF_CONST(EVP_PKEY_METHOD) diff --git a/crypto/rsa/rsa_ameth.c b/crypto/rsa/rsa_ameth.c index 42138ce9eb..97a37ba47d 100644 --- a/crypto/rsa/rsa_ameth.c +++ b/crypto/rsa/rsa_ameth.c @@ -984,6 +984,11 @@ static int rsa_cms_encrypt(CMS_RecipientInfo *ri) } #endif +static int rsa_pkey_check(const EVP_PKEY *pkey) +{ + return RSA_check_key_ex(pkey->pkey.rsa, NULL); +} + const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[2] = { { EVP_PKEY_RSA, @@ -1015,7 +1020,8 @@ const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[2] = { old_rsa_priv_encode, rsa_item_verify, rsa_item_sign, - rsa_sig_info_set + rsa_sig_info_set, + rsa_pkey_check }, { @@ -1053,4 +1059,6 @@ const EVP_PKEY_ASN1_METHOD rsa_pss_asn1_meth = { 0, 0, rsa_item_verify, rsa_item_sign, + 0, + rsa_pkey_check }; |