From 340b53f4fd48d826dcf7e895991cf317f40539ef Mon Sep 17 00:00:00 2001 From: Christian Hohnstaedt Date: Wed, 15 Aug 2018 13:01:42 +0200 Subject: [PATCH] Close #55: Add Certificate counter row for requests. (XCA 2.x - Relationship CSR <-> issued Certificate broken) This counter is dynamic and not stored in the DB. In comparison to the signed flag, which is stored and remains set in the DB, even if all certificates issued by signing this request are deleted. --- lib/db_x509req.cpp | 11 ++++++++++- lib/db_x509req.h | 1 + lib/headerlist.h | 1 + lib/pki_base.cpp | 4 ++-- lib/pki_base.h | 2 +- lib/pki_x509.cpp | 2 ++ lib/pki_x509req.cpp | 39 +++++++++++++++++++++++++++++++++++++++ lib/pki_x509req.h | 6 ++++-- lib/pki_x509super.cpp | 2 +- lib/pki_x509super.h | 2 +- 10 files changed, 62 insertions(+), 8 deletions(-) diff --git a/lib/db_x509req.cpp b/lib/db_x509req.cpp index 0bfde90b..be7d97aa 100644 --- a/lib/db_x509req.cpp +++ b/lib/db_x509req.cpp @@ -32,7 +32,10 @@ dbheaderList db_x509req::getHeaders() new dbheader(HD_req_unstr_name, false, tr("Unstructured name"), QString(OBJ_nid2ln(NID_pkcs9_unstructuredName))) << new dbheader(HD_req_chall_pass, false, tr("Challenge password"), - QString(OBJ_nid2ln(NID_pkcs9_challengePassword))); + QString(OBJ_nid2ln(NID_pkcs9_challengePassword))) << + new dbheader(HD_req_certs, true, tr("x509 count"), + tr("Number of certificates in the database with the same public key")); + return h; } @@ -149,6 +152,12 @@ void db_x509req::signReq(QModelIndex index) emit newCert(req); } +void db_x509req::resetX509count() +{ + foreach(pki_x509req *r, getAllRequests()) + r->resetX509count(); +} + QList db_x509req::getAllRequests() { return sqlSELECTpki("SELECT item FROM requests"); diff --git a/lib/db_x509req.h b/lib/db_x509req.h index 032798ba..bd9aed9e 100644 --- a/lib/db_x509req.h +++ b/lib/db_x509req.h @@ -30,6 +30,7 @@ class db_x509req: public db_x509super void toRequest(QModelIndex index); void load(); QList getAllRequests(); + void resetX509count(); public slots: void newItem(pki_temp *temp, pki_x509req *orig = NULL); diff --git a/lib/headerlist.h b/lib/headerlist.h index 118e7c06..4fd9060b 100644 --- a/lib/headerlist.h +++ b/lib/headerlist.h @@ -44,6 +44,7 @@ #define HD_req_signed -20 #define HD_req_unstr_name -21 #define HD_req_chall_pass -22 +#define HD_req_certs -23 //#define HD_temp_type -30 #define HD_crl_signer -40 diff --git a/lib/pki_base.cpp b/lib/pki_base.cpp index 53c9073f..6b868e8e 100644 --- a/lib/pki_base.cpp +++ b/lib/pki_base.cpp @@ -345,7 +345,7 @@ bool pki_base::compare(const pki_base *ref) const return ret; } -/* Signed 32 bit interger */ +/* Unsigned 32 bit integer */ unsigned pki_base::hash(QByteArray ba) { unsigned char md[EVP_MAX_MD_SIZE]; @@ -356,7 +356,7 @@ unsigned pki_base::hash(QByteArray ba) ((unsigned)md[2]<<16L) | ((unsigned)md[3]<<24L) ) & 0x7fffffffL; } -unsigned pki_base::hash() +unsigned pki_base::hash() const { return hash(i2d()); } diff --git a/lib/pki_base.h b/lib/pki_base.h index fbe6b711..34a6c2e0 100644 --- a/lib/pki_base.h +++ b/lib/pki_base.h @@ -172,7 +172,7 @@ class pki_base : public QObject } virtual void restoreSql(const QSqlRecord &rec); QSqlError sqlItemNotFound(QVariant sqlId) const; - unsigned hash(); + unsigned hash() const; QString pki_source_name() const; QString get_dump_filename(const QString &dir, QString ext); void selfComment(QString msg); diff --git a/lib/pki_x509.cpp b/lib/pki_x509.cpp index cd651efe..042363f8 100644 --- a/lib/pki_x509.cpp +++ b/lib/pki_x509.cpp @@ -94,6 +94,7 @@ QSqlError pki_x509::insertSqlData() q.bindValue(5, (int)isCA()); q.bindValue(6, i2d_b64()); q.exec(); + MainWindow::reqs->resetX509count(); if (!isCA()) return q.lastError(); @@ -171,6 +172,7 @@ QSqlError pki_x509::deleteSqlData() foreach(pki_base *pki, list) AffectedItems(pki->getSqlItemId()); + MainWindow::reqs->resetX509count(); return q.lastError(); } diff --git a/lib/pki_x509req.cpp b/lib/pki_x509req.cpp index 1b59b981..b4f3533a 100644 --- a/lib/pki_x509req.cpp +++ b/lib/pki_x509req.cpp @@ -6,10 +6,12 @@ */ +#include #include "pki_x509.h" #include "pki_evp.h" #include "func.h" +#include "db_base.h" #include "x509name.h" #include "exception.h" #include @@ -28,6 +30,7 @@ pki_x509req::pki_x509req(const QString name) pki_openssl_error(); pkiType=x509_req; done = false; + resetX509count(); } pki_x509req::~pki_x509req() @@ -312,6 +315,40 @@ QString pki_x509req::getAttribute(int nid) const return ret.join(", "); } +int pki_x509req::issuedCerts() const +{ + XSqlQuery q; + int count = 0; + + if (x509count != -1) + return x509count; + + SQL_PREPARE(q, "SELECT item FROM x509super WHERE key_hash=?"); + q.bindValue(0, pubHash()); + q.exec(); + if (q.lastError().isValid()) + return 0; + pki_key *k = getPubKey(); + if (!k) + return 0; + while (q.next()) { + pki_x509super *x; + x = db_base::lookupPki(q.value(0)); + if (!x) { + qDebug("x509 with id %d not found", + q.value(0).toInt()); + continue; + } + if (typeid(*x) == typeid(pki_x509) && x->compareRefKey(k)) + count++; + qDebug() << "Req:" << getIntName() << "Cert with hash" + << x->getIntName() << count; + } + delete k; + x509count = count; + return count; +} + QVariant pki_x509req::column_data(const dbheader *hd) const { switch (hd->id) { @@ -321,6 +358,8 @@ QVariant pki_x509req::column_data(const dbheader *hd) const return getAttribute(NID_pkcs9_unstructuredName); case HD_req_chall_pass: return getAttribute(NID_pkcs9_challengePassword); + case HD_req_certs: + return QVariant(issuedCerts()); } return pki_x509super::column_data(hd); } diff --git a/lib/pki_x509req.h b/lib/pki_x509req.h index 20f884b0..94a5ffcd 100644 --- a/lib/pki_x509req.h +++ b/lib/pki_x509req.h @@ -24,6 +24,7 @@ class pki_x509req : public pki_x509super { Q_OBJECT + mutable int x509count; protected: X509_REQ *request; bool done; @@ -46,6 +47,7 @@ class pki_x509req : public pki_x509super } void addAttribute(int nid, QString content); QString getAttribute(int nid) const; + int issuedCerts() const; int verify() const; pki_key *getPubKey() const; @@ -58,9 +60,9 @@ class pki_x509req : public pki_x509super { done = d; } - bool getDone() + void resetX509count() const { - return done; + x509count = -1; } virtual QString getMsg(msg_type msg) const; void d2i(QByteArray &ba); diff --git a/lib/pki_x509super.cpp b/lib/pki_x509super.cpp index 08d445bb..fadd38f9 100644 --- a/lib/pki_x509super.cpp +++ b/lib/pki_x509super.cpp @@ -88,7 +88,7 @@ pki_key *pki_x509super::getRefKey() const return privkey; } -unsigned pki_x509super::pubHash() +unsigned pki_x509super::pubHash() const { unsigned hash = 0; if (privkey) { diff --git a/lib/pki_x509super.h b/lib/pki_x509super.h index f55fedb4..594d3e0c 100644 --- a/lib/pki_x509super.h +++ b/lib/pki_x509super.h @@ -36,7 +36,7 @@ class pki_x509super : public pki_x509name public: pki_x509super(const QString name = ""); virtual ~pki_x509super(); - unsigned pubHash(); + unsigned pubHash() const; virtual pki_key *getPubKey() const = 0; virtual extList getV3ext() const = 0; virtual QString getSigAlg() const;