Refactor CRL handling

This commit is contained in:
Christian Hohnstaedt 2015-04-18 10:03:37 +02:00
parent 25a53441e9
commit 90f351b2cb
24 changed files with 1055 additions and 574 deletions

View File

@ -50,17 +50,19 @@ void db_crl::load()
void db_crl::revokeCerts(pki_crl *crl)
{
int numc, i;
x509revList revlist;
if (!mainwin->certs)
return;
x509rev revok;
pki_x509 *signer = crl->getIssuer();
if (!signer)
return;
numc = crl->numRev();
for (i=0; i<numc; i++) {
revok = crl->getRev(i);
mainwin->certs->revokeCert(revok, signer);
revlist = crl->getRevList();
signer->mergeRevList(revlist);
foreach(x509rev revok, revlist) {
pki_x509 *crt = signer->getBySerial(revok.getSerial());
if (crt)
crt->setRevoked(revok);
}
}
@ -91,7 +93,6 @@ void db_crl::inToCont(pki_base *pki)
}
crl->setIssuer(iss);
}
revokeCerts(crl);
db_base::inToCont(pki);
}
@ -105,6 +106,10 @@ pki_base *db_crl::insert(pki_base *item)
return NULL;
}
insertPKI(crl);
revokeCerts(crl);
pki_x509 *issuer = crl->getIssuer();
if (issuer)
mainwin->certs->updateAfterCrlLoad(issuer);
return crl;
}
@ -155,17 +160,17 @@ void db_crl::store()
delete dlg;
}
pki_crl *db_crl::newItem(pki_x509 *cert)
void db_crl::newItem(pki_x509 *cert)
{
if (!cert)
return NULL;
return;
pki_crl *crl = NULL;
NewCrl *dlg = new NewCrl(mainwin, cert);
if (!dlg->exec()) {
delete dlg;
return NULL;
return;
}
try {
x509v3ext e;
@ -176,13 +181,9 @@ pki_crl *db_crl::newItem(pki_x509 *cert)
crl = new pki_crl();
crl->createCrl(cert->getIntName(), cert);
QList<pki_x509*> list = mainwin->certs->getIssuedCerts(cert);
bool reason = dlg->revocationReasons->isChecked();
for (int i =0; i<list.size(); i++) {
if (list.at(i)->isRevoked() ) {
crl->addRev(list.at(i)->getRev(reason));
}
}
bool withReason = dlg->revocationReasons->isChecked();
foreach(x509rev rev, cert->revList)
crl->addRev(rev, withReason);
if (dlg->authKeyId->isChecked()) {
crl->addV3ext(e.create(NID_authority_key_identifier,
@ -211,7 +212,7 @@ pki_crl *db_crl::newItem(pki_x509 *cert)
crl = NULL;
}
delete dlg;
return crl;
return;
}
void db_crl::showContextMenu(QContextMenuEvent *e, const QModelIndex &index)

View File

@ -27,13 +27,13 @@ class db_crl: public db_x509name
void revokeCerts(pki_crl *crl);
void inToCont(pki_base *pki);
pki_base *insert(pki_base *item);
pki_crl *newItem(pki_x509 *cert);
void showContextMenu(QContextMenuEvent *e, const QModelIndex &index);
void removeSigner(pki_base *signer);
public slots:
void store();
void load();
void showPki(pki_base *pki);
void newItem(pki_x509 *cert);
signals:
void updateCertView();
};

View File

@ -16,10 +16,10 @@
#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 "ui_Revoke.h"
#include <QtGui/QMessageBox>
#include <QtGui/QContextMenuEvent>
#include <QtGui/QAction>
@ -36,6 +36,22 @@ db_x509::db_x509(QString DBfile, MainWindow *mw)
loadContainer();
}
void db_x509::updateAfterCrlLoad(pki_x509 *pki)
{
if (pki->revList.merged) {
fprintf(stderr, "Update '%s'\n", CCHAR(pki->getIntName()));
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();
@ -229,20 +245,6 @@ void db_x509::inToCont(pki_base *pki)
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;
@ -261,23 +263,6 @@ pki_x509 *db_x509::getBySubject(const x509name &xname, pki_x509 *last)
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;
@ -321,18 +306,16 @@ a1int db_x509::getUniqueSerial(pki_x509 *signer)
{
// returnes an unused unique serial
a1int serial;
bool dup;
do {
dup = false;
x509rev rev;
while (true) {
serial = signer->getIncCaSerial();
FOR_ALL_pki(pki, pki_x509)
if (pki->getSigner() == signer) {
if (serial == pki->getSerial()) {
dup = true;
break;
}
}
} while (dup);
rev.setSerial(serial);
if (signer->revList.contains(rev))
continue;
if (signer->getBySerial(serial))
continue;
break;
}
if (!signer->usesRandomSerial())
updatePKI(signer);
return serial;
@ -668,6 +651,8 @@ void db_x509::showContextMenu(QContextMenuEvent *e, const QModelIndex &index)
subCa = menu->addMenu(tr("CA"));
subCa->addAction(tr("Properties"), this, SLOT(caProperties()));
subCa->addAction(tr("Generate CRL"), this, SLOT(genCrl()));
subCa->addAction(tr("Manage revocations"),
this, SLOT(manageRevocations()));
subCa->setEnabled(canSign);
menu->addSeparator();
menu->addAction(tr("Renewal"), this, SLOT(extendCert()))->
@ -944,6 +929,21 @@ void db_x509::deleteFromToken()
}
}
void db_x509::manageRevocations()
{
pki_x509 *cert = static_cast<pki_x509*>(currentIdx.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);
}
}
void db_x509::setTrust()
{
int state, newstate = 0;
@ -964,7 +964,6 @@ void db_x509::setTrust()
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;
@ -1016,6 +1015,9 @@ void db_x509::extendCert()
newcert->sign(signkey, oldcert->getDigest());
newcert = (pki_x509 *)insert(newcert);
createSuccess(newcert);
if (dlg->revoke->isChecked())
revoke();
}
catch (errorEx &err) {
MainWindow::Error(err);
@ -1032,25 +1034,37 @@ void db_x509::revoke()
pki_x509 *cert = static_cast<pki_x509*>(currentIdx.internalPointer());
if (!cert)
return;
Ui::Revoke ui;
QDialog *revoke = new QDialog(mainwin, 0);
ui.setupUi(revoke);
ui.invalid->setNow();
ui.reason->addItems(x509rev::crlreasons());
Revocation *revoke = new Revocation(mainwin, cert);
if (revoke->exec()) {
cert->setRevoked(true, ui.invalid->getDate(),
ui.reason->currentText());
updatePKI(cert);
const x509rev r = revoke->getRevocation();
cert->setRevoked(r);
pki_x509 *iss = cert->getSigner();
if (iss) {
x509revList rl(r);
iss->mergeRevList(rl);
updatePKI(iss);
}
}
}
void db_x509::unRevoke()
{
pki_x509 *cert = static_cast<pki_x509*>(currentIdx.internalPointer());
pki_x509 *sig;
int idx;
x509rev rev;
if (!cert)
return;
cert->setRevoked(false);
updatePKI(cert);
sig = cert->getSigner();
if (!sig)
return;
cert->setRevoked(x509rev());
rev.setSerial(cert->getSerial());
idx = sig->revList.indexOf(rev);
if (idx != -1)
sig->revList.takeAt(idx);
updatePKI(sig);
}
void db_x509::genCrl()
@ -1146,4 +1160,3 @@ void db_x509::caProperties()
}
delete dlg;
}

View File

@ -10,8 +10,8 @@
#define __DB_X509_H
#include <QtGui/QListView>
#include <QtCore/QObject>
#include <QtGui/QPixmap>
#include <QtGui/QTreeWidget>
#include "widgets/ExportDialog.h"
#include "db_key.h"
#include "db_x509super.h"
@ -33,6 +33,9 @@ class db_x509: public db_x509super
db_x509(QString DBfile, MainWindow *mw);
pki_base *newPKI(db_header_t *head = NULL);
pki_x509 *findSigner(pki_x509 *client);
void updateAfterDbLoad();
void updateAfterCrlLoad(pki_x509 *pki);
bool updateView();
void updateViewAll();
void updateViewPKI(pki_base *pki);
@ -40,7 +43,6 @@ class db_x509: public db_x509super
QStringList getPrivateDesc();
QStringList getSignerDesc();
void calcEffTrust();
QList<pki_x509*> getIssuedCerts(const pki_x509 *issuer);
QList<pki_x509*> getCerts(bool onlyTrusted);
a1int searchSerial(pki_x509 *signer);
void writeAllCerts(const QString fname, bool onlyTrusted);
@ -62,7 +64,6 @@ class db_x509: public db_x509super
public slots:
void load(void);
void newItem(void);
void revokeCert(const x509rev &revok, const pki_x509 *issuer);
void showPki(pki_base *pki);
void setMultiTrust(QAbstractItemView* view);
void setTrust();
@ -80,6 +81,7 @@ class db_x509: public db_x509super
void newCert(pki_x509req *);
void loadPKCS12();
void loadPKCS7();
void manageRevocations();
};
#endif

View File

@ -154,9 +154,9 @@ QByteArray pki_crl::toData()
return ba;
}
void pki_crl::addRev(const x509rev &xrev)
void pki_crl::addRev(const x509rev &xrev, bool withReason)
{
X509_CRL_add0_revoked(crl, xrev.get());
X509_CRL_add0_revoked(crl, xrev.get(withReason));
pki_openssl_error();
}
@ -240,16 +240,18 @@ int pki_crl::numRev()
{
if (crl && crl->crl && crl->crl->revoked)
return sk_X509_REVOKED_num(crl->crl->revoked);
else
return 0;
return 0;
}
x509rev pki_crl::getRev(int num)
x509revList pki_crl::getRevList()
{
x509rev ret;
if (crl && crl->crl && crl->crl->revoked) {
ret.set(sk_X509_REVOKED_value(crl->crl->revoked, num));
x509revList ret;
int i, num = numRev();
for (i=0; i<num; i++) {
x509rev r(sk_X509_REVOKED_value(crl->crl->revoked, i));
pki_openssl_error();
ret << r;
}
return ret;
}

View File

@ -33,7 +33,7 @@ class pki_crl: public pki_x509name
void writeDefault(const QString fname);
static QPixmap *icon;
void createCrl(const QString d, pki_x509 *iss);
void addRev(const x509rev &rev);
void addRev(const x509rev &rev, bool withReason=true);
void addExt(int nid, QString value);
void write(QString fname);
void addV3ext(const x509v3ext &e);
@ -55,9 +55,9 @@ class pki_crl: public pki_x509name
void fromData(const unsigned char *p, db_header_t *head);
void oldFromData(unsigned char *p, int size);
QByteArray toData();
int numRev();
bool verify(pki_key *pkey);
x509rev getRev(int num);
int numRev();
x509revList getRevList();
QString printV3ext();
x509v3ext getExtByNid(int nid);
a1int getVersion();

View File

@ -41,12 +41,11 @@ pki_x509::pki_x509(const pki_x509 *crt)
setRefKey(crt->getRefKey());
trust = crt->trust;
efftrust = crt->efftrust;
revoked = crt->revoked;
caSerial = crt->caSerial;
caTemplate = crt->caTemplate;
revocation = crt->revocation;
crlDays = crt->crlDays;
crlExpiry = crt->crlExpiry;
isrevoked = isrevoked;
pki_openssl_error();
}
@ -134,18 +133,15 @@ void pki_x509::init()
psigner = NULL;
trust = 0;
efftrust = 0;
revoked = a1time::now();
caSerial = 1;
caTemplate = "";
crlDays = 30;
crlExpiry.setUndefined();
class_name = "pki_x509";
cert = NULL;
isrevoked = false;
dataVersion = 3;
dataVersion = 4;
pkiType = x509;
randomSerial = false;
revoke_reason = "";
}
void pki_x509::setSerial(const a1int &serial)
@ -164,6 +160,16 @@ a1int pki_x509::getSerial() const
return a;
}
pki_x509 *pki_x509::getBySerial(const a1int &a) const
{
foreach(pki_base *p, childItems) {
pki_x509 *pki = static_cast<pki_x509 *>(p);
if (a == pki->getSerial())
return pki;
}
return NULL;
}
#define SERIAL_LEN 8
a1int pki_x509::getIncCaSerial()
{
@ -493,6 +499,7 @@ void pki_x509::sign(pki_key *signkey, const EVP_MD *digest)
void pki_x509::fromData(const unsigned char *p, db_header_t *head)
{
int version, size;
bool isRevoked;
version = head->version;
size = head->len - sizeof(db_header_t);
@ -502,8 +509,15 @@ void pki_x509::fromData(const unsigned char *p, db_header_t *head)
d2i(ba);
pki_openssl_error();
trust = db::intFromData(ba);
isrevoked = db::boolFromData(ba);
revoked.d2i(ba);
if (version < 4) {
a1time revoked;
isRevoked = db::boolFromData(ba);
revoked.d2i(ba);
if (isRevoked) {
revocation.setDate(revoked);
revocation.setSerial(getSerial());
}
}
caSerial.setHex(db::stringFromData(ba));
caTemplate = db::stringFromData(ba);
crlDays = db::intFromData(ba);
@ -512,10 +526,22 @@ void pki_x509::fromData(const unsigned char *p, db_header_t *head)
randomSerial = db::boolFromData(ba);
else
randomSerial = false;
if (version > 2) {
if (version > 2)
crlNumber.setHex(db::stringFromData(ba));
revoke_reason = db::stringFromData(ba);
if (version > 2 && version < 4) {
// load own revocation info, to tell daddy about it
a1time invalDate;
QString revoke_reason = db::stringFromData(ba);
invalDate.d2i(ba);
if (isRevoked) {
revocation.setReason(revoke_reason);
revocation.setInvalDate(invalDate);
}
}
if (version > 3) {
x509revList curr(revList);
revList.fromBA(ba);
revList.merge(curr);
}
if (ba.count() > 0) {
my_error(tr("Wrong Size %1").arg(ba.count()));
@ -530,8 +556,7 @@ QByteArray pki_x509::toData()
ba += i2d(); // cert
ba += db::intToData(trust);
ba += db::boolToData(isrevoked);
ba += revoked.i2d(); // revocation date
// version 4: don't store isrevoked, revoked
// the serial if this is a CA
ba += db::stringToData(caSerial.toHex());
@ -542,8 +567,8 @@ QByteArray pki_x509::toData()
ba += crlExpiry.i2d(); // last CRL date
ba += db::boolToData(randomSerial);
ba += db::stringToData(crlNumber.toHex());
ba += db::stringToData(revoke_reason);
ba += invalDate.i2d();
// version 4: don't store own revocation but client revocations
ba += revList.toBA();
pki_openssl_error();
return ba;
}
@ -610,12 +635,34 @@ bool pki_x509::verify(pki_x509 *signer)
int i = X509_verify(cert, pub);
pki_ign_openssl_error();
if (i>0) {
int idx;
x509rev r;
r.setSerial(getSerial());
psigner = signer;
psigner->revList.merge(x509revList(revocation));
idx = psigner->revList.indexOf(r);
if (idx != -1)
revocation = psigner->revList[idx];
return true;
}
return false;
}
void pki_x509::setRevocations(const x509revList &rl)
{
revList = rl;
x509rev rev;
foreach(pki_base *p, childItems) {
pki_x509 *pki = static_cast<pki_x509 *>(p);
rev.setSerial(pki->getSerial());
int idx = revList.indexOf(rev);
if (idx != -1)
pki->revocation = revList[idx];
else
pki->revocation = x509rev();
}
}
pki_key *pki_x509::getPubKey() const
{
@ -727,34 +774,16 @@ void pki_x509::setEffTrust(int t)
bool pki_x509::isRevoked()
{
return isrevoked ;
return revocation.isValid();
}
void pki_x509::setRevoked(bool rev, a1time inval, QString reason)
void pki_x509::setRevoked(const x509rev &revok)
{
if (rev) {
revocation = revok;
if (revok.isValid()) {
setEffTrust(0);
revoked = a1time::now();
pki_openssl_error();
revoke_reason = reason;
invalDate = inval;
setTrust(0);
}
isrevoked = rev;
pki_openssl_error();
}
a1time &pki_x509::getRevoked()
{
return revoked;
}
void pki_x509::setRevoked(const a1time &when)
{
isrevoked = true;
revoked = when;
setEffTrust(0);
setTrust(0);
pki_openssl_error();
}
int pki_x509::calcEffTrust()
@ -791,19 +820,6 @@ void pki_x509::setCrlExpiry(const a1time &time)
pki_openssl_error();
}
x509rev pki_x509::getRev(bool reason)
{
x509rev a;
a.setDate(getRevoked());
a.setSerial(getSerial());
if (reason) {
a.setReason(revoke_reason);
a.setInvalDate(invalDate);
}
pki_openssl_error();
return a;
}
bool pki_x509::caAndPathLen(bool *ca, a1int *pathlen, bool *hasLen)
{
x509v3ext e = getExtByNid(NID_basic_constraints);
@ -837,7 +853,7 @@ QVariant pki_x509::column_data(dbheader *hd)
return QVariant(truststatus[getTrust()]);
case HD_cert_revocation:
return QVariant(isRevoked() ?
getRevoked().toSortable() : "");
revocation.getDate().toSortable() : "");
case HD_cert_crl_expire:
if (canSign() && !crlExpiry.isUndefined())
return QVariant(crlExpiry.toSortable());
@ -975,12 +991,14 @@ void pki_x509::oldFromData(unsigned char *p, int size)
trust = intFromData(ba);
sRev = intFromData(ba);
if (sRev) {
if (version != 3) isrevoked = true;
revoked.d2i(ba);
}
else {
isrevoked = false;
revoked = a1time::now();
a1time r;
r.d2i(ba);
if (version != 3) {
revocation.setSerial(getSerial());
revocation.setDate(r);
}
} else {
revocation = x509rev();
}
if (version == 1) {
@ -1016,7 +1034,6 @@ void pki_x509::oldFromData(unsigned char *p, int size)
}
else { // old version
d2i(ba);
revoked = NULL;
trust = 1;
efftrust = 1;
}
@ -1029,4 +1046,3 @@ void pki_x509::oldFromData(unsigned char *p, int size)
my_error(tr("Wrong Size %1").arg(ba.count()));
}
}

View File

@ -26,8 +26,8 @@ class pki_x509 : public pki_x509super
Q_OBJECT
private:
pki_x509 *psigner;
a1time revoked, crlExpiry, invalDate;
bool isrevoked, randomSerial;
a1time crlExpiry;
bool randomSerial;
int trust;
int efftrust;
a1int caSerial;
@ -35,14 +35,17 @@ class pki_x509 : public pki_x509super
int crlDays;
QString caTemplate;
X509 *cert;
QString revoke_reason;
void init();
x509rev revocation;
protected:
ASN1_OBJECT *sigAlg();
public:
static QPixmap *icon[6];
static bool dont_colorize_expiries;
static bool disable_netscape;
x509revList revList;
pki_x509(X509 *c);
pki_x509(const pki_x509 *crt);
pki_x509(const QString name = "");
@ -93,9 +96,9 @@ class pki_x509 : public pki_x509super
void setEffTrust(int t);
void setRevoked(bool rev, a1time inval = a1time(),
QString reason = QString());
void setRevoked(const a1time &when);
a1time &getRevoked();
void setRevoked(const x509rev &revok);
bool isRevoked();
pki_x509 *getBySerial(const a1int &a) const;
int calcEffTrust();
a1int getIncCaSerial();
a1int getCaSerial()
@ -136,13 +139,16 @@ class pki_x509 : public pki_x509super
{
randomSerial = r;
}
x509rev getRevocation()
{
return revocation;
}
pk11_attlist objectAttributes();
void setCrlExpiry(const a1time &time);
bool hasExtension(int nid);
bool cmpIssuerAndSerial(pki_x509 *refcert);
bool visible();
void updateView();
x509rev getRev(bool reason = true);
x509v3ext getExtByNid(int nid);
QVariant column_data(dbheader *hd);
QVariant getIcon(dbheader *hd);
@ -154,6 +160,10 @@ class pki_x509 : public pki_x509super
virtual int renameOnToken(slotid slot, QString name);
BIO *pem(BIO *, int);
virtual QVariant bg_color(dbheader *hd);
void mergeRevList(x509revList l) {
revList.merge(l);
}
void setRevocations(const x509revList &rl);
};
#endif

View File

@ -6,8 +6,10 @@
*/
#include "x509rev.h"
#include "db.h"
#include "base.h"
#include "func.h"
#include "exception.h"
#include <openssl/x509v3.h>
#include <QtCore/QStringList>
@ -47,153 +49,158 @@ QStringList x509rev::crlreasons()
return l;
}
static X509_REVOKED *X509_REVOKED_dup(const X509_REVOKED *n)
{
int len;
X509_REVOKED *ret;
unsigned char *buf, *p;
len = i2d_X509_REVOKED((X509_REVOKED *)n, NULL);
buf = (unsigned char *)OPENSSL_malloc(len);
p = buf;
i2d_X509_REVOKED((X509_REVOKED *)n, &p);
p = buf;
ret = d2i_X509_REVOKED(NULL, (const unsigned char **)&p, len);
OPENSSL_free(buf);
return(ret);
}
x509rev::x509rev()
{
rev = X509_REVOKED_new();
}
x509rev::x509rev(const X509_REVOKED *n)
{
rev = X509_REVOKED_dup(n);
}
x509rev::x509rev(const x509rev &n)
{
rev = NULL;
set(n.rev);
}
x509rev::~x509rev()
{
X509_REVOKED_free(rev);
}
x509rev &x509rev::set(const X509_REVOKED *n)
{
if (rev != NULL)
X509_REVOKED_free(rev);
rev = X509_REVOKED_dup(n);
return *this;
}
bool x509rev::operator == (const x509rev &x) const
{
return (getSerial() == x.getSerial() &&
getDate() == x.getDate());
}
x509rev &x509rev::operator = (const x509rev &x)
{
set(x.rev);
return *this;
}
void x509rev::setSerial(const a1int &i)
{
if (rev->serialNumber != NULL)
ASN1_INTEGER_free(rev->serialNumber);
rev->serialNumber = i.get();
}
void x509rev::setDate(const a1time &a)
{
a1time t(a);
X509_REVOKED_set_revocationDate(rev, t.get_utc());
}
a1int x509rev::getSerial() const
{
a1int a(rev->serialNumber);
return a;
}
a1time x509rev::getDate() const
{
a1time t(rev->revocationDate);
return t;
}
void x509rev::setInvalDate(const a1time &date)
{
a1time t(date);
X509_REVOKED_add1_ext_i2d(rev, NID_invalidity_date, t.get(), 0, 0);
openssl_error();
}
void x509rev::setReason(const QString &reason)
{
/* RFC says to not add the extension if it is "unspecified" */
if (reason == crl_reasons[0].lname)
return;
ASN1_ENUMERATED *a = ASN1_ENUMERATED_new();
openssl_error();
for (int i=0; crl_reasons[i].lname; i++) {
if (reason == crl_reasons[i].lname) {
ASN1_ENUMERATED_set(a, crl_reasons[i].bitnum);
break;
}
}
openssl_error();
X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, a, 0, 0);
openssl_error();
ASN1_ENUMERATED_free(a);
}
QString x509rev::getReason() const
{
ASN1_ENUMERATED *reason;
int j, r;
reason = (ASN1_ENUMERATED *)X509_REVOKED_get_ext_d2i(rev,
NID_crl_reason, &j, NULL);
openssl_error();
if (j == -1)
return QString(crl_reasons[0].lname);
r = ASN1_ENUMERATED_get(reason);
openssl_error();
ASN1_ENUMERATED_free(reason);
for (int i=0; crl_reasons[i].lname; i++) {
if (r == crl_reasons[i].bitnum) {
return QString(crl_reasons[i].lname);
}
}
return QString();
return crl_reasons[reason_idx].lname;
}
a1time x509rev::getInvalDate() const
void x509rev::fromREVOKED(const X509_REVOKED *rev)
{
ASN1_ENUMERATED *reason;
ASN1_TIME *at;
a1time a;
int j;
at = (ASN1_TIME *)X509_REVOKED_get_ext_d2i(rev,
int j = -1, r;
if (!rev)
return;
serial = a1int(rev->serialNumber);
date = a1time(rev->revocationDate);
reason = (ASN1_ENUMERATED *)X509_REVOKED_get_ext_d2i(
(X509_REVOKED *)rev, NID_crl_reason, &j, NULL);
openssl_error();
reason_idx = 0;
if (reason) {
r = ASN1_ENUMERATED_get(reason);
openssl_error();
for (int i=0; crl_reasons[i].lname; i++) {
if (r == crl_reasons[i].bitnum) {
reason_idx = i;
}
}
ASN1_ENUMERATED_free(reason);
}
ivalDate.setUndefined();
at = (ASN1_TIME *)X509_REVOKED_get_ext_d2i((X509_REVOKED *)rev,
NID_invalidity_date, &j, NULL);
openssl_error();
if (j == -1) {
a.setUndefined();
return a;
if (at) {
ivalDate = a1time(at);
ASN1_GENERALIZEDTIME_free(at);
}
a.set(at);
ASN1_GENERALIZEDTIME_free(at);
return a;
//dump();
}
X509_REVOKED *x509rev::get() const
X509_REVOKED *x509rev::toREVOKED(bool withReason) const
{
return X509_REVOKED_dup(rev);
a1time i = ivalDate;
a1time d = date;
X509_REVOKED *rev = X509_REVOKED_new();
check_oom(rev);
rev->serialNumber = serial.get();
X509_REVOKED_set_revocationDate(rev, d.get_utc());
X509_REVOKED_add1_ext_i2d(rev, NID_invalidity_date,
i.get(), 0, 0);
/* RFC says to not add the extension if it is "unspecified" */
if (reason_idx != 0 && withReason) {
ASN1_ENUMERATED *a = ASN1_ENUMERATED_new();
ASN1_ENUMERATED_set(a, crl_reasons[reason_idx].bitnum);
X509_REVOKED_add1_ext_i2d(rev, NID_crl_reason, a, 0, 0);
ASN1_ENUMERATED_free(a);
}
openssl_error();
//dump();
return rev;
}
void x509rev::d2i(QByteArray &ba)
{
X509_REVOKED *r;
r = (X509_REVOKED *)d2i_bytearray(D2I_VOID(d2i_X509_REVOKED), ba);
if (!r)
return;
fromREVOKED(r);
X509_REVOKED_free(r);
}
QByteArray x509rev::i2d() const
{
QByteArray ba;
X509_REVOKED *r = toREVOKED();
ba = i2d_bytearray(I2D_VOID(i2d_X509_REVOKED), r);
X509_REVOKED_free(r);
return ba;
}
void x509rev::set(const x509rev &x)
{
serial = x.serial;
date = x.date;
ivalDate = x.ivalDate;
reason_idx = x.reason_idx;
}
bool x509rev::identical(const x509rev &x) const
{
return serial == x.serial &&
date == x.date &&
ivalDate == x.ivalDate &&
reason_idx == x.reason_idx;
}
void x509rev::dump() const
{
fprintf(stderr, "Rev: %s D:%s I:%s Reason: %d '%s'\n",
CCHAR(serial.toHex()), CCHAR(date.toSortable()),
CCHAR(ivalDate.toSortable()), reason_idx,
CCHAR(crl_reasons[reason_idx].lname));
}
void x509revList::fromBA(QByteArray &ba)
{
int i, num = db::intFromData(ba);
x509rev r;
clear();
merged = false;
for (i=0; i<num; i++) {
r.d2i(ba);
append(r);
}
}
QByteArray x509revList::toBA()
{
int i, len = size();
QByteArray ba(db::intToData(len));
for (i=0; i<len; i++) {
ba += at(i).i2d();
}
return ba;
}
void x509revList::merge(const x509revList &other)
{
foreach(x509rev r, other) {
if (r.isValid() && !contains(r)) {
merged = true;
append(r);
}
}
}
bool x509revList::identical(const x509revList &other) const
{
if (size() != other.size())
return false;
for (int i=0; i<size(); i++) {
x509rev r = at(i);
int c = other.indexOf(r);
if (c == -1)
return false;
if (!r.identical(other.at(c)))
return false;
}
return true;
}

View File

@ -8,7 +8,7 @@
#ifndef __X509REV_H
#define __X509REV_H
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <openssl/x509.h>
#include "asn1time.h"
#include "asn1int.h"
@ -16,25 +16,111 @@
class x509rev
{
private:
X509_REVOKED *rev;
a1int serial;
a1time date, ivalDate;
int reason_idx;
void set(const x509rev &x);
X509_REVOKED *toREVOKED(bool withReason=true) const;
void fromREVOKED(const X509_REVOKED *rev);
void dump() const;
public:
x509rev();
x509rev(const X509_REVOKED *n);
x509rev(const x509rev &n);
~x509rev();
static QStringList crlreasons();
x509rev &set(const X509_REVOKED *n);
x509rev &operator = (const x509rev &x);
bool operator == (const x509rev &x) const;
void setSerial(const a1int &i);
void setDate(const a1time &t);
a1int getSerial() const;
a1time getDate() const;
void setInvalDate(const a1time &date);
a1time getInvalDate() const;
void setReason(const QString &reason);
void d2i(QByteArray &ba);
QByteArray i2d() const;
QString getReason() const;
X509_REVOKED *get() const;
bool identical(const x509rev &x) const;
x509rev()
{
reason_idx = 0;
date.setUndefined();
}
x509rev(X509_REVOKED *n)
{
fromREVOKED(n);
}
x509rev(const x509rev &n)
{
set(n);
}
bool isValid() const
{
return serial.getLong() != 0 &&
!date.isUndefined();
}
x509rev &set(const X509_REVOKED *r)
{
fromREVOKED(r);
return *this;
}
bool operator == (const x509rev &x) const
{
return serial == x.serial;
}
x509rev &operator = (const x509rev &x)
{
set(x);
return *this;
}
void setSerial(const a1int &i)
{
serial = i;
}
void setDate(const a1time &t)
{
date = t;
}
void setInvalDate(const a1time &t)
{
ivalDate = t;
}
void setReason(const QString &reason)
{
reason_idx = crlreasons().indexOf(reason);
}
a1int getSerial() const
{
return serial;
}
a1time getDate() const
{
return date;
}
a1time getInvalDate() const
{
return ivalDate;
}
X509_REVOKED *get(bool withReason=true) const
{
return toREVOKED();
}
};
class x509revList : public QList<x509rev>
{
public:
bool merged;
QByteArray toBA();
void fromBA(QByteArray &ba);
void merge(const x509revList &other);
bool identical(const x509revList &other) const;
x509revList() : QList<x509rev>()
{
merged = false;
}
x509revList(const x509revList &r) : QList<x509rev>(r)
{
merged = r.merged;
}
x509revList(const x509rev &r) : QList<x509rev>()
{
if (r.isValid()) {
merged = false;
append(r);
}
}
};
#endif

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>760</width>
<height>288</height>
<width>411</width>
<height>416</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
@ -95,126 +95,130 @@
</spacer>
</item>
<item>
<layout class="QHBoxLayout">
<property name="spacing">
<number>6</number>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Validity</string>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Validity</string>
</property>
<layout class="QVBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="margin">
<number>8</number>
</property>
<item>
<layout class="QGridLayout">
<property name="margin">
<number>0</number>
</property>
<property name="spacing">
<number>6</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="TextLabel1_2">
<property name="text">
<string>Not before</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="TextLabel2_4">
<property name="text">
<string>Not after</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="Validity" name="notBefore">
<property name="calendarPopup">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="Validity" name="notAfter">
<property name="calendarPopup">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Time range</string>
</property>
<layout class="QGridLayout" name="gridLayout_1">
<item row="0" column="0" colspan="2">
<widget class="QLineEdit" name="validNumber"/>
</item>
<item row="0" column="2">
<widget class="QComboBox" name="validRange">
<item>
<property name="text">
<string>Days</string>
</property>
</item>
<item>
<property name="text">
<string>Months</string>
</property>
</item>
<item>
<property name="text">
<string>Years</string>
</property>
</item>
</widget>
</item>
<item row="0" column="3">
<widget class="QPushButton" name="applyTime">
<layout class="QVBoxLayout">
<property name="margin">
<number>8</number>
</property>
<item>
<layout class="QGridLayout">
<item row="0" column="0">
<widget class="QLabel" name="TextLabel1_2">
<property name="text">
<string>Apply</string>
<string>Not before</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="midnightCB">
<widget class="QLabel" name="TextLabel2_4">
<property name="text">
<string>Midnight</string>
<string>Not after</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="Validity" name="notBefore">
<property name="calendarPopup">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="checkBox">
<property name="text">
<string>Local time</string>
</property>
</widget>
</item>
<item row="1" column="2" colspan="2">
<widget class="QCheckBox" name="noWellDefinedExpDate">
<property name="text">
<string>No well-defined expiration</string>
<widget class="Validity" name="notAfter">
<property name="calendarPopup">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Time range</string>
</property>
<layout class="QGridLayout" name="gridLayout_1">
<item row="1" column="1">
<widget class="QCheckBox" name="checkBox">
<property name="text">
<string>Local time</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QComboBox" name="validRange">
<item>
<property name="text">
<string>Days</string>
</property>
</item>
<item>
<property name="text">
<string>Months</string>
</property>
</item>
<item>
<property name="text">
<string>Years</string>
</property>
</item>
</widget>
</item>
<item row="1" column="2" colspan="2">
<widget class="QCheckBox" name="noWellDefinedExpDate">
<property name="text">
<string>No well-defined expiration</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="midnightCB">
<property name="text">
<string>Midnight</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QPushButton" name="applyTime">
<property name="text">
<string>Apply</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QLineEdit" name="validNumber"/>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>2</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="revoke">
<property name="text">
<string>Revoke old certificate</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer>
@ -269,8 +273,8 @@
<slot>hideTimeCheck(int)</slot>
<hints>
<hint type="sourcelabel">
<x>456</x>
<y>193</y>
<x>453</x>
<y>197</y>
</hint>
<hint type="destinationlabel">
<x>231</x>
@ -289,8 +293,8 @@
<y>193</y>
</hint>
<hint type="destinationlabel">
<x>351</x>
<y>194</y>
<x>331</x>
<y>200</y>
</hint>
</hints>
</connection>
@ -301,8 +305,8 @@
<slot>hideTimeCheck(int)</slot>
<hints>
<hint type="sourcelabel">
<x>456</x>
<y>193</y>
<x>453</x>
<y>197</y>
</hint>
<hint type="destinationlabel">
<x>239</x>
@ -353,8 +357,8 @@
<y>182</y>
</hint>
<hint type="destinationlabel">
<x>487</x>
<y>176</y>
<x>544</x>
<y>197</y>
</hint>
</hints>
</connection>
@ -369,8 +373,8 @@
<y>189</y>
</hint>
<hint type="destinationlabel">
<x>344</x>
<y>151</y>
<x>331</x>
<y>164</y>
</hint>
</hints>
</connection>
@ -385,8 +389,8 @@
<y>190</y>
</hint>
<hint type="destinationlabel">
<x>334</x>
<y>191</y>
<x>331</x>
<y>200</y>
</hint>
</hints>
</connection>

View File

@ -6,22 +6,13 @@
<rect>
<x>0</x>
<y>0</y>
<width>488</width>
<height>352</height>
<width>530</width>
<height>381</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QWidget" name="widget" native="true"/>
</item>
<item>
<layout class="QHBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="TextLabel1">
<property name="font">
@ -80,16 +71,13 @@
<item>
<widget class="QTabWidget" name="tabview">
<property name="currentIndex">
<number>0</number>
<number>3</number>
</property>
<widget class="QWidget" name="unnamed">
<attribute name="title">
<string>&amp;Status</string>
</attribute>
<layout class="QVBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="margin">
<number>8</number>
</property>
@ -121,17 +109,8 @@
<property name="margin">
<number>8</number>
</property>
<property name="spacing">
<number>6</number>
</property>
<item row="2" column="1">
<layout class="QHBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="ClickLabel" name="signCheck"/>
</item>
@ -203,9 +182,6 @@
<property name="margin">
<number>8</number>
</property>
<property name="spacing">
<number>6</number>
</property>
<item row="1" column="0">
<widget class="QLabel" name="TextLabel2_2">
<property name="text">
@ -252,9 +228,6 @@
<string>&amp;Issuer</string>
</attribute>
<layout class="QVBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="margin">
<number>11</number>
</property>
@ -268,9 +241,6 @@
<string>&amp;Extensions</string>
</attribute>
<layout class="QVBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="margin">
<number>11</number>
</property>
@ -291,9 +261,6 @@
<string>&amp;Revocation list</string>
</attribute>
<layout class="QVBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="margin">
<number>11</number>
</property>
@ -305,15 +272,9 @@
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="uniformRowHeights">
<bool>true</bool>
</property>
<column>
<property name="text">
<string>0</string>
<string notr="true">1</string>
</property>
</column>
</widget>
@ -358,8 +319,8 @@
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>349</x>
<y>321</y>
<x>355</x>
<y>376</y>
</hint>
<hint type="destinationlabel">
<x>169</x>

View File

@ -8,7 +8,8 @@ UI_H = ui_About.h ui_CaProperties.h ui_CertDetail.h ui_CertExtend.h \
ui_CrlDetail.h ui_ExportDialog.h ui_Help.h \
ui_ImportMulti.h ui_KeyDetail.h ui_MainWindow.h ui_NewCrl.h \
ui_NewKey.h ui_NewX509.h ui_Options.h ui_PwDialog.h ui_Revoke.h \
ui_SelectToken.h ui_TrustState.h ui_v3ext.h ui_SearchPkcs11.h
ui_SelectToken.h ui_TrustState.h ui_v3ext.h ui_SearchPkcs11.h \
ui_RevocationList.h
include $(TOPDIR)/Rules.mak

168
ui/RevocationList.ui Normal file
View File

@ -0,0 +1,168 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>RevocationList</class>
<widget class="QDialog" name="RevocationList">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>628</width>
<height>320</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_3">
<property name="font">
<font>
<family>Arial</family>
<pointsize>14</pointsize>
<weight>50</weight>
<italic>false</italic>
<bold>false</bold>
<underline>false</underline>
<strikeout>false</strikeout>
</font>
</property>
<property name="text">
<string>Manage revocations</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="image">
<property name="minimumSize">
<size>
<width>95</width>
<height>40</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>95</width>
<height>40</height>
</size>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QTreeWidget" name="certList">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::MultiSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="addRev">
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="delRev">
<property name="text">
<string>Delete</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Abort|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>RevocationList</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>341</x>
<y>291</y>
</hint>
<hint type="destinationlabel">
<x>292</x>
<y>254</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>RevocationList</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>445</x>
<y>292</y>
</hint>
<hint type="destinationlabel">
<x>445</x>
<y>237</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -6,46 +6,126 @@
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>195</height>
<width>417</width>
<height>282</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="capt">
<property name="font">
<font>
<family>Arial</family>
<pointsize>14</pointsize>
<weight>50</weight>
<italic>false</italic>
<bold>false</bold>
<underline>false</underline>
<strikeout>false</strikeout>
</font>
</property>
<property name="text">
<string>Certificate revocation</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>78</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="image">
<property name="minimumSize">
<size>
<width>95</width>
<height>40</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>95</width>
<height>40</height>
</size>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>10</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Revocation details</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Invalid since</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="Validity" name="invalid">
<property name="calendarPopup">
<bool>true</bool>
</property>
</widget>
<widget class="QLineEdit" name="serial"/>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="checkBox">
<property name="text">
<string>Local time</string>
</property>
</widget>
</item>
<item row="2" column="0">
<item row="3" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Revocation reason</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="Validity" name="invalid">
<property name="calendarPopup">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="checkBox">
<property name="text">
<string>Local time</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Invalid since</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Serial</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="reason"/>
</item>
</layout>
@ -57,7 +137,7 @@
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Ok</set>
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
@ -100,12 +180,12 @@
<slot>localTime(int)</slot>
<hints>
<hint type="sourcelabel">
<x>244</x>
<y>82</y>
<x>397</x>
<y>122</y>
</hint>
<hint type="destinationlabel">
<x>244</x>
<y>55</y>
<x>389</x>
<y>93</y>
</hint>
</hints>
</connection>

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>435</width>
<height>288</height>
<height>211</height>
</rect>
</property>
<property name="windowTitle">
@ -16,12 +16,6 @@
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="TextLabel1">
<property name="font">
@ -36,7 +30,7 @@
</font>
</property>
<property name="text">
<string>Set trustment of the Certificate</string>
<string>Certificate trust</string>
</property>
</widget>
</item>
@ -93,31 +87,12 @@
</property>
</spacer>
</item>
<item>
<widget class="ClickLabel" name="certName"/>
</item>
<item>
<spacer>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Trustment</string>
</property>
<layout class="QVBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="margin">
<number>8</number>
</property>
@ -154,13 +129,6 @@
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>ClickLabel</class>
<extends>QLabel</extends>
<header>widgets/clicklabel.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>trust0</tabstop>
<tabstop>trust1</tabstop>

View File

@ -125,10 +125,11 @@ void CertDetail::setCert(pki_x509 *cert)
// validation of the Date
dateValid->disableToolTip();
if (cert->isRevoked()) {
x509rev rev = cert->getRevocation();
dateValid->setText(tr("Revoked: ") +
cert->getRevoked().toPretty());
rev.getDate().toPretty());
dateValid->setRed();
dateValid->setToolTip(cert->getRevoked().toPrettyGMT());
dateValid->setToolTip(rev.getDate().toPrettyGMT());
} else if (!cert->checkDate()) {
dateValid->setText(tr("Not valid"));
dateValid->setRed();

View File

@ -11,6 +11,7 @@
#include "lib/pki_crl.h"
#include "widgets/distname.h"
#include "widgets/clicklabel.h"
#include "widgets/RevocationList.h"
#include <QtGui/QLabel>
#include <QtGui/QTextEdit>
#include <QtGui/QLineEdit>
@ -22,25 +23,14 @@ CrlDetail::CrlDetail(MainWindow *mainwin)
setupUi(this);
setWindowTitle(tr(XCA_TITLE));
certList->clear();
certList->setColumnCount(3);
QStringList sl;
sl << tr("Name") << tr("Serial") << tr("Revocation") << tr("Reason") <<
tr("Invalidation");
certList->setHeaderLabels(sl);
image->setPixmap(*MainWindow::revImg);
descr->setReadOnly(true);
}
void CrlDetail::setCrl(pki_crl *crl)
{
int numc, i;
pki_x509 *iss, *rev;
x509rev revit;
pki_x509 *iss;
x509v3ext e1, e2;
QStringList sl;
iss = crl->getIssuer();
signCheck->disableToolTip();
@ -74,29 +64,7 @@ void CrlDetail::setCrl(pki_crl *crl)
issuer->setX509name(crl->getSubject());
numc = crl->numRev();
for (i=0; i<numc; i++) {
QTreeWidgetItem *current;
a1time a;
revit = crl->getRev(i);
rev = mw->certs->getByIssSerial(iss, revit.getSerial());
certList->setColumnCount(5);
current = new QTreeWidgetItem(certList);
if (rev != NULL) {
current->setText(0, rev->getIntName() );
} else {
current->setText(0, tr("Unknown certificate"));
}
current->setIcon(0, *pki_x509::icon[2]);
current->setText(1, revit.getSerial().toHex()) ;
current->setText(2, revit.getDate().toSortable());
current->setText(3, revit.getReason());
a = revit.getInvalDate();
if (!a.isUndefined())
current->setText(4, a.toSortable());
}
for (i=0; i<5; i++)
certList->resizeColumnToContents(i);
certList->setSortingEnabled(true);
RevocationList::setupRevocationView(certList, crl->getRevList(), iss);
v3extensions->document()->setHtml(crl->printV3ext());
}

View File

@ -52,6 +52,7 @@ int MainWindow::init_database()
certs = new db_x509(dbfile, this);
temps = new db_temp(dbfile, this);
crls = new db_crl(dbfile, this);
certs->updateAfterDbLoad();
}
catch (errorEx &err) {
Error(err);

View File

@ -818,8 +818,9 @@ pki_multi *MainWindow::probeAnything(QString file, int *ret)
if (file.endsWith(".xdb")) {
try {
int r;
db mydb(file);
mydb.verify_magic();
db *mydb = new db(file);
mydb->verify_magic();
delete mydb;
r = changeDB(file);
delete pki;
if (ret)

View File

@ -7,7 +7,7 @@ endif
MOC_NAMES=MainWindow KeyDetail clicklabel XcaTreeView NewX509 \
validity v3ext distname CertDetail CertExtend PwDialog \
ImportMulti CrlDetail ExportDialog hashBox Options NewKey kvView \
NewCrl SearchPkcs11
NewCrl SearchPkcs11 RevocationList
NAMES=$(MOC_NAMES) NewX509_ext MW_menu MW_help MW_database
OBJS=$(patsubst %,moc_%.o,$(MOC_NAMES)) $(patsubst %,%.o,$(NAMES))

140
widgets/RevocationList.cpp Normal file
View File

@ -0,0 +1,140 @@
/* vi: set sw=4 ts=4:
*
* Copyright (C) 2015 Christian Hohnstaedt.
*
* All rights reserved.
*/
#include "RevocationList.h"
#include "MainWindow.h"
#include "lib/asn1int.h"
#include "lib/pki_x509.h"
enum revCol { Cserial, Cdate, Creason, CiDate };
static void addRevItem(QTreeWidget *certList, const x509rev &revit,
const pki_x509 *iss)
{
QTreeWidgetItem *current;
pki_x509 *rev;
a1time a;
rev = iss->getBySerial(revit.getSerial());
current = new QTreeWidgetItem(certList);
if (rev != NULL) {
current->setToolTip(Cserial, rev->getIntName() );
}
current->setText(Cserial, revit.getSerial().toHex()) ;
current->setText(Cdate, revit.getDate().toSortable());
current->setText(Creason, revit.getReason());
a = revit.getInvalDate();
if (!a.isUndefined())
current->setText(CiDate, a.toSortable());
}
void RevocationList::setupRevocationView(QTreeWidget *certList,
const x509revList &revList, const pki_x509 *iss)
{
QStringList sl;
int cols, i;
certList->clear();
sl << tr("Serial") << tr("Revocation") << tr("Reason") <<
tr("Invalidation");
cols = sl.size();
certList->setColumnCount(cols);
certList->setHeaderLabels(sl);
certList->setItemsExpandable(false);
certList->setRootIsDecorated(false);
foreach(x509rev revit, revList) {
addRevItem(certList, revit, iss);
}
for (i=0; i<cols; i++)
certList->resizeColumnToContents(i);
certList->setSortingEnabled(true);
}
RevocationList::RevocationList(QWidget *w) : QDialog(w)
{
QPushButton *genCrl;
setupUi(this);
setWindowTitle(XCA_TITLE);
image->setPixmap(*MainWindow::revImg);
genCrl = buttonBox->addButton(tr("Generate CRL"),
QDialogButtonBox::ActionRole);
connect(genCrl, SIGNAL(clicked(void)), this, SLOT(gencrl(void)));
}
void RevocationList::gencrl(void)
{
issuer->setRevocations(getRevList());
emit genCRL(issuer);
}
void RevocationList::setRevList(const x509revList &rl, pki_x509 *iss)
{
issuer = iss;
revList = rl;
setupRevocationView(certList, revList, issuer);
}
const x509revList &RevocationList::getRevList()
{
return revList;
}
void RevocationList::on_addRev_clicked(void)
{
Revocation *revoke = new Revocation(this, NULL);
if (revoke->exec()) {
x509rev revit = revoke->getRevocation();
revList << revit;
addRevItem(certList, revit, issuer);
}
}
void RevocationList::on_delRev_clicked(void)
{
QTreeWidgetItem *current = certList->currentItem();
x509rev rev;
int idx;
a1int a1_serial;
if (!current)
return;
idx = certList->indexOfTopLevelItem(current);
certList->takeTopLevelItem(idx);
a1_serial.setHex(current->text(Cserial));
rev.setSerial(a1_serial);
idx = revList.indexOf(rev);
if (idx != -1)
revList.takeAt(idx);
}
Revocation::Revocation(QWidget *w, pki_x509 *r) : QDialog(w)
{
setupUi(this);
setWindowTitle(XCA_TITLE);
reason->addItems(x509rev::crlreasons());
invalid->setNow();
if (r) {
serial->setText(r->getSerial().toHex());
serial->setEnabled(false);
}
}
x509rev Revocation::getRevocation()
{
x509rev r;
a1int i;
i.setHex(serial->text());
r.setSerial(i);
r.setDate(a1time::now());
r.setInvalDate(invalid->getDate());
r.setReason(reason->currentText());
return r;
}

48
widgets/RevocationList.h Normal file
View File

@ -0,0 +1,48 @@
/* vi: set sw=4 ts=4:
*
* Copyright (C) 2015 Christian Hohnstaedt.
*
* All rights reserved.
*/
#ifndef __REVOCATIONLIST_H
#define __REVOCATIONLIST_H
#include "ui_RevocationList.h"
#include "ui_Revoke.h"
#include "lib/x509rev.h"
class pki_x509;
class RevocationList: public QDialog, public Ui::RevocationList
{
Q_OBJECT
private:
x509revList revList;
pki_x509 *issuer;
public:
static void setupRevocationView(QTreeWidget *certList,
const x509revList &revList, const pki_x509 *iss);
RevocationList(QWidget *w);
void setRevList(const x509revList &rl, pki_x509 *issuer);
const x509revList &getRevList();
public slots:
void on_addRev_clicked(void);
void on_delRev_clicked(void);
void gencrl(void);
signals:
void genCRL(pki_x509 *iss);
};
class Revocation: public QDialog, public Ui::Revoke
{
Q_OBJECT
public:
Revocation(QWidget *w, pki_x509 *r);
x509rev getRevocation();
};
#endif

View File

@ -81,6 +81,7 @@ HEADERS += local.h \
widgets/v3ext.h \
widgets/validity.h \
widgets/SearchPkcs11.h \
widgets/RevocationList.h \
widgets/XcaTreeView.h
FORMS += ui/About.ui \
@ -103,6 +104,7 @@ FORMS += ui/About.ui \
ui/TrustState.ui \
ui/SearchPkcs11.ui \
ui/v3ext.ui \
ui/RevocationList.ui
SOURCES += lib/asn1int.cpp \
lib/asn1time.cpp \
@ -165,6 +167,7 @@ SOURCES += lib/asn1int.cpp \
widgets/v3ext.cpp \
widgets/validity.cpp \
widgets/SearchPkcs11.cpp \
widgets/RevocationList.cpp \
widgets/XcaTreeView.cpp
TRANSLATIONS += lang/xca_de.ts lang/xca_es.ts lang/xca_ru.ts lang/xca.ts lang/xca_tr.ts lang/xca_fr.ts lang/xca_hr.ts