From e0d8523e801b7a1fcdda698f9c28dd7a0617cd02 Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Tue, 7 Jan 2020 11:49:08 +0100 Subject: [PATCH] EVP: If a key can't be exported to provider, fallback to legacy Currently, the operations that do try to export a legacy key to providers will fail if the export failed. It makes more sense to simply use the legacy method instead, as a fallback for things not being implemented (yet) in a provider. Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/10771) --- crypto/evp/exchange.c | 16 +++++++--------- crypto/evp/m_sigver.c | 18 +++++++++++------- crypto/evp/pmeth_fn.c | 14 ++++++-------- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/crypto/evp/exchange.c b/crypto/evp/exchange.c index 189c1c0f45..3e7c00103c 100644 --- a/crypto/evp/exchange.c +++ b/crypto/evp/exchange.c @@ -208,10 +208,9 @@ int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx) if (ctx->pkey != NULL) { provkey = evp_keymgmt_export_to_provider(ctx->pkey, ctx->keymgmt, 0); - if (provkey == NULL) { - EVPerr(0, EVP_R_INITIALIZATION_ERROR); - goto err; - } + /* If export failed, legacy may be able to pick it up */ + if (provkey == NULL) + goto legacy; } ctx->op.kex.exchprovctx = exchange->newctx(ossl_provider_ctx(exchange->prov)); if (ctx->op.kex.exchprovctx == NULL) { @@ -227,7 +226,7 @@ int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx) return 0; legacy: - if (ctx == NULL || ctx->pmeth == NULL || ctx->pmeth->derive == NULL) { + if (ctx->pmeth == NULL || ctx->pmeth->derive == NULL) { EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); return -2; } @@ -261,10 +260,9 @@ int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) } provkey = evp_keymgmt_export_to_provider(peer, ctx->keymgmt, 0); - if (provkey == NULL) { - EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, ERR_R_INTERNAL_ERROR); - return 0; - } + /* If export failed, legacy may be able to pick it up */ + if (provkey == NULL) + goto legacy; return ctx->op.kex.exchange->set_peer(ctx->op.kex.exchprovctx, provkey); legacy: diff --git a/crypto/evp/m_sigver.c b/crypto/evp/m_sigver.c index 7a21f680b9..9d12e9b96a 100644 --- a/crypto/evp/m_sigver.c +++ b/crypto/evp/m_sigver.c @@ -104,6 +104,12 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, locpctx->op.sig.signature = signature; + provkey = + evp_keymgmt_export_to_provider(locpctx->pkey, locpctx->keymgmt, 0); + /* If export failed, legacy may be able to pick it up */ + if (provkey == NULL) + goto legacy; + locpctx->operation = ver ? EVP_PKEY_OP_VERIFYCTX : EVP_PKEY_OP_SIGNCTX; @@ -113,13 +119,6 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); goto err; } - provkey = - evp_keymgmt_export_to_provider(locpctx->pkey, locpctx->keymgmt, 0); - if (provkey == NULL) { - ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); - goto err; - } - if (type != NULL) { ctx->reqdigest = type; } else { @@ -156,6 +155,11 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, return 0; legacy: + if (ctx->pctx->pmeth == NULL) { + EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + if (!(ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM)) { if (type == NULL) { diff --git a/crypto/evp/pmeth_fn.c b/crypto/evp/pmeth_fn.c index 638619051e..0ce4ff9522 100644 --- a/crypto/evp/pmeth_fn.c +++ b/crypto/evp/pmeth_fn.c @@ -367,10 +367,9 @@ static int evp_pkey_signature_init(EVP_PKEY_CTX *ctx, int operation) if (ctx->pkey != NULL) { provkey = evp_keymgmt_export_to_provider(ctx->pkey, ctx->keymgmt, 0); - if (provkey == NULL) { - EVPerr(0, EVP_R_INITIALIZATION_ERROR); - goto err; - } + /* If export failed, legacy may be able to pick it up */ + if (provkey == NULL) + goto legacy; } ctx->op.sig.sigprovctx = signature->newctx(ossl_provider_ctx(signature->prov)); if (ctx->op.sig.sigprovctx == NULL) { @@ -617,10 +616,9 @@ static int evp_pkey_asym_cipher_init(EVP_PKEY_CTX *ctx, int operation) if (ctx->pkey != NULL) { provkey = evp_keymgmt_export_to_provider(ctx->pkey, ctx->keymgmt, 0); - if (provkey == NULL) { - EVPerr(0, EVP_R_INITIALIZATION_ERROR); - goto err; - } + /* If export failed, legacy may be able to pick it up */ + if (provkey == NULL) + goto legacy; } ctx->op.ciph.ciphprovctx = cipher->newctx(ossl_provider_ctx(cipher->prov)); if (ctx->op.ciph.ciphprovctx == NULL) {