From 2a0a4630ae5a2f2c73fec32dc51ecb8c1d786cd9 Mon Sep 17 00:00:00 2001 From: Christian Hohnstaedt Date: Thu, 22 Jun 2017 06:03:50 +0200 Subject: [PATCH] Extend authority table and fix CaProperties --- lib/db_base.cpp | 28 +++++---------- lib/db_base.h | 7 ++-- lib/db_temp.cpp | 4 +-- lib/db_temp.h | 2 +- lib/db_x509.cpp | 80 ++++++++++++++++++++++++++++++----------- lib/pki_crl.cpp | 5 ++- lib/pki_key.cpp | 2 +- lib/pki_temp.cpp | 4 +-- lib/pki_x509.cpp | 45 +++++++++++++++++------ lib/pki_x509.h | 20 +++++++---- lib/pki_x509super.cpp | 2 +- ui/CaProperties.ui | 7 +++- widgets/ItemCombo.h | 5 +++ widgets/MW_database.cpp | 20 ++++++++--- widgets/MainWindow.cpp | 2 +- widgets/NewX509.cpp | 31 ++++++++++++++-- widgets/NewX509.h | 2 +- 17 files changed, 188 insertions(+), 78 deletions(-) diff --git a/lib/db_base.cpp b/lib/db_base.cpp index 28b85c87..dbada2cf 100644 --- a/lib/db_base.cpp +++ b/lib/db_base.cpp @@ -93,7 +93,7 @@ QList db_base::sqlSELECTpki(QString query, QList values) q.exec(); mainwin->dbSqlError(q.lastError()); while (q.next()) - x << lookupPki(q.value(0).toULongLong()); + x << lookupPki(q.value(0)); return x; } @@ -291,13 +291,6 @@ void db_base::deletePKI(QModelIndex idx) } } -void db_base::updatePKI(pki_base *pki) -{ - (void)pki; -#warning UPDATING updatePKI - fprintf(stderr, "UUUUUUUUUUUUPDATE MIT SQL FEHLER\n"); -} - void db_base::showItem(const QModelIndex &index) { showPki(static_cast(index.internalPointer())); @@ -336,11 +329,11 @@ void db_base::inToCont(pki_base *pki) pki_base *db_base::getByName(QString desc) { - FOR_ALL_pki(pki, pki_base) { - if (pki->getIntName() == desc) - return pki; - } - return NULL; + QList list = sqlSELECTpki( + QString("SELECT id FROM items WHERE name=? AND ") + + sqlItemSelector(), + QList() << QVariant(desc)); + return list.isEmpty() ? NULL : list[0]; } pki_base *db_base::getByReference(pki_base *refpki) @@ -357,14 +350,9 @@ pki_base *db_base::getByReference(pki_base *refpki) return NULL; } -QStringList db_base::getDesc() +QList db_base::getAll() { - QStringList x; - x.clear(); - FOR_ALL_pki(pki, pki_base) { - x.append(pki->getIntName()); - } - return x; + return sqlSELECTpki(QString("SELECT item FROM %1").arg(sqlHashTable)); } pki_base *db_base::insert(pki_base *item) diff --git a/lib/db_base.h b/lib/db_base.h index 06ef71ab..7d184098 100644 --- a/lib/db_base.h +++ b/lib/db_base.h @@ -62,6 +62,10 @@ class db_base: public QAbstractItemModel { return lookup[i]; } + static pki_base *lookupPki(QVariant v) + { + return lookupPki(v.toULongLong()); + } static void flushLookup() { lookup.clear(); @@ -75,12 +79,11 @@ class db_base: public QAbstractItemModel virtual ~db_base(); virtual void insertPKI(pki_base *pki); virtual QSqlError insertPKI_noTransaction(pki_base *pki); - virtual void updatePKI(pki_base *pki); pki_base *getByName(QString desc); pki_base *getByReference(pki_base *refpki); pki_base *getByPtr(void *); virtual void loadContainer(); - QStringList getDesc(); + QList getAll(); virtual pki_base* insert(pki_base *item); virtual void inToCont(pki_base *pki); virtual void remFromCont(QModelIndex &idx); diff --git a/lib/db_temp.cpp b/lib/db_temp.cpp index 7b2a3cdb..366885f9 100644 --- a/lib/db_temp.cpp +++ b/lib/db_temp.cpp @@ -69,9 +69,9 @@ pki_base *db_temp::newPKI(enum pki_type type) return new pki_temp(""); } -QList db_temp::getDescPredefs() +QList db_temp::getAllAndPredefs() { - return predefs << sqlSELECTpki("SELECT item FROM templates");; + return predefs << getAll(); } bool db_temp::runTempDlg(pki_temp *temp) diff --git a/lib/db_temp.h b/lib/db_temp.h index a176e7b8..b2d2d9c0 100644 --- a/lib/db_temp.h +++ b/lib/db_temp.h @@ -29,7 +29,7 @@ class db_temp: public db_x509name bool runTempDlg(pki_temp *temp); bool alterTemp(pki_temp *temp); void fillContextMenu(QMenu *menu, const QModelIndex &index); - QList getDescPredefs(); + QList getAllAndPredefs(); void newItem(); void showPki(pki_base *pki); void load(); diff --git a/lib/db_x509.cpp b/lib/db_x509.cpp index 4f44e4c7..68244f8c 100644 --- a/lib/db_x509.cpp +++ b/lib/db_x509.cpp @@ -42,15 +42,15 @@ void db_x509::dereferenceIssuer() while (q.next()) { pki_base *root = rootItem; pki_x509 *cert = static_cast( - lookupPki(q.value(0).toULongLong())); + lookupPki(q.value(0))); pki_x509 *issuer = static_cast( - lookupPki(q.value(1).toULongLong())); + lookupPki(q.value(1))); if (cert && issuer) { cert->setSigner(issuer); if (cert != issuer) root = issuer; } - if (cert->getParent() != root) { + if (cert && cert->getParent() != root) { fprintf(stderr, "MOVE '%s' from '%s' to '%s'\n", CCHAR(cert->getIntName()), CCHAR(cert->getParent()->getIntName()), @@ -508,7 +508,6 @@ void db_x509::newCert(NewX509 *dlg) cert->pkiSource = dlg->getPkiSource(); cert = (pki_x509*)insert(cert); createSuccess(cert); - updatePKI(signcert); if (cert && clientkey->isToken()) { pki_scard *card = (pki_scard*)clientkey; if (XCA_YESNO(tr("Store the certificate to the key on the token '%1 (#%2)' ?"). @@ -1001,9 +1000,10 @@ void db_x509::toToken(QModelIndex idx, bool alwaysSelect) void db_x509::caProperties(QModelIndex idx) { + QStringList actions; Ui::CaProperties ui; + QString policy; int i; -#warning FIXME for Policies pki_x509 *cert = static_cast(idx.internalPointer()); if (!cert) @@ -1015,14 +1015,16 @@ void db_x509::caProperties(QModelIndex idx) ui.days->setMaximum(1000000); ui.days->setValue(cert->getCrlDays()); ui.image->setPixmap(*MainWindow::certImg); - QString templ; //cert->getTemplate()->getIntName(); - QStringList tempList = mainwin->temps->getDesc(); - for (i=0; iaddItems(tempList); - ui.temp->setCurrentIndex(i); + + QVariant tmplId = cert->getTemplateSqlId(); + pki_base *templ = mainwin->temps->lookupPki(tmplId); + + ui.temp->insertPkiItems(mainwin->temps->getAll()); + ui.temp->setNullItem(tr("No template")); + ui.temp->setCurrentIndex(0); + if (templ) + ui.temp->setCurrentPkiItem(templ); + ui.certName->setTitle(cert->getIntName()); QStringList sl; @@ -1034,16 +1036,54 @@ void db_x509::caProperties(QModelIndex idx) sl << QString(OBJ_nid2ln(nid)); ui.subjectManager->setKeys(sl, 0); - sl.clear(); - sl << "From request" << "From template" << "Erase" << "Match" - << "Template as regex"; - ui.subjectManager->setKeys(sl, 1); + actions << "From request" << "From template" << "Erase" << "Match"; + ui.subjectManager->setKeys(actions, 1); + + sl = cert->getDnPolicy().split(","); + + printf("Policy: '%s'\n", CCHAR(cert->getDnPolicy())); + ui.subjectManager->deleteAllRows(); + foreach(policy, sl) { + QStringList polKV, l = policy.split(":"); + if (l.size() != 2) + continue; + printf("Option: %d\n", l[1].toInt()); + polKV << QString(OBJ_nid2ln(OBJ_sn2nid(CCHAR(l[0])))); + polKV << actions[l[1].toInt()]; + ui.subjectManager->addRow(polKV); + } if (dlg->exec()) { + int rows = ui.subjectManager->rowCount(); + XSqlQuery q; + QSqlError e; + templ = ui.temp->currentPkiItem(); + tmplId = templ ? templ->getSqlItemId() : QVariant(); + + sl.clear(); + for (i=0; igetRow(i); + int idx = actions.indexOf(l[1]); + if (idx == -1) + continue; + sl << QString("%1:%2") + .arg(OBJ_nid2sn(OBJ_ln2nid(CCHAR(l[0])))) + .arg(idx); + } + policy = sl.join(","); + cert->setTemplateSqlId(tmplId); cert->setCrlDays(ui.days->value()); -#warning Fixme, too -// cert->setTemplate(ui.temp->currentText()); - updatePKI(cert); + cert->setDnPolicy(policy); + + SQL_PREPARE(q, "UPDATE authority SET crlDays=?, dnPolicy=?, " + "template=? WHERE item=?"); + + q.bindValue(0, cert->getCrlDays()); + q.bindValue(1, policy); + q.bindValue(2, tmplId); + q.bindValue(3, cert->getSqlItemId()); + q.exec(); + mainwin->dbSqlError(q.lastError()); } delete dlg; } diff --git a/lib/pki_crl.cpp b/lib/pki_crl.cpp index 2f85c8f1..05b41c7f 100644 --- a/lib/pki_crl.cpp +++ b/lib/pki_crl.cpp @@ -72,7 +72,7 @@ QSqlError pki_crl::insertSqlData() return q.lastError(); while (q.next()) { pki_x509 *x = static_cast( - db_base::lookupPki(q.value(0).toULongLong())); + db_base::lookupPki(q.value(0))); if (!x) { qDebug("CA certificate with id %d not found", q.value(0).toInt()); @@ -110,8 +110,7 @@ QSqlError pki_crl::restoreSql(QVariant sqlId) return sqlItemNotFound(sqlId); QByteArray ba = QByteArray::fromBase64(q.value(0).toByteArray()); d2i(ba); - setIssuer(static_cast( - db_base::lookupPki(q.value(1).toULongLong()))); + setIssuer(static_cast( db_base::lookupPki(q.value(1)))); return e; } diff --git a/lib/pki_key.cpp b/lib/pki_key.cpp index 2df4f57b..9a51882a 100644 --- a/lib/pki_key.cpp +++ b/lib/pki_key.cpp @@ -457,7 +457,7 @@ QSqlError pki_key::insertSqlData() return q.lastError(); while (q.next()) { pki_x509super *x = static_cast( - db_base::lookupPki(q.value(0).toULongLong())); + db_base::lookupPki(q.value(0))); if (!x) { qDebug("X509 Super class with id %d not found", q.value(0).toInt()); diff --git a/lib/pki_temp.cpp b/lib/pki_temp.cpp index 8fc76c4b..072712e6 100644 --- a/lib/pki_temp.cpp +++ b/lib/pki_temp.cpp @@ -430,12 +430,12 @@ BIO *pki_temp::pem(BIO *b, int format) void pki_temp::fromExportData(QByteArray data) { - int size, version; + int version; if (data.size() < (int)sizeof(uint32_t)) my_error(tr("Template file content error (too small)")); - size = db::intFromData(data); + db::intFromData(data); version = db::intFromData(data); fromData((const unsigned char*)data.constData(), data.size(), version); diff --git a/lib/pki_x509.cpp b/lib/pki_x509.cpp index 4135cc29..ec876aef 100644 --- a/lib/pki_x509.cpp +++ b/lib/pki_x509.cpp @@ -47,7 +47,7 @@ pki_x509::pki_x509(const pki_x509 *crt) pki_openssl_error(); psigner = crt->psigner; setRefKey(crt->getRefKey()); - caTemplate = crt->caTemplate; + caTemplateSqlId = crt->caTemplateSqlId; revocation = crt->revocation; crlDays = crt->crlDays; crlExpire = crt->crlExpire; @@ -92,16 +92,23 @@ QSqlError pki_x509::insertSqlData() return e; SQL_PREPARE(q, "INSERT INTO certs (item, hash, iss_hash, serial, issuer, " - "ca, crlExpire, crlNo, cert) " - "VALUES (?, ?, ?, ?, ?, ?, ?, 0, ?)"); + "ca, cert) " + "VALUES (?, ?, ?, ?, ?, ?, ?)"); q.bindValue(0, sqlItemId); q.bindValue(1, hash()); q.bindValue(2, (uint)getIssuerName().hashNum()); q.bindValue(3, getSerial().toHex()); q.bindValue(4, signer ? signer->getSqlItemId() : QVariant()); q.bindValue(5, (int)isCA()); - q.bindValue(6, now.toPlain()); - q.bindValue(7, i2d_b64()); + q.bindValue(6, i2d_b64()); + q.exec(); + if (!isCA()) + return q.lastError(); + + SQL_PREPARE(q, "INSERT INTO authority (item, crlExpire, crlNo) " + "VALUES (?, ?, 0)"); + q.bindValue(0, sqlItemId); + q.bindValue(1, now.toPlain()); q.exec(); return q.lastError(); } @@ -114,7 +121,8 @@ QSqlError pki_x509::restoreSql(QVariant sqlId) e = pki_x509super::restoreSql(sqlId); if (e.isValid()) return e; - SQL_PREPARE(q, "SELECT cert, issuer, crlNo, crlExpire, serial FROM certs " + + SQL_PREPARE(q, "SELECT cert, issuer, serial FROM certs " "WHERE item=?"); q.bindValue(0, sqlId); q.exec(); @@ -126,11 +134,22 @@ QSqlError pki_x509::restoreSql(QVariant sqlId) QByteArray ba = QByteArray::fromBase64(q.value(0).toByteArray()); d2i(ba); signerSqlId = q.value(1); - crlNumber.set(q.value(2).toUInt()); - crlExpire.fromPlain(q.value(3).toString()); revList = x509revList::fromSql(sqlId); QVariant serial = q.value(4); + SQL_PREPARE(q, "SELECT crlNo, crlExpire, template FROM authority " + "WHERE item=?"); + q.bindValue(0, sqlId); + q.exec(); + e = q.lastError(); + if (e.isValid()) + return e; + if (q.first()) { + crlNumber.set(q.value(0).toUInt()); + crlExpire.fromPlain(q.value(1).toString()); + caTemplateSqlId = q.value(2); + } + SQL_PREPARE(q, "SELECT serial, date, invaldate, crlNo, reasonBit " "FROM revocations WHERE caId=? AND serial=?"); q.bindValue(0, signerSqlId); @@ -154,6 +173,12 @@ QSqlError pki_x509::deleteSqlData() q.bindValue(0, sqlItemId); q.exec(); e = q.lastError(); + if (e.isValid()) + return e; + SQL_PREPARE(q, "DELETE FROM authority WHERE item=?"); + q.bindValue(0, sqlItemId); + q.exec(); + e = q.lastError(); if (e.isValid()) return e; SQL_PREPARE(q, "UPDATE crls SET issuer=NULL WHERE issuer=?"); @@ -195,7 +220,7 @@ pki_x509 *pki_x509::findIssuer() q.exec(); while (q.next()) { issuer = static_cast( - db_base::lookupPki(q.value(0).toULongLong())); + db_base::lookupPki(q.value(0))); if (!issuer) { qDebug("Certificate with id %d not found", q.value(0).toInt()); @@ -257,7 +282,7 @@ pki_x509::~pki_x509() void pki_x509::init() { psigner = NULL; - caTemplate = NULL; + caTemplateSqlId = QVariant(); crlDays = 30; crlExpire.setUndefined(); cert = NULL; diff --git a/lib/pki_x509.h b/lib/pki_x509.h index 8f2f3a2b..508453a2 100644 --- a/lib/pki_x509.h +++ b/lib/pki_x509.h @@ -31,10 +31,11 @@ class pki_x509 : public pki_x509super a1time crlExpire; a1int crlNumber; int crlDays; - pki_temp *caTemplate; + QVariant caTemplateSqlId; X509 *cert; void init(); x509rev revocation; + QString dnPolicy; protected: int sigAlg(); @@ -109,14 +110,13 @@ class pki_x509 : public pki_x509super if (n > crlNumber) crlNumber = n; } - void setTemplate(pki_temp *t) + void setTemplateSqlId(QVariant sqlId) { - if (t) - caTemplate = t; + caTemplateSqlId = sqlId; } - pki_temp *getTemplate() + QVariant getTemplateSqlId() { - return caTemplate; + return caTemplateSqlId; } void setCrlDays(int s) { @@ -131,6 +131,14 @@ class pki_x509 : public pki_x509super { return revocation; } + void setDnPolicy(QString policy) + { + dnPolicy = policy; + } + QString getDnPolicy() + { + return dnPolicy; + } pk11_attlist objectAttributes(); bool hasExtension(int nid); bool cmpIssuerAndSerial(pki_x509 *refcert); diff --git a/lib/pki_x509super.cpp b/lib/pki_x509super.cpp index ba5077c8..9cd22976 100644 --- a/lib/pki_x509super.cpp +++ b/lib/pki_x509super.cpp @@ -32,7 +32,7 @@ QSqlError pki_x509super::insertSqlData() return q.lastError(); while (q.next()) { pki_key *x = static_cast( - db_base::lookupPki(q.value(0).toULongLong())); + db_base::lookupPki(q.value(0))); if (!x) { qDebug("Public key with id %d not found", q.value(0).toInt()); diff --git a/ui/CaProperties.ui b/ui/CaProperties.ui index 28c8336f..c998d487 100644 --- a/ui/CaProperties.ui +++ b/ui/CaProperties.ui @@ -147,7 +147,7 @@ - + @@ -186,6 +186,11 @@ deleteCurrentRow() + + itemCombo + QComboBox +
widgets/ItemCombo.h
+
diff --git a/widgets/ItemCombo.h b/widgets/ItemCombo.h index de89468a..d2464e3f 100644 --- a/widgets/ItemCombo.h +++ b/widgets/ItemCombo.h @@ -25,6 +25,11 @@ class itemCombo : public QComboBox pki_base *currentPkiItem() { return itemData(currentIndex()).value(); } + void setNullItem(QString text) { + if (itemData(0).value() == NULL) + removeItem(0); + insertItem(0, text, QVariant::fromValue(NULL)); + } int setCurrentPkiItem(pki_base *p) { int idx = findData(QVariant::fromValue(p)); setCurrentIndex(idx); diff --git a/widgets/MW_database.cpp b/widgets/MW_database.cpp index 065c234c..10bdc2a9 100644 --- a/widgets/MW_database.cpp +++ b/widgets/MW_database.cpp @@ -69,6 +69,7 @@ QSqlError MainWindow::initSqlDB() "id SERIAL PRIMARY KEY, " "name VARCHAR(128), " /* Internal name of the item */ "type INTEGER, " /* enum pki_type */ + "source INTEGER, " /* enum pki_source */ "date "DB_DATE", " /* Time of insertion (creation/import) */ "comment VARCHAR(2048))" @@ -158,12 +159,23 @@ QSqlError MainWindow::initSqlDB() "serial VARCHAR(64), " /* Serial number of the certificate */ "issuer INTEGER, " /* The items(id) of the issuer or NULL */ "ca INTEGER, " /* CA: yes / no from BasicConstraints */ - "crlExpire "DB_DATE", " /* CRL expiry date */ - "crlNo INTEGER, " /* Last CRL Number */ "cert "B64_BLOB", " /* B64(DER(certificate)) */ "FOREIGN KEY (item) REFERENCES items (id), " "FOREIGN KEY (issuer) REFERENCES items (id)) " +/* + * X509 cartificate Authority data + */ +<< "CREATE TABLE authority (" + "item INTEGER, " /* reference to items(id) */ + "template INTEGER, " /* reference to items(id) of the default template*/ + "crlExpire "DB_DATE", " /* CRL expiry date */ + "crlNo INTEGER, " /* Last CRL Number */ + "crlDays INTEGER, " /* CRL days until renewal */ + "dnPolicy, " /* DistinguishedName policy */ + "FOREIGN KEY (item) REFERENCES items (id), " + "FOREIGN KEY (template) REFERENCES items (id)) " + /* * Storage of CRLs */ @@ -216,7 +228,7 @@ QSqlError MainWindow::initSqlDB() QSqlError MainWindow::openSqlDB() { -#define POSTGRES 1 +//#define POSTGRES 1 #ifndef POSTGRES db.setDatabaseName(dbfile); #else @@ -268,7 +280,7 @@ void MainWindow::dbSqlError(QSqlError err) bool MainWindow::checkForOldDbFormat() { // 0x ca db 19 69 - static const char magic[] = { 0xca, 0xdb, 0x19, 0x69 }; + static const unsigned char magic[] = { 0xca, 0xdb, 0x19, 0x69 }; char head[4]; QFile file(dbfile); diff --git a/widgets/MainWindow.cpp b/widgets/MainWindow.cpp index e9db73b5..cef0d32a 100644 --- a/widgets/MainWindow.cpp +++ b/widgets/MainWindow.cpp @@ -119,7 +119,7 @@ MainWindow::MainWindow(QWidget *parent) fprintf(stderr, "DB driver: '%s'\n", CCHAR(driver)); } -#define POSTGRES 1 +//#define POSTGRES 1 #ifndef POSTGRES db = QSqlDatabase::addDatabase("QSQLITE"); #else diff --git a/widgets/NewX509.cpp b/widgets/NewX509.cpp index 2f4095cc..1f4f19b8 100644 --- a/widgets/NewX509.cpp +++ b/widgets/NewX509.cpp @@ -100,8 +100,8 @@ NewX509::NewX509(QWidget *parent) on_applyTime_clicked(); // settings for the templates .... - QList templates = MainWindow::temps->getDescPredefs(); - tempList->insertPkiItems(templates); + tempList->insertPkiItems(MainWindow::temps->getAllAndPredefs()); + tempList->setNullItem(tr("No template")); // setup Extended keyusage foreach(int nid, eku_nid) @@ -443,6 +443,29 @@ void NewX509::fromX509super(pki_x509super *cert_or_req) } +pki_temp *NewX509::caTemplate(pki_x509 *ca) const +{ + QVariant sqlId = ca->getTemplateSqlId(); + if (!sqlId.isValid()) + return NULL; + return (pki_temp*)MainWindow::temps->lookupPki(sqlId); +} + +/* Preset all values from another cert to create a aimilar one */ +void NewX509::defineCert(pki_x509 *cert) +{ + fromX509super(cert); + + pki_x509 *signer = cert->getSigner(); + if (signer == cert) { + foreignSignRB->setChecked(false); + } else if (signer) { + defineSigner(signer); + } + notBefore->setDate(cert->getNotBefore()); + notAfter->setDate(cert->getNotAfter()); +} + /* Preset the signing certificate */ void NewX509::defineSigner(pki_x509 *defcert, bool applyTemp) { @@ -671,7 +694,7 @@ void NewX509::on_certList_currentIndexChanged(int) if (!cert) return; - pki_temp *templ = cert->getTemplate(); + pki_temp *templ = caTemplate(cert); snb = cert->getNotBefore(); sna = cert->getNotAfter(); if (snb > notBefore->getDate()) @@ -720,6 +743,8 @@ void NewX509::selfComment(QString msg) void NewX509::on_applyTemplate_clicked() { pki_temp *t = currentTemplate(); + if (!t) + return; fromTemplate(t); selfComment(tr("Template '%1' applied").arg(t->comboText())); } diff --git a/widgets/NewX509.h b/widgets/NewX509.h index 1d525c80..b16d42d2 100644 --- a/widgets/NewX509.h +++ b/widgets/NewX509.h @@ -67,7 +67,7 @@ class NewX509: public QDialog, public Ui::NewX509 void selfComment(QString msg); QMap templateLineEdits; QMap templateCheckBoxes; - + pki_temp *caTemplate(pki_x509 *ca) const; public: QLineEdit *description; NewX509(QWidget *parent);