xca/xca-2.5-pastekey.patch
Patrick Monnerat ac87b08d92 Fix crashes
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.
2024-01-25 08:45:44 +01:00

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);
}