xca/lib/db_x509.cpp
Christian Hohnstaedt 356cab3401 check for duplicate x509 v3 extensions
- while taking extensions from the request, the advanced tab
   and the other tabs, extensions may be duplicated.

   They will be now diplayed in
   detail and duplicates are found and shown clearly.
   Warning message will allow for modifications.

 - Fixes
    [ 1881482 ] Copy extensions from request seems to fail
    [ 1998815 ] xca adds basic constraint "CA" twice resulting in invalid CA
2009-03-03 21:52:32 +01:00

1033 lines
24 KiB
C++

/* vi: set sw=4 ts=4:
*
* Copyright (C) 2001 - 2007 Christian Hohnstaedt.
*
* All rights reserved.
*/
#include "db_x509.h"
#include "pki_pkcs12.h"
#include "pki_pkcs7.h"
#include "widgets/CertDetail.h"
#include "widgets/CertExtend.h"
#include "widgets/ExportCert.h"
#include "widgets/MainWindow.h"
#include "ui_TrustState.h"
#include "ui_CaProperties.h"
#include "ui_PassWrite.h"
#include <qmessagebox.h>
#include <qevent.h>
#include <qaction.h>
bool db_x509::treeview = true;
db_x509::db_x509(QString DBfile, MainWindow *mw)
:db_x509super(DBfile, mw)
{
rootItem->setIntName("[x509 root]");
headertext << tr("Internal name") << tr("Common name") << tr("Serial") <<
tr("not After") << tr("Trust state") << tr("Revocation");
delete_txt = tr("Delete the certificate(s)");
view = mw->certView;
class_name = "certificates";
loadContainer();
}
pki_base *db_x509::newPKI(){
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<pki_base*>(currentIdx.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);
return;
}
void db_x509::changeView()
{
pki_base *temproot;
int rows = rowCount(QModelIndex());
if (!rows)
return;
temproot = new pki_base();
mainwin->certView->setModel(NULL);
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;
mainwin->certView->setModel(this);
}
void db_x509::calcEffTrust()
{
FOR_ALL_pki(pki, pki_x509)
pki->calcEffTrust();
}
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 = rootItem;
insertChild(root, pki);
/* search for dangling certificates, which signer this is */
FOR_ALL_pki(client, pki_x509) {
if (client->getSigner() == NULL) {
if (client->verify(cert) && treeview ) {
int row = client->row();
pki_x509 *s;
/* recursive signing check */
for (s = cert; s; s = s->getSigner()) {
if (s == s->getSigner()) {
s = NULL;
break;
}
if (s == client) {
printf("Recursive signing: '%s' <-> '%s'\n",
CCHAR(client->getIntName()),
CCHAR(cert->getIntName()));
break;
}
}
if (s)
continue;
beginRemoveRows(QModelIndex(), row, row);
rootItem->takeChild(client);
endRemoveRows();
insertChild(pki, client);
client = (pki_x509*)rootItem;
}
}
}
findKey(cert);
calcEffTrust();
}
QList<pki_x509*> db_x509::getIssuedCerts(const pki_x509 *issuer)
{
QList<pki_x509*> c;
c.clear();
if (!issuer)
return c;
FOR_ALL_pki(pki, pki_x509) {
if (pki->getSigner() == issuer)
c.append(pki);
}
return c;
}
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::revokeCert(const x509rev &revok, const pki_x509 *iss)
{
pki_x509 *crt = getByIssSerial(iss, revok.getSerial());
if (crt)
crt->setRevoked(revok.getDate());
}
pki_x509 *db_x509::getByIssSerial(const pki_x509 *issuer, const a1int &a)
{
if (!issuer ) return NULL;
FOR_ALL_pki(pki, pki_x509) {
if ((pki->getSigner() == issuer) && (a == pki->getSerial()))
return pki;
}
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.toAscii(), true, append);
append = true;
}
}
QList<pki_x509*> db_x509::getCerts(bool onlyTrusted)
{
QList<pki_x509*> c;
c.clear();
FOR_ALL_pki(pki, pki_x509) {
if (onlyTrusted && pki->getTrust() != 2) continue;
c.append(pki);
}
return c;
}
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;
}
pki_base *db_x509::insert(pki_base *item)
{
pki_x509 *cert = (pki_x509 *)item;
pki_x509 *oldcert = (pki_x509 *)getByReference(cert);
if (oldcert) {
QMessageBox::information(mainwin, XCA_TITLE,
tr("The certificate already exists in the database as") +":\n'" +
oldcert->getIntName() +
"'\n" + tr("and so it was not imported"), "OK");
delete(cert);
return oldcert;
}
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);
}
updatePKI(cert);
return cert;
}
void db_x509::load(void)
{
load_cert c;
load_default(c);
}
void db_x509::loadPKCS12()
{
load_pkcs12 l;
load_default(l);
}
void db_x509::loadPKCS7()
{
load_pkcs7 l;
load_default(l);
}
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<pki_x509*>(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);
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);
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(NewX509 *dlg)
{
pki_x509 *cert = NULL;
pki_x509 *signcert = NULL;
pki_x509req *req = NULL;
pki_key *signkey = NULL, *clientkey = NULL, *tempkey = NULL;
a1int serial;
a1time notBefore, notAfter;
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;
}
subject = req->getSubject();
intname = req->getIntName();
}
// 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 = signcert->getIncCaSerial();
signkey = signcert->getRefKey();
cert->setTrust(1);
#ifdef WG_QA_SERIAL
} else if (dlg->selfQASignRB->isChecked()){
Ui::PassWrite ui;
QDialog *dlg1 = new QDialog(mainwin);
ui.setupUi(dlg1);
ui.image->setPixmap( *MainWindow::keyImg );
ui.description->setText(tr("Please enter the new hexadecimal secret number for the QA process."));
dlg1->setWindowTitle(XCA_TITLE);
ui.passA->setFocus();
ui.passA->setValidator(new QRegExpValidator(QRegExp("[0-9a-fA-F]*"),
ui.passA));
ui.passB->setValidator(new QRegExpValidator(QRegExp("[0-9a-fA-F]*"),
ui.passB));
QString A = "x", B="";
while (dlg1->exec()) {
A = ui.passA->text();
B = ui.passB->text();
if (A==B)
break;
else
QMessageBox::warning(mainwin, XCA_TITLE,
tr("The two secret numbers don't match."));
}
delete dlg1;
if (A!=B)
throw errorEx(tr("The QA process has been terminated by the user."));
signcert = cert;
signkey = clientkey;
serial.setHex(A);
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()) {
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() );
cert->setNotAfter( dlg->notAfter->getDate() );
if (cert->resetTimes(signcert) > 0) {
if (QMessageBox::information(mainwin,tr(XCA_TITLE),
tr("The validity times for the certificate need to get adjusted to not exceed those of the signer"),
tr("Continue creation"), tr("Abort")
))
throw errorEx("");
}
// STEP 4 handle extensions
if (dlg->copyReqExtCB->isChecked() && dlg->fromReqCB->isChecked()) {
extList el = req->getV3ext();
int m = el.count();
for (int i=0; i<m; i++)
cert->addV3ext(el[i]);
}
// apply all extensions to the subject cert in the context
dlg->getAllExt();
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);
insert(cert);
updatePKI(signcert);
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->signCert, SIGNAL( doubleClicked(QString) ),
this, SLOT( showItem(QString) ));
dlg->exec();
delete dlg;
}
}
void db_x509::showContextMenu(QContextMenuEvent *e, const QModelIndex &index)
{
QMenu *menu = new QMenu(mainwin);
QMenu *subExport, *subCa;
QAction *itemReq, *itemRevoke, *itemExtend,
*itemTrust;
bool parentCanSign, canSign, hasTemplates, hasPrivkey;
currentIdx = index;
pki_x509 *cert = static_cast<pki_x509*>(index.internalPointer());
menu->addAction(tr("New Certificate"), this, SLOT(newItem()));
menu->addAction(tr("Import"), this, SLOT(load()));
menu->addAction(tr("Import PKCS#12"), this, SLOT(loadPKCS12()));
menu->addAction(tr("Import from PKCS#7"), this, SLOT(loadPKCS7()));
if (index != QModelIndex()) {
menu->addAction(tr("Rename"), this, SLOT(edit()));
menu->addAction(tr("Show Details"), this, SLOT(showItem()));
subExport = menu->addMenu(tr("Export"));
subExport->addAction(tr("File"), this, SLOT(store()));
itemReq = subExport->addAction(tr("Request"),
this, SLOT(toRequest()));
menu->addAction(tr("Delete"), this, SLOT(delete_ask()));
itemTrust = menu->addAction(tr("Trust"), this, SLOT(setTrust()));
menu->addSeparator();
subCa = menu->addMenu(tr("CA"));
subCa->addAction(tr("Properties"), this, SLOT(caProperties()));
subCa->addAction(tr("Generate CRL"), this, SLOT(genCrl()));
#if 0
QMenu *subP7 = menu->addMenu(tr("PKCS#7"));
subP7->addAction(tr("Sign"), this, SLOT(signP7()));
subP7->addAction(tr("Encrypt"), this, SLOT(encryptP7()));
#endif
menu->addSeparator();
itemExtend = menu->addAction(tr("Renewal"),
this, SLOT(extendCert()));
if (cert->isRevoked()) {
itemRevoke = menu->addAction(tr("Unrevoke"),
this, SLOT(unRevoke()));
itemTrust->setEnabled(false);
} else {
itemRevoke = menu->addAction(tr("Revoke"),
this, SLOT(revoke()));
}
parentCanSign = (cert->getSigner() && cert->getSigner()->canSign()
&& (cert->getSigner() != cert));
canSign = cert->canSign();
#warning templates
hasTemplates = mainwin->temps->getDesc().count() > 0 ;
hasPrivkey = cert->getRefKey();
itemRevoke->setEnabled(parentCanSign);
itemExtend->setEnabled(parentCanSign);
subCa->setEnabled(canSign);
itemReq->setEnabled(hasPrivkey);
#if 0
subP7->setEnabled(hasPrivkey);
#endif
}
menu->exec(e->globalPos());
delete menu;
currentIdx = QModelIndex();
return;
}
#define P7_ONLY 0
#define P7_CHAIN 1
#define P7_TRUSTED 2
#define P7_ALL 3
void db_x509::store()
{
QStringList filt;
bool pkcs8 = false, append;
if (!currentIdx.isValid())
return;
pki_x509 *crt = static_cast<pki_x509*>(currentIdx.internalPointer());
pki_x509 *oldcrt = NULL;
if (!crt)
return;
pki_key *privkey = crt->getRefKey();
QString fn = mainwin->getPath() + QDir::separator() +
crt->getUnderlinedName() + ".crt";
ExportCert *dlg = new ExportCert(mainwin, fn,
(privkey && privkey->isPrivKey()) );
dlg->image->setPixmap(*MainWindow::certImg);
int dlgret = dlg->exec();
if (!dlgret) {
delete dlg;
return;
}
QString fname = dlg->filename->text();
if (fname == "") {
delete dlg;
return;
}
mainwin->setPath(fname.mid(0, fname.lastIndexOf(QRegExp("[/\\\\]")) ));
try {
switch (dlg->exportFormat->currentIndex()) {
case 0: // PEM
crt->writeCert(fname,true,false);
break;
case 1: // PEM with chain
append = false;
while(crt && crt != oldcrt) {
crt->writeCert(fname, true, append);
append = true;
oldcrt = crt;
crt = crt->getSigner();
}
break;
case 2: // PEM all trusted Certificates
writeAllCerts(fname,true);
break;
case 3: // PEM all Certificates
writeAllCerts(fname,false);
break;
case 4: // DER
crt->writeCert(fname,false,false);
break;
case 5: // P7 lonely
writePKCS7(crt,fname, P7_ONLY);
break;
case 6: // P7
writePKCS7(crt,fname, P7_CHAIN);
break;
case 7: // P7
writePKCS7(crt,fname, P7_TRUSTED);
break;
case 8: // P7
writePKCS7(crt,fname, P7_ALL);
break;
case 9: // P12
writePKCS12(crt,fname,false);
break;
case 10: // P12 + cert chain
writePKCS12(crt,fname,true);
break;
case 12: // Certificate and Key in PKCS8 format
pkcs8 = true;
case 11: // Certificate and Key in PEM format for apache
pki_key *privkey = crt->getRefKey();
if (!privkey || privkey->isPubKey()) {
QMessageBox::warning(mainwin, tr(XCA_TITLE),
tr("There was no key found for the Certificate: ") +
crt->getIntName() );
return;
}
if (pkcs8) {
privkey->writePKCS8(fname, NULL, NULL, true);
} else {
privkey->writeKey(fname, NULL, NULL, true);
}
crt->writeCert(fname, true, true);
}
}
catch (errorEx &err) {
MainWindow::Error(err);
}
delete dlg;
}
void db_x509::writePKCS12(pki_x509 *cert, QString s, bool chain)
{
QStringList filt;
try {
pki_key *privkey = cert->getRefKey();
if (!privkey || privkey->isPubKey()) {
QMessageBox::warning(mainwin, tr(XCA_TITLE),
tr("There was no key found for the Certificate: ") +
cert->getIntName() );
return;
}
if (s.isEmpty())
return;
s = QDir::convertSeparators(s);
pki_pkcs12 *p12 = new pki_pkcs12(cert->getIntName(), cert, privkey,
MainWindow::passWrite);
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, int type)
{
pki_pkcs7 *p7 = NULL;
QList<pki_base> list;
try {
p7 = new pki_pkcs7("");
switch (type) {
case P7_CHAIN:
while (cert != NULL) {
p7->addCert(cert);
if (cert->getSigner() == cert)
cert = NULL;
else
cert = cert->getSigner();
}
break;
case P7_ONLY:
p7->addCert(cert);
break;
case P7_TRUSTED:
case P7_ALL:
FOR_ALL_pki(cer, pki_x509) {
if ((type == P7_ALL) || (cer->getTrust() == 2))
p7->addCert(cer);
}
}
p7->writeP7(s, false);
}
catch (errorEx &err) {
MainWindow::Error(err);
}
if (p7 != NULL )
delete p7;
}
# if 0
void ::signP7()
{
QStringList filt;
try {
pki_x509 *cert = (pki_x509 *)getSelected();
if (!cert) return;
pki_key *privkey = cert->getRefKey();
if (!privkey || privkey->isPubKey()) {
QMessageBox::warning(this,tr(XCA_TITLE),
tr("There was no key found for the Certificate: ") +
cert->getIntName());
return;
}
filt.append("All Files ( * )");
QString s="";
QStringList slist;
Q3FileDialog *dlg = new Q3FileDialog(this,0,true);
dlg->setCaption(tr("Import Certificate signing request"));
dlg->setFilters(filt);
dlg->setMode( Q3FileDialog::ExistingFiles );
dlg->setDir(MainWindow::getPath());
if (dlg->exec()) {
slist = dlg->selectedFiles();
MainWindow::setPath(dlg->dirPath());
}
delete dlg;
pki_pkcs7 * p7 = new pki_pkcs7("");
for ( QStringList::Iterator it = slist.begin(); it != slist.end(); ++it ) {
s = *it;
s = QDir::convertSeparators(s);
p7->signFile(cert, s);
p7->writeP7((s + ".p7s"), true);
}
delete p7;
}
catch (errorEx &err) {
Qt::SocketError(err);
}
}
void CertView::encryptP7()
{
QStringList filt;
try {
pki_x509 *cert = (pki_x509 *)getSelected();
if (!cert) return;
pki_key *privkey = cert->getRefKey();
if (!privkey || privkey->isPubKey()) {
QMessageBox::warning(this,tr(XCA_TITLE),
tr("There was no key found for the Certificate: ") +
cert->getIntName()) ;
return;
}
filt.append("All Files ( * )");
QString s="";
QStringList slist;
Q3FileDialog *dlg = new Q3FileDialog(this,0,true);
dlg->setCaption(tr("Import Certificate signing request"));
dlg->setFilters(filt);
dlg->setMode( Q3FileDialog::ExistingFiles );
dlg->setDir(MainWindow::getPath());
if (dlg->exec()) {
slist = dlg->selectedFiles();
MainWindow::setPath(dlg->dirPath());
}
delete dlg;
pki_pkcs7 * p7 = new pki_pkcs7("");
for ( QStringList::Iterator it = slist.begin(); it != slist.end(); ++it ) {
s = *it;
s = QDir::convertSeparators(s);
p7->encryptFile(cert, s);
p7->writeP7((s + ".p7m"), true);
}
delete p7;
}
catch (errorEx &err) {
Qt::SocketError(err);
}
}
#endif
void db_x509::setMultiTrust(QAbstractItemView* view)
{
QItemSelectionModel *selectionModel = view->selectionModel();
QModelIndexList indexes = selectionModel->selectedIndexes();
QString items;
foreach(currentIdx, indexes) {
setTrust();
}
currentIdx = QModelIndex();
}
void db_x509::setTrust()
{
int state, newstate = 0;
Ui::TrustState ui;
pki_x509 *cert = static_cast<pki_x509*>(currentIdx.internalPointer());
if (!cert)
return;
QDialog *dlg = new QDialog(mainwin);
ui.setupUi(dlg);
ui.image->setPixmap(*MainWindow::certImg);
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);
ui.certName->setText(cert->getIntName());
if (dlg->exec()) {
if (ui.trust0->isChecked()) newstate = 0;
if (ui.trust1->isChecked()) newstate = 1;
if (ui.trust2->isChecked()) newstate = 2;
if (newstate!=state) {
cert->setTrust(newstate);
updatePKI(cert);
}
}
delete dlg;
}
void db_x509::extendCert()
{
pki_x509 *oldcert = NULL, *signer = NULL, *newcert =NULL;
pki_key *signkey = NULL;
a1time time;
a1int serial;
try {
CertExtend *dlg = new CertExtend(mainwin);
if (!dlg->exec()) {
delete dlg;
return;
}
oldcert = static_cast<pki_x509*>(currentIdx.internalPointer());
if (!oldcert ||
!(signer = oldcert->getSigner()) ||
!(signkey = signer->getRefKey()) ||
signkey->isPubKey())
return;
newcert = new pki_x509(oldcert);
serial = signer->getIncCaSerial();
// get signers own serial to avoid having the same
if (serial == signer->getSerial()) {
serial = signer->getIncCaSerial(); // just take the next one
}
updatePKI(signer);
// change date and serial
newcert->setSerial(serial);
newcert->setNotBefore(dlg->notBefore->getDate());
newcert->setNotAfter(dlg->notAfter->getDate());
if (newcert->resetTimes(signer) > 0) {
if (QMessageBox::information(mainwin, tr(XCA_TITLE),
tr("The validity times for the certificate need to get adjusted to not exceed those of the signer"),
tr("Continue creation"), tr("Abort")
))
throw errorEx("");
}
// and finally sign the request
newcert->sign(signkey, oldcert->getDigest());
insert(newcert);
delete dlg;
}
catch (errorEx &err) {
MainWindow::Error(err);
if (newcert)
delete newcert;
}
}
void db_x509::revoke()
{
pki_x509 *cert = static_cast<pki_x509*>(currentIdx.internalPointer());
if (!cert)
return;
cert->setRevoked(true);
updatePKI(cert);
}
void db_x509::unRevoke()
{
pki_x509 *cert = static_cast<pki_x509*>(currentIdx.internalPointer());
if (!cert)
return;
cert->setRevoked(false);
updatePKI(cert);
}
void db_x509::genCrl()
{
pki_x509 *cert = static_cast<pki_x509*>(currentIdx.internalPointer());
mainwin->crls->newItem(cert);
}
void db_x509::toRequest()
{
pki_x509 *cert = static_cast<pki_x509*>(currentIdx.internalPointer());
if (!cert)
return;
try {
pki_x509req *req = new pki_x509req();
req->setIntName(cert->getIntName());
req->createReq(cert->getRefKey(), cert->getSubject(),
cert->getRefKey()->getDefaultMD(), cert->getExt());
mainwin->reqs->insert(req);
}
catch (errorEx &err) {
mainwin->Error(err);
}
}
void db_x509::caProperties()
{
Ui::CaProperties ui;
int i;
pki_x509 *cert = static_cast<pki_x509*>(currentIdx.internalPointer());
if (!cert)
return;
QDialog *dlg = new QDialog(mainwin);
ui.setupUi(dlg);
ui.serial->setText(cert->getCaSerial().toHex());
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; i<tempList.count(); i++) {
if (tempList[i] == templ)
break;
}
ui.temp->addItems(tempList);
ui.temp->setCurrentIndex(i);
ui.certName->setText(cert->getIntName());
if (dlg->exec()) {
a1int nserial;
cert->setCrlDays(ui.days->value());
nserial.setHex(ui.serial->text());
if (nserial > cert->getCaSerial())
cert->setCaSerial(nserial);
cert->setTemplate(ui.temp->currentText());
updatePKI(cert);
}
delete dlg;
}