OSSL_STORE: restore diagnostics on decrypt error; provide password hints

Fixes #13493

Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/13525)
This commit is contained in:
Dr. David von Oheimb 2020-11-26 08:35:26 +01:00 committed by Dr. David von Oheimb
parent e3a2ba7547
commit 39a61e69b8
4 changed files with 24 additions and 11 deletions

View File

@ -13,6 +13,7 @@
#include <openssl/provider.h> #include <openssl/provider.h>
#include <openssl/evperr.h> #include <openssl/evperr.h>
#include <openssl/ecerr.h> #include <openssl/ecerr.h>
#include <openssl/pkcs12err.h>
#include <openssl/x509err.h> #include <openssl/x509err.h>
#include <openssl/trace.h> #include <openssl/trace.h>
#include "internal/passphrase.h" #include "internal/passphrase.h"
@ -511,7 +512,7 @@ static int decoder_process(const OSSL_PARAM params[], void *arg)
BIO *bio = data->bio; BIO *bio = data->bio;
long loc; long loc;
size_t i; size_t i;
int err, ok = 0; int err, lib, reason, ok = 0;
/* For recursions */ /* For recursions */
struct decoder_process_data_st new_data; struct decoder_process_data_st new_data;
const char *data_type = NULL; const char *data_type = NULL;
@ -750,14 +751,16 @@ static int decoder_process(const OSSL_PARAM params[], void *arg)
* errors, so we preserve them in the error queue and stop. * errors, so we preserve them in the error queue and stop.
*/ */
err = ERR_peek_last_error(); err = ERR_peek_last_error();
if ((ERR_GET_LIB(err) == ERR_LIB_EVP lib = ERR_GET_LIB(err);
&& ERR_GET_REASON(err) == EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM) reason = ERR_GET_REASON(err);
if ((lib == ERR_LIB_EVP
&& reason == EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM)
#ifndef OPENSSL_NO_EC #ifndef OPENSSL_NO_EC
|| (ERR_GET_LIB(err) == ERR_LIB_EC || (lib == ERR_LIB_EC && reason == EC_R_UNKNOWN_GROUP)
&& ERR_GET_REASON(err) == EC_R_UNKNOWN_GROUP)
#endif #endif
|| (ERR_GET_LIB(err) == ERR_LIB_X509 || (lib == ERR_LIB_X509 && reason == X509_R_UNSUPPORTED_ALGORITHM)
&& ERR_GET_REASON(err) == X509_R_UNSUPPORTED_ALGORITHM)) || (lib == ERR_LIB_PKCS12
&& reason == PKCS12_R_PKCS12_CIPHERFINAL_ERROR))
goto end; goto end;
} }

View File

@ -81,7 +81,9 @@ unsigned char *PKCS12_pbe_crypt(const X509_ALGOR *algor,
if (!EVP_CipherFinal_ex(ctx, out + i, &i)) { if (!EVP_CipherFinal_ex(ctx, out + i, &i)) {
OPENSSL_free(out); OPENSSL_free(out);
out = NULL; out = NULL;
ERR_raise(ERR_LIB_PKCS12, PKCS12_R_PKCS12_CIPHERFINAL_ERROR); ERR_raise_data(ERR_LIB_PKCS12, PKCS12_R_PKCS12_CIPHERFINAL_ERROR,
passlen == 0 ? "empty password"
: "maybe wrong password");
goto err; goto err;
} }
outlen += i; outlen += i;

View File

@ -564,8 +564,10 @@ static int try_pkcs12(struct extracted_param_data_st *data, OSSL_STORE_INFO **v,
} }
pass = tpass; pass = tpass;
if (!PKCS12_verify_mac(p12, pass, strlen(pass))) { if (!PKCS12_verify_mac(p12, pass, strlen(pass))) {
ERR_raise(ERR_LIB_OSSL_STORE, ERR_raise_data(ERR_LIB_OSSL_STORE,
OSSL_STORE_R_ERROR_VERIFYING_PKCS12_MAC); OSSL_STORE_R_ERROR_VERIFYING_PKCS12_MAC,
strlen(pass) == 0 ? "empty password" :
"maybe wrong password");
goto p12_end; goto p12_end;
} }
} }

View File

@ -260,6 +260,7 @@ static int der2key_decode(void *vctx, OSSL_CORE_BIO *cin, int selection,
EVP_PKEY *pkey = NULL; EVP_PKEY *pkey = NULL;
void *key = NULL; void *key = NULL;
int orig_selection = selection; int orig_selection = selection;
int dec_err;
int ok = 0; int ok = 0;
/* /*
@ -319,8 +320,13 @@ static int der2key_decode(void *vctx, OSSL_CORE_BIO *cin, int selection,
der = new_der; der = new_der;
der_len = new_der_len; der_len = new_der_len;
} }
RESET_ERR_MARK(); /* decryption errors are fatal and should be reported */
dec_err = ERR_peek_last_error();
if (ERR_GET_LIB(dec_err) == ERR_LIB_PROV
&& ERR_GET_REASON(dec_err) == PROV_R_BAD_DECRYPT)
goto end;
RESET_ERR_MARK();
if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
derp = der; derp = der;
pkey = evp_privatekey_from_binary(ctx->desc->evp_type, NULL, pkey = evp_privatekey_from_binary(ctx->desc->evp_type, NULL,