Compare commits

..

2 commits

Author SHA1 Message Date
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
Patrick Monnerat
8fbcdf0907 New upstream release.
Build using cmake.
Doc file "README.IMPORTANT" for needed passord reset.
2023-10-07 00:54:15 +02:00
8 changed files with 190 additions and 595 deletions

3
.gitignore vendored
View file

@ -14,6 +14,3 @@ xca-0.8.1.tar.gz
/xca-2.3.0.tar.gz
/xca-2.4.0.tar.gz
/xca-2.5.0.tar.gz
/xca-2.6.0.tar.gz
/xca-2.7.0.tar.gz
/xca-2.9.0.tar.gz

View file

@ -1 +1 @@
SHA512 (xca-2.9.0.tar.gz) = e635b83668d0053acb1ad5a8a20a2a1854de90a1e2a8806ecd38e83528d17bc87042d44fcea0f75f2e17df1ed135cc473449547fe273e7e3ea1fe175a4ddf054
SHA512 (xca-2.5.0.tar.gz) = 36b9b97ff0649934fbe78e38048e75883555aab5d86ee2cbd629f9789326d16463f182cf0bbcc76b1ac8f631b24fa187f1b64c466e04de010724ea5f9ebfa11e

View file

@ -0,0 +1,23 @@
diff -Naurp xca-2.5.0.orig/lib/db_x509.cpp xca-2.5.0.new/lib/db_x509.cpp
--- xca-2.5.0.orig/lib/db_x509.cpp 2023-09-24 20:22:03.000000000 +0200
+++ xca-2.5.0.new/lib/db_x509.cpp 2024-01-22 08:22:11.704982550 +0100
@@ -768,13 +768,15 @@ void db_x509::certRenewal(QModelIndexLis
newcert->sign(signkey, oldcert->getDigest());
newcert = dynamic_cast<pki_x509 *>(insert(newcert));
createSuccess(newcert);
-
- // delete old certificate if requested
- if (doReplace)
- deletePKI(idx);
}
if (doRevoke)
do_revoke(indexes, r);
+
+ // delete old certificates if requested
+ if (doReplace)
+ foreach(idx, indexes)
+ if (fromIndex<pki_x509>(idx))
+ deletePKI(idx);
}
catch (errorEx &err) {
XCA_ERROR(err);

90
xca-2.5-pastekey.patch Normal file
View file

@ -0,0 +1,90 @@
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);
}

46
xca-2.5-revokedel.patch Normal file
View file

@ -0,0 +1,46 @@
From 43e1b336d23e7512b246da142c78307baad4cbff Mon Sep 17 00:00:00 2001
From: Christian Hohnstaedt <christian@hohnstaedt.de>
Date: Mon, 30 Oct 2023 01:11:30 +0100
Subject: [PATCH] Fix crash when deleting CA certificates
If a CA certificate is deleted, all issued certificates must be moved to
an other issuer or the top-level list.
The CA cert will be taken from the model together with the issued certs
first. Then the issued certs are re-inserted.
To make this work correctly, the issuer must be erased from the issued certs
to be interpreted as insertion and not as move.
---
lib/db_base.cpp | 2 +-
lib/pki_base.cpp | 5 ++++-
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/lib/db_base.cpp b/lib/db_base.cpp
index 4d7cc87d..a2e4250f 100644
--- a/lib/db_base.cpp
+++ b/lib/db_base.cpp
@@ -302,7 +302,7 @@ void db_base::insertChild(pki_base *child, pki_base *parent)
if (parent != treeItem && treeview)
idx = index(parent);
- if (curr_parent) { // && curr_parent != parent)
+ if (curr_parent) {
int row = curr_parent->indexOf(child);
beginMoveRows(index(curr_parent), row, row, idx, 0);
curr_parent->takeChild(child);
diff --git a/lib/pki_base.cpp b/lib/pki_base.cpp
index 62ca3ac5..77722cb2 100644
--- a/lib/pki_base.cpp
+++ b/lib/pki_base.cpp
@@ -269,7 +269,10 @@ QList<pki_base*> pki_base::getChildItems() const
pki_base *pki_base::takeFirst()
{
- return childItems.takeFirst();
+ pki_base *pki = childItems.takeFirst();
+ if (pki)
+ pki->setParent(nullptr);
+ return pki;
}
QString pki_base::pki_source_name() const

View file

@ -1,6 +1,5 @@
When trying to use a private key when working on a database protected by
a password set by xca version < 2.0.0, version 2.5.0 and above might issue an
error like:
a password set by xca version < 2.0.0, version 2.5.0 might issue an error like:
---
The following error occurred:
@ -23,6 +22,6 @@ If some private keys have their own password, reset the latter the same
way (right click --> Change password).
Once these operations have been performed, the database is ready for use with
xca version >= 2.5.
xca version 2.5.
See https://github.com/chris2511/xca/discussions/468.

View file

@ -1,504 +0,0 @@
diff -Naurp xca-2.9.0.orig/lib/asn1int.cpp xca-2.9.0.new/lib/asn1int.cpp
--- xca-2.9.0.orig/lib/asn1int.cpp 2025-03-28 19:28:15.000000000 +0100
+++ xca-2.9.0.new/lib/asn1int.cpp 2026-07-21 14:50:45.138768332 +0200
@@ -10,6 +10,7 @@
#include "func_base.h"
#include "exception.h"
#include "limits.h"
+#include "openssl_compat.h"
#include <openssl/err.h>
#include <openssl/bn.h>
@@ -67,7 +68,7 @@ a1int &a1int::set(long l)
QString a1int::toQString(int dec) const
{
QString r;
- if (in->length == 0) {
+ if (xca_asn1_string_length(in.get()) == 0) {
return r;
}
QSharedPointer<BIGNUM> bn(ASN1_INTEGER_to_BN(get0(), NULL), BN_free);
diff -Naurp xca-2.9.0.orig/lib/asn1time.cpp xca-2.9.0.new/lib/asn1time.cpp
--- xca-2.9.0.orig/lib/asn1time.cpp 2025-03-28 19:28:15.000000000 +0100
+++ xca-2.9.0.new/lib/asn1time.cpp 2026-07-21 15:48:01.479132516 +0200
@@ -11,6 +11,7 @@
#include "func.h"
#include "exception.h"
#include "asn1time.h"
+#include "openssl_compat.h"
#include <openssl/x509.h>
#include <openssl/err.h>
#include <openssl/opensslv.h>
@@ -50,7 +51,8 @@ int a1time::from_asn1(const ASN1_TIME *a
gt = ASN1_TIME_to_generalizedtime((ASN1_TIME*)a, NULL);
if (!gt)
return -1;
- t = QString::fromLatin1((char*)gt->data, gt->length);
+ t = QString::fromLatin1((char*)xca_asn1_string_get0_data(gt),
+ xca_asn1_string_length(gt));
ASN1_GENERALIZEDTIME_free(gt);
return fromPlain(t);
}
@@ -68,11 +70,15 @@ int a1time::fromPlain(const QString &pla
int a1time::set_asn1(const QString &str, int type) const
{
- if (!atime)
- atime = ASN1_TIME_new();
- if (!atime)
- return -1;
- atime->type = type;
+ if (atime && xca_asn1_string_type(atime) != type) {
+ ASN1_STRING_free(atime);
+ atime = NULL;
+ }
+ if (!atime) {
+ atime = ASN1_STRING_type_new(type);
+ if (!atime)
+ return -1;
+ }
if (ASN1_STRING_set(atime, str.toLatin1(), str.length()))
return -1;
return 0;
diff -Naurp xca-2.9.0.orig/lib/openssl_compat.h xca-2.9.0.new/lib/openssl_compat.h
--- xca-2.9.0.orig/lib/openssl_compat.h 2025-03-28 19:28:15.000000000 +0100
+++ xca-2.9.0.new/lib/openssl_compat.h 2026-07-21 16:05:30.252809689 +0200
@@ -35,4 +35,15 @@ EVP_DigestVerify(EVP_MD_CTX *ctx, const
}
#endif
+
+#if OPENSSL_VERSION_NUMBER < 0x40000000L
+#define xca_asn1_string_length(p) ((p)->length)
+#define xca_asn1_string_get0_data(p) ((p)->data)
+#define xca_asn1_string_type(p) ((p)->type)
+#else
+#define xca_asn1_string_length(p) ASN1_STRING_length(p)
+#define xca_asn1_string_get0_data(p) ASN1_STRING_get0_data(p)
+#define xca_asn1_string_type(p) ASN1_STRING_type(p)
+#endif
+
#endif
diff -Naurp xca-2.9.0.orig/lib/pkcs11.cpp xca-2.9.0.new/lib/pkcs11.cpp
--- xca-2.9.0.orig/lib/pkcs11.cpp 2025-03-28 19:28:15.000000000 +0100
+++ xca-2.9.0.new/lib/pkcs11.cpp 2026-07-22 17:10:39.158463523 +0200
@@ -650,29 +650,6 @@ int pkcs11::encrypt(int flen, const unsi
return size;
}
-#if not defined OPENSSL_NO_EC and defined EVP_PKEY_ED25519
-// Shared between libressl and openssl
-static int eng_idx = -1;
-static int eng_finish(ENGINE *e)
-{
- pkcs11 *p11 = (pkcs11 *)ENGINE_get_ex_data(e, eng_idx);
- delete p11;
- ENGINE_set_ex_data(e, eng_idx, NULL);
- return 1;
-}
-
-#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
-static int eng_pmeth_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
-#else
-static int eng_pmeth_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
-#endif
-{
- void *p = EVP_PKEY_CTX_get_app_data((EVP_PKEY_CTX *)src);
- EVP_PKEY_CTX_set_app_data(dst, p);
- return 1;
-}
-#endif
-
static int rsa_privdata_free(RSA *rsa)
{
pkcs11 *priv = (pkcs11*)RSA_get_app_data(rsa);
@@ -830,10 +807,33 @@ static EC_KEY_METHOD *setup_ec_key_meth(
ec_set_private_proc, ec_set_public_proc);
return ec_key_meth;
}
-#ifdef EVP_PKEY_ED25519
+
+
+#if defined(EVP_PKEY_ED25519) && OPENSSL_VERSION_NUMBER < 0x40000000L
static EVP_PKEY_METHOD *p11_eddsa_method;
+// Shared between libressl and openssl
+static int eng_idx = -1;
+static int eng_finish(ENGINE *e)
+{
+ pkcs11 *p11 = (pkcs11 *)ENGINE_get_ex_data(e, eng_idx);
+ delete p11;
+ ENGINE_set_ex_data(e, eng_idx, NULL);
+ return 1;
+}
+
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+static int eng_pmeth_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
+#else
+static int eng_pmeth_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+#endif
+{
+ void *p = EVP_PKEY_CTX_get_app_data((EVP_PKEY_CTX *)src);
+ EVP_PKEY_CTX_set_app_data(dst, p);
+ return 1;
+}
+
static int eddsa_eng_meths(ENGINE *e, EVP_PKEY_METHOD **m, const int **nids, int nid)
{
static const int my_nids[] = {EVP_PKEY_ED25519 };
@@ -904,7 +904,7 @@ EVP_PKEY *pkcs11::getPrivateKey(EVP_PKEY
#ifndef OPENSSL_NO_EC
static EC_KEY_METHOD *ec_key_meth = NULL;
EC_KEY *ec;
-#ifdef EVP_PKEY_ED25519
+#if defined(EVP_PKEY_ED25519) && OPENSSL_VERSION_NUMBER < 0x40000000L
static ENGINE *e = NULL;
if (!e) {
@@ -991,6 +991,7 @@ EVP_PKEY *pkcs11::getPrivateKey(EVP_PKEY
#ifdef EVP_PKEY_ED25519
case EVP_PKEY_ED25519:
size_t len;
+#if OPENSSL_VERSION_NUMBER < 0x40000000L
if (ENGINE_get_ex_data(e, eng_idx))
qWarning() << "We forgot to free the previous Card key.";
ENGINE_set_ex_data(e, eng_idx, this);
@@ -1003,6 +1004,17 @@ EVP_PKEY *pkcs11::getPrivateKey(EVP_PKEY
openssl_error();
OPENSSL_free(pubkey);
//EVP_PKEY_set1_engine(evp, e);
+#else
+ p11obj = obj;
+ EVP_PKEY_get_raw_public_key(pub, NULL, &len);
+ unsigned char *pubkey = (unsigned char *)OPENSSL_malloc(len);
+ Q_CHECK_PTR(pubkey);
+ EVP_PKEY_get_raw_public_key(pub, pubkey, &len);
+ evp = EVP_PKEY_new_raw_public_key_ex(OSSL_LIB_CTX_get0_global_default(),
+ "ED25519", NULL, pubkey, len);
+ openssl_error();
+ OPENSSL_free(pubkey);
+#endif
break;
#endif
#endif
diff -Naurp xca-2.9.0.orig/lib/pki_pkcs12.cpp xca-2.9.0.new/lib/pki_pkcs12.cpp
--- xca-2.9.0.orig/lib/pki_pkcs12.cpp 2025-03-28 19:28:15.000000000 +0100
+++ xca-2.9.0.new/lib/pki_pkcs12.cpp 2026-07-21 14:41:11.421805953 +0200
@@ -85,7 +85,7 @@ pki_pkcs12::pki_pkcs12(const QString &fn
}
pki_ign_openssl_error();
if (mycert) {
- unsigned char *str = X509_alias_get0(mycert, NULL);
+ const unsigned char *str = X509_alias_get0(mycert, NULL);
if (str)
alias = QString::fromUtf8((const char *)str);
alias = QString::fromUtf8(alias.toLatin1());
diff -Naurp xca-2.9.0.orig/lib/pki_scard.cpp xca-2.9.0.new/lib/pki_scard.cpp
--- xca-2.9.0.orig/lib/pki_scard.cpp 2025-03-28 19:28:15.000000000 +0100
+++ xca-2.9.0.new/lib/pki_scard.cpp 2026-07-21 16:07:19.266072856 +0200
@@ -14,6 +14,7 @@
#include "pkcs11.h"
#include "x509name.h"
#include "func.h"
+#include "openssl_compat.h"
#include "XcaProgress.h"
#include "XcaWarningCore.h"
@@ -187,7 +188,8 @@ EVP_PKEY *pki_scard::load_pubkey(pkcs11
d2i_bytearray(D2I_VOID(d2i_ASN1_OCTET_STRING), ba);
pki_openssl_error();
- BIGNUM *bn = BN_bin2bn(os->data, os->length, NULL);
+ BIGNUM *bn = BN_bin2bn(xca_asn1_string_get0_data(os),
+ xca_asn1_string_length(os), NULL);
pki_openssl_error();
EC_POINT *point = EC_POINT_bn2point(group, bn, NULL, NULL);
@@ -215,8 +217,8 @@ EVP_PKEY *pki_scard::load_pubkey(pkcs11
d2i_bytearray(D2I_VOID(d2i_ASN1_OCTET_STRING), ba);
pki_openssl_error();
pkey = EVP_PKEY_new_raw_public_key(EVP_PKEY_ED25519, NULL,
- (const uint8_t *)os->data,
- os->length);
+ (const uint8_t *)xca_asn1_string_get0_data(os),
+ xca_asn1_string_length(os));
pki_openssl_error();
ASN1_OCTET_STRING_free(os);
pki_openssl_error();
diff -Naurp xca-2.9.0.orig/lib/pki_x509.cpp xca-2.9.0.new/lib/pki_x509.cpp
--- xca-2.9.0.orig/lib/pki_x509.cpp 2025-03-28 19:28:15.000000000 +0100
+++ xca-2.9.0.new/lib/pki_x509.cpp 2026-07-21 16:09:29.644513174 +0200
@@ -836,7 +836,7 @@ pki_key *pki_x509::getPubKey() const
bool pki_x509::compareNameAndKey(pki_x509 *other)
{
int r;
- X509_NAME *s1, *s2;
+ const X509_NAME *s1, *s2;
EVP_PKEY *pub1, *pub2;
if (!cert || !other->cert)
diff -Naurp xca-2.9.0.orig/lib/pki_x509req.cpp xca-2.9.0.new/lib/pki_x509req.cpp
--- xca-2.9.0.orig/lib/pki_x509req.cpp 2025-03-28 19:28:15.000000000 +0100
+++ xca-2.9.0.new/lib/pki_x509req.cpp 2026-07-21 16:11:59.068866756 +0200
@@ -15,6 +15,7 @@
#include "db_base.h"
#include "x509name.h"
#include "exception.h"
+#include "openssl_compat.h"
#include <openssl/bio.h>
pki_x509req::pki_x509req(const QString &name)
@@ -204,7 +205,9 @@ void pki_x509req::addAttribute(int nid,
return;
ASN1_STRING *a = QStringToAsn1(content, nid);
- X509_REQ_add1_attr_by_NID(request, nid, a->type, a->data, a->length);
+ X509_REQ_add1_attr_by_NID(request, nid, xca_asn1_string_type(a),
+ xca_asn1_string_get0_data(a),
+ xca_asn1_string_length(a));
ASN1_STRING_free(a);
openssl_error_msg(QString("'%1' (%2)").arg(content).arg(OBJ_nid2ln(nid)));
}
diff -Naurp xca-2.9.0.orig/lib/x509name.cpp xca-2.9.0.new/lib/x509name.cpp
--- xca-2.9.0.orig/lib/x509name.cpp 2025-03-28 19:28:15.000000000 +0100
+++ xca-2.9.0.new/lib/x509name.cpp 2026-07-21 15:56:14.876877763 +0200
@@ -9,6 +9,7 @@
#include "base.h"
#include "func_base.h"
#include "BioByteArray.h"
+#include "openssl_compat.h"
#include <openssl/asn1.h>
#include <openssl/err.h>
#include "exception.h"
@@ -89,7 +90,7 @@ QString x509name::getMostPopular() const
QString x509name::getEntry(int i) const
{
QString ret;
- ASN1_STRING *d;
+ const ASN1_STRING *d;
if ( i<0 || i>entryCount() )
return ret;
@@ -102,7 +103,7 @@ QString x509name::getEntry(int i) const
QString x509name::getEntryTag(int i) const
{
QString s = QObject::tr("Invalid");
- ASN1_STRING *d;
+ const ASN1_STRING *d;
if (i<0 || i>=entryCount())
i = entryCount() - 1;
@@ -111,7 +112,7 @@ QString x509name::getEntryTag(int i) con
if (!d)
return s;
- s = ASN1_tag2str(d->type);
+ s = ASN1_tag2str(xca_asn1_string_type(d));
return s;
}
@@ -154,13 +155,13 @@ QStringList x509name::entryList(int i) c
int x509name::nid(int i) const
{
- X509_NAME_ENTRY *ne = X509_NAME_get_entry(get0(), i);
+ const X509_NAME_ENTRY *ne = X509_NAME_get_entry(get0(), i);
return ne ? OBJ_obj2nid(X509_NAME_ENTRY_get_object(ne)) : NID_undef;
}
QString x509name::getOid(int i) const
{
- X509_NAME_ENTRY *ne = X509_NAME_get_entry(_get(), i);
+ const X509_NAME_ENTRY *ne = X509_NAME_get_entry(_get(), i);
return ne ? OBJ_obj2QString(X509_NAME_ENTRY_get_object(ne), 1) : QString();
}
@@ -258,7 +259,10 @@ void x509name::addEntryByNid(int nid, co
if (entry.isEmpty())
return;
ASN1_STRING *a = QStringToAsn1(entry.simplified(), nid);
- X509_NAME_add_entry_by_NID(_get(), nid, a->type, a->data, a->length, -1, 0);
+ X509_NAME_add_entry_by_NID(_get(), nid,
+ xca_asn1_string_type(a),
+ xca_asn1_string_get0_data(a),
+ xca_asn1_string_length(a), -1, 0);
ASN1_STRING_free(a);
openssl_error_msg(QString("'%1' (%2)").arg(entry).arg(OBJ_nid2ln(nid)));
}
diff -Naurp xca-2.9.0.orig/lib/x509v3ext.cpp xca-2.9.0.new/lib/x509v3ext.cpp
--- xca-2.9.0.orig/lib/x509v3ext.cpp 2025-03-28 19:28:15.000000000 +0100
+++ xca-2.9.0.new/lib/x509v3ext.cpp 2026-07-22 17:43:52.060374543 +0200
@@ -10,6 +10,7 @@
#include "asn1int.h"
#include "func.h"
#include "exception.h"
+#include "openssl_compat.h"
#include <openssl/x509v3.h>
#include <openssl/stack.h>
#include <QStringList>
@@ -49,8 +50,8 @@ x509v3ext::~x509v3ext()
x509v3ext &x509v3ext::set(const X509_EXTENSION *n)
{
if (n) {
- ASN1_OCTET_STRING *str = X509_EXTENSION_get_data((X509_EXTENSION *)n);
- if (!str || !str->length)
+ const ASN1_OCTET_STRING *str = X509_EXTENSION_get_data((X509_EXTENSION *)n);
+ if (!str || !xca_asn1_string_length(str))
n = nullptr;
}
if (ext != nullptr)
@@ -116,7 +117,7 @@ x509v3ext &x509v3ext::create_ia5(int nid
const ASN1_OBJECT *x509v3ext::object() const
{
- ASN1_OBJECT *obj = nullptr;
+ const ASN1_OBJECT *obj = nullptr;
if (ext) {
obj = X509_EXTENSION_get_object(ext);
ign_openssl_error();
@@ -166,9 +167,9 @@ int x509v3ext::getCritical() const
return ext ? X509_EXTENSION_get_critical(ext) : 0;
}
-ASN1_OCTET_STRING *x509v3ext::getData() const
+const ASN1_OCTET_STRING *x509v3ext::getData() const
{
- return ext ? X509_EXTENSION_get_data(ext) : nullptr;;
+ return ext ? X509_EXTENSION_get_data(ext) : nullptr;
}
QString x509v3ext::getValue() const
@@ -318,7 +319,7 @@ static QString ipv6_from_binary(const un
static bool
genName2conf(GENERAL_NAME *gen, QString tag, QString *single, QString *sect)
{
- unsigned char *p;
+ const unsigned char *p;
QString ret;
switch (gen->type) {
@@ -335,22 +336,23 @@ genName2conf(GENERAL_NAME *gen, QString
return true;
}
case GEN_IPADD:
- p = gen->d.ip->data;
- if (gen->d.ip->length == 4) {
+ p = xca_asn1_string_get0_data(gen->d.ip);
+ if (xca_asn1_string_length(gen->d.ip) == 4) {
*single = QString("IP:%1.%2.%3.%4").
arg(p[0]).arg(p[1]).arg(p[2]).arg(p[3]);
return true;
- } else if(gen->d.ip->length == 8) {
+ } else if(xca_asn1_string_length(gen->d.ip) == 8) {
*single = QString("IP:%1.%2.%3.%4/%5.%6.%7.%8").
arg(p[0]).arg(p[1]).arg(p[2]).arg(p[3]).
arg(p[4]).arg(p[5]).arg(p[6]).arg(p[7]);
return true;
- } else if(gen->d.ip->length == 16) {
- *single = "IP:" + ipv6_from_binary(gen->d.ip->data);
+ } else if(xca_asn1_string_length(gen->d.ip) == 16) {
+ *single = "IP:" + ipv6_from_binary(xca_asn1_string_get0_data(gen->d.ip));
return true;
- } else if(gen->d.ip->length == 32) {
- *single = "IP:" + ipv6_from_binary(gen->d.ip->data) +
- "/" + ipv6_from_binary(gen->d.ip->data +16);
+ } else if(xca_asn1_string_length(gen->d.ip) == 32) {
+ *single = "IP:" +
+ ipv6_from_binary(xca_asn1_string_get0_data(gen->d.ip)) +
+ "/" + ipv6_from_binary(xca_asn1_string_get0_data(gen->d.ip) + 16);
return true;
}
return false;
@@ -372,9 +374,9 @@ genName2conf(GENERAL_NAME *gen, QString
*single = QString("otherName:%1;FORMAT:HEX,%2").
arg(obj2SnOid(gen->d.otherName->type_id)).
arg(asn1Type2Name(type));
- for (int i=0; i<a->length; i++) {
+ for (int i=0; i<xca_asn1_string_length(a); i++) {
*single += QString(":%1").
- arg((int)(a->data[i]), 2, 16, QChar('0'));
+ arg((int)(xca_asn1_string_get0_data(a)[i]), 2, 16, QChar('0'));
}
}
return true;
@@ -423,12 +425,12 @@ bool x509v3ext::parse_ia5(QString *singl
return false;
if (!str) {
- const unsigned char *p = getData()->data;
- str = d2i_ASN1_OCTET_STRING(NULL, &p, getData()->length);
+ const unsigned char *p = xca_asn1_string_get0_data(getData());
+ str = d2i_ASN1_OCTET_STRING(NULL, &p, xca_asn1_string_length(getData()));
if (ign_openssl_error() || !str)
return false;
ret = QString("<ERROR: NOT IA5 but %1>%2").
- arg(asn1Type2Name(str->type)).
+ arg(asn1Type2Name(xca_asn1_string_type(str))).
arg(QString(asn1ToQString(str)));
} else {
ret = QString(asn1ToQString(str));
@@ -824,10 +826,10 @@ bool x509v3ext::parse_generic(QString *,
const ASN1_OBJECT *o = object();
QString der, obj = o ? obj2SnOid(o) : QString("INVALID");
- ASN1_OCTET_STRING *v = getData();
+ const ASN1_OCTET_STRING *v = getData();
- for (int i=0; v && i < v->length; i++)
- der += QString(":%1").arg((int)(v->data[i]), 2, 16, QChar('0'));
+ for (int i=0; v && i < xca_asn1_string_length(v); i++)
+ der += QString(":%1").arg((int)(xca_asn1_string_get0_data(v)[i]), 2, 16, QChar('0'));
if (adv)
*adv = QString("%1=%2DER%3\n").arg(obj).
@@ -1037,7 +1039,7 @@ X509_EXTENSION *x509v3ext::get() const
bool x509v3ext::isValid() const
{
- return ext && getData() && getData()->length > 0 &&
+ return ext && getData() && xca_asn1_string_length(getData()) > 0 &&
OBJ_obj2nid(X509_EXTENSION_get_object(ext)) != NID_undef;
}
diff -Naurp xca-2.9.0.orig/lib/x509v3ext.h xca-2.9.0.new/lib/x509v3ext.h
--- xca-2.9.0.orig/lib/x509v3ext.h 2025-03-28 19:28:15.000000000 +0100
+++ xca-2.9.0.new/lib/x509v3ext.h 2026-07-22 17:33:42.586049536 +0200
@@ -35,7 +35,7 @@ class x509v3ext
// bool operator == (const x509v3ext &x) const;
QString getObject() const;
int getCritical() const;
- ASN1_OCTET_STRING *getData() const;
+ const ASN1_OCTET_STRING *getData() const;
QString getValue() const;
QString getHtmlValue() const;
QString getConsoleValue(const QString &indent) const;
diff -Naurp xca-2.9.0.orig/widgets/CertDetail.cpp xca-2.9.0.new/widgets/CertDetail.cpp
--- xca-2.9.0.orig/widgets/CertDetail.cpp 2025-03-28 19:28:15.000000000 +0100
+++ xca-2.9.0.new/widgets/CertDetail.cpp 2026-07-22 17:48:13.703356907 +0200
@@ -16,6 +16,7 @@
#include "lib/func_base.h"
#include "lib/func.h"
#include "lib/XcaWarningCore.h"
+#include "lib/openssl_compat.h"
#include <QLabel>
#include <QPushButton>
#include <QLineEdit>
@@ -269,7 +270,7 @@ void CertDetail::setReq(pki_x509req *req
int count = X509_ATTRIBUTE_count(att);
for (int j=0; j<count; j++) {
- ASN1_TYPE *at = X509_ATTRIBUTE_get0_type(att, j);
+ const ASN1_TYPE *at = X509_ATTRIBUTE_get0_type(att, j);
label = labelFromAsn1String(at->value.asn1_string);
attrLayout->addWidget(label, ii, j +1);
}
@@ -289,7 +290,7 @@ QLabel *CertDetail::labelFromAsn1String(
QLabel *label;
label = new CopyLabel(this);
label->setText(asn1ToQString(s));
- label->setToolTip(QString(ASN1_tag2str(s->type)));
+ label->setToolTip(QString(ASN1_tag2str(xca_asn1_string_type(s))));
return label;
}

112
xca.spec
View file

@ -3,39 +3,34 @@
Summary: Graphical X.509 certificate management tool
Name: xca
Version: 2.9.0
Release: 5%{?dist}
# Automatically converted from old format: BSD - review is highly recommended.
License: LicenseRef-Callaway-BSD
Version: 2.5.0
Release: 3%{?dist}
License: BSD
URL: https://hohnstaedt.de/xca/
Source0: https://github.com/%{gitowner0}/%{gitproject0}/releases/download/RELEASE.%{version}/%{name}-%{version}.tar.gz
Source1: xca-2.5.0-README.IMPORTANT
Patch1: xca-2.9.0-openssl4.patch
Patch1: xca-2.5-pastekey.patch
Patch2: xca-2.5-revokedel.patch
Patch3: xca-2.5-delete_after_revoke.patch
BuildRequires: cmake
BuildRequires: make
BuildRequires: gcc-c++
BuildRequires: cmake(Qt6Core)
BuildRequires: cmake(Qt6Widgets)
BuildRequires: cmake(Qt6Sql)
BuildRequires: cmake(Qt6Help)
BuildRequires: cmake(Qt6LinguistTools)
BuildRequires: cmake(Qt6Test)
BuildRequires: qt5-qtbase-devel
BuildRequires: qt5-qttools-devel
BuildRequires: qt5-linguist
BuildRequires: openssl-devel
%if 0%{?fedora} >= 41 && 0%{?fedora} <= 44
BuildRequires: openssl-devel-engine
%endif
BuildRequires: desktop-file-utils
BuildRequires: libappstream-glib
BuildRequires: xdg-utils
BuildRequires: libtool-ltdl-devel
BuildRequires: python3-sphinx
BuildRequires: python3-sphinxcontrib-qthelp
Requires: hicolor-icon-theme
Suggests: qt6-qtbase-mysql
Suggests: qt6-qtbase-postgresql
Suggests: qt6-qtbase-odbc
Suggests: qt5-qtbase-mysql
Suggests: qt5-qtbase-postgresql
Suggests: qt5-qtbase-odbc
%description
@ -46,10 +41,10 @@ OpenSSL library for the cryptographic operations.
Certificate signing requests (PKCS#10), certificates (X509v3), the signing
of requests, the creation of self-signed certificates, certificate revocation
lists and SmartCards are supported. For an easy company-wide use, customizable
templates can be used for certificate and request generation. The PKI
structures can be imported and exported in several formats like PKCS#7,
PKCS#12, PEM, DER, PKCS#8. All cryptographic data are stored in a byte order
agnostic file format, portable across operating systems.
templates can be used for certificate and request generation. The PKI structures
can be imported and exported in several formats like PKCS#7, PKCS#12, PEM,
DER, PKCS#8. All cryptographic data are stored in a byte order agnostic file
format, portable across operating systems.
#-------------------------------------------------------------------------------
@ -89,42 +84,33 @@ mv '%{buildroot}%{_datadir}/xca/html' '%{buildroot}%{_docdir}/xca/'
install -d -m 755 '%{buildroot}%{_datadir}/mime/packages'
install -p -m 644 misc/xca.xml '%{buildroot}%{_datadir}/mime/packages/'
# Validate desktop files.
desktop-file-validate \
'%{buildroot}%{_datadir}/applications/de.hohnstaedt.xca.desktop'
appstream-util validate-relax --nonet \
'%{buildroot}%{_metainfodir}/de.hohnstaedt.xca.metainfo.xml'
# Template contains neither translations nor language code.
rm -f '%{buildroot}%{_datadir}/xca/i18n/xca.qm'
# Install desktop application file.
desktop-file-install --mode 0644 \
--dir '%{buildroot}%{_datadir}/applications' \
--delete-original \
--add-mime-type application/x-xca-database \
--remove-category QT \
--set-icon=xca \
'%{buildroot}%{_datadir}/applications/xca.desktop'
# Tag translation files.
%find_lang '%{name}' --with-qt
#-------------------------------------------------------------------------------
%check
#-------------------------------------------------------------------------------
# Do not test GUI.
%ctest -E '^testxca$' || :
#-------------------------------------------------------------------------------
%files -f %{name}.lang
#-------------------------------------------------------------------------------
%doc AUTHORS COPYRIGHT README.IMPORTANT
%doc %{_docdir}/xca/*
%{_bindir}/xca
%{_bindir}/*
%dir %{_datadir}/xca
%{_datadir}/xca/*.txt
%{_datadir}/xca/*.xca
%{_datadir}/icons/*/*/*/*.png
%{_datadir}/mime/packages/%{name}.*
%{_datadir}/applications/de.hohnstaedt.xca.desktop
%{_datadir}/applications/*
%{_datadir}/bash-completion/
%{_metainfodir}/de.hohnstaedt.xca.metainfo.xml
%attr(0644, root, root) %{_mandir}/*/*
@ -132,48 +118,6 @@ rm -f '%{buildroot}%{_datadir}/xca/i18n/xca.qm'
%changelog
#-------------------------------------------------------------------------------
* Wed Jul 22 2026 Patrick Monnerat <patrick@monnerat.net> 2.9.0-5
- Patch "openssl4" for openssl version 4 compatibility.
- Remove BR openssl-devel-engine for Fedora > 44.
- Perform tests.
* Fri Jul 17 2026 Fedora Release Engineering <releng@fedoraproject.org> - 2.9.0-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_45_Mass_Rebuild
* Sat Jun 13 2026 Yaakov Selkowitz <yselkowi@redhat.com> - 2.9.0-3
- Rebuilt for openssl 4.0
* Sat Jan 17 2026 Fedora Release Engineering <releng@fedoraproject.org> - 2.9.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_44_Mass_Rebuild
* Mon Sep 01 2025 Yaakov Selkowitz <yselkowi@redhat.com> - 2.9.0-1
- Update to 2.9.0
* Fri Jul 25 2025 Fedora Release Engineering <releng@fedoraproject.org> - 2.7.0-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild
* Sun Jan 19 2025 Fedora Release Engineering <releng@fedoraproject.org> - 2.7.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild
* Fri Sep 6 2024 Patrick Monnerat <patrick@monnerat.net> 2.7.0-1
- New upstream release.
* Wed Sep 4 2024 Miroslav Suchý <msuchy@redhat.com> - 2.6.0-5
- convert license to SPDX
* Tue Jul 23 2024 Patrick Monnerat <patrick@monnerat.net> 2.6.0-4
- BR openssl-devel-engine for Fedora >= 41.
* Sat Jul 20 2024 Fedora Release Engineering <releng@fedoraproject.org> - 2.6.0-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild
* Mon May 6 2024 Patrick Monnerat <patrick@monnerat.net> 2.6.0-2
- Fix application icon.
https://bugzilla.redhat.com/show_bug.cgi?id=2279161
* Sun Mar 17 2024 Patrick Monnerat <patrick@monnerat.net> 2.6.0-1
- New upstream release.
* Mon Jan 22 2024 Patrick Monnerat <patrick@monnerat.net> 2.5.0-3
- Patch "pastekey" fixes a crash pasting an encrypted private key.
https://github.com/chris2511/xca/commit/d29d55a