/* vi: set sw=4 ts=4: * * Copyright (C) 2001 - 2014 Christian Hohnstaedt. * * All rights reserved. */ #include "db_x509.h" #include "pki_pkcs12.h" #include "pki_pkcs7.h" #include "pki_evp.h" #include "pki_scard.h" #include "pass_info.h" #include "widgets/CertDetail.h" #include "widgets/CertExtend.h" #include "widgets/ExportDialog.h" #include "widgets/MainWindow.h" #include "widgets/PwDialog.h" #include "widgets/RevocationList.h" #include "ui_TrustState.h" #include "ui_CaProperties.h" #include "ui_About.h" #include #include #include bool db_x509::treeview = true; db_x509::db_x509(QString DBfile, MainWindow *mw) :db_x509super(DBfile, mw) { rootItem->setIntName("[x509 root]"); class_name = "certificates"; pkitype << x509; updateHeaders(); loadContainer(); } void db_x509::updateAfterCrlLoad(pki_x509 *pki) { if (pki->revList.merged) { updatePKI(pki); pki->revList.merged = false; } } void db_x509::updateAfterDbLoad() { FOR_ALL_pki(pki, pki_x509) { updateAfterCrlLoad(pki); } } dbheaderList db_x509::getHeaders() { dbheaderList h = db_x509super::getHeaders(); h << new dbheader(HD_cert_ca, true, tr("CA"), tr("reflects the basic Constraints extension")) << new dbheader(HD_cert_serial, true, tr("Serial")) << new dbheader(HD_cert_md5fp, false,tr("MD5 fingerprint")) << new dbheader(HD_cert_sha1fp, false,tr("SHA1 fingerprint")) << new dbheader(HD_cert_sha256fp, false,tr("SHA256 fingerprint")) << new dbheader(HD_cert_notBefore, false,tr("Start date"), tr("Not before")) << new dbheader(HD_cert_notAfter, true, tr("Expiry date"), tr("Not after")) << new dbheader(HD_cert_trust, false,tr("Trust state")) << new dbheader(HD_cert_revocation,false, tr("Revocation")) << new dbheader(HD_cert_crl_expire,true, tr("CRL Expiration")); return h; } pki_base *db_x509::newPKI(db_header_t *) { return new pki_x509(); } pki_x509 *db_x509::findSigner(pki_x509 *client) { pki_x509 *signer; if ((signer = client->getSigner()) != NULL) return signer; // first check for self-signed if (client->verify(client)) { return client; } FOR_ALL_pki(pki, pki_x509) { if (client->verify(pki)) { return pki; } } return NULL; } QStringList db_x509::getPrivateDesc() { QStringList x; FOR_ALL_pki(pki, pki_x509) if (pki->getRefKey()) x.append(pki->getIntName()); return x; } QStringList db_x509::getSignerDesc() { QStringList x; FOR_ALL_pki(pki, pki_x509) if (pki->canSign()) x.append(pki->getIntName()); return x; } void db_x509::remFromCont(QModelIndex &idx) { int row; pki_base *pki = static_cast(idx.internalPointer()); pki_base *parent_pki = pki->getParent(); row = pki->row(); pki_x509 *child; pki_base *new_parent; QModelIndex new_idx; beginRemoveRows(parent(idx), row, row); parent_pki->takeChild(pki); endRemoveRows(); while (pki->childCount()) { child = (pki_x509*)pki->childItems.takeFirst(); child->delSigner((pki_x509*)pki); new_parent = findSigner(child); insertChild(new_parent, child); } mainwin->crls->removeSigner(pki); pki_key *pub = ((pki_x509*)pki)->getPubKey(); if (pub) { if (mainwin->certs->findByPubKey(pub).count() == 0) { QList reqs; reqs = mainwin->reqs->findByPubKey(pub); foreach(pki_x509super *r, reqs) ((pki_x509req*)r)->setDone(false); } delete pub; } return; } void db_x509::changeView() { pki_base *temproot; int rows = rowCount(QModelIndex()); if (!rows) return; temproot = new pki_base(); beginRemoveRows(QModelIndex(), 0, rows -1); pki_base *pki = rootItem; pki_base *parent; while(pki->childCount()) { pki = pki->takeFirst(); while(pki != rootItem && !pki->childCount()) { parent = pki->getParent(); temproot->append(pki); pki = parent; } } endRemoveRows(); treeview = !treeview; if (treeview) mainwin->BNviewState->setText(tr("Plain View")); else mainwin->BNviewState->setText(tr("Tree View")); while ((temproot->childCount())) { pki = temproot->takeFirst(); inToCont(pki); } delete temproot; } void db_x509::calcEffTrust() { FOR_ALL_pki(pki, pki_x509) pki->calcEffTrust(); } static bool recursiveSigning(pki_x509 *cert, pki_x509 *client) { /* recursive signing check */ for (pki_x509 *s = cert->getSigner(); s; s = s->getSigner()) { if (s == s->getSigner()) { return false; } if (s == client) { printf("Recursive signing: '%s' <-> '%s'\n", CCHAR(s->getIntName()), CCHAR(cert->getIntName())); return true; } } return false; } void db_x509::inToCont(pki_base *pki) { pki_x509 *cert = (pki_x509*)pki; cert->setParent(NULL); cert->delSigner(cert->getSigner()); findSigner(cert); pki_base *root = cert->getSigner(); if (!treeview || root == cert || root == NULL) root = rootItem; insertChild(root, cert); QList childs; /* Search for another certificate (name and key) * and use its childs if we are newer */ FOR_ALL_pki(client, pki_x509) { if (client == cert) continue; if (!client->compareNameAndKey(cert)) continue; if (cert->getNotAfter() < client->getNotAfter()) continue; foreach(pki_base *_child, client->childItems) { pki_x509 *child = static_cast(_child); child->delSigner(client); childs << child; } } /* Search rootItem childs, whether they are ours */ foreach(pki_base *_child, rootItem->childItems) { pki_x509 *child = static_cast(_child); if (child == cert || child->getSigner() == child) continue; if (child->verify_only(cert)) childs << child; } /* move collected childs to us */ foreach(pki_x509 *child, childs) { int row; if (recursiveSigning(cert, child)) continue; if (!child->verify(cert)) continue; row = child->row(); beginRemoveRows(index(child), row, row); child->getParent()->takeChild(child); endRemoveRows(); if (treeview) insertChild(cert, child); else insertChild(rootItem, child); } findKey(cert); pki_key *pub = cert->getPubKey(); if (pub) { QList reqs = mainwin->reqs->findByPubKey(pub); delete pub; foreach(pki_x509super *r, reqs) { ((pki_x509req*)r)->setDone(); } } calcEffTrust(); } pki_x509 *db_x509::getBySubject(const x509name &xname, pki_x509 *last) { bool lastfound = false; if (last == NULL) lastfound = true; FOR_ALL_pki(pki, pki_x509) { if ( pki->getSubject() == xname) { if (lastfound) { return pki; } } if (pki == last) { lastfound = true; } } return NULL; } void db_x509::writeAllCerts(const QString fname, bool onlyTrusted) { bool append = false; FOR_ALL_pki(pki, pki_x509) { if (onlyTrusted && pki->getTrust() != 2) continue; pki->writeCert(fname.toLatin1(), true, append); append = true; } } QList db_x509::getCerts(bool onlyTrusted) { QList c; c.clear(); FOR_ALL_pki(pki, pki_x509) { if (onlyTrusted && pki->getTrust() != 2) continue; c.append(pki); } return c; } void db_x509::writeIndex(const QString fname, bool hierarchy) { bool append = false; if (hierarchy) { FOR_ALL_pki(pki, pki_x509) { if (pki->childCount()) { QString newfname = fname + "." + pki->getIntName().replace(QRegExp("[^a-zA-Z0-9]"),QString(""));; append = false; foreach(pki_base *_child, pki->childItems) { pki_x509 *child = static_cast(_child); child->writeIndexEntry(newfname, append); append = true; } } } } else { FOR_ALL_pki(pki, pki_x509) { pki->writeIndexEntry(fname, append); append = true; } } } a1int db_x509::searchSerial(pki_x509 *signer) { // returns the highest certificate serial // of all certs with this signer (itself too) a1int sserial, myserial; if (!signer) return sserial; sserial = signer->getCaSerial(); FOR_ALL_pki(pki, pki_x509) if (pki->getSigner() == signer) { myserial = pki->getSerial(); if (sserial < myserial) { sserial = myserial; } } return sserial; } a1int db_x509::getUniqueSerial(pki_x509 *signer) { // returnes an unused unique serial a1int serial; x509rev rev; while (true) { serial = signer->getIncCaSerial(); rev.setSerial(serial); if (signer->revList.contains(rev)) continue; if (signer->getBySerial(serial)) continue; break; } if (!signer->usesRandomSerial()) updatePKI(signer); return serial; } pki_base *db_x509::insert(pki_base *item) { pki_x509 *cert = (pki_x509 *)item; pki_x509 *oldcert = (pki_x509 *)getByReference(cert); if (oldcert) { XCA_INFO(tr("The certificate already exists in the database as:\n'%1'\nand so it was not imported").arg(oldcert->getIntName())); delete(cert); return NULL; } cert->setCaSerial((cert->getSerial())); insertPKI(cert); a1int serial; // check the CA serial of the CA of this cert to avoid serial doubles if (cert->getSigner() != cert && cert->getSigner()) { serial = cert->getSerial(); if (cert->getSigner()->getCaSerial() < ++serial ) { cert->getSigner()->setCaSerial(serial); updatePKI(cert->getSigner()); } } // check CA serial of this cert serial = searchSerial(cert); if ( ++serial > cert->getCaSerial()) { cert->setCaSerial(serial); } if (mainwin->crls) { mainwin->crls->updateRevocations(cert); } updatePKI(cert); return cert; } void db_x509::load(void) { load_cert c; load_default(c); } pki_x509 *db_x509::get1SelectedCert() { QModelIndexList indexes = mainwin->certView->getSelectedIndexes(); QModelIndex index; if (indexes.count()) index = indexes[0]; if (index == QModelIndex()) return NULL; return static_cast(index.internalPointer()); } void db_x509::newItem() { NewX509 *dlg = new NewX509(mainwin); emit connNewX509(dlg); dlg->setCert(); pki_x509 *sigcert = get1SelectedCert(); dlg->defineSigner((pki_x509*)sigcert, true); if (dlg->exec()) { newCert(dlg); } delete dlg; } void db_x509::newCert(pki_x509req *req) { NewX509 *dlg = new NewX509(mainwin); emit connNewX509(dlg); pki_x509 *sigcert = get1SelectedCert(); dlg->setCert(); dlg->defineRequest(req); dlg->defineSigner(sigcert, true); if (dlg->exec()) { newCert(dlg); } delete dlg; } void db_x509::newCert(pki_temp *temp) { NewX509 *dlg = new NewX509(mainwin); emit connNewX509(dlg); dlg->setCert(); dlg->defineTemplate(temp); if (dlg->exec()) { newCert(dlg); } delete dlg; } void db_x509::newCert(pki_x509 *cert) { NewX509 *dlg = new NewX509(mainwin); emit connNewX509(dlg); dlg->setCert(); dlg->fromX509super(cert, false); if (dlg->exec()) { newCert(dlg); } delete dlg; } void db_x509::newCert(NewX509 *dlg) { pki_x509 *cert = NULL; pki_x509 *signcert = NULL; pki_x509req *req = NULL; pki_key *signkey = NULL, *clientkey = NULL, *tempkey = NULL; a1int serial; x509name subject; QString intname; try { // Step 1 - Subject and key if (!dlg->fromReqCB->isChecked()) { clientkey = dlg->getSelectedKey(); if (!clientkey) return; subject = dlg->getX509name(); intname = dlg->description->text(); } else { // A PKCS#10 Request was selected req = dlg->getSelectedReq(); if (!req) return; clientkey = req->getRefKey(); if (clientkey == NULL) { clientkey = req->getPubKey(); tempkey = clientkey; } if (dlg->reqSubChange->isChecked()) subject = dlg->getX509name(); else subject = req->getSubject(); intname = req->getIntName(); } if (clientkey == NULL) throw errorEx(tr("Invalid public key")); // initially create cert cert = new pki_x509(); cert->setIntName(intname); cert->setSubject(subject); cert->setPubKey(clientkey); // Step 2 - select Signing if (dlg->foreignSignRB->isChecked()) { signcert = dlg->getSelectedSigner(); if (!signcert) return; serial = getUniqueSerial(signcert); signkey = signcert->getRefKey(); cert->setTrust(1); #ifdef WG_QA_SERIAL } else if (dlg->selfQASignRB->isChecked()){ Passwd pass; pass_info p(XCA_TITLE, tr("Please enter the new hexadecimal secret number for the QA process.")); if (PwDialog::execute(&p, &pass, true) != 1) throw errorEx(tr("The QA process has been terminated by the user.")); signcert = cert; signkey = clientkey; serial.setHex(pass); cert->setTrust(2); #endif } else { signcert = cert; signkey = clientkey; serial.setHex(dlg->serialNr->text()); cert->setTrust(2); } dlg->initCtx(cert, signcert, NULL); // if we can not sign if (! signkey || signkey->isPubKey()) { delete cert; throw errorEx(tr("The key you selected for signing is not a private one.")); } // set the issuers name cert->setIssuer(signcert->getSubject()); cert->setSerial(serial); // Step 3 - Choose the Date // Date handling cert->setNotBefore(dlg->notBefore->getDate()); a1time a; if (dlg->noWellDefinedExpDate->isChecked()) a.setUndefined(); else a = dlg->notAfter->getDate(); cert->setNotAfter(a); // STEP 4 handle extensions // apply all extensions to the subject cert in the context dlg->getAllExt(); // apply extensions from CSR if requested if (dlg->copyReqExtCB->isChecked() && dlg->fromReqCB->isChecked()) { extList el = req->getV3ext(); int m = el.count(); for (int i=0; iaddV3ext(el[i], true); } const EVP_MD *hashAlgo = dlg->hashAlgo->currentHash(); #ifdef WG_QA_SERIAL if (dlg->selfQASignRB->isChecked()) { // sign the request intermediately in order to finally fill // up the cert_info substructure. cert->sign(signkey, hashAlgo); // now set the QA serial. cert->setSerial(cert->hashInfo(EVP_md5())); } #endif // and finally sign the request cert->sign(signkey, hashAlgo); 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)' ?"). arg(card->getCardLabel()).arg(card->getSerial()))) { try { cert->store_token(false); } catch (errorEx &err) { mainwin->Error(err); } } } if (tempkey != NULL) delete(tempkey); } catch (errorEx &err) { mainwin->Error(err); delete cert; if (tempkey != NULL) delete(tempkey); } } void db_x509::showPki(pki_base *pki) { pki_x509 *crt = (pki_x509 *)pki; CertDetail *dlg; dlg = new CertDetail(mainwin); if (dlg) { dlg->setCert(crt); connect(dlg->privKey, SIGNAL(doubleClicked(QString)), mainwin->keys, SLOT(showItem(QString))); connect(dlg->signature, SIGNAL(doubleClicked(QString)), this, SLOT( showItem(QString) )); dlg->exec(); delete dlg; } } void db_x509::store(QModelIndex idx) { QModelIndexList l; l << idx; store(l); } void db_x509::store(QModelIndexList list) { QStringList filt; bool append, chain; QList types, usual; if (list.size() == 0) return; pki_x509 *crt = static_cast(list[0].internalPointer()); pki_x509 *oldcrt = NULL; if (!crt) return; pki_key *privkey = crt->getRefKey(); pki_evp *pkey; chain = crt->getSigner() && crt->getSigner() != crt; usual << exportType(exportType::PEM, "crt", "PEM") << exportType(exportType::PKCS7, "p7b", "PKCS #7"); types << exportType(exportType::DER, "cer", "DER"); if (list.size() > 1) { usual << exportType(exportType::PEM_selected, "pem", "PEM selected") << exportType(exportType::PKCS7_selected, "pem", "PKCS7 selected"); } if (chain) { types << exportType(exportType::PEM_chain, "pem", tr("PEM chain")) << exportType(exportType::PKCS7_chain, "p7b", tr("PKCS#7 chain")); } if (privkey && privkey->isPrivKey() && !privkey->isToken()) { if (chain) { usual << exportType(exportType::PKCS12_chain, "p12", tr("PKCS#12 chain")); types << exportType(exportType::PKCS12, "p12", "PKCS #12"); } else { usual << exportType(exportType::PKCS12, "p12", "PKCS #12"); } types << exportType(exportType::PEM_cert_key, "pem", tr("PEM + key")) << exportType(exportType::PEM_cert_pk8, "pem", "PEM + PKCS#8"); } types << exportType() << exportType(exportType::PKCS7_trusted, "p7b", tr("PKCS#7 trusted")) << exportType(exportType::PKCS7_all, "p7b", tr("PKCS#7 all")) << exportType(exportType::PEM_trusted, "pem", tr("PEM trusted")) << exportType(exportType::PEM_all, "pem", tr("PEM all")) << exportType(exportType::Index, "txt", tr("Certificate Index file")); types = usual << exportType() << types; ExportDialog *dlg = new ExportDialog(mainwin, tr("Certificate export"), tr("X509 Certificates ( *.pem *.cer *.crt *.p12 *.p7b )"), crt, MainWindow::certImg, types); if (!dlg->exec()) { delete dlg; return; } QString fname = dlg->filename->text(); enum exportType::etype type = dlg->type(); delete dlg; try { switch (type) { case exportType::PEM: crt->writeCert(fname, true, false); break; case exportType::PEM_chain: append = false; while(crt && crt != oldcrt) { crt->writeCert(fname, true, append); append = true; oldcrt = crt; crt = crt->getSigner(); } break; case exportType::PEM_selected: append = false; foreach(QModelIndex idx, list) { crt = static_cast(idx.internalPointer()); crt->writeCert(fname, true, append); append = true; } break; case exportType::PEM_trusted: writeAllCerts(fname,true); break; case exportType::PEM_all: writeAllCerts(fname,false); break; case exportType::DER: crt->writeCert(fname,false,false); break; case exportType::PKCS7: case exportType::PKCS7_chain: case exportType::PKCS7_trusted: case exportType::PKCS7_selected: case exportType::PKCS7_all: writePKCS7(crt, fname, type, list); break; case exportType::PKCS12: writePKCS12(crt, fname,false); break; case exportType::PKCS12_chain: writePKCS12(crt, fname,true); break; case exportType::PEM_cert_pk8: case exportType::PEM_cert_key: pkey = (pki_evp *)crt->getRefKey(); if (!pkey || pkey->isPubKey()) { XCA_WARN(tr("There was no key found for the Certificate: '%1'"). arg(crt->getIntName())); return; } if (pkey->isToken()) { XCA_WARN(tr("Not possible for a token key: '%1'"). arg(crt->getIntName())); return; } if (type == exportType::PEM_cert_pk8) { pkey->writePKCS8(fname, EVP_des_ede3_cbc(), PwDialog::pwCallback, true); } else { pkey->writeKey(fname, NULL, NULL, true); } crt->writeCert(fname, true, true); break; case exportType::Index: append = false; foreach(QModelIndex idx, list) { crt = static_cast(idx.internalPointer()); crt->writeIndexEntry(fname, append); append = true; } break; default: exit(1); } } catch (errorEx &err) { MainWindow::Error(err); } } void db_x509::writePKCS12(pki_x509 *cert, QString s, bool chain) { QStringList filt; try { pki_evp *privkey = (pki_evp *)cert->getRefKey(); if (!privkey || privkey->isPubKey()) { XCA_WARN(tr("There was no key found for the Certificate: '%1'").arg(cert->getIntName())); return; } if (privkey->isToken()) { XCA_WARN(tr("Not possible for the token-key Certificate '%1'"). arg(cert->getIntName())); return; } if (s.isEmpty()) return; s = nativeSeparator(s); pki_pkcs12 *p12 = new pki_pkcs12(cert->getIntName(), cert, privkey); pki_x509 *signer = cert->getSigner(); while ((signer != NULL ) && (signer != cert) && chain) { p12->addCaCert(signer); cert=signer; signer=signer->getSigner(); } p12->writePKCS12(s); delete p12; } catch (errorEx &err) { MainWindow::Error(err); } } void db_x509::writePKCS7(pki_x509 *cert, QString s, exportType::etype type, QModelIndexList list) { pki_pkcs7 *p7 = NULL; try { p7 = new pki_pkcs7(""); switch (type) { case exportType::PKCS7_chain: while (cert != NULL) { p7->addCert(cert); if (cert->getSigner() == cert) cert = NULL; else cert = cert->getSigner(); } break; case exportType::PKCS7: p7->addCert(cert); break; case exportType::PKCS7_selected: foreach(QModelIndex idx, list) { cert = static_cast(idx.internalPointer()); p7->addCert(cert); } break; case exportType::PKCS7_trusted: case exportType::PKCS7_all: FOR_ALL_pki(cer, pki_x509) { if ((type == exportType::PKCS7_all) || (cer->getTrust() == 2)) p7->addCert(cer); } break; default: exit(1); } p7->writeP7(s, false); } catch (errorEx &err) { MainWindow::Error(err); } if (p7 != NULL ) delete p7; } void db_x509::manageRevocations(QModelIndex idx) { pki_x509 *cert = static_cast(idx.internalPointer()); if (!cert) return; RevocationList *dlg = new RevocationList(mainwin); dlg->setRevList(cert->revList, cert); connect(dlg, SIGNAL(genCRL(pki_x509*)), mainwin->crls, SLOT(newItem(pki_x509*))); if (dlg->exec()) { cert->setRevocations(dlg->getRevList()); updatePKI(cert); emit columnsContentChanged(); } } void db_x509::setTrust(QModelIndexList indexes) { int newstate = -1; Ui::TrustState ui; pki_x509 *cert = NULL; if (indexes.size() == 0) return; if (indexes.size() == 1) cert = static_cast(indexes[0].internalPointer()); QDialog *dlg = new QDialog(mainwin); ui.setupUi(dlg); ui.image->setPixmap(*MainWindow::certImg); if (cert) { int state = cert->getTrust(); if (cert->getSigner() == cert) { if (state == 1) state = 0; ui.trust1->setDisabled(true); } if (state == 0 ) ui.trust0->setChecked(true); if (state == 1 ) ui.trust1->setChecked(true); if (state == 2 ) ui.trust2->setChecked(true); } if (!dlg->exec()) { delete dlg; return; } if (ui.trust0->isChecked()) newstate = 0; if (ui.trust1->isChecked()) newstate = 1; if (ui.trust2->isChecked()) newstate = 2; delete dlg; if (newstate == -1) { return; } foreach(QModelIndex idx, indexes) { cert = static_cast(idx.internalPointer()); if (newstate != cert->getTrust()) { cert->setTrust(newstate); updatePKI(cert); } } } void db_x509::certRenewal(QModelIndexList indexes) { pki_x509 *oldcert = NULL, *signer = NULL, *newcert =NULL; pki_key *signkey = NULL; a1time time; a1int serial; CertExtend *dlg = NULL; x509rev r; bool doRevoke = false; if (indexes.size() == 0) return; QModelIndex idx = indexes[0]; try { oldcert = static_cast(idx.internalPointer()); if (!oldcert || !(signer = oldcert->getSigner()) || !(signkey = signer->getRefKey()) || signkey->isPubKey()) return; CertExtend *dlg = new CertExtend(mainwin, signer); if (!dlg->exec()) { delete dlg; return; } if (dlg->revoke->isChecked()) { Revocation *revoke = new Revocation(mainwin, indexes); doRevoke = revoke->exec(); r = revoke->getRevocation(); delete revoke; } foreach(idx, indexes) { oldcert = static_cast (idx.internalPointer()); newcert = new pki_x509(oldcert); serial = getUniqueSerial(signer); newcert->setRevoked(x509rev()); // change date and serial newcert->setSerial(serial); newcert->setNotBefore(dlg->notBefore->getDate()); a1time a; if (dlg->noWellDefinedExpDate->isChecked()) a.setUndefined(); else a = dlg->notAfter->getDate(); newcert->setNotAfter(a); // and finally sign the cert newcert->sign(signkey, oldcert->getDigest()); newcert = (pki_x509 *)insert(newcert); createSuccess(newcert); } if (doRevoke) do_revoke(indexes, r); } catch (errorEx &err) { MainWindow::Error(err); if (newcert) delete newcert; } if (dlg) delete dlg; emit columnsContentChanged(); } void db_x509::revoke(QModelIndexList indexes) { if (indexes.size() == 0) return; Revocation *revoke = new Revocation(mainwin, indexes); if (revoke->exec()) { do_revoke(indexes, revoke->getRevocation()); } emit columnsContentChanged(); } void db_x509::do_revoke(QModelIndexList indexes, const x509rev &r) { pki_x509 *parent = NULL, *cert, *iss; x509revList revlist; foreach(QModelIndex idx, indexes) { cert = static_cast(idx.internalPointer()); iss = cert->getSigner(); if (parent == NULL) { parent = iss; } else if (parent != iss) { parent = NULL; break; } } if (!parent) { qWarning("%s(%d): Certs have different/no signer\n", __func__, __LINE__); } foreach(QModelIndex idx, indexes) { pki_x509 *cert = static_cast(idx.internalPointer()); x509rev rev(r); rev.setSerial(cert->getSerial()); cert->setRevoked(rev); revlist << rev; } parent->mergeRevList(revlist); updatePKI(parent); } void db_x509::unRevoke(QModelIndexList indexes) { pki_x509 *parent = NULL; foreach(QModelIndex idx, indexes) { pki_x509 *cert = static_cast(idx.internalPointer()); if (!cert) return; pki_x509 *iss = cert->getSigner(); if (parent == NULL) { parent = iss; } else if (parent != iss) { parent = NULL; break; } } if (!parent) { qWarning("%s(%d): Certs have different/no signer\n", __func__, __LINE__); } foreach(QModelIndex idx, indexes) { pki_x509 *cert = static_cast(idx.internalPointer()); int i; x509rev rev; cert->setRevoked(x509rev()); rev.setSerial(cert->getSerial()); i = parent->revList.indexOf(rev); if (i != -1) parent->revList.takeAt(i); } updatePKI(parent); emit columnsContentChanged(); } void db_x509::toCertificate(QModelIndex index) { pki_x509 *cert = static_cast(index.internalPointer()); if (!cert) return; if (!cert->getRefKey() && cert->getSigner() != cert) extractPubkey(index); newCert(cert); } void db_x509::toRequest(QModelIndex idx) { pki_x509 *cert = static_cast(idx.internalPointer()); if (!cert) return; try { pki_x509req *req = new pki_x509req(); check_oom(req); req->setIntName(cert->getIntName()); req->createReq(cert->getRefKey(), cert->getSubject(), cert->getDigest(), cert->getV3ext()); createSuccess(mainwin->reqs->insert(req)); } catch (errorEx &err) { mainwin->Error(err); } } void db_x509::toToken(QModelIndex idx, bool alwaysSelect) { pki_x509 *cert = static_cast(idx.internalPointer()); if (!cert) return; try { cert->store_token(alwaysSelect); } catch (errorEx &err) { mainwin->Error(err); } } void db_x509::caProperties(QModelIndex idx) { Ui::CaProperties ui; int i; pki_x509 *cert = static_cast(idx.internalPointer()); if (!cert) return; QDialog *dlg = new QDialog(mainwin); ui.setupUi(dlg); ui.serial->setText(cert->getCaSerial().toHex()); ui.serial->setDisabled(cert->usesRandomSerial()); ui.randomSerial->setChecked(cert->usesRandomSerial()); ui.days->setSuffix(tr(" days")); ui.days->setMaximum(1000000); ui.days->setValue(cert->getCrlDays()); ui.image->setPixmap(*MainWindow::certImg); QString templ = cert->getTemplate(); QStringList tempList = mainwin->temps->getDesc(); for (i=0; iaddItems(tempList); ui.temp->setCurrentIndex(i); ui.certName->setTitle(cert->getIntName()); if (dlg->exec()) { a1int nserial; cert->setCrlDays(ui.days->value()); nserial.setHex(ui.serial->text()); cert->setCaSerial(nserial); cert->setTemplate(ui.temp->currentText()); cert->setUseRandomSerial(ui.randomSerial->isChecked()); updatePKI(cert); } delete dlg; }