Patch "pastekey" fixes a crash pasting an encrypted private key. Patch "revokedel" fixes a freeze when deleting a certificate. Patch "delete_after_revoke" fixes a crash deleting+revoking a certificate.
90 lines
2.9 KiB
Diff
90 lines
2.9 KiB
Diff
From d29d55ab20509d3e7d279f1fcd85374b5fecdcd8 Mon Sep 17 00:00:00 2001
|
|
From: Christian Hohnstaedt <christian@hohnstaedt.de>
|
|
Date: Thu, 2 Nov 2023 14:06:12 +0100
|
|
Subject: [PATCH] Close #477: paste an encrypted private key results in a crash
|
|
|
|
Improve error- and password handling:
|
|
- Also identify: (ERR_LIB_PROV:PROV_R_BAD_DECRYPT) as password error.
|
|
- Do not use the OpenSSL internal bitfield definition (0xff000fff)
|
|
but the official API: ERR_GET_LIB(), ERR_GET_REASON()
|
|
Especially ERR_LIB_OFFSET changed from 24 to 23 in Openssl 3.0.0
|
|
- First check for "Cancel", then for invalid password to avoid
|
|
an "Invalid Password" message after aborting the password input dialog.
|
|
---
|
|
lib/pki_evp.cpp | 16 +++++++++++-----
|
|
lib/pki_multi.cpp | 3 +++
|
|
2 files changed, 14 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/lib/pki_evp.cpp b/lib/pki_evp.cpp
|
|
index d2097ed2..54846d5c 100644
|
|
--- a/lib/pki_evp.cpp
|
|
+++ b/lib/pki_evp.cpp
|
|
@@ -22,6 +22,7 @@
|
|
#include <openssl/pem.h>
|
|
#include <openssl/pkcs12.h>
|
|
#include <openssl/err.h>
|
|
+#include <openssl/proverr.h>
|
|
|
|
Passwd pki_evp::passwd;
|
|
|
|
@@ -213,10 +214,14 @@ pki_evp::pki_evp(EVP_PKEY *pkey)
|
|
|
|
bool pki_evp::openssl_pw_error() const
|
|
{
|
|
- switch (ERR_peek_error() & 0xff000fff) {
|
|
+ unsigned long e = ERR_peek_error();
|
|
+
|
|
+ switch (ERR_PACK(ERR_GET_LIB(e), 0, ERR_GET_REASON(e))) {
|
|
case ERR_PACK(ERR_LIB_PEM, 0, PEM_R_BAD_DECRYPT):
|
|
case ERR_PACK(ERR_LIB_PEM, 0, PEM_R_BAD_PASSWORD_READ):
|
|
case ERR_PACK(ERR_LIB_EVP, 0, EVP_R_BAD_DECRYPT):
|
|
+ case ERR_PACK(ERR_LIB_PROV, 0, PROV_R_BAD_DECRYPT):
|
|
+ case ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_PKCS12_CIPHERFINAL_ERROR):
|
|
pki_ign_openssl_error();
|
|
return true;
|
|
}
|
|
@@ -230,14 +235,15 @@ void pki_evp::fromPEMbyteArray(const QByteArray &ba, const QString &name)
|
|
tr("Please enter the password to decrypt the private key %1.")
|
|
.arg(name));
|
|
pkey = load_ssh_ed25519_privatekey(ba, p);
|
|
+ pki_ign_openssl_error();
|
|
|
|
while (!pkey) {
|
|
pkey = PEM_read_bio_PrivateKey(BioByteArray(ba).ro(), NULL,
|
|
PwDialogCore::pwCallback, &p);
|
|
- if (openssl_pw_error())
|
|
- XCA_PASSWD_ERROR();
|
|
if (p.getResult() != pw_ok)
|
|
throw p.getResult();
|
|
+ if (openssl_pw_error())
|
|
+ XCA_PASSWD_ERROR();
|
|
if (pki_ign_openssl_error())
|
|
break;
|
|
}
|
|
@@ -396,10 +402,10 @@ void pki_evp::fload(const QString &fname)
|
|
do {
|
|
pkey = PEM_read_bio_PrivateKey(BioByteArray(ba).ro(),
|
|
NULL, cb, &p);
|
|
- if (openssl_pw_error())
|
|
- XCA_PASSWD_ERROR();
|
|
if (p.getResult() != pw_ok)
|
|
throw p.getResult();
|
|
+ if (openssl_pw_error())
|
|
+ XCA_PASSWD_ERROR();
|
|
if (pki_ign_openssl_error())
|
|
break;
|
|
} while (!pkey);
|
|
diff --git a/lib/pki_multi.cpp b/lib/pki_multi.cpp
|
|
index 1ed81035..f3c6332e 100644
|
|
--- a/lib/pki_multi.cpp
|
|
+++ b/lib/pki_multi.cpp
|
|
@@ -127,6 +127,9 @@ void pki_multi::fromPEMbyteArray(const QByteArray &_ba, const QString &name)
|
|
XCA_ERROR(err);
|
|
delete item;
|
|
item = NULL;
|
|
+ } catch (...) {
|
|
+ delete item;
|
|
+ item = NULL;
|
|
}
|
|
ba.remove(0, sizeof BEGIN -1);
|
|
}
|