mirror of
https://github.com/chris2511/xca.git
synced 2026-09-12 19:51:05 +05:00
Refactor context menu
Better support multiple selections - Export all selected items into one PEM file - Batch Revoke/unrevoke/renew of many selected certificates of the same issuer - allow exporting templates as PEM Add Feat. Reg. #83 Option to revoke old certificate when renewing Always put all signed certificate to the newest CA. If a CA certificate is renewed, all certificates issued by the old CA are now shown as signed by the new one.
This commit is contained in:
parent
5b40ac664b
commit
75a6d117f3
1
Makefile
1
Makefile
@ -160,7 +160,6 @@ $(DMGSTAGE): xca$(SUFFIX) xca_db_stat$(SUFFIX)
|
||||
ln -s xca.html $(DMGSTAGE)/manual/index.html
|
||||
$(MACDEPLOYQT) $(DMGSTAGE)/xca.app
|
||||
codesign -s "Open Source Developer, Christian Hohnstaedt" $(DMGSTAGE)/xca.app
|
||||
tar zcf $(MACTARGET).tar.gz $(DMGSTAGE)
|
||||
|
||||
xca.dmg: $(MACTARGET).dmg
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ CPPFLAGS += -I$(TOPDIR) -I$(BUILD) -I$(BUILD)/ui
|
||||
all: .build-stamp
|
||||
|
||||
.build-stamp: $(OBJS)
|
||||
echo $(patsubst %, $(shell pwd)/%, $(OBJS)) > $@
|
||||
for i in $(patsubst %, $(shell pwd)/%, $(OBJS)); do echo $$i; done > $@
|
||||
@$(PRINT) " DONE [$(BASENAME)]"
|
||||
|
||||
SRCS=$(patsubst %.o, %.cpp, $(OBJS))
|
||||
|
||||
263
lib/db_base.cpp
263
lib/db_base.cpp
@ -97,7 +97,7 @@ int db_base::handleBadEntry(unsigned char *p, db_header_t *head)
|
||||
|
||||
size_t l;
|
||||
db_header_t h;
|
||||
FILE *fp = fopen(QString2filename(s), "w");
|
||||
FILE *fp = fopen(QString2filename(s), "wb");
|
||||
if (!fp) {
|
||||
throw errorEx(tr("Error opening file: '%1': %2").
|
||||
arg(s).arg(strerror(errno)), class_name);
|
||||
@ -287,47 +287,41 @@ void db_base::insertPKI(pki_base *pki)
|
||||
emit columnsContentChanged();
|
||||
}
|
||||
|
||||
void db_base::delete_ask()
|
||||
QString db_base::pem2QString(QModelIndexList indexes)
|
||||
{
|
||||
if (!currentIdx.isValid())
|
||||
return;
|
||||
pki_base *pki = static_cast<pki_base*>(currentIdx.internalPointer());
|
||||
|
||||
if (!XCA_OKCANCEL(pki->getMsg(pki_base::msg_delete).arg(pki->getIntName())))
|
||||
return;
|
||||
|
||||
deletePKI();
|
||||
}
|
||||
|
||||
void db_base::pem2clipboard()
|
||||
{
|
||||
long l;
|
||||
const char *p;
|
||||
exportType::etype format;
|
||||
QString msg;
|
||||
|
||||
format = clipboardFormat(indexes);
|
||||
foreach(QModelIndex idx, indexes) {
|
||||
long l;
|
||||
const char *p;
|
||||
BIO *bio = BIO_new(BIO_s_mem());
|
||||
pki_base *pki = static_cast<pki_base*>
|
||||
(idx.internalPointer());
|
||||
pki->pem(bio, format);
|
||||
openssl_error();
|
||||
l = BIO_get_mem_data(bio, &p);
|
||||
msg += QString::fromUtf8(p, l);
|
||||
BIO_free(bio);
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
void db_base::pem2clipboard(QModelIndexList indexes)
|
||||
{
|
||||
QString msg = pem2QString(indexes);
|
||||
QClipboard *cb = QApplication::clipboard();
|
||||
|
||||
BIO *bio = BIO_new(BIO_s_mem());
|
||||
if (!currentIdx.isValid())
|
||||
return;
|
||||
pki_base *pki = static_cast<pki_base*>(currentIdx.internalPointer());
|
||||
format = clipboardFormat();
|
||||
pki->pem(bio, format);
|
||||
openssl_error();
|
||||
l = BIO_get_mem_data(bio, &p);
|
||||
msg = QString::fromUtf8(p, l);
|
||||
BIO_free(bio);
|
||||
if (cb->supportsSelection())
|
||||
cb->setText(msg, QClipboard::Selection);
|
||||
else
|
||||
cb->setText(msg);
|
||||
}
|
||||
|
||||
void db_base::deletePKI()
|
||||
void db_base::deletePKI(QModelIndex idx)
|
||||
{
|
||||
if (!currentIdx.isValid())
|
||||
return;
|
||||
pki_base *pki = static_cast<pki_base*>(currentIdx.internalPointer());
|
||||
pki_base *pki = static_cast<pki_base*>(idx.internalPointer());
|
||||
try {
|
||||
try {
|
||||
pki->deleteFromToken();
|
||||
@ -335,7 +329,7 @@ void db_base::deletePKI()
|
||||
MainWindow::Error(err);
|
||||
}
|
||||
|
||||
remFromCont(currentIdx);
|
||||
remFromCont(idx);
|
||||
|
||||
db mydb(dbName);
|
||||
mydb.find(pki->getType(), pki->getIntName());
|
||||
@ -358,84 +352,9 @@ void db_base::updatePKI(pki_base *pki)
|
||||
}
|
||||
}
|
||||
|
||||
void db_base::deleteSelectedItems(XcaTreeView* view)
|
||||
{
|
||||
QModelIndexList indexes = view->getSelectedIndexes();
|
||||
QModelIndex index;
|
||||
QString items, msg;
|
||||
int count = 0;
|
||||
pki_base *pki = NULL;
|
||||
|
||||
if (indexes.count() == 0)
|
||||
return;
|
||||
|
||||
foreach(index, indexes) {
|
||||
pki = static_cast<pki_base*>(index.internalPointer());
|
||||
items += "'" + pki->getIntName() + "' ";
|
||||
count++;
|
||||
}
|
||||
if (count == 1)
|
||||
msg = pki->getMsg(pki_base::msg_delete).arg(pki->getIntName());
|
||||
else
|
||||
msg = pki->getMsg(pki_base::msg_delete_multi).arg(count).
|
||||
arg(items);
|
||||
|
||||
if (!XCA_OKCANCEL(msg))
|
||||
return;
|
||||
|
||||
foreach(index, indexes) {
|
||||
currentIdx = index;
|
||||
deletePKI();
|
||||
}
|
||||
currentIdx = QModelIndex();
|
||||
}
|
||||
|
||||
void db_base::showSelectedItems(XcaTreeView* view)
|
||||
{
|
||||
QModelIndexList indexes = view->getSelectedIndexes();
|
||||
QModelIndex index;
|
||||
QString items;
|
||||
|
||||
foreach(index, indexes) {
|
||||
currentIdx = index;
|
||||
showItem();
|
||||
}
|
||||
currentIdx = QModelIndex();
|
||||
}
|
||||
|
||||
|
||||
void db_base::storeSelectedItems(XcaTreeView* view)
|
||||
{
|
||||
QModelIndexList list = view->getSelectedIndexes();
|
||||
if (list.size() == 0)
|
||||
return;
|
||||
if (!currentIdx.isValid())
|
||||
currentIdx = list[0];
|
||||
store(list);
|
||||
}
|
||||
|
||||
void db_base::store(QModelIndexList list)
|
||||
{
|
||||
QModelIndex index;
|
||||
QString items;
|
||||
|
||||
foreach(index, list) {
|
||||
if (index.column() != 0)
|
||||
continue;
|
||||
try {
|
||||
currentIdx = index;
|
||||
store();
|
||||
} catch (errorEx &err) {
|
||||
MainWindow::Error(err);
|
||||
}
|
||||
|
||||
}
|
||||
currentIdx = QModelIndex();
|
||||
}
|
||||
|
||||
void db_base::showItem(const QModelIndex &index)
|
||||
{
|
||||
showPki(static_cast<pki_key*>(index.internalPointer()));
|
||||
showPki(static_cast<pki_base*>(index.internalPointer()));
|
||||
}
|
||||
|
||||
void db_base::showItem(const QString name)
|
||||
@ -542,6 +461,8 @@ QModelIndex db_base::index(int row, int column, const QModelIndex &parent)
|
||||
|
||||
QModelIndex db_base::index(pki_base *pki) const
|
||||
{
|
||||
if (!pki)
|
||||
return QModelIndex();
|
||||
return createIndex(pki->row(), 0, pki);
|
||||
}
|
||||
|
||||
@ -688,18 +609,45 @@ void db_base::load_default(load_base &load)
|
||||
delete dlgi;
|
||||
}
|
||||
|
||||
void db_base::edit()
|
||||
void db_base::store(QModelIndexList indexes)
|
||||
{
|
||||
if (!currentIdx.isValid())
|
||||
return;
|
||||
emit editItem(currentIdx);
|
||||
}
|
||||
int ret;
|
||||
|
||||
void db_base::showItem()
|
||||
{
|
||||
if (!currentIdx.isValid())
|
||||
xcaWarning msg(mainwin, tr("How to export the %1 selected items").
|
||||
arg(indexes.size()));
|
||||
msg.addButton(QMessageBox::Ok)->setText(tr("All in one PEM file"));
|
||||
msg.addButton(QMessageBox::Apply)->setText(tr("Each item in one file"));
|
||||
msg.addButton(QMessageBox::Cancel);
|
||||
ret = msg.exec();
|
||||
if (ret == QMessageBox::Apply) {
|
||||
foreach(QModelIndex i, indexes)
|
||||
store(i);
|
||||
return;
|
||||
showItem(currentIdx);
|
||||
} else if (ret != QMessageBox::Ok) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString fn = mainwin->getPath() + QDir::separator() + "export.pem";
|
||||
QString s = QFileDialog::getSaveFileName(mainwin,
|
||||
tr("Save %1 items in one file as").arg(indexes.size()), fn,
|
||||
tr("PEM Files( *.pem );; All files ( * )"));
|
||||
if (s.isEmpty())
|
||||
return;
|
||||
s = QDir::convertSeparators(s);
|
||||
mainwin->setPath(s.mid(0, s.lastIndexOf(QRegExp("[/\\\\]")) ));
|
||||
try {
|
||||
QString pem = pem2QString(indexes);
|
||||
FILE *fp = fopen(QString2filename(s), "wb");
|
||||
if (!fp) {
|
||||
throw errorEx(tr("Error opening file: '%1': %2").
|
||||
arg(s).arg(strerror(errno)), class_name);
|
||||
}
|
||||
fwrite(pem.toAscii(), pem.size(), 1, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
catch (errorEx &err) {
|
||||
MainWindow::Error(err);
|
||||
}
|
||||
}
|
||||
|
||||
bool db_base::columnHidden(int col) const
|
||||
@ -723,86 +671,3 @@ bool db_base::isNumericCol(int col) const
|
||||
{
|
||||
return allHeaders[col]->isNumeric();
|
||||
}
|
||||
|
||||
void db_base::showHeaderMenu(QContextMenuEvent *e, int sect)
|
||||
{
|
||||
contextMenu(e, NULL, sect);
|
||||
}
|
||||
|
||||
void db_base::contextMenu(QContextMenuEvent *e, QMenu *parent, int)
|
||||
{
|
||||
int shown = 0;
|
||||
tipMenu *menu, *dn, *v3ext, *current, *v3ns;
|
||||
QAction *a, *sep;
|
||||
dbheader *hd;
|
||||
|
||||
menu = new tipMenu(QString(), mainwin);
|
||||
dn = new tipMenu(tr("Subject entries"), mainwin);
|
||||
v3ext = new tipMenu(tr("X509v3 Extensions"), mainwin);
|
||||
v3ns = new tipMenu(tr("Netscape extensions"), mainwin);
|
||||
menu->addAction(tr("Reset"), this, SLOT(columnResetDefaults()));
|
||||
sep = menu->addSeparator();
|
||||
foreach(hd, allHeaders) {
|
||||
switch (hd->type) {
|
||||
case dbheader::hd_x509name:
|
||||
current = dn;
|
||||
break;
|
||||
case dbheader::hd_v3ext:
|
||||
current = v3ext;
|
||||
break;
|
||||
case dbheader::hd_v3ext_ns:
|
||||
if (pki_x509::disable_netscape)
|
||||
continue;
|
||||
current = v3ns;
|
||||
break;
|
||||
default:
|
||||
current = menu;
|
||||
break;
|
||||
}
|
||||
a = current->addAction(hd->getName());
|
||||
a->setCheckable(true);
|
||||
a->setChecked(hd->show);
|
||||
a->setToolTip(hd->getTooltip());
|
||||
hd->action = a;
|
||||
}
|
||||
if (!dn->isEmpty() || !v3ext->isEmpty())
|
||||
menu->insertSeparator(sep);
|
||||
|
||||
if (!dn->isEmpty())
|
||||
menu->insertMenu(sep, dn);
|
||||
else
|
||||
delete dn;
|
||||
|
||||
if (!v3ext->isEmpty()) {
|
||||
if (!v3ns->isEmpty()) {
|
||||
v3ext->addSeparator();
|
||||
v3ext->addMenu(v3ns);
|
||||
} else {
|
||||
delete v3ns;
|
||||
}
|
||||
menu->insertMenu(sep, v3ext);
|
||||
} else {
|
||||
delete v3ext;
|
||||
delete v3ns;
|
||||
}
|
||||
if (parent) {
|
||||
parent->addAction(tr("Paste PEM data"), mainwin,
|
||||
SLOT(pastePem()));
|
||||
parent->addMenu(menu)->setText(tr("Columns"));
|
||||
parent->exec(e->globalPos());
|
||||
} else {
|
||||
menu->exec(e->globalPos());
|
||||
}
|
||||
foreach(hd, allHeaders) {
|
||||
if (hd->action)
|
||||
hd->show = hd->action->isChecked();
|
||||
shown += hd->show ? 1 : 0;
|
||||
hd->action = NULL;
|
||||
}
|
||||
if (!shown)
|
||||
allHeaders[0]->show = true;
|
||||
delete menu;
|
||||
if (parent)
|
||||
delete parent;
|
||||
emit updateHeader();
|
||||
}
|
||||
|
||||
@ -45,7 +45,8 @@ class db_base: public QAbstractItemModel
|
||||
virtual dbheaderList getHeaders();
|
||||
int colResizing;
|
||||
int handleBadEntry(unsigned char *p, db_header_t *head);
|
||||
virtual exportType::etype clipboardFormat() {
|
||||
virtual exportType::etype clipboardFormat(QModelIndexList indexes)
|
||||
{
|
||||
return exportType::Separator;
|
||||
}
|
||||
|
||||
@ -69,9 +70,6 @@ class db_base: public QAbstractItemModel
|
||||
QPixmap *loadImg(const char *name);
|
||||
void writeAll(void);
|
||||
void dump(QString dirname);
|
||||
virtual void showContextMenu(QContextMenuEvent * ,
|
||||
const QModelIndex &) {};
|
||||
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent)const;
|
||||
QModelIndex index(pki_base *pki)const;
|
||||
QModelIndex parent(const QModelIndex &index) const;
|
||||
@ -82,18 +80,13 @@ class db_base: public QAbstractItemModel
|
||||
int role) const;
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role);
|
||||
void deleteSelectedItems(XcaTreeView* view);
|
||||
void showSelectedItems(XcaTreeView *view);
|
||||
void storeSelectedItems(XcaTreeView *view);
|
||||
void deleteSelectedItems(QModelIndexList indexes);
|
||||
void load_default(load_base &load);
|
||||
void insertChild(pki_base *parent, pki_base *child);
|
||||
void createSuccess(pki_base *pki);
|
||||
void showHeaderMenu(QContextMenuEvent *e, int sect);
|
||||
bool columnHidden(int col) const;
|
||||
bool isNumericCol(int col) const;
|
||||
void saveHeaderState();
|
||||
void contextMenu(QContextMenuEvent *e,
|
||||
QMenu *parent = NULL, int sect = -1);
|
||||
void initHeaderView(QHeaderView *hv);
|
||||
void setVisualIndex(int i, int visualIndex);
|
||||
bool fixedHeaderSize(int sect);
|
||||
@ -105,31 +98,31 @@ class db_base: public QAbstractItemModel
|
||||
{
|
||||
colResizing--;
|
||||
}
|
||||
virtual void store(QModelIndexList list);
|
||||
virtual void store(QModelIndexList indexes);
|
||||
virtual void store(QModelIndex index) { };
|
||||
dbheaderList getAllHeaders() {
|
||||
return allHeaders;
|
||||
}
|
||||
void pem2clipboard(QModelIndexList indexes);
|
||||
QString pem2QString(QModelIndexList indexes);
|
||||
|
||||
void deletePKI(QModelIndex idx);
|
||||
|
||||
public slots:
|
||||
void deletePKI();
|
||||
void delete_ask();
|
||||
void edit();
|
||||
virtual void newItem() { }
|
||||
virtual void load() { }
|
||||
void columnResetDefaults();
|
||||
virtual void showItem();
|
||||
virtual void store()
|
||||
{
|
||||
store(QModelIndexList());
|
||||
};
|
||||
virtual void showPki(pki_base *) {};
|
||||
virtual void showItem(const QModelIndex &index);
|
||||
virtual void showItem(const QString keyname);
|
||||
void sectionResized(int i, int, int newSize);
|
||||
void sortIndicatorChanged(int logicalIndex, Qt::SortOrder order);
|
||||
void pem2clipboard();
|
||||
void sortIndicatorChanged(int, Qt::SortOrder);
|
||||
|
||||
signals:
|
||||
void connNewX509(NewX509 *dlg);
|
||||
void resetHeader();
|
||||
void updateHeader();
|
||||
void columnsContentChanged();
|
||||
void editItem(const QModelIndex &);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -78,20 +78,27 @@ void db_crl::inToCont(pki_base *pki)
|
||||
{
|
||||
pki_crl *crl = (pki_crl *)pki;
|
||||
if (crl->getIssuer() == NULL) {
|
||||
pki_x509 *iss = NULL, *last = NULL;
|
||||
pki_x509 *iss = NULL, *last = NULL, *newest = NULL;
|
||||
x509name issname = crl->getSubject();
|
||||
while ((iss = mainwin->certs->getBySubject(issname, last)) != NULL) {
|
||||
pki_key *key = iss->getPubKey();
|
||||
if (key) {
|
||||
if (crl->verify(key)) {
|
||||
delete key;
|
||||
break;
|
||||
}
|
||||
if (!key)
|
||||
continue;
|
||||
|
||||
if (!crl->verify(key)) {
|
||||
delete key;
|
||||
continue;
|
||||
}
|
||||
delete key;
|
||||
last = iss;
|
||||
if (!newest) {
|
||||
newest = iss;
|
||||
} else {
|
||||
if (newest->getNotAfter() < iss->getNotAfter())
|
||||
newest = iss;
|
||||
}
|
||||
}
|
||||
crl->setIssuer(iss);
|
||||
crl->setIssuer(newest);
|
||||
}
|
||||
db_base::inToCont(pki);
|
||||
}
|
||||
@ -128,14 +135,13 @@ void db_crl::showPki(pki_base *pki)
|
||||
}
|
||||
}
|
||||
|
||||
void db_crl::store()
|
||||
void db_crl::store(QModelIndex index)
|
||||
{
|
||||
QList<exportType> types;
|
||||
|
||||
if (!currentIdx.isValid())
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
pki_crl *crl = static_cast<pki_crl*>(currentIdx.internalPointer());
|
||||
pki_crl *crl = static_cast<pki_crl*>(index.internalPointer());
|
||||
if (!crl)
|
||||
return;
|
||||
|
||||
@ -160,6 +166,40 @@ void db_crl::store()
|
||||
delete dlg;
|
||||
}
|
||||
|
||||
void db_crl::updateRevocations(pki_x509 *cert)
|
||||
{
|
||||
x509name issname = cert->getSubject();
|
||||
x509revList revlist;
|
||||
pki_crl *latest = NULL;
|
||||
|
||||
FOR_ALL_pki(crl, pki_crl) {
|
||||
if (!(issname == crl->getSubject()))
|
||||
continue;
|
||||
pki_key *key = cert->getPubKey();
|
||||
if (!key)
|
||||
continue;
|
||||
if (!crl->verify(key)) {
|
||||
delete key;
|
||||
continue;
|
||||
}
|
||||
delete key;
|
||||
pki_x509 *old = crl->getIssuer();
|
||||
if (!old) {
|
||||
crl->setIssuer(cert);
|
||||
} else if (old != cert) {
|
||||
if (old->getNotAfter() < cert->getNotAfter())
|
||||
crl->setIssuer(cert);
|
||||
}
|
||||
if (!latest || (latest->getCrlNumber() < crl->getCrlNumber()))
|
||||
latest = crl;
|
||||
}
|
||||
if (latest) {
|
||||
revlist = latest->getRevList();
|
||||
cert->mergeRevList(revlist);
|
||||
cert->setCrlNumber(latest->getCrlNumber());
|
||||
}
|
||||
}
|
||||
|
||||
void db_crl::newItem(pki_x509 *cert)
|
||||
{
|
||||
if (!cert)
|
||||
@ -214,23 +254,3 @@ void db_crl::newItem(pki_x509 *cert)
|
||||
delete dlg;
|
||||
return;
|
||||
}
|
||||
|
||||
void db_crl::showContextMenu(QContextMenuEvent *e, const QModelIndex &index)
|
||||
{
|
||||
QMenu *menu = new QMenu(mainwin);
|
||||
currentIdx = index;
|
||||
QMenu *subExport;
|
||||
|
||||
menu->addAction(tr("Import"), this, SLOT(load()));
|
||||
if (index != QModelIndex()) {
|
||||
menu->addAction(tr("Rename"), this, SLOT(edit()));
|
||||
subExport = menu->addMenu(tr("Export"));
|
||||
subExport->addAction(tr("Clipboard"), this,
|
||||
SLOT(pem2clipboard()));
|
||||
subExport->addAction(tr("File"), this, SLOT(store()));
|
||||
menu->addAction(tr("Delete"), this, SLOT(delete_ask()));
|
||||
}
|
||||
contextMenu(e, menu);
|
||||
currentIdx = QModelIndex();
|
||||
return;
|
||||
}
|
||||
|
||||
10
lib/db_crl.h
10
lib/db_crl.h
@ -27,15 +27,15 @@ class db_crl: public db_x509name
|
||||
void revokeCerts(pki_crl *crl);
|
||||
void inToCont(pki_base *pki);
|
||||
pki_base *insert(pki_base *item);
|
||||
void showContextMenu(QContextMenuEvent *e, const QModelIndex &index);
|
||||
void removeSigner(pki_base *signer);
|
||||
public slots:
|
||||
void store();
|
||||
void store(QModelIndex index);
|
||||
void load();
|
||||
void showPki(pki_base *pki);
|
||||
void newItem(pki_x509 *cert);
|
||||
signals:
|
||||
void updateCertView();
|
||||
void updateRevocations(pki_x509 *cert);
|
||||
|
||||
public slots:
|
||||
void newItem(pki_x509 *cert);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
198
lib/db_key.cpp
198
lib/db_key.cpp
@ -82,7 +82,7 @@ QStringList db_key::get0KeyDesc(bool all)
|
||||
void db_key::remFromCont(QModelIndex &idx)
|
||||
{
|
||||
db_base::remFromCont(idx);
|
||||
pki_base *pki = static_cast<pki_base*>(currentIdx.internalPointer());
|
||||
pki_base *pki = static_cast<pki_base*>(idx.internalPointer());
|
||||
emit delKey((pki_key *)pki);
|
||||
}
|
||||
|
||||
@ -109,9 +109,7 @@ pki_base* db_key::insert(pki_base *item)
|
||||
XCA_INFO(
|
||||
tr("The database already contains the public part of the imported key as\n'%1\nand will be completed by the new, private part of the key").arg(oldkey->getIntName()));
|
||||
lkey->setIntName(oldkey->getIntName());
|
||||
currentIdx = index(oldkey->row(), 0, QModelIndex());
|
||||
deletePKI();
|
||||
currentIdx = QModelIndex();
|
||||
deletePKI(index(oldkey->row(), 0, QModelIndex()));
|
||||
}
|
||||
}
|
||||
insertPKI(lkey);
|
||||
@ -187,35 +185,6 @@ void db_key::load(void)
|
||||
load_default(l);
|
||||
}
|
||||
|
||||
void db_key::toToken()
|
||||
{
|
||||
pki_key *key = static_cast<pki_scard*>(currentIdx.internalPointer());
|
||||
if (!key || !pkcs11::loaded() || key->isToken())
|
||||
return;
|
||||
|
||||
pki_scard *card = NULL;
|
||||
try {
|
||||
pkcs11 p11;
|
||||
slotid slot;
|
||||
|
||||
if (!p11.selectToken(&slot, mainwin))
|
||||
return;
|
||||
card = new pki_scard(key->getIntName());
|
||||
card->store_token(slot, key->decryptKey());
|
||||
QString msg = tr("Shall the original key '%1' be replaced by the key on the token?\nThis will delete the key '%1' and make it unexportable").
|
||||
arg(key->getIntName());
|
||||
if (XCA_YESNO(msg)) {
|
||||
deletePKI();
|
||||
insertPKI(card);
|
||||
card = NULL;
|
||||
}
|
||||
} catch (errorEx &err) {
|
||||
mainwin->Error(err);
|
||||
}
|
||||
if (card)
|
||||
delete card;
|
||||
}
|
||||
|
||||
void db_key::showPki(pki_base *pki)
|
||||
{
|
||||
pki_evp *key = (pki_evp *)pki;
|
||||
@ -226,77 +195,35 @@ void db_key::showPki(pki_base *pki)
|
||||
delete dlg;
|
||||
}
|
||||
}
|
||||
|
||||
void db_key::showContextMenu(QContextMenuEvent *e, const QModelIndex &index)
|
||||
exportType::etype db_key::clipboardFormat(QModelIndexList indexes)
|
||||
{
|
||||
QMenu *menu = new QMenu(mainwin);
|
||||
QMenu *subExport;
|
||||
|
||||
currentIdx = index;
|
||||
|
||||
pki_key *key = static_cast<pki_key*>(currentIdx.internalPointer());
|
||||
|
||||
menu->addAction(tr("New Key"), this, SLOT(newItem()));
|
||||
menu->addAction(tr("Import"), this, SLOT(load()));
|
||||
if (index != QModelIndex()) {
|
||||
menu->addAction(tr("Rename"), this, SLOT(edit()));
|
||||
menu->addAction(tr("Show Details"), this, SLOT(showItem()));
|
||||
menu->addAction(tr("Delete"), this, SLOT(delete_ask()));
|
||||
subExport = menu->addMenu(tr("Export"));
|
||||
subExport->addAction(tr("Clipboard"), this,
|
||||
SLOT(pem2clipboard()));
|
||||
subExport->addAction(tr("File"), this, SLOT(store()));
|
||||
if (key->isPrivKey() && !key->isToken()) {
|
||||
switch (key->getOwnPass()) {
|
||||
case pki_key::ptCommon:
|
||||
menu->addAction(tr("Change password"), this,
|
||||
SLOT(setOwnPass()));
|
||||
break;
|
||||
case pki_key::ptPrivate:
|
||||
menu->addAction(tr("Reset password"), this,
|
||||
SLOT(resetOwnPass()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (key->isToken() && pkcs11::loaded()) {
|
||||
menu->addAction(tr("Change PIN"), this,
|
||||
SLOT(changePin()));
|
||||
menu->addAction(tr("Init PIN with SO PIN (PUK)"), this,
|
||||
SLOT(initPin()));
|
||||
menu->addAction(tr("Change SO PIN (PUK)"), this,
|
||||
SLOT(changeSoPin()));
|
||||
}
|
||||
if (!key->isToken() && pkcs11::loaded()) {
|
||||
menu->addAction(tr("Store on Security token"),
|
||||
this, SLOT(toToken()));
|
||||
}
|
||||
}
|
||||
contextMenu(e, menu);
|
||||
currentIdx = QModelIndex();
|
||||
return;
|
||||
}
|
||||
|
||||
exportType::etype db_key::clipboardFormat()
|
||||
{
|
||||
QString title = tr("Export public key [%1]");
|
||||
QList<exportType> types;
|
||||
bool allPriv = true;
|
||||
bool allRSADSA = true;
|
||||
|
||||
pki_key *key =static_cast<pki_evp*>(currentIdx.internalPointer());
|
||||
foreach(QModelIndex idx, indexes) {
|
||||
pki_key *key = static_cast<pki_key*>
|
||||
(idx.internalPointer());
|
||||
if (key->isPubKey() || key->isToken())
|
||||
allPriv = false;
|
||||
if (key->getKeyType() != EVP_PKEY_RSA &&
|
||||
key->getKeyType() != EVP_PKEY_DSA)
|
||||
allRSADSA = false;
|
||||
}
|
||||
if (!allPriv && !allRSADSA)
|
||||
return exportType::PEM_key;
|
||||
|
||||
types << exportType(exportType::PEM_key, "pem", tr("PEM public"));
|
||||
if (key->getKeyType() == EVP_PKEY_RSA ||
|
||||
key->getKeyType() == EVP_PKEY_DSA)
|
||||
if (allRSADSA)
|
||||
types << exportType(exportType::SSH2_public,
|
||||
"pub", tr("SSH2 public"));
|
||||
if (!key->isPubKey() && !key->isToken()) {
|
||||
if (allPriv)
|
||||
types << exportType(exportType::PEM_private, "pem",
|
||||
tr("PEM private"));
|
||||
title = tr("Export private key [%1]");
|
||||
}
|
||||
|
||||
ExportDialog *dlg = new ExportDialog(mainwin,
|
||||
title.arg(key->getTypeString()), QString(), key,
|
||||
key->isToken() ? MainWindow::scardImg : MainWindow::keyImg,
|
||||
types);
|
||||
tr("Export keys to CLipboard"), QString(), NULL,
|
||||
MainWindow::keyImg, types);
|
||||
|
||||
dlg->filename->setText(tr("Clipboard"));
|
||||
dlg->filename->setEnabled(false);
|
||||
@ -308,16 +235,16 @@ exportType::etype db_key::clipboardFormat()
|
||||
return dlg->type();
|
||||
}
|
||||
|
||||
void db_key::store()
|
||||
void db_key::store(QModelIndex index)
|
||||
{
|
||||
const EVP_CIPHER *enc = NULL;
|
||||
QString title = tr("Export public key [%1]");
|
||||
QList<exportType> types;
|
||||
|
||||
if (!currentIdx.isValid())
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
pki_key *key =static_cast<pki_evp*>(currentIdx.internalPointer());
|
||||
pki_key *key =static_cast<pki_evp*>(index.internalPointer());
|
||||
pki_evp *privkey = (pki_evp *)key;
|
||||
|
||||
types <<
|
||||
@ -395,84 +322,15 @@ void db_key::store()
|
||||
delete dlg;
|
||||
}
|
||||
|
||||
void db_key::setOwnPass()
|
||||
{
|
||||
try {
|
||||
__setOwnPass(pki_key::ptPrivate);
|
||||
}
|
||||
catch (errorEx &err) {
|
||||
mainwin->Error(err);
|
||||
}
|
||||
}
|
||||
|
||||
void db_key::resetOwnPass()
|
||||
{
|
||||
try {
|
||||
__setOwnPass(pki_key::ptCommon);
|
||||
}
|
||||
catch (errorEx &err) {
|
||||
mainwin->Error(err);
|
||||
}
|
||||
}
|
||||
|
||||
void db_key::__setOwnPass(enum pki_key::passType x)
|
||||
void db_key::setOwnPass(QModelIndex idx, enum pki_key::passType x)
|
||||
{
|
||||
pki_evp *targetKey;
|
||||
if (!currentIdx.isValid())
|
||||
return;
|
||||
targetKey = static_cast<pki_evp*>(currentIdx.internalPointer());
|
||||
if (!idx.isValid())
|
||||
return;
|
||||
targetKey = static_cast<pki_evp*>(idx.internalPointer());
|
||||
if (targetKey->isToken()) {
|
||||
throw errorEx(tr("Tried to change password of a token"));
|
||||
}
|
||||
targetKey->setOwnPass(x);
|
||||
updatePKI(targetKey);
|
||||
}
|
||||
|
||||
void db_key::changePin()
|
||||
{
|
||||
pki_scard *scard;
|
||||
if (!currentIdx.isValid())
|
||||
return;
|
||||
scard = static_cast<pki_scard*>(currentIdx.internalPointer());
|
||||
try {
|
||||
if (!scard->isToken()) {
|
||||
throw errorEx(tr("Tried to change PIN of a key"));
|
||||
}
|
||||
scard->changePin();
|
||||
} catch (errorEx &err) {
|
||||
mainwin->Error(err);
|
||||
}
|
||||
}
|
||||
|
||||
void db_key::initPin()
|
||||
{
|
||||
pki_scard *scard;
|
||||
if (!currentIdx.isValid())
|
||||
return;
|
||||
scard = static_cast<pki_scard*>(currentIdx.internalPointer());
|
||||
try {
|
||||
if (!scard->isToken()) {
|
||||
throw errorEx(tr("Tried to init PIN of a key"));
|
||||
}
|
||||
scard->initPin();
|
||||
} catch (errorEx &err) {
|
||||
mainwin->Error(err);
|
||||
}
|
||||
}
|
||||
|
||||
void db_key::changeSoPin()
|
||||
{
|
||||
pki_scard *scard;
|
||||
if (!currentIdx.isValid())
|
||||
return;
|
||||
scard = static_cast<pki_scard*>(currentIdx.internalPointer());
|
||||
try {
|
||||
if (!scard->isToken()) {
|
||||
throw errorEx(tr("Tried to change SO PIN of a key"));
|
||||
}
|
||||
scard->changeSoPin();
|
||||
} catch (errorEx &err) {
|
||||
mainwin->Error(err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
15
lib/db_key.h
15
lib/db_key.h
@ -20,11 +20,10 @@ class QContextMenuEvent;
|
||||
class db_key: public db_base
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
protected:
|
||||
virtual dbheaderList getHeaders();
|
||||
exportType::etype clipboardFormat();
|
||||
private:
|
||||
void __setOwnPass(enum pki_key::passType);
|
||||
exportType::etype clipboardFormat(QModelIndexList indexes);
|
||||
public:
|
||||
db_key(QString db, MainWindow *mw);
|
||||
QStringList getPrivateDesc();
|
||||
@ -34,20 +33,14 @@ class db_key: public db_base
|
||||
void remFromCont(QModelIndex &idx);
|
||||
pki_base* insert(pki_base *item);
|
||||
void writeAll();
|
||||
void showContextMenu(QContextMenuEvent * e, const QModelIndex &index);
|
||||
void setOwnPass(QModelIndex idx, enum pki_key::passType);
|
||||
|
||||
public slots:
|
||||
void newItem();
|
||||
void newItem(QString name);
|
||||
void load();
|
||||
void store();
|
||||
void store(QModelIndex index);
|
||||
void showPki(pki_base *pki);
|
||||
void setOwnPass();
|
||||
void resetOwnPass();
|
||||
void changePin();
|
||||
void initPin();
|
||||
void changeSoPin();
|
||||
void toToken();
|
||||
|
||||
signals:
|
||||
void delKey(pki_key *delkey);
|
||||
|
||||
@ -145,36 +145,9 @@ void db_temp::newItem()
|
||||
}
|
||||
delete temp;
|
||||
}
|
||||
|
||||
void db_temp::changeTemp()
|
||||
{
|
||||
if (!currentIdx.isValid())
|
||||
return;
|
||||
pki_temp *temp = static_cast<pki_temp*>(currentIdx.internalPointer());
|
||||
alterTemp(temp);
|
||||
}
|
||||
|
||||
void db_temp::duplicateTemp()
|
||||
{
|
||||
if (!currentIdx.isValid())
|
||||
return;
|
||||
pki_temp *temp = static_cast<pki_temp*>(currentIdx.internalPointer());
|
||||
pki_temp *newtemp = new pki_temp(temp);
|
||||
newtemp->setIntName(newtemp->getIntName() + " " + tr("copy"));
|
||||
insertPKI(newtemp);
|
||||
}
|
||||
|
||||
bool db_temp::alterTemp(pki_temp *temp)
|
||||
{
|
||||
if (!runTempDlg(temp))
|
||||
return false;
|
||||
updatePKI(temp);
|
||||
return true;
|
||||
}
|
||||
|
||||
void db_temp::showPki(pki_base *pki)
|
||||
{
|
||||
alterTemp((pki_temp *)pki);
|
||||
alterTemp(static_cast<pki_temp *>(pki));
|
||||
}
|
||||
|
||||
void db_temp::load()
|
||||
@ -183,11 +156,12 @@ void db_temp::load()
|
||||
load_default(l);
|
||||
}
|
||||
|
||||
void db_temp::store()
|
||||
void db_temp::store(QModelIndex index)
|
||||
{
|
||||
if (!currentIdx.isValid())
|
||||
if (!index.isValid())
|
||||
return;
|
||||
pki_temp *temp = static_cast<pki_temp*>(currentIdx.internalPointer());
|
||||
|
||||
pki_temp *temp = static_cast<pki_temp*>(index.internalPointer());
|
||||
|
||||
QString fn = mainwin->getPath() + QDir::separator() +
|
||||
temp->getUnderlinedName() + ".xca";
|
||||
@ -206,48 +180,10 @@ void db_temp::store()
|
||||
}
|
||||
}
|
||||
|
||||
void db_temp::certFromTemp()
|
||||
bool db_temp::alterTemp(pki_temp *temp)
|
||||
{
|
||||
if (!currentIdx.isValid())
|
||||
return;
|
||||
pki_temp *temp = static_cast<pki_temp*>(currentIdx.internalPointer());
|
||||
emit newCert(temp);
|
||||
}
|
||||
|
||||
void db_temp::reqFromTemp()
|
||||
{
|
||||
if (!currentIdx.isValid())
|
||||
return;
|
||||
pki_temp *temp = static_cast<pki_temp*>(currentIdx.internalPointer());
|
||||
emit newReq(temp);
|
||||
}
|
||||
|
||||
void db_temp::alterTemp()
|
||||
{
|
||||
if (!currentIdx.isValid())
|
||||
return;
|
||||
pki_temp *temp = static_cast<pki_temp*>(currentIdx.internalPointer());
|
||||
alterTemp(temp);
|
||||
}
|
||||
|
||||
void db_temp::showContextMenu(QContextMenuEvent *e, const QModelIndex &index)
|
||||
{
|
||||
QMenu *menu = new QMenu(mainwin);
|
||||
currentIdx = index;
|
||||
|
||||
menu->addAction(tr("New Template"), this, SLOT(newItem()));
|
||||
menu->addAction(tr("Import"), this, SLOT(load()));
|
||||
if (index != QModelIndex()) {
|
||||
menu->addAction(tr("Rename"), this, SLOT(edit()));
|
||||
menu->addAction(tr("Export"), this, SLOT(store()));
|
||||
menu->addAction(tr("Change"), this, SLOT(alterTemp()));
|
||||
menu->addAction(tr("Delete"), this, SLOT(delete_ask()));
|
||||
menu->addAction(tr("Duplicate"), this, SLOT(duplicateTemp()));
|
||||
menu->addAction(tr("Create certificate"), this,
|
||||
SLOT(certFromTemp()));
|
||||
menu->addAction(tr("Create request"), this, SLOT(reqFromTemp()));
|
||||
}
|
||||
contextMenu(e, menu);
|
||||
currentIdx = QModelIndex();
|
||||
return;
|
||||
if (!runTempDlg(temp))
|
||||
return false;
|
||||
updatePKI(temp);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -15,8 +15,6 @@
|
||||
#include <QtCore/QObject>
|
||||
#include <QtGui/QPixmap>
|
||||
|
||||
class Mainwin;
|
||||
|
||||
class db_temp: public db_x509name
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -31,23 +29,12 @@ class db_temp: public db_x509name
|
||||
pki_base *newPKI(db_header_t *head = NULL);
|
||||
bool runTempDlg(pki_temp *temp);
|
||||
bool alterTemp(pki_temp *temp);
|
||||
void showContextMenu(QContextMenuEvent *e, const QModelIndex &index);
|
||||
void fillContextMenu(QMenu *menu, const QModelIndex &index);
|
||||
pki_base *getByName(QString desc);
|
||||
QStringList getDescPredefs();
|
||||
|
||||
public slots:
|
||||
void newItem();
|
||||
void changeTemp();
|
||||
void showPki(pki_base *pki);
|
||||
void load();
|
||||
void store();
|
||||
void certFromTemp();
|
||||
void reqFromTemp();
|
||||
void alterTemp();
|
||||
void duplicateTemp();
|
||||
signals:
|
||||
void newReq(pki_temp *);
|
||||
void newCert(pki_temp *);
|
||||
|
||||
void store(QModelIndex index);
|
||||
};
|
||||
#endif
|
||||
|
||||
477
lib/db_x509.cpp
477
lib/db_x509.cpp
@ -39,7 +39,6 @@ db_x509::db_x509(QString DBfile, MainWindow *mw)
|
||||
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;
|
||||
}
|
||||
@ -115,7 +114,7 @@ QStringList db_x509::getSignerDesc()
|
||||
void db_x509::remFromCont(QModelIndex &idx)
|
||||
{
|
||||
int row;
|
||||
pki_base *pki = static_cast<pki_base*>(currentIdx.internalPointer());
|
||||
pki_base *pki = static_cast<pki_base*>(idx.internalPointer());
|
||||
pki_base *parent_pki = pki->getParent();
|
||||
row = pki->row();
|
||||
pki_x509 *child;
|
||||
@ -155,8 +154,6 @@ void db_x509::changeView()
|
||||
return;
|
||||
|
||||
temproot = new pki_base();
|
||||
mainwin->certView->hide();
|
||||
mainwin->certView->setModel(NULL);
|
||||
beginRemoveRows(QModelIndex(), 0, rows -1);
|
||||
pki_base *pki = rootItem;
|
||||
pki_base *parent;
|
||||
@ -181,8 +178,6 @@ void db_x509::changeView()
|
||||
inToCont(pki);
|
||||
}
|
||||
delete temproot;
|
||||
mainwin->certView->setModel(this);
|
||||
mainwin->certView->show();
|
||||
}
|
||||
|
||||
void db_x509::calcEffTrust()
|
||||
@ -191,6 +186,23 @@ void db_x509::calcEffTrust()
|
||||
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;
|
||||
@ -198,47 +210,68 @@ void db_x509::inToCont(pki_base *pki)
|
||||
cert->delSigner(cert->getSigner());
|
||||
findSigner(cert);
|
||||
pki_base *root = cert->getSigner();
|
||||
if (!treeview || root == cert)
|
||||
if (!treeview || root == cert || root == NULL)
|
||||
root = rootItem;
|
||||
fprintf(stderr, "INSERT '%s' below '%s'\n",
|
||||
CCHAR(cert->getIntName()),
|
||||
CCHAR(root->getIntName()));
|
||||
|
||||
insertChild(root, pki);
|
||||
/* search for dangling certificates, which signer this is */
|
||||
insertChild(root, cert);
|
||||
|
||||
QList<pki_x509 *> childs;
|
||||
/* Search for another certificate (name and key)
|
||||
* and use its childs if we are newer */
|
||||
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;
|
||||
}
|
||||
if (client == cert)
|
||||
continue;
|
||||
if (!client->compareNameAndKey(cert))
|
||||
continue;
|
||||
if (cert->getNotAfter() < client->getNotAfter())
|
||||
continue;
|
||||
fprintf(stderr, "Other CA '%s' is older then us '%s'\n",
|
||||
CCHAR(client->getIntName()),
|
||||
CCHAR(cert->getIntName()));
|
||||
foreach(pki_base *_child, client->childItems) {
|
||||
pki_x509 *child = static_cast<pki_x509*>(_child);
|
||||
child->delSigner(client);
|
||||
childs << child;
|
||||
}
|
||||
}
|
||||
/* Search rootItem childs, whether they are ours */
|
||||
foreach(pki_base *_child, rootItem->childItems) {
|
||||
pki_x509 *child = static_cast<pki_x509*>(_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;
|
||||
fprintf(stderr, "MOVE Child '%s' from '%s' to '%s'\n",
|
||||
CCHAR(child->getIntName()),
|
||||
CCHAR(child->getParent()->getIntName()),
|
||||
CCHAR(cert->getIntName()));
|
||||
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<pki_x509super *> reqs = mainwin->reqs->findByPubKey(pub);
|
||||
delete pub;
|
||||
|
||||
foreach (pki_x509super *r, reqs) {
|
||||
foreach(pki_x509super *r, reqs) {
|
||||
((pki_x509req*)r)->setDone();
|
||||
}
|
||||
}
|
||||
@ -348,6 +381,9 @@ pki_base *db_x509::insert(pki_base *item)
|
||||
if ( ++serial > cert->getCaSerial()) {
|
||||
cert->setCaSerial(serial);
|
||||
}
|
||||
if (mainwin->crls) {
|
||||
mainwin->crls->updateRevocations(cert);
|
||||
}
|
||||
updatePKI(cert);
|
||||
return cert;
|
||||
}
|
||||
@ -358,18 +394,6 @@ void db_x509::load(void)
|
||||
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();
|
||||
@ -584,110 +608,29 @@ void db_x509::showPki(pki_base *pki)
|
||||
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) ),
|
||||
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::showContextMenu(QContextMenuEvent *e, const QModelIndex &index)
|
||||
{
|
||||
QMenu *menu = new QMenu(mainwin);
|
||||
QMenu *subExport, *subCa, *transform;
|
||||
QAction *action;
|
||||
QList<QAction*> scardItems;
|
||||
|
||||
bool parentCanSign, canSign, hasScard;
|
||||
currentIdx = index;
|
||||
pki_key *privkey;
|
||||
|
||||
pki_x509 *cert = static_cast<pki_x509*>(index.internalPointer());
|
||||
pki_x509 *parent;
|
||||
|
||||
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()) {
|
||||
privkey = cert->getRefKey();
|
||||
parent = cert->getSigner();
|
||||
parentCanSign = parent && parent->canSign() && (parent != cert);
|
||||
canSign = cert->canSign();
|
||||
|
||||
menu->addAction(tr("Rename"), this, SLOT(edit()));
|
||||
menu->addAction(tr("Show Details"), this, SLOT(showItem()));
|
||||
subExport = menu->addMenu(tr("Export"));
|
||||
subExport->addAction(tr("Clipboard"), this,
|
||||
SLOT(pem2clipboard()));
|
||||
subExport->addAction(tr("File"), this, SLOT(store()));
|
||||
scardItems += subExport->addAction(tr("Security token"),
|
||||
this, SLOT(toToken()));
|
||||
scardItems += subExport->addAction(tr("Other token"),
|
||||
this, SLOT(toOtherToken()));
|
||||
subExport->addAction(tr("OpenSSL config"),
|
||||
this, SLOT(toOpenssl()));
|
||||
|
||||
transform = menu->addMenu(tr("Transform"));
|
||||
transform->addAction(tr("Public Key"),
|
||||
this, SLOT(extractPubkey()))->
|
||||
setEnabled(!privkey);
|
||||
transform->addAction(tr("Request"),
|
||||
this, SLOT(toRequest()))->
|
||||
setEnabled(privkey && privkey->isPrivKey());
|
||||
transform->addAction(tr("Similar Certificate"),
|
||||
this, SLOT(toCertificate()));
|
||||
transform->addAction(tr("Template"), this, SLOT(toTemplate()));
|
||||
|
||||
menu->addAction(tr("Delete"), this, SLOT(delete_ask()));
|
||||
scardItems += menu->addAction(
|
||||
tr("Delete from Security token"),
|
||||
this, SLOT(deleteFromToken()));
|
||||
menu->addAction(tr("Trust"), this,SLOT(setTrust()))->
|
||||
setEnabled(!cert->isRevoked());
|
||||
menu->addSeparator();
|
||||
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()))->
|
||||
setEnabled(parentCanSign);
|
||||
if (cert->isRevoked()) {
|
||||
menu->addAction(tr("Unrevoke"),
|
||||
this, SLOT(unRevoke()))->
|
||||
setEnabled(parentCanSign);
|
||||
} else {
|
||||
menu->addAction(tr("Revoke"), this, SLOT(revoke()))->
|
||||
setEnabled(parentCanSign);
|
||||
}
|
||||
hasScard = pkcs11::loaded();
|
||||
|
||||
foreach(action, scardItems)
|
||||
action->setEnabled(hasScard);
|
||||
}
|
||||
contextMenu(e, menu);
|
||||
currentIdx = QModelIndex();
|
||||
return;
|
||||
}
|
||||
|
||||
void db_x509::store(QModelIndexList list)
|
||||
{
|
||||
QStringList filt;
|
||||
bool append, chain;
|
||||
QList<exportType> types, usual;
|
||||
|
||||
if (!currentIdx.isValid())
|
||||
if (list.size() == 0)
|
||||
return;
|
||||
|
||||
pki_x509 *crt = static_cast<pki_x509*>(currentIdx.internalPointer());
|
||||
pki_x509 *crt = static_cast<pki_x509*>(list[0].internalPointer());
|
||||
pki_x509 *oldcrt = NULL;
|
||||
if (!crt)
|
||||
return;
|
||||
|
||||
pki_key *privkey = crt->getRefKey();
|
||||
pki_evp *pkey;
|
||||
chain = crt->getSigner() && crt->getSigner() != crt;
|
||||
@ -905,33 +848,9 @@ void db_x509::writePKCS7(pki_x509 *cert, QString s, exportType::etype type,
|
||||
|
||||
}
|
||||
|
||||
void db_x509::setMultiTrust(QAbstractItemView* view)
|
||||
void db_x509::manageRevocations(QModelIndex idx)
|
||||
{
|
||||
QItemSelectionModel *selectionModel = view->selectionModel();
|
||||
QModelIndexList indexes = selectionModel->selectedIndexes();
|
||||
QString items;
|
||||
|
||||
foreach(currentIdx, indexes) {
|
||||
setTrust();
|
||||
}
|
||||
currentIdx = QModelIndex();
|
||||
}
|
||||
|
||||
void db_x509::deleteFromToken()
|
||||
{
|
||||
if (!currentIdx.isValid())
|
||||
return;
|
||||
pki_x509 *pki = static_cast<pki_x509*>(currentIdx.internalPointer());
|
||||
try {
|
||||
pki->deleteFromToken();
|
||||
} catch (errorEx &err) {
|
||||
mainwin->Error(err);
|
||||
}
|
||||
}
|
||||
|
||||
void db_x509::manageRevocations()
|
||||
{
|
||||
pki_x509 *cert = static_cast<pki_x509*>(currentIdx.internalPointer());
|
||||
pki_x509 *cert = static_cast<pki_x509*>(idx.internalPointer());
|
||||
if (!cert)
|
||||
return;
|
||||
RevocationList *dlg = new RevocationList(mainwin);
|
||||
@ -941,51 +860,71 @@ void db_x509::manageRevocations()
|
||||
if (dlg->exec()) {
|
||||
cert->setRevocations(dlg->getRevList());
|
||||
updatePKI(cert);
|
||||
emit columnsContentChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void db_x509::setTrust()
|
||||
void db_x509::setTrust(QModelIndexList indexes)
|
||||
{
|
||||
int state, newstate = 0;
|
||||
int newstate = -1;
|
||||
Ui::TrustState ui;
|
||||
pki_x509 *cert = static_cast<pki_x509*>(currentIdx.internalPointer());
|
||||
if (!cert)
|
||||
pki_x509 *cert = NULL;
|
||||
|
||||
if (indexes.size() == 0)
|
||||
return;
|
||||
if (indexes.size() == 1)
|
||||
cert = static_cast<pki_x509*>(indexes[0].internalPointer());
|
||||
|
||||
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 (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 (state == 0 ) ui.trust0->setChecked(true);
|
||||
if (state == 1 ) ui.trust1->setChecked(true);
|
||||
if (state == 2 ) ui.trust2->setChecked(true);
|
||||
if (dlg->exec()) {
|
||||
if (ui.trust0->isChecked()) newstate = 0;
|
||||
if (ui.trust1->isChecked()) newstate = 1;
|
||||
if (ui.trust2->isChecked()) newstate = 2;
|
||||
if (newstate!=state) {
|
||||
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<pki_x509*>(idx.internalPointer());
|
||||
if (newstate != cert->getTrust()) {
|
||||
cert->setTrust(newstate);
|
||||
updatePKI(cert);
|
||||
}
|
||||
}
|
||||
delete dlg;
|
||||
}
|
||||
|
||||
void db_x509::extendCert()
|
||||
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<pki_x509*>(currentIdx.internalPointer());
|
||||
oldcert = static_cast<pki_x509*>(idx.internalPointer());
|
||||
if (!oldcert ||
|
||||
!(signer = oldcert->getSigner()) ||
|
||||
!(signkey = signer->getRefKey()) ||
|
||||
@ -997,27 +936,37 @@ void db_x509::extendCert()
|
||||
delete dlg;
|
||||
return;
|
||||
}
|
||||
newcert = new pki_x509(oldcert);
|
||||
serial = getUniqueSerial(signer);
|
||||
if (dlg->revoke->isChecked()) {
|
||||
Revocation *revoke = new Revocation(mainwin, indexes);
|
||||
doRevoke = revoke->exec();
|
||||
r = revoke->getRevocation();
|
||||
delete revoke;
|
||||
}
|
||||
foreach(idx, indexes) {
|
||||
oldcert = static_cast<pki_x509*>
|
||||
(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();
|
||||
// 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);
|
||||
newcert->setNotAfter(a);
|
||||
|
||||
// and finally sign the cert
|
||||
newcert->sign(signkey, oldcert->getDigest());
|
||||
newcert = (pki_x509 *)insert(newcert);
|
||||
createSuccess(newcert);
|
||||
|
||||
if (dlg->revoke->isChecked())
|
||||
revoke();
|
||||
// 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);
|
||||
@ -1026,66 +975,98 @@ void db_x509::extendCert()
|
||||
}
|
||||
if (dlg)
|
||||
delete dlg;
|
||||
emit columnsContentChanged();
|
||||
}
|
||||
|
||||
|
||||
void db_x509::revoke()
|
||||
void db_x509::revoke(QModelIndexList indexes)
|
||||
{
|
||||
pki_x509 *cert = static_cast<pki_x509*>(currentIdx.internalPointer());
|
||||
if (!cert)
|
||||
if (indexes.size() == 0)
|
||||
return;
|
||||
Revocation *revoke = new Revocation(mainwin, cert);
|
||||
Revocation *revoke = new Revocation(mainwin, indexes);
|
||||
if (revoke->exec()) {
|
||||
const x509rev r = revoke->getRevocation();
|
||||
cert->setRevoked(r);
|
||||
pki_x509 *iss = cert->getSigner();
|
||||
if (iss) {
|
||||
x509revList rl(r);
|
||||
iss->mergeRevList(rl);
|
||||
updatePKI(iss);
|
||||
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<pki_x509*>(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<pki_x509*>(idx.internalPointer());
|
||||
x509rev rev(r);
|
||||
rev.setSerial(cert->getSerial());
|
||||
cert->setRevoked(rev);
|
||||
revlist << rev;
|
||||
}
|
||||
parent->mergeRevList(revlist);
|
||||
updatePKI(parent);
|
||||
}
|
||||
|
||||
void db_x509::unRevoke()
|
||||
void db_x509::unRevoke(QModelIndexList indexes)
|
||||
{
|
||||
pki_x509 *cert = static_cast<pki_x509*>(currentIdx.internalPointer());
|
||||
pki_x509 *sig;
|
||||
int idx;
|
||||
x509rev rev;
|
||||
pki_x509 *parent = NULL;
|
||||
foreach(QModelIndex idx, indexes) {
|
||||
pki_x509 *cert = static_cast<pki_x509*>(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<pki_x509*>(idx.internalPointer());
|
||||
int idx;
|
||||
x509rev rev;
|
||||
|
||||
if (!cert)
|
||||
return;
|
||||
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);
|
||||
cert->setRevoked(x509rev());
|
||||
rev.setSerial(cert->getSerial());
|
||||
idx = parent->revList.indexOf(rev);
|
||||
if (idx != -1)
|
||||
parent->revList.takeAt(idx);
|
||||
}
|
||||
updatePKI(parent);
|
||||
emit columnsContentChanged();
|
||||
}
|
||||
|
||||
void db_x509::genCrl()
|
||||
void db_x509::toCertificate(QModelIndex index)
|
||||
{
|
||||
pki_x509 *cert = static_cast<pki_x509*>(currentIdx.internalPointer());
|
||||
mainwin->crls->newItem(cert);
|
||||
}
|
||||
|
||||
void db_x509::toCertificate()
|
||||
{
|
||||
pki_x509 *cert = static_cast<pki_x509*>(currentIdx.internalPointer());
|
||||
pki_x509 *cert = static_cast<pki_x509*>(index.internalPointer());
|
||||
if (!cert)
|
||||
return;
|
||||
if (!cert->getRefKey() && cert->getSigner() != cert)
|
||||
extractPubkey();
|
||||
extractPubkey(index);
|
||||
newCert(cert);
|
||||
}
|
||||
|
||||
void db_x509::toRequest()
|
||||
void db_x509::toRequest(QModelIndex idx)
|
||||
{
|
||||
pki_x509 *cert = static_cast<pki_x509*>(currentIdx.internalPointer());
|
||||
pki_x509 *cert = static_cast<pki_x509*>(idx.internalPointer());
|
||||
if (!cert)
|
||||
return;
|
||||
|
||||
@ -1102,9 +1083,9 @@ void db_x509::toRequest()
|
||||
}
|
||||
}
|
||||
|
||||
void db_x509::myToToken(bool alwaysSelect)
|
||||
void db_x509::toToken(QModelIndex idx, bool alwaysSelect)
|
||||
{
|
||||
pki_x509 *cert = static_cast<pki_x509*>(currentIdx.internalPointer());
|
||||
pki_x509 *cert = static_cast<pki_x509*>(idx.internalPointer());
|
||||
if (!cert)
|
||||
return;
|
||||
try {
|
||||
@ -1114,23 +1095,15 @@ void db_x509::myToToken(bool alwaysSelect)
|
||||
}
|
||||
}
|
||||
|
||||
void db_x509::toToken()
|
||||
{
|
||||
myToToken(false);
|
||||
}
|
||||
|
||||
void db_x509::toOtherToken()
|
||||
{
|
||||
myToToken(true);
|
||||
}
|
||||
|
||||
void db_x509::caProperties()
|
||||
void db_x509::caProperties(QModelIndex idx)
|
||||
{
|
||||
Ui::CaProperties ui;
|
||||
int i;
|
||||
pki_x509 *cert = static_cast<pki_x509*>(currentIdx.internalPointer());
|
||||
|
||||
pki_x509 *cert = static_cast<pki_x509*>(idx.internalPointer());
|
||||
if (!cert)
|
||||
return;
|
||||
|
||||
QDialog *dlg = new QDialog(mainwin);
|
||||
ui.setupUi(dlg);
|
||||
ui.serial->setText(cert->getCaSerial().toHex());
|
||||
|
||||
@ -54,34 +54,29 @@ class db_x509: public db_x509super
|
||||
void writePKCS12(pki_x509 *cert, QString s, bool chain);
|
||||
void writePKCS7(pki_x509 *cert, QString s,
|
||||
exportType::etype type, QModelIndexList list);
|
||||
void showContextMenu(QContextMenuEvent *e, const QModelIndex &index);
|
||||
void fillContextMenu(QMenu *menu, const QModelIndex &index);
|
||||
void inToCont(pki_base *pki);
|
||||
void changeView();
|
||||
a1int getUniqueSerial(pki_x509 *signer);
|
||||
void myToToken(bool alwaysSelect);
|
||||
void toToken(QModelIndex idx, bool alwaysSelect);
|
||||
void toRequest(QModelIndex idx);
|
||||
void store(QModelIndexList list);
|
||||
void showPki(pki_base *pki);
|
||||
void load();
|
||||
void caProperties(QModelIndex idx);
|
||||
void toCertificate(QModelIndex index);
|
||||
void manageRevocations(QModelIndex idx);
|
||||
void certRenewal(QModelIndexList indexes);
|
||||
void revoke(QModelIndexList indexes);
|
||||
void do_revoke(QModelIndexList indexes, const x509rev &r);
|
||||
void unRevoke(QModelIndexList indexes);
|
||||
void setTrust(QModelIndexList indexes);
|
||||
|
||||
public slots:
|
||||
void load(void);
|
||||
void newItem(void);
|
||||
void showPki(pki_base *pki);
|
||||
void setMultiTrust(QAbstractItemView* view);
|
||||
void setTrust();
|
||||
void deleteFromToken();
|
||||
void extendCert();
|
||||
void revoke();
|
||||
void unRevoke();
|
||||
void genCrl();
|
||||
void caProperties();
|
||||
void toRequest();
|
||||
void toCertificate();
|
||||
void toToken();
|
||||
void toOtherToken();
|
||||
void newItem();
|
||||
|
||||
void newCert(pki_temp *);
|
||||
void newCert(pki_x509req *);
|
||||
void loadPKCS12();
|
||||
void loadPKCS7();
|
||||
void manageRevocations();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -55,6 +55,11 @@ pki_base *db_x509req::insert(pki_base *item)
|
||||
return req;
|
||||
}
|
||||
|
||||
void db_x509req::newItem()
|
||||
{
|
||||
newItem(NULL, NULL);
|
||||
}
|
||||
|
||||
void db_x509req::newItem(pki_temp *temp, pki_x509req *orig)
|
||||
{
|
||||
pki_x509req *req = NULL;
|
||||
@ -67,7 +72,7 @@ void db_x509req::newItem(pki_temp *temp, pki_x509req *orig)
|
||||
dlg->fromX509super(orig);
|
||||
}
|
||||
dlg->setRequest();
|
||||
if (! dlg->exec()){
|
||||
if (!dlg->exec()){
|
||||
delete dlg;
|
||||
return;
|
||||
}
|
||||
@ -90,10 +95,9 @@ void db_x509req::newItem(pki_temp *temp, pki_x509req *orig)
|
||||
}
|
||||
}
|
||||
|
||||
void db_x509req::toRequest(void)
|
||||
void db_x509req::toRequest(QModelIndex index)
|
||||
{
|
||||
pki_x509req *req = static_cast<pki_x509req*>
|
||||
(currentIdx.internalPointer());
|
||||
pki_x509req *req = static_cast<pki_x509req*>(index.internalPointer());
|
||||
if (!req)
|
||||
return;
|
||||
newItem(NULL, req);
|
||||
@ -136,16 +140,14 @@ void db_x509req::showPki(pki_base *pki)
|
||||
}
|
||||
}
|
||||
|
||||
void db_x509req::store()
|
||||
void db_x509req::store(QModelIndex index)
|
||||
{
|
||||
QList<exportType> types;
|
||||
|
||||
if (!currentIdx.isValid())
|
||||
return;
|
||||
|
||||
pki_x509req *req = static_cast<pki_x509req*>(currentIdx.internalPointer());
|
||||
pki_x509req *req = static_cast<pki_x509req*>(index.internalPointer());
|
||||
if (!req)
|
||||
return;
|
||||
|
||||
types << exportType(exportType::PEM, "pem", "PEM") <<
|
||||
exportType(exportType::DER, "der", "DER");
|
||||
|
||||
@ -167,51 +169,8 @@ void db_x509req::store()
|
||||
delete dlg;
|
||||
}
|
||||
|
||||
|
||||
void db_x509req::signReq()
|
||||
void db_x509req::signReq(QModelIndex index)
|
||||
{
|
||||
if (!currentIdx.isValid())
|
||||
return;
|
||||
|
||||
pki_x509req *req = static_cast<pki_x509req*>(currentIdx.internalPointer());
|
||||
pki_x509req *req = static_cast<pki_x509req*>(index.internalPointer());
|
||||
emit newCert(req);
|
||||
}
|
||||
|
||||
void db_x509req::showContextMenu(QContextMenuEvent *e, const QModelIndex &index)
|
||||
{
|
||||
QMenu *menu = new QMenu(mainwin);
|
||||
QMenu *subExport, *transform;
|
||||
currentIdx = index;
|
||||
|
||||
pki_x509req *req = static_cast<pki_x509req*>(index.internalPointer());
|
||||
|
||||
menu->addAction(tr("New Request"), this, SLOT(newItem()));
|
||||
menu->addAction(tr("Import"), this, SLOT(load()));
|
||||
if (index != QModelIndex()) {
|
||||
menu->addAction(tr("Rename"), this, SLOT(edit()));
|
||||
menu->addAction(tr("Show Details"), this, SLOT(showItem()));
|
||||
menu->addAction(tr("Sign"), this, SLOT(signReq()));
|
||||
|
||||
subExport = menu->addMenu(tr("Export"));
|
||||
subExport->addAction(tr("Clipboard"), this,
|
||||
SLOT(pem2clipboard()));
|
||||
subExport->addAction(tr("File"), this, SLOT(store()));
|
||||
subExport->addAction(tr("OpenSSL config"), this,
|
||||
SLOT(toOpenssl()));
|
||||
subExport->setEnabled(!req->isSpki());
|
||||
|
||||
transform = menu->addMenu(tr("Transform"));
|
||||
transform->addAction(tr("Template"), this,
|
||||
SLOT(toTemplate()))->
|
||||
setEnabled(!req->isSpki());
|
||||
transform->addAction(tr("Public Key"), this,
|
||||
SLOT(extractPubkey()))->
|
||||
setEnabled(!req->getRefKey());
|
||||
transform->addAction(tr("Similar Request"),
|
||||
this, SLOT(toRequest()));
|
||||
menu->addAction(tr("Delete"), this, SLOT(delete_ask()));
|
||||
}
|
||||
contextMenu(e, menu);
|
||||
currentIdx = QModelIndex();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -24,16 +24,18 @@ class db_x509req: public db_x509super
|
||||
db_x509req(QString DBfile, MainWindow *mw);
|
||||
pki_base* insert(pki_base *item);
|
||||
pki_base *newPKI(db_header_t *head = NULL);
|
||||
void showContextMenu(QContextMenuEvent *e, const QModelIndex &index);
|
||||
void fillContextMenu(QMenu *menu, const QModelIndex &index);
|
||||
void inToCont(pki_base *pki);
|
||||
void store(QModelIndex index);
|
||||
void signReq(QModelIndex index);
|
||||
void toRequest(QModelIndex index);
|
||||
void load();
|
||||
void showPki(pki_base *pki);
|
||||
|
||||
public slots:
|
||||
void newItem(pki_temp *temp = NULL, pki_x509req *orig = NULL);
|
||||
void load();
|
||||
void store();
|
||||
void showPki(pki_base *pki);
|
||||
void signReq();
|
||||
void toRequest(void);
|
||||
void newItem(pki_temp *temp, pki_x509req *orig = NULL);
|
||||
void newItem();
|
||||
|
||||
signals:
|
||||
void newCert(pki_x509req *req);
|
||||
};
|
||||
|
||||
@ -112,10 +112,11 @@ QList<pki_x509super *> db_x509super::findByPubKey(pki_key *refkey)
|
||||
return list;
|
||||
}
|
||||
|
||||
void db_x509super::extractPubkey()
|
||||
void db_x509super::extractPubkey(QModelIndex index)
|
||||
{
|
||||
pki_key *key;
|
||||
pki_x509super *pki = static_cast<pki_x509super*>(currentIdx.internalPointer());
|
||||
pki_x509super *pki = static_cast<pki_x509super*>
|
||||
(index.internalPointer());
|
||||
if (!pki)
|
||||
return;
|
||||
key = pki->getPubKey();
|
||||
@ -130,9 +131,9 @@ void db_x509super::extractPubkey()
|
||||
XCA_INFO(key->getMsg(pki_base::msg_import).arg(pki->getIntName()));
|
||||
}
|
||||
|
||||
void db_x509super::toOpenssl() const
|
||||
void db_x509super::toOpenssl(QModelIndex index) const
|
||||
{
|
||||
pki_x509super *pki = static_cast<pki_x509super*>(currentIdx.internalPointer());
|
||||
pki_x509super *pki = static_cast<pki_x509super*>(index.internalPointer());
|
||||
QString fn = mainwin->getPath() + QDir::separator() +
|
||||
pki->getUnderlinedName() + ".conf";
|
||||
QString fname = QFileDialog::getSaveFileName(mainwin,
|
||||
@ -145,9 +146,9 @@ void db_x509super::toOpenssl() const
|
||||
pki->opensslConf(fname);
|
||||
}
|
||||
|
||||
void db_x509super::toTemplate()
|
||||
void db_x509super::toTemplate(QModelIndex index)
|
||||
{
|
||||
pki_x509super *pki = static_cast<pki_x509super*>(currentIdx.internalPointer());
|
||||
pki_x509super *pki = static_cast<pki_x509super*>(index.internalPointer());
|
||||
if (!pki)
|
||||
return;
|
||||
|
||||
|
||||
@ -34,13 +34,13 @@ class db_x509super: public db_x509name
|
||||
db_x509super(QString db, MainWindow *mw);
|
||||
pki_key *findKey(pki_x509super *ref);
|
||||
QList<pki_x509super *> findByPubKey(pki_key *refkey);
|
||||
void extractPubkey(QModelIndex index);
|
||||
void toTemplate(QModelIndex index);
|
||||
void toOpenssl(QModelIndex index) const;
|
||||
|
||||
public slots:
|
||||
void delKey(pki_key *delkey);
|
||||
void newKey(pki_key *newKey);
|
||||
void extractPubkey();
|
||||
void toTemplate();
|
||||
void toOpenssl() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -269,10 +269,10 @@ bool pki_crl::verify(pki_key *key)
|
||||
{
|
||||
bool ret=false;
|
||||
if (crl && crl->crl && key) {
|
||||
ret = (X509_CRL_verify(crl , key->getPubKey()) == 1);
|
||||
ret = (X509_CRL_verify(crl, key->getPubKey()) == 1);
|
||||
pki_ign_openssl_error();
|
||||
}
|
||||
return ret ;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void pki_crl::setCrlNumber(a1int num)
|
||||
@ -284,6 +284,14 @@ void pki_crl::setCrlNumber(a1int num)
|
||||
pki_openssl_error();
|
||||
}
|
||||
|
||||
a1int pki_crl::getCrlNumber()
|
||||
{
|
||||
a1int num;
|
||||
if (!getCrlNumber(&num))
|
||||
num.set(0L);
|
||||
return num;
|
||||
}
|
||||
|
||||
bool pki_crl::getCrlNumber(a1int *num)
|
||||
{
|
||||
int j;
|
||||
|
||||
@ -68,6 +68,7 @@ class pki_crl: public pki_x509name
|
||||
QByteArray i2d();
|
||||
void setCrlNumber(a1int num);
|
||||
bool getCrlNumber(a1int *num);
|
||||
a1int getCrlNumber();
|
||||
BIO *pem(BIO *, int);
|
||||
bool visible();
|
||||
};
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
#include "pki_pkcs7.h"
|
||||
#include "pki_pkcs12.h"
|
||||
#include "pki_crl.h"
|
||||
#include "pki_temp.h"
|
||||
#include "load_obj.h"
|
||||
#include "exception.h"
|
||||
#include "func.h"
|
||||
@ -40,12 +41,12 @@ pki_base *pki_multi::pull()
|
||||
return multi.takeFirst();
|
||||
}
|
||||
|
||||
#define D5 "-----"
|
||||
#define BEGIN D5 "BEGIN "
|
||||
/* General PEM loader */
|
||||
static pki_base *pkiByPEM(QString text, int *skip)
|
||||
{
|
||||
int pos;
|
||||
#define D5 "-----"
|
||||
#define BEGIN D5 "BEGIN "
|
||||
pos = text.indexOf(BEGIN);
|
||||
if (pos <0) {
|
||||
if (skip)
|
||||
@ -74,6 +75,9 @@ static pki_base *pkiByPEM(QString text, int *skip)
|
||||
if (text.startsWith(PEM_STRING_X509_CRL D5))
|
||||
return new pki_crl();
|
||||
|
||||
if (text.startsWith(PEM_STRING_XCA_TEMPLATE D5))
|
||||
return new pki_temp();
|
||||
|
||||
if (text.startsWith(PEM_STRING_EVP_PKEY D5) ||
|
||||
text.startsWith(PEM_STRING_PUBLIC D5) ||
|
||||
text.startsWith(PEM_STRING_RSA D5) ||
|
||||
@ -155,7 +159,8 @@ void pki_multi::probeAnything(const QString fname)
|
||||
load_base *lb;
|
||||
QList<load_base *> lbs;
|
||||
|
||||
lbs << new load_cert() << new load_pkcs7() << new load_pkcs12() <<
|
||||
lbs << new load_pem() <<
|
||||
new load_cert() << new load_pkcs7() << new load_pkcs12() <<
|
||||
new load_crl() << new load_req() << new load_key() <<
|
||||
new load_temp();
|
||||
|
||||
|
||||
178
lib/pki_temp.cpp
178
lib/pki_temp.cpp
@ -251,7 +251,7 @@ void pki_temp::fromData(const unsigned char *p, int size, int version)
|
||||
eKeyUseCrit = db::boolFromData(ba);
|
||||
subKey = db::boolFromData(ba);
|
||||
authKey = db::boolFromData(ba);
|
||||
ca = db:: intFromData(ba);
|
||||
ca = db::intFromData(ba);
|
||||
if (version > 5) {
|
||||
pathLen = db::stringFromData(ba);
|
||||
} else {
|
||||
@ -330,25 +330,113 @@ QByteArray pki_temp::toData()
|
||||
return ba;
|
||||
}
|
||||
|
||||
void pki_temp::writeDefault(const QString fname)
|
||||
QByteArray pki_temp::toExportData()
|
||||
{
|
||||
writeTemp(fname + QDir::separator() + getIntName() + ".xca");
|
||||
QByteArray data, header;
|
||||
data = toData();
|
||||
header = db::intToData(data.count());
|
||||
header += db::intToData(dataVersion);
|
||||
header += data;
|
||||
return header;
|
||||
}
|
||||
|
||||
void pki_temp::writeTemp(QString fname)
|
||||
{
|
||||
QByteArray data, header;
|
||||
FILE *fp = fopen(QString2filename(fname),"wb");
|
||||
|
||||
if (fp == NULL) {
|
||||
fopen_error(fname);
|
||||
return;
|
||||
}
|
||||
data = toData();
|
||||
header = db::intToData(data.count());
|
||||
header += db::intToData(dataVersion);
|
||||
header += data;
|
||||
fwrite_ba(fp, header, fname);
|
||||
fwrite_ba(fp, toExportData(), fname);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
void pki_temp::writeDefault(const QString fname)
|
||||
{
|
||||
writeTemp(fname + QDir::separator() + getIntName() + ".xca");
|
||||
}
|
||||
|
||||
BIO *pki_temp::pem(BIO *b, int format)
|
||||
{
|
||||
QByteArray ba = toExportData();
|
||||
if (!b)
|
||||
b = BIO_new(BIO_s_mem());
|
||||
PEM_write_bio(b, PEM_STRING_XCA_TEMPLATE, "",
|
||||
(const unsigned char*)ba.constData(), ba.size());
|
||||
pki_openssl_error();
|
||||
return b;
|
||||
}
|
||||
|
||||
void pki_temp::fromExportData(QByteArray data)
|
||||
{
|
||||
int size, version;
|
||||
const int hsize = sizeof(uint32_t);
|
||||
bool oldimport = false;
|
||||
|
||||
if (data.size() < hsize) {
|
||||
my_error(tr("Template file content error (too small)"));
|
||||
}
|
||||
|
||||
QByteArray header = data.mid(0, hsize);
|
||||
size = db::intFromData(header);
|
||||
|
||||
if (size > 65535 || size <0) {
|
||||
/* oldimport templates are prepended by its size in
|
||||
* host endianess. Recover the size */
|
||||
size = intFromData(data);
|
||||
if (size > 65535 || size <0) {
|
||||
my_error(tr("Template file content error (bad size)"));
|
||||
}
|
||||
oldimport = true;
|
||||
}
|
||||
if (oldimport) {
|
||||
oldFromData((const unsigned char*)data.constData(),
|
||||
data.size());
|
||||
} else {
|
||||
size = db::intFromData(data);
|
||||
version = db::intFromData(data);
|
||||
fromData((const unsigned char*)data.constData(),
|
||||
data.size(), version);
|
||||
}
|
||||
}
|
||||
|
||||
void pki_temp::try_fload(QString fname, const char *mode)
|
||||
{
|
||||
FILE *fp = fopen(QString2filename(fname), mode);
|
||||
char buf[4096];
|
||||
QByteArray ba;
|
||||
BIO *b;
|
||||
|
||||
if (fp == NULL) {
|
||||
fopen_error(fname);
|
||||
return;
|
||||
}
|
||||
b = BIO_new(BIO_s_file());
|
||||
pki_openssl_error();
|
||||
BIO_set_fp(b,fp,BIO_NOCLOSE);
|
||||
try {
|
||||
fromPEM_BIO(b, fname);
|
||||
BIO_free(b);
|
||||
return;
|
||||
} catch (errorEx &err) {
|
||||
BIO_free(b);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
}
|
||||
while (1) {
|
||||
size_t ret = fread(buf, 1, sizeof buf, fp);
|
||||
ba.append(buf, ret);
|
||||
if (ret < sizeof buf)
|
||||
break;
|
||||
}
|
||||
int err = ferror(fp);
|
||||
fclose(fp);
|
||||
if (err) {
|
||||
my_error(tr("Template file content error (too small): %1").
|
||||
arg(fname));
|
||||
}
|
||||
fromExportData(ba);
|
||||
setIntName(rmslashdot(fname));
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
@ -367,58 +455,30 @@ void pki_temp::fload(QString fname)
|
||||
}
|
||||
}
|
||||
|
||||
void pki_temp::try_fload(QString fname, const char *mode)
|
||||
void pki_temp::fromPEM_BIO(BIO *bio, QString name)
|
||||
{
|
||||
int size, s, version;
|
||||
const int hsize = 2 * sizeof(uint32_t);
|
||||
char buf[hsize];
|
||||
unsigned char *p;
|
||||
FILE *fp = fopen(QString2filename(fname), mode);
|
||||
bool oldimport = false;
|
||||
QByteArray ba;
|
||||
QString msg;
|
||||
char *nm = NULL, *header = NULL;
|
||||
unsigned char *data = NULL;
|
||||
long len;
|
||||
|
||||
if (fp == NULL) {
|
||||
fopen_error(fname);
|
||||
return;
|
||||
PEM_read_bio(bio, &nm, &header, &data, &len);
|
||||
|
||||
pki_openssl_error();
|
||||
|
||||
if (!strcmp(nm, PEM_STRING_XCA_TEMPLATE)) {
|
||||
ba = QByteArray::fromRawData((char*)data, len);
|
||||
fromExportData(ba);
|
||||
setIntName(rmslashdot(name));
|
||||
} else {
|
||||
msg = tr("Not an XCA Template, but '%1'").arg(nm);
|
||||
}
|
||||
if (fread(buf, hsize, 1, fp) != 1) {
|
||||
fclose(fp);
|
||||
my_error(tr("Template file content error (too small): %1").
|
||||
arg(fname));
|
||||
}
|
||||
|
||||
QByteArray header(buf, hsize);
|
||||
QByteArray backup = header;
|
||||
|
||||
size = db::intFromData(header);
|
||||
version = db::intFromData(header);
|
||||
|
||||
if (size > 65535 || size <0) {
|
||||
/* oldimport templates are prepended by its size in host endianess.
|
||||
Set fp after the first int and recover the size */
|
||||
fseek(fp, sizeof(int), SEEK_SET);
|
||||
size = intFromData(backup);
|
||||
if (size > 65535 || size <0) {
|
||||
fclose(fp);
|
||||
my_error(tr("Template file content error (bad size): %1 ").arg(fname));
|
||||
}
|
||||
oldimport = true;
|
||||
}
|
||||
p = (unsigned char *)OPENSSL_malloc(size);
|
||||
if (p) {
|
||||
if ((s=fread(p, 1, size, fp)) != size) {
|
||||
OPENSSL_free(p);
|
||||
fclose(fp);
|
||||
my_error(tr("Template file content error (bad length) :%1").arg(fname));
|
||||
}
|
||||
}
|
||||
if (oldimport)
|
||||
oldFromData(p, size);
|
||||
else
|
||||
fromData(p, size, version);
|
||||
OPENSSL_free(p);
|
||||
|
||||
setIntName(rmslashdot(fname));
|
||||
fclose(fp);
|
||||
OPENSSL_free(nm);
|
||||
OPENSSL_free(header);
|
||||
OPENSSL_free(data);
|
||||
if (!msg.isEmpty())
|
||||
my_error(msg);
|
||||
}
|
||||
|
||||
pki_temp::~pki_temp()
|
||||
@ -447,7 +507,7 @@ QVariant pki_temp::getIcon(dbheader *hd)
|
||||
return hd->id == HD_internal_name ? QVariant(*icon) : QVariant();
|
||||
}
|
||||
|
||||
void pki_temp::oldFromData(unsigned char *p, int size)
|
||||
void pki_temp::oldFromData(const unsigned char *p, int size)
|
||||
{
|
||||
int version;
|
||||
|
||||
|
||||
@ -13,6 +13,9 @@
|
||||
#include "asn1time.h"
|
||||
#include "pki_x509.h"
|
||||
|
||||
#define D5 "-----"
|
||||
#define PEM_STRING_XCA_TEMPLATE "XCA TEMPLATE"
|
||||
|
||||
class pki_temp: public pki_x509name
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -41,7 +44,7 @@ class pki_temp: public pki_x509name
|
||||
~pki_temp();
|
||||
void fromData(const unsigned char *p, int size, int version);
|
||||
void fromData(const unsigned char *p, db_header_t *head );
|
||||
void oldFromData(unsigned char *p, int size);
|
||||
void oldFromData(const unsigned char *p, int size);
|
||||
|
||||
QByteArray toData();
|
||||
bool compare(pki_base *ref);
|
||||
@ -50,6 +53,10 @@ class pki_temp: public pki_x509name
|
||||
QVariant getIcon(dbheader *hd);
|
||||
virtual QString getMsg(msg_type msg);
|
||||
x509name getSubject() const;
|
||||
BIO *pem(BIO *b, int format);
|
||||
QByteArray toExportData();
|
||||
void fromPEM_BIO(BIO *, QString);
|
||||
void fromExportData(QByteArray data);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -194,17 +194,6 @@ a1int pki_x509::hashInfo(const EVP_MD *md) const
|
||||
return a;
|
||||
}
|
||||
|
||||
a1int pki_x509::getQASerial(const a1int &secret) const
|
||||
{
|
||||
ASN1_INTEGER *hold = cert->cert_info->serialNumber;
|
||||
cert->cert_info->serialNumber = secret.get();
|
||||
a1int ret = hashInfo(EVP_md5());
|
||||
ASN1_INTEGER_free(cert->cert_info->serialNumber);
|
||||
cert->cert_info->serialNumber = hold;
|
||||
pki_openssl_error();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void pki_x509::load_token(pkcs11 &p11, CK_OBJECT_HANDLE object)
|
||||
{
|
||||
QString desc;
|
||||
@ -382,11 +371,6 @@ int pki_x509::renameOnToken(slotid slot, QString name)
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool pki_x509::verifyQASerial(const a1int &secret) const
|
||||
{
|
||||
return getQASerial(secret) == getSerial();
|
||||
}
|
||||
|
||||
void pki_x509::setNotBefore(const a1time &a)
|
||||
{
|
||||
a1time t(a);
|
||||
@ -615,13 +599,9 @@ bool pki_x509::cmpIssuerAndSerial(pki_x509 *refcert)
|
||||
|
||||
}
|
||||
|
||||
bool pki_x509::verify(pki_x509 *signer)
|
||||
bool pki_x509::verify_only(pki_x509 *signer)
|
||||
{
|
||||
if (psigner == signer)
|
||||
return true;
|
||||
if ((psigner != NULL )||( signer == NULL))
|
||||
return false;
|
||||
X509_NAME *subject = X509_get_subject_name(signer->cert);
|
||||
X509_NAME *subject = X509_get_subject_name(signer->cert);
|
||||
X509_NAME *issuer = X509_get_issuer_name(cert);
|
||||
pki_openssl_error();
|
||||
if (X509_NAME_cmp(subject, issuer)) {
|
||||
@ -634,7 +614,16 @@ bool pki_x509::verify(pki_x509 *signer)
|
||||
}
|
||||
int i = X509_verify(cert, pub);
|
||||
pki_ign_openssl_error();
|
||||
if (i>0) {
|
||||
return i>0;
|
||||
}
|
||||
|
||||
bool pki_x509::verify(pki_x509 *signer)
|
||||
{
|
||||
if (psigner == signer)
|
||||
return true;
|
||||
if ((psigner != NULL) || (signer == NULL))
|
||||
return false;
|
||||
if (verify_only(signer)) {
|
||||
int idx;
|
||||
x509rev r;
|
||||
r.setSerial(getSerial());
|
||||
@ -675,6 +664,25 @@ pki_key *pki_x509::getPubKey() const
|
||||
return key;
|
||||
}
|
||||
|
||||
bool pki_x509::compareNameAndKey(pki_x509 *other)
|
||||
{
|
||||
X509_NAME *subject = X509_get_subject_name(other->cert);
|
||||
X509_NAME *issuer = X509_get_issuer_name(cert);
|
||||
pki_openssl_error();
|
||||
if (!subject || !issuer)
|
||||
return false;
|
||||
if (X509_NAME_cmp(subject, issuer))
|
||||
return false;
|
||||
EVP_PKEY *pub1 = X509_get_pubkey(cert);
|
||||
EVP_PKEY *pub2 = X509_get_pubkey(other->cert);
|
||||
pki_ign_openssl_error();
|
||||
if (!pub1 || !pub2)
|
||||
return false;
|
||||
int r = EVP_PKEY_cmp(pub1, pub2);
|
||||
pki_openssl_error();
|
||||
return r == 1;
|
||||
}
|
||||
|
||||
void pki_x509::setPubKey(pki_key *key)
|
||||
{
|
||||
X509_set_pubkey(cert, key->getPubKey());
|
||||
|
||||
@ -57,8 +57,6 @@ class pki_x509 : public pki_x509super
|
||||
void fromPEM_BIO(BIO *bio, QString name);
|
||||
void writeDefault(const QString fname);
|
||||
a1int hashInfo(const EVP_MD *md) const;
|
||||
a1int getQASerial(const a1int &secret) const;
|
||||
bool verifyQASerial(const a1int &secret) const;
|
||||
void setSerial(const a1int &serial);
|
||||
a1int getSerial() const;
|
||||
void setNotBefore(const a1time &a);
|
||||
@ -77,6 +75,7 @@ class pki_x509 : public pki_x509super
|
||||
bool canSign();
|
||||
void writeCert(const QString fname, bool PEM, bool append = false);
|
||||
bool verify(pki_x509 *signer);
|
||||
bool verify_only(pki_x509 *signer);
|
||||
pki_key *getPubKey() const;
|
||||
void setPubKey(pki_key *key);
|
||||
pki_x509 *getSigner();
|
||||
@ -113,6 +112,11 @@ class pki_x509 : public pki_x509super
|
||||
{
|
||||
return ++crlNumber;
|
||||
}
|
||||
void setCrlNumber(a1int n)
|
||||
{
|
||||
if (n > crlNumber)
|
||||
crlNumber = n;
|
||||
}
|
||||
void setTemplate(QString s)
|
||||
{
|
||||
if (s.length() > 0)
|
||||
@ -164,6 +168,7 @@ class pki_x509 : public pki_x509super
|
||||
revList.merge(l);
|
||||
}
|
||||
void setRevocations(const x509revList &rl);
|
||||
bool compareNameAndKey(pki_x509 *other);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -52,6 +52,10 @@ class pki_x509super : public pki_x509name
|
||||
};
|
||||
virtual QString getSigAlg();
|
||||
virtual const EVP_MD *getDigest();
|
||||
virtual bool isSpki() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
pki_key *getRefKey() const;
|
||||
void setRefKey(pki_key *ref);
|
||||
void delRefKey(pki_key *ref);
|
||||
|
||||
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>653</width>
|
||||
<height>370</height>
|
||||
<width>589</width>
|
||||
<height>331</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
||||
532
ui/MainWindow.ui
532
ui/MainWindow.ui
@ -12,30 +12,21 @@
|
||||
</property>
|
||||
<widget class="QWidget" name="centralWidget">
|
||||
<layout class="QVBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabView">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
<number>2</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="RSATab">
|
||||
<attribute name="title">
|
||||
<string>Private Keys</string>
|
||||
</attribute>
|
||||
<layout class="QHBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="XcaTreeView" name="keyView"/>
|
||||
<widget class="KeyTreeView" name="keyView"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="keyButtons">
|
||||
@ -133,14 +124,11 @@
|
||||
<string>Certificate signing requests</string>
|
||||
</attribute>
|
||||
<layout class="QHBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="XcaTreeView" name="reqView"/>
|
||||
<widget class="ReqTreeView" name="reqView"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="reqButtons">
|
||||
@ -157,9 +145,6 @@
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
@ -237,14 +222,11 @@
|
||||
<string>Certificates</string>
|
||||
</attribute>
|
||||
<layout class="QHBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="XcaTreeView" name="certView"/>
|
||||
<widget class="CertTreeView" name="certView"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="certButtons">
|
||||
@ -255,9 +237,6 @@
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>11</number>
|
||||
</property>
|
||||
@ -356,14 +335,11 @@
|
||||
<string>Templates</string>
|
||||
</attribute>
|
||||
<layout class="QHBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="XcaTreeView" name="tempView">
|
||||
<widget class="TempTreeView" name="tempView">
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
@ -378,9 +354,6 @@
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>11</number>
|
||||
</property>
|
||||
@ -458,12 +431,6 @@
|
||||
<string>Revocation lists</string>
|
||||
</attribute>
|
||||
<layout class="QHBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="XcaTreeView" name="crlView"/>
|
||||
</item>
|
||||
@ -476,12 +443,6 @@
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="BNexportCrl">
|
||||
<property name="text">
|
||||
@ -554,8 +515,489 @@
|
||||
<class>XcaTreeView</class>
|
||||
<extends>QTreeView</extends>
|
||||
<header>widgets/XcaTreeView.h</header>
|
||||
<slots>
|
||||
<slot>newItem()</slot>
|
||||
<slot>load()</slot>
|
||||
<slot>storeItems()</slot>
|
||||
<slot>showItems()</slot>
|
||||
<slot>deleteItems()</slot>
|
||||
</slots>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>KeyTreeView</class>
|
||||
<extends>QTreeView</extends>
|
||||
<header>widgets/KeyTreeView.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>TempTreeView</class>
|
||||
<extends>QTreeView</extends>
|
||||
<header>widgets/TempTreeView.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ReqTreeView</class>
|
||||
<extends>QTreeView</extends>
|
||||
<header>widgets/ReqTreeView.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>CertTreeView</class>
|
||||
<extends>QTreeView</extends>
|
||||
<header>widgets/CertTreeView.h</header>
|
||||
<slots>
|
||||
<slot>loadPKCS12()</slot>
|
||||
<slot>loadPKCS7()</slot>
|
||||
<slot>changeView()</slot>
|
||||
</slots>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>BNimportKey</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>keyView</receiver>
|
||||
<slot>load()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>505</x>
|
||||
<y>129</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>382</x>
|
||||
<y>135</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>BNnewKey</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>keyView</receiver>
|
||||
<slot>newItem()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>488</x>
|
||||
<y>67</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>392</x>
|
||||
<y>67</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>BNexportKey</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>keyView</receiver>
|
||||
<slot>storeItems()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>526</x>
|
||||
<y>99</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>393</x>
|
||||
<y>99</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>BNdetailsKey</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>keyView</receiver>
|
||||
<slot>showItems()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>473</x>
|
||||
<y>200</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>405</x>
|
||||
<y>200</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>BNdeleteKey</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>keyView</receiver>
|
||||
<slot>deleteItems()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>470</x>
|
||||
<y>229</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>404</x>
|
||||
<y>230</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>BNnewReq</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>reqView</receiver>
|
||||
<slot>newItem()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>496</x>
|
||||
<y>57</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>371</x>
|
||||
<y>58</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>BNexportReq</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>reqView</receiver>
|
||||
<slot>storeItems()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>489</x>
|
||||
<y>91</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>400</x>
|
||||
<y>95</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>BNimportReq</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>reqView</receiver>
|
||||
<slot>load()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>500</x>
|
||||
<y>123</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>412</x>
|
||||
<y>130</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>BNdetailsReq</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>reqView</receiver>
|
||||
<slot>showItems()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>497</x>
|
||||
<y>157</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>419</x>
|
||||
<y>166</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>BNdeleteReq</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>reqView</receiver>
|
||||
<slot>deleteItems()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>475</x>
|
||||
<y>196</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>399</x>
|
||||
<y>196</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>BNnewCert</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>certView</receiver>
|
||||
<slot>newItem()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>478</x>
|
||||
<y>63</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>398</x>
|
||||
<y>63</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>BNexportCert</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>certView</receiver>
|
||||
<slot>storeItems()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>499</x>
|
||||
<y>97</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>401</x>
|
||||
<y>99</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>BNimportCert</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>certView</receiver>
|
||||
<slot>load()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>475</x>
|
||||
<y>127</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>401</x>
|
||||
<y>128</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>BNdetailsCert</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>certView</receiver>
|
||||
<slot>showItems()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>486</x>
|
||||
<y>162</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>395</x>
|
||||
<y>165</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>BNdeleteCert</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>certView</receiver>
|
||||
<slot>deleteItems()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>482</x>
|
||||
<y>203</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>357</x>
|
||||
<y>207</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>BNnewTemp</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>tempView</receiver>
|
||||
<slot>newItem()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>513</x>
|
||||
<y>60</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>363</x>
|
||||
<y>62</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>BNchangeTemp</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>tempView</receiver>
|
||||
<slot>showItems()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>481</x>
|
||||
<y>94</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>415</x>
|
||||
<y>97</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>BNdeleteTemp</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>tempView</receiver>
|
||||
<slot>deleteItems()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>482</x>
|
||||
<y>126</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>428</x>
|
||||
<y>126</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>BNimportTemp</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>tempView</receiver>
|
||||
<slot>load()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>487</x>
|
||||
<y>165</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>407</x>
|
||||
<y>165</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>BNexportTemp</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>tempView</receiver>
|
||||
<slot>storeItems()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>488</x>
|
||||
<y>201</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>428</x>
|
||||
<y>201</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>BNexportCrl</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>crlView</receiver>
|
||||
<slot>storeItems()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>472</x>
|
||||
<y>70</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>381</x>
|
||||
<y>70</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>BNimportCrl</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>crlView</receiver>
|
||||
<slot>load()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>496</x>
|
||||
<y>99</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>382</x>
|
||||
<y>99</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>BNdetailsCrl</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>crlView</receiver>
|
||||
<slot>showItems()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>477</x>
|
||||
<y>131</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>391</x>
|
||||
<y>131</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>BNdeleteCrl</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>crlView</receiver>
|
||||
<slot>deleteItems()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>471</x>
|
||||
<y>173</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>386</x>
|
||||
<y>172</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>BNimportPKCS12</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>certView</receiver>
|
||||
<slot>loadPKCS12()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>504</x>
|
||||
<y>239</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>420</x>
|
||||
<y>234</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>BNimportPKCS7</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>certView</receiver>
|
||||
<slot>loadPKCS7()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>544</x>
|
||||
<y>265</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>406</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>BNimportPFX</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>certView</receiver>
|
||||
<slot>loadPKCS12()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>483</x>
|
||||
<y>170</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>230</x>
|
||||
<y>263</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>BNviewState</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>certView</receiver>
|
||||
<slot>changeView()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>472</x>
|
||||
<y>304</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>402</x>
|
||||
<y>301</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
|
||||
@ -124,7 +124,7 @@
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Abort|QDialogButtonBox::Ok</set>
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
26
ui/Revoke.ui
26
ui/Revoke.ui
@ -164,8 +164,8 @@
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>236</x>
|
||||
<y>185</y>
|
||||
<x>242</x>
|
||||
<y>277</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
@ -180,12 +180,28 @@
|
||||
<slot>localTime(int)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>397</x>
|
||||
<y>122</y>
|
||||
<x>398</x>
|
||||
<y>194</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>389</x>
|
||||
<y>93</y>
|
||||
<y>167</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>Revoke</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>97</x>
|
||||
<y>268</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>109</x>
|
||||
<y>59</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
|
||||
198
widgets/CertTreeView.cpp
Normal file
198
widgets/CertTreeView.cpp
Normal file
@ -0,0 +1,198 @@
|
||||
/* vi: set sw=4 ts=4:
|
||||
*
|
||||
* Copyright (C) 2015 Christian Hohnstaedt.
|
||||
*
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#include "lib/pki_x509.h"
|
||||
#include "CertTreeView.h"
|
||||
#include "MainWindow.h"
|
||||
#include <QtCore/QAbstractItemModel>
|
||||
#include <QtGui/QAbstractItemView>
|
||||
#include <QtGui/QMenu>
|
||||
|
||||
void CertTreeView::fillContextMenu(QMenu *menu, QMenu *subExport,
|
||||
const QModelIndex &index, QModelIndexList indexes)
|
||||
{
|
||||
QMenu *subCa;
|
||||
bool parentCanSign, multi, hasScard, sameParent,
|
||||
allRevoked, allUnrevoked;
|
||||
pki_key *privkey;
|
||||
|
||||
X509SuperTreeView::fillContextMenu(menu, subExport, index, indexes);
|
||||
|
||||
menu->addAction(tr("Import PKCS#12"), this, SLOT(loadPKCS12()));
|
||||
menu->addAction(tr("Import from PKCS#7"), this, SLOT(loadPKCS7()));
|
||||
|
||||
if (indexes.size() == 0)
|
||||
return;
|
||||
|
||||
pki_x509 *cert = static_cast<pki_x509*>(index.internalPointer());
|
||||
pki_x509 *parent;
|
||||
|
||||
privkey = cert->getRefKey();
|
||||
parent = cert->getSigner();
|
||||
parentCanSign = parent && parent->canSign() && (parent != cert);
|
||||
hasScard = pkcs11::loaded();
|
||||
|
||||
multi = indexes.size() > 1;
|
||||
|
||||
allUnrevoked = allRevoked = sameParent = true;
|
||||
foreach(QModelIndex i, indexes) {
|
||||
pki_x509 *c = static_cast<pki_x509*>
|
||||
(i.internalPointer());
|
||||
if (c->getSigner() != parent)
|
||||
sameParent = false;
|
||||
if (c->isRevoked())
|
||||
allUnrevoked = false;
|
||||
else
|
||||
allRevoked = false;
|
||||
}
|
||||
|
||||
if (!multi) {
|
||||
transform->addAction(tr("Request"), this, SLOT(toRequest()))->
|
||||
setEnabled(privkey && privkey->isPrivKey());
|
||||
subExport->addAction(tr("Security token"), this,
|
||||
SLOT(toToken()))->setEnabled(hasScard);
|
||||
subExport->addAction(tr("Other token"), this,
|
||||
SLOT(toOtherToken()))->setEnabled(hasScard);
|
||||
|
||||
transform->addAction(tr("Similar Certificate"), this,
|
||||
SLOT(toCertificate()));
|
||||
|
||||
menu->addAction(tr("Delete from Security token"), this,
|
||||
SLOT(deleteFromToken()))->setEnabled(hasScard);
|
||||
|
||||
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(cert->canSign());
|
||||
}
|
||||
menu->addAction(tr("Trust"), this,
|
||||
SLOT(setTrust()))->setEnabled(allUnrevoked);
|
||||
if (sameParent && parentCanSign) {
|
||||
QString n = multi ? QString(" [%1]").arg(indexes.size()) : "";
|
||||
menu->addAction(tr("Renewal") +n, this, SLOT(certRenewal()));
|
||||
if (allUnrevoked)
|
||||
menu->addAction(tr("Revoke") +n, this, SLOT(revoke()));
|
||||
if (allRevoked)
|
||||
menu->addAction(tr("Unrevoke") +n, this,
|
||||
SLOT(unRevoke()));
|
||||
}
|
||||
}
|
||||
|
||||
void CertTreeView::changeView()
|
||||
{
|
||||
if (!certs)
|
||||
return;
|
||||
|
||||
db_x509 *c = certs;
|
||||
|
||||
hide();
|
||||
setModel();
|
||||
|
||||
c->changeView();
|
||||
|
||||
setModel(c);
|
||||
show();
|
||||
setRootIsDecorated(db_x509::treeview);
|
||||
}
|
||||
|
||||
void CertTreeView::toRequest()
|
||||
{
|
||||
if (certs)
|
||||
certs->toRequest(currentIndex());
|
||||
}
|
||||
|
||||
void CertTreeView::toToken()
|
||||
{
|
||||
if (certs)
|
||||
certs->toToken(currentIndex(), false);
|
||||
}
|
||||
|
||||
void CertTreeView::toOtherToken()
|
||||
{
|
||||
if (certs)
|
||||
certs->toToken(currentIndex(), true);
|
||||
}
|
||||
|
||||
void CertTreeView::loadPKCS12()
|
||||
{
|
||||
if (certs) {
|
||||
load_pkcs12 l;
|
||||
certs->load_default(l);
|
||||
}
|
||||
}
|
||||
|
||||
void CertTreeView::loadPKCS7()
|
||||
{
|
||||
if (certs) {
|
||||
load_pkcs7 l;
|
||||
certs->load_default(l);
|
||||
}
|
||||
}
|
||||
|
||||
void CertTreeView::genCrl()
|
||||
{
|
||||
pki_x509 *cert = static_cast<pki_x509*>
|
||||
(currentIndex().internalPointer());
|
||||
mainwin->crls->newItem(cert);
|
||||
}
|
||||
|
||||
void CertTreeView::toCertificate()
|
||||
{
|
||||
if (certs)
|
||||
certs->toCertificate(currentIndex());
|
||||
}
|
||||
|
||||
void CertTreeView::deleteFromToken()
|
||||
{
|
||||
pki_x509 *cert = static_cast<pki_x509*>
|
||||
(currentIndex().internalPointer());
|
||||
try {
|
||||
cert->deleteFromToken();
|
||||
} catch (errorEx &err) {
|
||||
mainwin->Error(err);
|
||||
}
|
||||
}
|
||||
|
||||
void CertTreeView::manageRevocations()
|
||||
{
|
||||
if (certs)
|
||||
certs->manageRevocations(currentIndex());
|
||||
}
|
||||
|
||||
void CertTreeView::caProperties()
|
||||
{
|
||||
if (certs)
|
||||
certs->caProperties(currentIndex());
|
||||
}
|
||||
|
||||
void CertTreeView::certRenewal()
|
||||
{
|
||||
if (certs)
|
||||
certs->certRenewal(getSelectedIndexes());
|
||||
}
|
||||
|
||||
void CertTreeView::revoke()
|
||||
{
|
||||
if (certs)
|
||||
certs->revoke(getSelectedIndexes());
|
||||
}
|
||||
|
||||
void CertTreeView::unRevoke()
|
||||
{
|
||||
if (certs)
|
||||
certs->unRevoke(getSelectedIndexes());
|
||||
}
|
||||
|
||||
void CertTreeView::setTrust()
|
||||
{
|
||||
if (certs)
|
||||
certs->setTrust(getSelectedIndexes());
|
||||
proxy->invalidate();
|
||||
}
|
||||
|
||||
49
widgets/CertTreeView.h
Normal file
49
widgets/CertTreeView.h
Normal file
@ -0,0 +1,49 @@
|
||||
/* vi: set sw=4 ts=4:
|
||||
*
|
||||
* Copyright (C) 2015 Christian Hohnstaedt.
|
||||
*
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __CERTTREEVIEW_H
|
||||
#define __CERTTREEVIEW_H
|
||||
|
||||
#include "X509SuperTreeView.h"
|
||||
#include "lib/db_x509.h"
|
||||
|
||||
class CertTreeView: public X509SuperTreeView
|
||||
{
|
||||
Q_OBJECT
|
||||
db_x509 *certs;
|
||||
|
||||
public:
|
||||
CertTreeView(QWidget *parent) : X509SuperTreeView(parent)
|
||||
{
|
||||
certs = NULL;
|
||||
}
|
||||
void fillContextMenu(QMenu *menu, QMenu *subExport,
|
||||
const QModelIndex &index, QModelIndexList indexes);
|
||||
void setModel(db_x509 *model=NULL)
|
||||
{
|
||||
certs = model;
|
||||
X509SuperTreeView::setModel(model);
|
||||
}
|
||||
|
||||
public slots:
|
||||
void changeView();
|
||||
void toRequest();
|
||||
void toCertificate();
|
||||
void toToken();
|
||||
void toOtherToken();
|
||||
void genCrl();
|
||||
void loadPKCS7();
|
||||
void loadPKCS12();
|
||||
void deleteFromToken();
|
||||
void manageRevocations();
|
||||
void certRenewal();
|
||||
void caProperties();
|
||||
void revoke();
|
||||
void unRevoke();
|
||||
void setTrust();
|
||||
};
|
||||
#endif
|
||||
@ -24,13 +24,16 @@ ExportDialog::ExportDialog(MainWindow *mw, QString title, QString filt,
|
||||
setupUi(this);
|
||||
mainwin = mw;
|
||||
setWindowTitle(XCA_TITLE);
|
||||
descr->setText(pki->getIntName());
|
||||
if (pki)
|
||||
descr->setText(pki->getIntName());
|
||||
descr->setReadOnly(true);
|
||||
image->setPixmap(*img);
|
||||
label->setText(title);
|
||||
QString fn = mainwin->getPath() + QDir::separator() +
|
||||
pki->getUnderlinedName() + "." + types[0].extension;
|
||||
filename->setText(fn);
|
||||
if (pki) {
|
||||
QString fn = mainwin->getPath() + QDir::separator() +
|
||||
pki->getUnderlinedName() + "." + types[0].extension;
|
||||
filename->setText(fn);
|
||||
}
|
||||
filter = filt + ";;" + tr("All files ( * )");
|
||||
|
||||
foreach(exportType t, types) {
|
||||
|
||||
158
widgets/KeyTreeView.cpp
Normal file
158
widgets/KeyTreeView.cpp
Normal file
@ -0,0 +1,158 @@
|
||||
/* vi: set sw=4 ts=4:
|
||||
*
|
||||
* Copyright (C) 2015 Christian Hohnstaedt.
|
||||
*
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#include "lib/pki_scard.h"
|
||||
#include "XcaTreeView.h"
|
||||
#include "MainWindow.h"
|
||||
#include <QtCore/QAbstractItemModel>
|
||||
#include <QtGui/QAbstractItemView>
|
||||
#include <QtGui/QMenu>
|
||||
|
||||
void KeyTreeView::fillContextMenu(QMenu *menu, QMenu *subExport,
|
||||
const QModelIndex &index, QModelIndexList indexes)
|
||||
{
|
||||
bool multi = indexes.size() > 1;
|
||||
|
||||
pki_key *key = static_cast<pki_key*>(index.internalPointer());
|
||||
|
||||
if (index == QModelIndex())
|
||||
return;
|
||||
|
||||
if (!multi && key && key->isPrivKey() && !key->isToken()) {
|
||||
switch (key->getOwnPass()) {
|
||||
case pki_key::ptCommon:
|
||||
menu->addAction(tr("Change password"), this,
|
||||
SLOT(setOwnPass()));
|
||||
break;
|
||||
case pki_key::ptPrivate:
|
||||
menu->addAction(tr("Reset password"), this,
|
||||
SLOT(resetOwnPass()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pkcs11::loaded() || multi)
|
||||
return;
|
||||
|
||||
if (key->isToken()) {
|
||||
menu->addAction(tr("Change PIN"), this,
|
||||
SLOT(changePin()));
|
||||
menu->addAction(tr("Init PIN with SO PIN (PUK)"), this,
|
||||
SLOT(initPin()));
|
||||
menu->addAction(tr("Change SO PIN (PUK)"), this,
|
||||
SLOT(changeSoPin()));
|
||||
} else {
|
||||
menu->addAction(tr("Store on Security token"),
|
||||
this, SLOT(toToken()));
|
||||
}
|
||||
}
|
||||
|
||||
void KeyTreeView::setOwnPass()
|
||||
{
|
||||
try {
|
||||
keys->setOwnPass(currentIndex(), pki_key::ptPrivate);
|
||||
} catch (errorEx &err) {
|
||||
mainwin->Error(err);
|
||||
}
|
||||
}
|
||||
|
||||
void KeyTreeView::resetOwnPass()
|
||||
{
|
||||
try {
|
||||
keys->setOwnPass(currentIndex(), pki_key::ptCommon);
|
||||
} catch (errorEx &err) {
|
||||
mainwin->Error(err);
|
||||
}
|
||||
}
|
||||
|
||||
void KeyTreeView::changePin()
|
||||
{
|
||||
pki_scard *scard;
|
||||
QModelIndex currentIdx = currentIndex();
|
||||
|
||||
if (!currentIdx.isValid())
|
||||
return;
|
||||
scard = static_cast<pki_scard*>(currentIdx.internalPointer());
|
||||
try {
|
||||
if (!scard->isToken()) {
|
||||
throw errorEx(tr("Tried to change PIN of a key"));
|
||||
}
|
||||
scard->changePin();
|
||||
} catch (errorEx &err) {
|
||||
mainwin->Error(err);
|
||||
}
|
||||
}
|
||||
|
||||
void KeyTreeView::initPin()
|
||||
{
|
||||
pki_scard *scard;
|
||||
QModelIndex currentIdx = currentIndex();
|
||||
|
||||
if (!currentIdx.isValid())
|
||||
return;
|
||||
scard = static_cast<pki_scard*>(currentIdx.internalPointer());
|
||||
try {
|
||||
if (!scard->isToken()) {
|
||||
throw errorEx(tr("Tried to init PIN of a key"));
|
||||
}
|
||||
scard->initPin();
|
||||
} catch (errorEx &err) {
|
||||
mainwin->Error(err);
|
||||
}
|
||||
}
|
||||
|
||||
void KeyTreeView::changeSoPin()
|
||||
{
|
||||
pki_scard *scard;
|
||||
QModelIndex currentIdx = currentIndex();
|
||||
|
||||
if (!currentIdx.isValid())
|
||||
return;
|
||||
scard = static_cast<pki_scard*>(currentIdx.internalPointer());
|
||||
try {
|
||||
if (!scard->isToken()) {
|
||||
throw errorEx(tr("Tried to change SO PIN of a key"));
|
||||
}
|
||||
scard->changeSoPin();
|
||||
} catch (errorEx &err) {
|
||||
mainwin->Error(err);
|
||||
}
|
||||
}
|
||||
|
||||
void KeyTreeView::toToken()
|
||||
{
|
||||
QModelIndex currentIdx = currentIndex();
|
||||
|
||||
if (!currentIdx.isValid())
|
||||
return;
|
||||
|
||||
pki_key *key = static_cast<pki_scard*>(currentIdx.internalPointer());
|
||||
if (!key || !pkcs11::loaded() || key->isToken())
|
||||
return;
|
||||
|
||||
pki_scard *card = NULL;
|
||||
try {
|
||||
pkcs11 p11;
|
||||
slotid slot;
|
||||
|
||||
if (!p11.selectToken(&slot, mainwin))
|
||||
return;
|
||||
card = new pki_scard(key->getIntName());
|
||||
card->store_token(slot, key->decryptKey());
|
||||
QString msg = tr("Shall the original key '%1' be replaced by the key on the token?\nThis will delete the key '%1' and make it unexportable").
|
||||
arg(key->getIntName());
|
||||
if (XCA_YESNO(msg)) {
|
||||
keys->deletePKI(currentIdx);
|
||||
keys->insertPKI(card);
|
||||
card = NULL;
|
||||
}
|
||||
} catch (errorEx &err) {
|
||||
mainwin->Error(err);
|
||||
}
|
||||
if (card)
|
||||
delete card;
|
||||
}
|
||||
40
widgets/KeyTreeView.h
Normal file
40
widgets/KeyTreeView.h
Normal file
@ -0,0 +1,40 @@
|
||||
/* vi: set sw=4 ts=4:
|
||||
*
|
||||
* Copyright (C) 2006 - 2015 Christian Hohnstaedt.
|
||||
*
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __KEYTREEVIEW_H
|
||||
#define __KEYTREEVIEW_H
|
||||
|
||||
#include "XcaTreeView.h"
|
||||
#include "lib/db_key.h"
|
||||
|
||||
class KeyTreeView: public XcaTreeView
|
||||
{
|
||||
Q_OBJECT
|
||||
db_key *keys;
|
||||
|
||||
public:
|
||||
KeyTreeView(QWidget *parent) : XcaTreeView(parent)
|
||||
{
|
||||
keys = NULL;
|
||||
}
|
||||
void fillContextMenu(QMenu *menu, QMenu *subExport,
|
||||
const QModelIndex &index, QModelIndexList indexes);
|
||||
void setModel(db_key *model=NULL)
|
||||
{
|
||||
keys = model;
|
||||
XcaTreeView::setModel(model);
|
||||
}
|
||||
|
||||
public slots:
|
||||
void resetOwnPass();
|
||||
void setOwnPass();
|
||||
void changePin();
|
||||
void initPin();
|
||||
void changeSoPin();
|
||||
void toToken();
|
||||
};
|
||||
#endif
|
||||
@ -89,9 +89,9 @@ int MainWindow::init_database()
|
||||
|
||||
connect( reqs, SIGNAL(newCert(pki_x509req *)),
|
||||
certs, SLOT(newCert(pki_x509req *)) );
|
||||
connect( temps, SIGNAL(newCert(pki_temp *)),
|
||||
connect( tempView, SIGNAL(newCert(pki_temp *)),
|
||||
certs, SLOT(newCert(pki_temp *)) );
|
||||
connect( temps, SIGNAL(newReq(pki_temp *)),
|
||||
connect( tempView, SIGNAL(newReq(pki_temp *)),
|
||||
reqs, SLOT(newItem(pki_temp *)) );
|
||||
|
||||
keyView->setIconSize(pki_evp::icon[0]->size());
|
||||
@ -298,11 +298,11 @@ void MainWindow::close_database()
|
||||
statusBar()->removeWidget(searchEdit);
|
||||
dbindex->clear();
|
||||
|
||||
keyView->setModel(NULL);
|
||||
reqView->setModel(NULL);
|
||||
certView->setModel(NULL);
|
||||
tempView->setModel(NULL);
|
||||
crlView->setModel(NULL);
|
||||
keyView->setModel();
|
||||
reqView->setModel();
|
||||
certView->setModel();
|
||||
tempView->setModel();
|
||||
crlView->setModel();
|
||||
|
||||
if (crls)
|
||||
delete(crls);
|
||||
@ -406,188 +406,3 @@ void MainWindow::update_history(QString fname)
|
||||
file.close();
|
||||
update_history_menu();
|
||||
}
|
||||
|
||||
/* Asymetric Key buttons */
|
||||
void MainWindow::on_BNnewKey_clicked(void)
|
||||
{
|
||||
if (keys)
|
||||
keys->newItem();
|
||||
}
|
||||
void MainWindow::on_BNdeleteKey_clicked(void)
|
||||
{
|
||||
if (keys)
|
||||
keys->deleteSelectedItems(keyView);
|
||||
}
|
||||
void MainWindow::on_BNdetailsKey_clicked(void)
|
||||
{
|
||||
if (keys)
|
||||
keys->showSelectedItems(keyView);
|
||||
}
|
||||
void MainWindow::on_BNimportKey_clicked(void)
|
||||
{
|
||||
if (keys)
|
||||
keys->load();
|
||||
}
|
||||
void MainWindow::on_BNexportKey_clicked(void)
|
||||
{
|
||||
if (keys)
|
||||
keys->storeSelectedItems(keyView);
|
||||
}
|
||||
|
||||
void MainWindow::on_keyView_doubleClicked(const QModelIndex &m)
|
||||
{
|
||||
if (keys)
|
||||
keys->showItem(keyView->getIndex(m));
|
||||
}
|
||||
|
||||
void MainWindow::on_reqView_doubleClicked(const QModelIndex &m)
|
||||
{
|
||||
if (reqs)
|
||||
reqs->showItem(reqView->getIndex(m));
|
||||
}
|
||||
|
||||
void MainWindow::on_certView_doubleClicked(const QModelIndex &m)
|
||||
{
|
||||
if (certs)
|
||||
certs->showItem(certView->getIndex(m));
|
||||
}
|
||||
|
||||
void MainWindow::on_tempView_doubleClicked(const QModelIndex &m)
|
||||
{
|
||||
if (temps)
|
||||
temps->showItem(tempView->getIndex(m));
|
||||
}
|
||||
|
||||
void MainWindow::on_crlView_doubleClicked(const QModelIndex &m)
|
||||
{
|
||||
if (crls)
|
||||
crls->showItem(crlView->getIndex(m));
|
||||
}
|
||||
|
||||
void MainWindow::on_BNimportPFX_clicked(void)
|
||||
{
|
||||
if (certs)
|
||||
certs->loadPKCS12();
|
||||
}
|
||||
|
||||
/* Certificate request buttons */
|
||||
void MainWindow::on_BNnewReq_clicked(void)
|
||||
{
|
||||
if (reqs)
|
||||
reqs->newItem();
|
||||
}
|
||||
void MainWindow::on_BNdeleteReq_clicked(void)
|
||||
{
|
||||
if (reqs)
|
||||
reqs->deleteSelectedItems(reqView);
|
||||
}
|
||||
void MainWindow::on_BNdetailsReq_clicked(void)
|
||||
{
|
||||
if (reqs)
|
||||
reqs->showSelectedItems(reqView);
|
||||
}
|
||||
void MainWindow::on_BNimportReq_clicked(void)
|
||||
{
|
||||
if (reqs)
|
||||
reqs->load();
|
||||
}
|
||||
void MainWindow::on_BNexportReq_clicked(void)
|
||||
{
|
||||
if(reqs)
|
||||
reqs->storeSelectedItems(reqView);
|
||||
}
|
||||
|
||||
/* Certificate buttons */
|
||||
void MainWindow::on_BNnewCert_clicked(void)
|
||||
{
|
||||
if (certs)
|
||||
certs->newItem();
|
||||
}
|
||||
void MainWindow::on_BNdeleteCert_clicked(void)
|
||||
{
|
||||
if (certs)
|
||||
certs->deleteSelectedItems(certView);
|
||||
}
|
||||
void MainWindow::on_BNdetailsCert_clicked(void)
|
||||
{
|
||||
if (certs)
|
||||
certs->showSelectedItems(certView);
|
||||
}
|
||||
void MainWindow::on_BNimportCert_clicked(void)
|
||||
{
|
||||
if (certs)
|
||||
certs->load();
|
||||
}
|
||||
void MainWindow::on_BNexportCert_clicked(void)
|
||||
{
|
||||
if(certs)
|
||||
certs->storeSelectedItems(certView);
|
||||
}
|
||||
|
||||
void MainWindow::on_BNimportPKCS12_clicked(void)
|
||||
{
|
||||
if(certs)
|
||||
certs->loadPKCS12();
|
||||
}
|
||||
|
||||
void MainWindow::on_BNimportPKCS7_clicked(void)
|
||||
{
|
||||
if(certs)
|
||||
certs->loadPKCS7();
|
||||
}
|
||||
|
||||
void MainWindow::on_BNviewState_clicked(void)
|
||||
{
|
||||
if(certs)
|
||||
certs->changeView();
|
||||
certView->setRootIsDecorated(db_x509::treeview);
|
||||
}
|
||||
|
||||
/* Template buttons */
|
||||
void MainWindow::on_BNdeleteTemp_clicked(void)
|
||||
{
|
||||
if (temps)
|
||||
temps->deleteSelectedItems(tempView);
|
||||
}
|
||||
void MainWindow::on_BNchangeTemp_clicked(void)
|
||||
{
|
||||
if (temps)
|
||||
temps->showSelectedItems(tempView);
|
||||
}
|
||||
void MainWindow::on_BNimportTemp_clicked(void)
|
||||
{
|
||||
if (temps)
|
||||
temps->load();
|
||||
}
|
||||
void MainWindow::on_BNexportTemp_clicked(void)
|
||||
{
|
||||
if(temps)
|
||||
temps->storeSelectedItems(tempView);
|
||||
}
|
||||
void MainWindow::on_BNnewTemp_clicked(void)
|
||||
{
|
||||
if (temps)
|
||||
temps->newItem();
|
||||
}
|
||||
|
||||
/* CRL buttons */
|
||||
void MainWindow::on_BNdeleteCrl_clicked(void)
|
||||
{
|
||||
if (crls)
|
||||
crls->deleteSelectedItems(crlView);
|
||||
}
|
||||
void MainWindow::on_BNimportCrl_clicked(void)
|
||||
{
|
||||
if (crls)
|
||||
crls->load();
|
||||
}
|
||||
void MainWindow::on_BNexportCrl_clicked(void)
|
||||
{
|
||||
if (crls)
|
||||
crls->storeSelectedItems(crlView);
|
||||
}
|
||||
void MainWindow::on_BNdetailsCrl_clicked(void)
|
||||
{
|
||||
if(crls)
|
||||
crls->showSelectedItems(crlView);
|
||||
}
|
||||
|
||||
@ -119,24 +119,15 @@ void MainWindow::init_menu()
|
||||
file->addAction(a);
|
||||
|
||||
import = menuBar()->addMenu(tr("I&mport"));
|
||||
import->addAction(tr("Keys"), this,
|
||||
SLOT(on_BNimportKey_clicked()) );
|
||||
import->addAction(tr("Requests"), this,
|
||||
SLOT(on_BNimportReq_clicked()) );
|
||||
import->addAction(tr("Certificates"), this,
|
||||
SLOT(on_BNimportCert_clicked()) );
|
||||
import->addAction(tr("PKCS#12"), this,
|
||||
SLOT(on_BNimportPKCS12_clicked()) );
|
||||
import->addAction(tr("PKCS#7"), this,
|
||||
SLOT(on_BNimportPKCS7_clicked()) );
|
||||
import->addAction(tr("Template"), this,
|
||||
SLOT(on_BNimportTemp_clicked()) );
|
||||
import->addAction(tr("Revocation list"), this,
|
||||
SLOT(on_BNimportCrl_clicked()) );
|
||||
import->addAction(tr("PEM file"), this,
|
||||
SLOT(loadPem()) );
|
||||
import->addAction(tr("paste PEM file"), this,
|
||||
SLOT(pastePem()) );
|
||||
import->addAction(tr("Keys"), keyView, SLOT(load()) );
|
||||
import->addAction(tr("Requests"), reqView, SLOT(load()) );
|
||||
import->addAction(tr("Certificates"), certView, SLOT(load()) );
|
||||
import->addAction(tr("PKCS#12"), certView, SLOT(loadPKCS12()) );
|
||||
import->addAction(tr("PKCS#7"), certView, SLOT(loadPKCS7()) );
|
||||
import->addAction(tr("Template"), tempView, SLOT(load()) );
|
||||
import->addAction(tr("Revocation list"), crlView, SLOT(load()));
|
||||
import->addAction(tr("PEM file"), this, SLOT(loadPem()) );
|
||||
import->addAction(tr("paste PEM file"), this, SLOT(pastePem()));
|
||||
|
||||
token = menuBar()->addMenu(tr("&Token"));
|
||||
token->addAction(tr("&Manage Security token"), this,
|
||||
|
||||
@ -139,22 +139,11 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
|
||||
searchEdit = new QLineEdit();
|
||||
|
||||
connect(searchEdit, SIGNAL(textChanged(const QString &)),
|
||||
keyView, SLOT(setFilter(const QString&)));
|
||||
connect(searchEdit, SIGNAL(textChanged(const QString &)),
|
||||
reqView, SLOT(setFilter(const QString&)));
|
||||
connect(searchEdit, SIGNAL(textChanged(const QString &)),
|
||||
certView, SLOT(setFilter(const QString&)));
|
||||
connect(searchEdit, SIGNAL(textChanged(const QString &)),
|
||||
tempView, SLOT(setFilter(const QString&)));
|
||||
connect(searchEdit, SIGNAL(textChanged(const QString &)),
|
||||
crlView, SLOT(setFilter(const QString&)));
|
||||
|
||||
keyView->setModel(keys);
|
||||
reqView->setModel(reqs);
|
||||
certView->setModel(certs);
|
||||
tempView->setModel(temps);
|
||||
crlView->setModel(crls);
|
||||
keyView->setMainwin(this, searchEdit);
|
||||
reqView->setMainwin(this, searchEdit);
|
||||
certView->setMainwin(this, searchEdit);
|
||||
tempView->setMainwin(this, searchEdit);
|
||||
crlView->setMainwin(this, searchEdit);
|
||||
}
|
||||
|
||||
void MainWindow::dropEvent(QDropEvent *event)
|
||||
|
||||
@ -168,44 +168,5 @@ class MainWindow: public QMainWindow, public Ui::MainWindow
|
||||
void initPin();
|
||||
void generateDHparam();
|
||||
void open_database(QAction* a);
|
||||
|
||||
void on_keyView_doubleClicked(const QModelIndex &m);
|
||||
void on_reqView_doubleClicked(const QModelIndex &m);
|
||||
void on_certView_doubleClicked(const QModelIndex &m);
|
||||
void on_tempView_doubleClicked(const QModelIndex &m);
|
||||
void on_crlView_doubleClicked(const QModelIndex &m);
|
||||
|
||||
void on_BNnewKey_clicked();
|
||||
void on_BNdeleteKey_clicked();
|
||||
void on_BNdetailsKey_clicked();
|
||||
void on_BNimportKey_clicked();
|
||||
void on_BNexportKey_clicked();
|
||||
void on_BNimportPFX_clicked();
|
||||
|
||||
void on_BNnewReq_clicked();
|
||||
void on_BNdeleteReq_clicked();
|
||||
void on_BNdetailsReq_clicked();
|
||||
void on_BNimportReq_clicked();
|
||||
void on_BNexportReq_clicked();
|
||||
|
||||
void on_BNnewCert_clicked();
|
||||
void on_BNdeleteCert_clicked();
|
||||
void on_BNdetailsCert_clicked();
|
||||
void on_BNimportCert_clicked();
|
||||
void on_BNexportCert_clicked();
|
||||
void on_BNimportPKCS12_clicked();
|
||||
void on_BNimportPKCS7_clicked();
|
||||
void on_BNviewState_clicked();
|
||||
|
||||
void on_BNnewTemp_clicked();
|
||||
void on_BNdeleteTemp_clicked();
|
||||
void on_BNchangeTemp_clicked();
|
||||
void on_BNimportTemp_clicked();
|
||||
void on_BNexportTemp_clicked();
|
||||
|
||||
void on_BNdeleteCrl_clicked();
|
||||
void on_BNdetailsCrl_clicked();
|
||||
void on_BNimportCrl_clicked();
|
||||
void on_BNexportCrl_clicked();
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -7,7 +7,8 @@ endif
|
||||
MOC_NAMES=MainWindow KeyDetail clicklabel XcaTreeView NewX509 \
|
||||
validity v3ext distname CertDetail CertExtend PwDialog \
|
||||
ImportMulti CrlDetail ExportDialog hashBox Options NewKey kvView \
|
||||
NewCrl SearchPkcs11 RevocationList
|
||||
NewCrl SearchPkcs11 RevocationList XcaProxyModel XcaHeaderView \
|
||||
KeyTreeView TempTreeView ReqTreeView X509SuperTreeView CertTreeView
|
||||
|
||||
NAMES=$(MOC_NAMES) NewX509_ext MW_menu MW_help MW_database
|
||||
OBJS=$(patsubst %,moc_%.o,$(MOC_NAMES)) $(patsubst %,%.o,$(NAMES))
|
||||
|
||||
40
widgets/ReqTreeView.cpp
Normal file
40
widgets/ReqTreeView.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
/* vi: set sw=4 ts=4:
|
||||
*
|
||||
* Copyright (C) 2015 Christian Hohnstaedt.
|
||||
*
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#include "lib/pki_x509req.h"
|
||||
#include "ReqTreeView.h"
|
||||
#include "MainWindow.h"
|
||||
#include <QtCore/QAbstractItemModel>
|
||||
#include <QtGui/QAbstractItemView>
|
||||
#include <QtGui/QMenu>
|
||||
|
||||
void ReqTreeView::fillContextMenu(QMenu *menu, QMenu *subExport,
|
||||
const QModelIndex &index, QModelIndexList indexes)
|
||||
{
|
||||
X509SuperTreeView::fillContextMenu(menu, subExport, index, indexes);
|
||||
|
||||
if (indexes.size() != 1)
|
||||
return;
|
||||
|
||||
menu->addAction(tr("Sign"), this, SLOT(signReq()));
|
||||
if (transform) {
|
||||
transform->addAction(tr("Similar Request"), this,
|
||||
SLOT(toRequest()));
|
||||
}
|
||||
}
|
||||
|
||||
void ReqTreeView::toRequest()
|
||||
{
|
||||
if (reqs)
|
||||
reqs->toRequest(currentIndex());
|
||||
}
|
||||
|
||||
void ReqTreeView::signReq()
|
||||
{
|
||||
if (reqs)
|
||||
reqs->signReq(currentIndex());
|
||||
}
|
||||
36
widgets/ReqTreeView.h
Normal file
36
widgets/ReqTreeView.h
Normal file
@ -0,0 +1,36 @@
|
||||
/* vi: set sw=4 ts=4:
|
||||
*
|
||||
* Copyright (C) 2015 Christian Hohnstaedt.
|
||||
*
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __REQTREEVIEW_H
|
||||
#define __REQTREEVIEW_H
|
||||
|
||||
#include "X509SuperTreeView.h"
|
||||
#include "lib/db_x509req.h"
|
||||
|
||||
class ReqTreeView: public X509SuperTreeView
|
||||
{
|
||||
Q_OBJECT
|
||||
db_x509req *reqs;
|
||||
|
||||
public:
|
||||
ReqTreeView(QWidget *parent) : X509SuperTreeView(parent)
|
||||
{
|
||||
reqs = NULL;
|
||||
}
|
||||
void fillContextMenu(QMenu *menu, QMenu *subExport,
|
||||
const QModelIndex &index, QModelIndexList indexes);
|
||||
void setModel(db_x509req *model=NULL)
|
||||
{
|
||||
reqs = model;
|
||||
X509SuperTreeView::setModel(model);
|
||||
}
|
||||
|
||||
public slots:
|
||||
void toRequest();
|
||||
void signReq();
|
||||
};
|
||||
#endif
|
||||
@ -10,22 +10,50 @@
|
||||
#include "lib/asn1int.h"
|
||||
#include "lib/pki_x509.h"
|
||||
|
||||
enum revCol { Cserial, Cdate, Creason, CiDate };
|
||||
enum revCol { Cnumber, Cserial, Cdate, Creason, CiDate };
|
||||
|
||||
class revListItem : public QTreeWidgetItem
|
||||
{
|
||||
public:
|
||||
revListItem(QTreeWidget *w) : QTreeWidgetItem(w) { };
|
||||
bool operator < (const QTreeWidgetItem &other) const
|
||||
{
|
||||
int col = treeWidget()->sortColumn();
|
||||
switch (col) {
|
||||
case Cserial: {
|
||||
a1int ithis, iother;
|
||||
ithis.setHex(text(Cserial));
|
||||
iother.setHex(other.text(Cserial));
|
||||
return ithis < iother;
|
||||
}
|
||||
case Cnumber:
|
||||
return text(Cnumber).toLong() <
|
||||
other.text(Cnumber).toLong();
|
||||
default:
|
||||
return QTreeWidgetItem::operator < (other);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static void addRevItem(QTreeWidget *certList, const x509rev &revit,
|
||||
const pki_x509 *iss)
|
||||
int no, const pki_x509 *iss)
|
||||
{
|
||||
QTreeWidgetItem *current;
|
||||
revListItem *current;
|
||||
pki_x509 *rev;
|
||||
a1time a;
|
||||
rev = iss->getBySerial(revit.getSerial());
|
||||
current = new QTreeWidgetItem(certList);
|
||||
current = new revListItem(certList);
|
||||
if (rev != NULL) {
|
||||
current->setToolTip(Cserial, rev->getIntName() );
|
||||
}
|
||||
current->setText(Cserial, revit.getSerial().toHex()) ;
|
||||
current->setText(Cnumber, QString("%1").arg(no));
|
||||
current->setText(Cserial, revit.getSerial().toHex());
|
||||
current->setText(Cdate, revit.getDate().toSortable());
|
||||
current->setText(Creason, revit.getReason());
|
||||
|
||||
current->setTextAlignment(Cnumber, Qt::AlignRight);
|
||||
current->setTextAlignment(Cserial, Qt::AlignRight);
|
||||
|
||||
a = revit.getInvalDate();
|
||||
if (!a.isUndefined())
|
||||
current->setText(CiDate, a.toSortable());
|
||||
@ -39,7 +67,7 @@ void RevocationList::setupRevocationView(QTreeWidget *certList,
|
||||
|
||||
certList->clear();
|
||||
|
||||
sl << tr("Serial") << tr("Revocation") << tr("Reason") <<
|
||||
sl << tr("No.") << tr("Serial") << tr("Revocation") << tr("Reason") <<
|
||||
tr("Invalidation");
|
||||
|
||||
cols = sl.size();
|
||||
@ -47,9 +75,11 @@ void RevocationList::setupRevocationView(QTreeWidget *certList,
|
||||
certList->setHeaderLabels(sl);
|
||||
certList->setItemsExpandable(false);
|
||||
certList->setRootIsDecorated(false);
|
||||
certList->sortItems(Cnumber, Qt::AscendingOrder);
|
||||
|
||||
i=1;
|
||||
foreach(x509rev revit, revList) {
|
||||
addRevItem(certList, revit, iss);
|
||||
addRevItem(certList, revit, i++, iss);
|
||||
}
|
||||
for (i=0; i<cols; i++)
|
||||
certList->resizeColumnToContents(i);
|
||||
@ -88,11 +118,11 @@ const x509revList &RevocationList::getRevList()
|
||||
|
||||
void RevocationList::on_addRev_clicked(void)
|
||||
{
|
||||
Revocation *revoke = new Revocation(this, NULL);
|
||||
Revocation *revoke = new Revocation(this, QModelIndexList());
|
||||
if (revoke->exec()) {
|
||||
x509rev revit = revoke->getRevocation();
|
||||
revList << revit;
|
||||
addRevItem(certList, revit, issuer);
|
||||
addRevItem(certList, revit, revList.size(), issuer);
|
||||
}
|
||||
}
|
||||
|
||||
@ -114,14 +144,32 @@ void RevocationList::on_delRev_clicked(void)
|
||||
revList.takeAt(idx);
|
||||
}
|
||||
|
||||
Revocation::Revocation(QWidget *w, pki_x509 *r) : QDialog(w)
|
||||
Revocation::Revocation(QWidget *w, QModelIndexList indexes) : QDialog(w)
|
||||
{
|
||||
setupUi(this);
|
||||
setWindowTitle(XCA_TITLE);
|
||||
reason->addItems(x509rev::crlreasons());
|
||||
invalid->setNow();
|
||||
if (r) {
|
||||
serial->setText(r->getSerial().toHex());
|
||||
|
||||
if (indexes.size() > 1) {
|
||||
QList<a1int> serials;
|
||||
QStringList sl;
|
||||
serial->setText(QString("Batch revocation of %1 Certificates").
|
||||
arg(indexes.size()));
|
||||
foreach(QModelIndex idx, indexes) {
|
||||
pki_x509 *cert = static_cast<pki_x509*>
|
||||
(idx.internalPointer());
|
||||
serials << cert->getSerial();
|
||||
}
|
||||
qSort(serials.begin(), serials.end());
|
||||
foreach(a1int a, serials)
|
||||
sl << a.toHex();
|
||||
serial->setToolTip(sl.join("\n"));
|
||||
serial->setEnabled(false);
|
||||
} else if (indexes.size() == 1) {
|
||||
pki_x509 *cert = static_cast<pki_x509*>
|
||||
(indexes[0].internalPointer());
|
||||
serial->setText(cert->getSerial().toHex());
|
||||
serial->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
#include "ui_RevocationList.h"
|
||||
#include "ui_Revoke.h"
|
||||
#include "lib/x509rev.h"
|
||||
#include <QtCore/QModelIndex>
|
||||
|
||||
class pki_x509;
|
||||
|
||||
@ -42,7 +43,7 @@ class Revocation: public QDialog, public Ui::Revoke
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Revocation(QWidget *w, pki_x509 *r);
|
||||
Revocation(QWidget *w, QModelIndexList indexes);
|
||||
x509rev getRevocation();
|
||||
};
|
||||
#endif
|
||||
|
||||
55
widgets/TempTreeView.cpp
Normal file
55
widgets/TempTreeView.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
/* vi: set sw=4 ts=4:
|
||||
*
|
||||
* Copyright (C) 2015 Christian Hohnstaedt.
|
||||
*
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#include "lib/pki_temp.h"
|
||||
#include "XcaTreeView.h"
|
||||
#include "MainWindow.h"
|
||||
#include <QtCore/QAbstractItemModel>
|
||||
#include <QtGui/QAbstractItemView>
|
||||
#include <QtGui/QMenu>
|
||||
|
||||
void TempTreeView::fillContextMenu(QMenu *menu, QMenu *subExport,
|
||||
const QModelIndex &index, QModelIndexList indexes)
|
||||
{
|
||||
if (indexes.size() != 1)
|
||||
return;
|
||||
menu->addAction(tr("Duplicate"), this, SLOT(duplicateTemp()));
|
||||
menu->addAction(tr("Create certificate"), this, SLOT(certFromTemp()));
|
||||
menu->addAction(tr("Create request"), this, SLOT(reqFromTemp()));
|
||||
}
|
||||
|
||||
void TempTreeView::duplicateTemp()
|
||||
{
|
||||
QModelIndex currentIdx = currentIndex();
|
||||
|
||||
if (!currentIdx.isValid())
|
||||
return;
|
||||
pki_temp *temp = static_cast<pki_temp*>(currentIdx.internalPointer());
|
||||
pki_temp *newtemp = new pki_temp(temp);
|
||||
newtemp->setIntName(newtemp->getIntName() + " " + tr("copy"));
|
||||
temps->insertPKI(newtemp);
|
||||
}
|
||||
|
||||
void TempTreeView::certFromTemp()
|
||||
{
|
||||
QModelIndex currentIdx = currentIndex();
|
||||
|
||||
if (!currentIdx.isValid())
|
||||
return;
|
||||
pki_temp *temp = static_cast<pki_temp*>(currentIdx.internalPointer());
|
||||
emit newCert(temp);
|
||||
}
|
||||
|
||||
void TempTreeView::reqFromTemp()
|
||||
{
|
||||
QModelIndex currentIdx = currentIndex();
|
||||
|
||||
if (!currentIdx.isValid())
|
||||
return;
|
||||
pki_temp *temp = static_cast<pki_temp*>(currentIdx.internalPointer());
|
||||
emit newReq(temp);
|
||||
}
|
||||
40
widgets/TempTreeView.h
Normal file
40
widgets/TempTreeView.h
Normal file
@ -0,0 +1,40 @@
|
||||
/* vi: set sw=4 ts=4:
|
||||
*
|
||||
* Copyright (C) 2006 - 2015 Christian Hohnstaedt.
|
||||
*
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __TEMPTREEVIEW_H
|
||||
#define __TEMPTREEVIEW_H
|
||||
|
||||
#include "XcaTreeView.h"
|
||||
#include "lib/db_temp.h"
|
||||
|
||||
class TempTreeView: public XcaTreeView
|
||||
{
|
||||
Q_OBJECT
|
||||
db_temp *temps;
|
||||
|
||||
public:
|
||||
TempTreeView(QWidget *parent) : XcaTreeView(parent)
|
||||
{
|
||||
temps = NULL;
|
||||
}
|
||||
void fillContextMenu(QMenu *menu, QMenu *subExport,
|
||||
const QModelIndex &index, QModelIndexList indexes);
|
||||
void setModel(db_temp *model=NULL)
|
||||
{
|
||||
temps = model;
|
||||
XcaTreeView::setModel(model);
|
||||
}
|
||||
|
||||
public slots:
|
||||
void certFromTemp();
|
||||
void reqFromTemp();
|
||||
void duplicateTemp();
|
||||
signals:
|
||||
void newReq(pki_temp *);
|
||||
void newCert(pki_temp *);
|
||||
};
|
||||
#endif
|
||||
56
widgets/X509SuperTreeView.cpp
Normal file
56
widgets/X509SuperTreeView.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
/* vi: set sw=4 ts=4:
|
||||
*
|
||||
* Copyright (C) 2015 Christian Hohnstaedt.
|
||||
*
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#include "lib/pki_x509req.h"
|
||||
#include "X509SuperTreeView.h"
|
||||
#include "MainWindow.h"
|
||||
#include <QtCore/QAbstractItemModel>
|
||||
#include <QtGui/QAbstractItemView>
|
||||
#include <QtGui/QMenu>
|
||||
|
||||
void X509SuperTreeView::fillContextMenu(QMenu *menu, QMenu *subExport,
|
||||
const QModelIndex &index, QModelIndexList indexes)
|
||||
{
|
||||
pki_x509super *x = static_cast<pki_x509super *>
|
||||
(index.internalPointer());
|
||||
transform = NULL;
|
||||
|
||||
if (indexes.size() != 1)
|
||||
return;
|
||||
|
||||
subExport->addAction(tr("OpenSSL config"), this, SLOT(toOpenssl()));
|
||||
subExport->setEnabled(!x->isSpki());
|
||||
transform = menu->addMenu(tr("Transform"));
|
||||
transform->addAction(tr("Template"), this,
|
||||
SLOT(toTemplate()))->setEnabled(!x->isSpki());
|
||||
transform->addAction(tr("Public Key"), this,
|
||||
SLOT(extractPubkey()))->setEnabled(!x->getRefKey());
|
||||
}
|
||||
|
||||
void X509SuperTreeView::extractPubkey()
|
||||
{
|
||||
QModelIndex idx = currentIndex();
|
||||
|
||||
if (idx.isValid() && x509super)
|
||||
x509super->extractPubkey(idx);
|
||||
}
|
||||
|
||||
void X509SuperTreeView::toTemplate()
|
||||
{
|
||||
QModelIndex idx = currentIndex();
|
||||
|
||||
if (idx.isValid() && x509super)
|
||||
x509super->toTemplate(idx);
|
||||
}
|
||||
|
||||
void X509SuperTreeView::toOpenssl()
|
||||
{
|
||||
QModelIndex idx = currentIndex();
|
||||
|
||||
if (idx.isValid() && x509super)
|
||||
x509super->toOpenssl(idx);
|
||||
}
|
||||
38
widgets/X509SuperTreeView.h
Normal file
38
widgets/X509SuperTreeView.h
Normal file
@ -0,0 +1,38 @@
|
||||
/* vi: set sw=4 ts=4:
|
||||
*
|
||||
* Copyright (C) 2006 - 2015 Christian Hohnstaedt.
|
||||
*
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __X509SUPERTREEVIEW_H
|
||||
#define __X509SUPERTREEVIEW_H
|
||||
|
||||
#include "XcaTreeView.h"
|
||||
#include "lib/db_x509req.h"
|
||||
|
||||
class X509SuperTreeView: public XcaTreeView
|
||||
{
|
||||
Q_OBJECT
|
||||
db_x509super *x509super;
|
||||
|
||||
public:
|
||||
QMenu *transform;
|
||||
X509SuperTreeView(QWidget *parent) : XcaTreeView(parent)
|
||||
{
|
||||
x509super = NULL;
|
||||
}
|
||||
void fillContextMenu(QMenu *menu, QMenu *subExport,
|
||||
const QModelIndex &index, QModelIndexList indexes);
|
||||
void setModel(db_x509super *model=NULL)
|
||||
{
|
||||
x509super = model;
|
||||
XcaTreeView::setModel(model);
|
||||
}
|
||||
|
||||
public slots:
|
||||
void extractPubkey();
|
||||
void toTemplate();
|
||||
void toOpenssl();
|
||||
};
|
||||
#endif
|
||||
33
widgets/XcaHeaderView.cpp
Normal file
33
widgets/XcaHeaderView.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
/* vi: set sw=4 ts=4:
|
||||
*
|
||||
* Copyright (C) 2015 Christian Hohnstaedt.
|
||||
*
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#include "XcaHeaderView.h"
|
||||
#include "XcaTreeView.h"
|
||||
|
||||
XcaHeaderView::XcaHeaderView()
|
||||
:QHeaderView(Qt::Horizontal)
|
||||
{
|
||||
setMovable(true);
|
||||
}
|
||||
|
||||
void XcaHeaderView::contextMenuEvent(QContextMenuEvent *e)
|
||||
{
|
||||
XcaTreeView *tv = static_cast<XcaTreeView *>(parentWidget());
|
||||
if (tv)
|
||||
tv->headerEvent(e, logicalIndexAt(e->pos()));
|
||||
}
|
||||
|
||||
void XcaHeaderView::resetMoves()
|
||||
{
|
||||
for (int i=0; i<count(); i++) {
|
||||
if (i != visualIndex(i)) {
|
||||
moveSection(visualIndex(i), i);
|
||||
i=0;
|
||||
}
|
||||
}
|
||||
resizeSections(QHeaderView::ResizeToContents);
|
||||
}
|
||||
24
widgets/XcaHeaderView.h
Normal file
24
widgets/XcaHeaderView.h
Normal file
@ -0,0 +1,24 @@
|
||||
/* vi: set sw=4 ts=4:
|
||||
*
|
||||
* Copyright (C) 2015 Christian Hohnstaedt.
|
||||
*
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __XCAHEADERVIEW_H
|
||||
#define __XCAHEADERVIEW_H
|
||||
|
||||
#include <QtGui/QHeaderView>
|
||||
|
||||
class XcaHeaderView: public QHeaderView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
XcaHeaderView();
|
||||
void contextMenuEvent(QContextMenuEvent *e);
|
||||
|
||||
public slots:
|
||||
void resetMoves();
|
||||
};
|
||||
#endif
|
||||
62
widgets/XcaProxyModel.cpp
Normal file
62
widgets/XcaProxyModel.cpp
Normal file
@ -0,0 +1,62 @@
|
||||
/* vi: set sw=4 ts=4:
|
||||
*
|
||||
* Copyright (C) 2006 - 2015 Christian Hohnstaedt.
|
||||
*
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#include "XcaProxyModel.h"
|
||||
#include "lib/db_base.h"
|
||||
|
||||
bool XcaProxyModel::lessThan(const QModelIndex &left,
|
||||
const QModelIndex &right) const
|
||||
{
|
||||
db_base *db = (db_base *)sourceModel();
|
||||
if (!db)
|
||||
return QSortFilterProxyModel::lessThan(left, right);
|
||||
|
||||
if (db->isNumericCol(left.column()) &&
|
||||
db->isNumericCol(right.column()))
|
||||
{
|
||||
int diff;
|
||||
QString l = sourceModel()->data(left).toString();
|
||||
QString r = sourceModel()->data(right).toString();
|
||||
diff = l.size() - r.size();
|
||||
if (diff<0)
|
||||
return true;
|
||||
else if (diff>0)
|
||||
return false;
|
||||
else
|
||||
return l < r;
|
||||
}
|
||||
return QSortFilterProxyModel::lessThan(left, right);
|
||||
}
|
||||
|
||||
bool XcaProxyModel::filterAcceptsRow(int sourceRow,
|
||||
const QModelIndex &sourceParent) const
|
||||
{
|
||||
QModelIndex idx = sourceModel()->index(sourceRow, 0, sourceParent);
|
||||
return sourceModel()->data(idx, Qt::UserRole).toBool();
|
||||
}
|
||||
|
||||
QVariant XcaProxyModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
QModelIndex i;
|
||||
QString number;
|
||||
|
||||
if (index.column() != 1)
|
||||
return QSortFilterProxyModel::data(index, role);
|
||||
|
||||
/* Row number */
|
||||
switch (role) {
|
||||
case Qt::EditRole:
|
||||
case Qt::DisplayRole:
|
||||
for (i = index; i.isValid(); i = i.parent())
|
||||
number += QString(" %1").arg(i.row()+1);
|
||||
return QVariant(number);
|
||||
default:
|
||||
return QSortFilterProxyModel::data(index, role);
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
27
widgets/XcaProxyModel.h
Normal file
27
widgets/XcaProxyModel.h
Normal file
@ -0,0 +1,27 @@
|
||||
/* vi: set sw=4 ts=4:
|
||||
*
|
||||
* Copyright (C) 2006 - 2015 Christian Hohnstaedt.
|
||||
*
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __XCAPROXYMODEL_H
|
||||
#define __XCAPROXYMODEL_H
|
||||
|
||||
#include <QtGui/QWidget>
|
||||
#include <QtGui/QItemSelectionModel>
|
||||
#include <QtGui/QSortFilterProxyModel>
|
||||
|
||||
class XcaProxyModel: public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
XcaProxyModel(QWidget *parent = 0)
|
||||
:QSortFilterProxyModel(parent) { }
|
||||
bool lessThan(const QModelIndex &left, const QModelIndex &right) const;
|
||||
bool filterAcceptsRow(int sourceRow,
|
||||
const QModelIndex &sourceParent) const;
|
||||
QVariant data(const QModelIndex &index, int role) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -6,12 +6,14 @@
|
||||
*/
|
||||
|
||||
|
||||
#include "XcaHeaderView.h"
|
||||
#include "XcaTreeView.h"
|
||||
#include "lib/db_base.h"
|
||||
#include "XcaProxyModel.h"
|
||||
#include "MainWindow.h"
|
||||
#include <QtCore/QAbstractItemModel>
|
||||
#include <QtGui/QAbstractItemView>
|
||||
#include <QtGui/QHeaderView>
|
||||
#include <QtGui/QContextMenuEvent>
|
||||
#include <QtGui/QMenu>
|
||||
#include <QtCore/QVariant>
|
||||
#include <QtCore/QRegExp>
|
||||
|
||||
@ -19,6 +21,7 @@
|
||||
XcaTreeView::XcaTreeView(QWidget *parent)
|
||||
:QTreeView(parent)
|
||||
{
|
||||
mainwin = NULL;
|
||||
setHeader(new XcaHeaderView());
|
||||
setAlternatingRowColors(true);
|
||||
setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
@ -34,6 +37,8 @@ XcaTreeView::XcaTreeView(QWidget *parent)
|
||||
basemodel = NULL;
|
||||
connect(header(), SIGNAL(sectionHandleDoubleClicked(int)),
|
||||
this, SLOT(resizeColumnToContents(int)));
|
||||
connect(this, SIGNAL(doubleClicked(const QModelIndex &)),
|
||||
this, SLOT(doubleClick(const QModelIndex &)));
|
||||
header()->setClickable(true);
|
||||
}
|
||||
|
||||
@ -48,9 +53,7 @@ void XcaTreeView::contextMenuEvent(QContextMenuEvent * e)
|
||||
if (!basemodel)
|
||||
return;
|
||||
index = indexAt(e->pos());
|
||||
/* unselect all but the current on context menu */
|
||||
setCurrentIndex(index);
|
||||
basemodel->showContextMenu(e, getIndex(index));
|
||||
showContextMenu(e, getIndex(index));
|
||||
}
|
||||
|
||||
void XcaTreeView::showHideSections()
|
||||
@ -69,12 +72,18 @@ void XcaTreeView::showHideSections()
|
||||
columnsResize();
|
||||
}
|
||||
|
||||
void XcaTreeView::setMainwin(MainWindow *mw, QLineEdit *filter)
|
||||
{
|
||||
mainwin = mw;
|
||||
connect(filter, SIGNAL(textChanged(const QString &)),
|
||||
this, SLOT(setFilter(const QString&)));
|
||||
}
|
||||
|
||||
void XcaTreeView::setModel(QAbstractItemModel *model)
|
||||
{
|
||||
QByteArray ba;
|
||||
|
||||
basemodel = (db_base *)model;
|
||||
|
||||
proxy->setSourceModel(model);
|
||||
QTreeView::setModel(proxy);
|
||||
|
||||
@ -83,8 +92,6 @@ void XcaTreeView::setModel(QAbstractItemModel *model)
|
||||
header(), SLOT(resetMoves()));
|
||||
connect(basemodel, SIGNAL(resetHeader()),
|
||||
this, SLOT(columnsResize()));
|
||||
connect(basemodel, SIGNAL(updateHeader()),
|
||||
this, SLOT(showHideSections()));
|
||||
connect(header(), SIGNAL(sectionMoved(int,int,int)),
|
||||
this, SLOT(sectionMoved(int,int,int)));
|
||||
connect(header(), SIGNAL(sectionResized(int,int,int)),
|
||||
@ -95,8 +102,6 @@ void XcaTreeView::setModel(QAbstractItemModel *model)
|
||||
this, SLOT(columnsResize()));
|
||||
connect(basemodel, SIGNAL(columnsContentChanged()),
|
||||
proxy, SLOT(invalidate()));
|
||||
connect(basemodel, SIGNAL(editItem(const QModelIndex &)),
|
||||
this, SLOT(editIdx(const QModelIndex &)));
|
||||
|
||||
basemodel->initHeaderView(header());
|
||||
}
|
||||
@ -105,7 +110,7 @@ void XcaTreeView::setModel(QAbstractItemModel *model)
|
||||
|
||||
void XcaTreeView::headerEvent(QContextMenuEvent *e, int col)
|
||||
{
|
||||
basemodel->showHeaderMenu(e, col);
|
||||
contextMenu(e, NULL, col);
|
||||
}
|
||||
|
||||
QModelIndex XcaTreeView::getIndex(const QModelIndex &index)
|
||||
@ -158,90 +163,216 @@ void XcaTreeView::sectionMoved(int, int, int)
|
||||
}
|
||||
}
|
||||
|
||||
void XcaTreeView::editIdx(const QModelIndex &idx)
|
||||
QModelIndex XcaTreeView::currentIndex()
|
||||
{
|
||||
edit(proxy->mapFromSource(idx));
|
||||
QModelIndex idx = QTreeView::currentIndex();
|
||||
idx = getIndex(idx);
|
||||
idx = basemodel->index(idx.row(), 0, idx.parent());
|
||||
if (!idx.isValid()) {
|
||||
QModelIndexList l = getSelectedIndexes();
|
||||
if (l.size() > 0)
|
||||
idx = l[0];
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
void XcaTreeView::editIdx()
|
||||
{
|
||||
edit(getProxyIndex(currentIndex()));
|
||||
}
|
||||
|
||||
void XcaTreeView::setFilter(const QString &pattern)
|
||||
{
|
||||
pki_base::limitPattern = QRegExp(pattern,
|
||||
pki_base::limitPattern = QRegExp(pattern,
|
||||
Qt::CaseInsensitive, QRegExp::Wildcard);
|
||||
// Only to tell the model about the changed filter
|
||||
proxy->setFilterFixedString(pattern);
|
||||
proxy->setFilterFixedString(pattern);
|
||||
}
|
||||
|
||||
XcaProxyModel::XcaProxyModel(QWidget *parent)
|
||||
:QSortFilterProxyModel(parent)
|
||||
void XcaTreeView::deleteItems(void)
|
||||
{
|
||||
}
|
||||
QModelIndex index;
|
||||
QModelIndexList indexes = getSelectedIndexes();
|
||||
QString items, msg;
|
||||
int count = 0;
|
||||
pki_base *pki = NULL;
|
||||
|
||||
bool XcaProxyModel::lessThan(const QModelIndex &left,
|
||||
const QModelIndex &right) const
|
||||
{
|
||||
db_base *db = (db_base *)sourceModel();
|
||||
if (!db)
|
||||
return QSortFilterProxyModel::lessThan(left, right);
|
||||
if (indexes.count() == 0 || !basemodel)
|
||||
return;
|
||||
|
||||
if (db->isNumericCol(left.column()) &&
|
||||
db->isNumericCol(right.column()))
|
||||
{
|
||||
int diff;
|
||||
QString l = sourceModel()->data(left).toString();
|
||||
QString r = sourceModel()->data(right).toString();
|
||||
diff = l.size() - r.size();
|
||||
if (diff<0)
|
||||
return true;
|
||||
else if (diff>0)
|
||||
return false;
|
||||
else
|
||||
return l < r;
|
||||
foreach(index, indexes) {
|
||||
pki = static_cast<pki_base*>(index.internalPointer());
|
||||
items += "'" + pki->getIntName() + "' ";
|
||||
count++;
|
||||
}
|
||||
return QSortFilterProxyModel::lessThan(left, right);
|
||||
}
|
||||
|
||||
bool XcaProxyModel::filterAcceptsRow(int sourceRow,
|
||||
const QModelIndex &sourceParent) const
|
||||
{
|
||||
QModelIndex idx = sourceModel()->index(sourceRow, 0, sourceParent);
|
||||
return sourceModel()->data(idx, Qt::UserRole).toBool();
|
||||
}
|
||||
if (count == 1)
|
||||
msg = pki->getMsg(pki_base::msg_delete).arg(pki->getIntName());
|
||||
else
|
||||
msg = pki->getMsg(pki_base::msg_delete_multi).arg(count).
|
||||
arg(items);
|
||||
|
||||
QVariant XcaProxyModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
QModelIndex i;
|
||||
QString number;
|
||||
if (!XCA_OKCANCEL(msg))
|
||||
return;
|
||||
|
||||
if (index.column() != 1)
|
||||
return QSortFilterProxyModel::data(index, role);
|
||||
|
||||
/* Row number */
|
||||
switch (role) {
|
||||
case Qt::EditRole:
|
||||
case Qt::DisplayRole:
|
||||
for (i = index; i.isValid(); i = i.parent())
|
||||
number += QString(" %1").arg(i.row()+1);
|
||||
return QVariant(number);
|
||||
default:
|
||||
return QSortFilterProxyModel::data(index, role);
|
||||
foreach(index, indexes) {
|
||||
basemodel->deletePKI(index);
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void XcaHeaderView::contextMenuEvent(QContextMenuEvent * e)
|
||||
void XcaTreeView::storeItems(void)
|
||||
{
|
||||
XcaTreeView *tv = (XcaTreeView *)parentWidget();
|
||||
if (tv)
|
||||
tv->headerEvent(e, logicalIndexAt(e->pos()));
|
||||
}
|
||||
|
||||
void XcaHeaderView::resetMoves()
|
||||
{
|
||||
for (int i=0; i<count(); i++) {
|
||||
if (i != visualIndex(i)) {
|
||||
moveSection(visualIndex(i), i);
|
||||
i=0;
|
||||
QModelIndexList indexes = getSelectedIndexes();
|
||||
if (basemodel) {
|
||||
try {
|
||||
switch (indexes.size()) {
|
||||
case 0: return;
|
||||
case 1: basemodel->store(indexes[0]); return;
|
||||
default: basemodel->store(getSelectedIndexes());
|
||||
return;
|
||||
}
|
||||
} catch (errorEx &err) {
|
||||
MainWindow::Error(err);
|
||||
}
|
||||
}
|
||||
resizeSections(QHeaderView::ResizeToContents);
|
||||
}
|
||||
|
||||
void XcaTreeView::showItems(void)
|
||||
{
|
||||
if (basemodel) {
|
||||
QModelIndexList indexes = getSelectedIndexes();
|
||||
foreach(QModelIndex index, indexes)
|
||||
basemodel->showItem(index);
|
||||
}
|
||||
}
|
||||
|
||||
void XcaTreeView::newItem(void)
|
||||
{
|
||||
if (basemodel)
|
||||
basemodel->newItem();
|
||||
}
|
||||
|
||||
void XcaTreeView::load(void)
|
||||
{
|
||||
if (basemodel)
|
||||
basemodel->load();
|
||||
}
|
||||
|
||||
void XcaTreeView::doubleClick(const QModelIndex &m)
|
||||
{
|
||||
if (basemodel)
|
||||
basemodel->showItem(getIndex(m));
|
||||
}
|
||||
|
||||
void XcaTreeView::pem2clipboard(void)
|
||||
{
|
||||
if (basemodel)
|
||||
basemodel->pem2clipboard(getSelectedIndexes());
|
||||
}
|
||||
|
||||
void XcaTreeView::contextMenu(QContextMenuEvent *e, QMenu *parent, int)
|
||||
{
|
||||
int shown = 0;
|
||||
tipMenu *menu, *dn, *v3ext, *current, *v3ns;
|
||||
QAction *a, *sep;
|
||||
dbheader *hd;
|
||||
dbheaderList allHeaders = basemodel->getAllHeaders();
|
||||
|
||||
menu = new tipMenu(QString(), mainwin);
|
||||
dn = new tipMenu(tr("Subject entries"), mainwin);
|
||||
v3ext = new tipMenu(tr("X509v3 Extensions"), mainwin);
|
||||
v3ns = new tipMenu(tr("Netscape extensions"), mainwin);
|
||||
menu->addAction(tr("Reset"), basemodel, SLOT(columnResetDefaults()));
|
||||
sep = menu->addSeparator();
|
||||
foreach(hd, allHeaders) {
|
||||
switch (hd->type) {
|
||||
case dbheader::hd_x509name:
|
||||
current = dn;
|
||||
break;
|
||||
case dbheader::hd_v3ext:
|
||||
current = v3ext;
|
||||
break;
|
||||
case dbheader::hd_v3ext_ns:
|
||||
if (pki_x509::disable_netscape)
|
||||
continue;
|
||||
current = v3ns;
|
||||
break;
|
||||
default:
|
||||
current = menu;
|
||||
break;
|
||||
}
|
||||
a = current->addAction(hd->getName());
|
||||
a->setCheckable(true);
|
||||
a->setChecked(hd->show);
|
||||
a->setToolTip(hd->getTooltip());
|
||||
hd->action = a;
|
||||
}
|
||||
if (!dn->isEmpty() || !v3ext->isEmpty())
|
||||
menu->insertSeparator(sep);
|
||||
|
||||
if (!dn->isEmpty())
|
||||
menu->insertMenu(sep, dn);
|
||||
else
|
||||
delete dn;
|
||||
|
||||
if (!v3ext->isEmpty()) {
|
||||
if (!v3ns->isEmpty()) {
|
||||
v3ext->addSeparator();
|
||||
v3ext->addMenu(v3ns);
|
||||
} else {
|
||||
delete v3ns;
|
||||
}
|
||||
menu->insertMenu(sep, v3ext);
|
||||
} else {
|
||||
delete v3ext;
|
||||
delete v3ns;
|
||||
}
|
||||
if (parent) {
|
||||
parent->addSeparator();
|
||||
parent->addMenu(menu)->setText(tr("Columns"));
|
||||
parent->exec(e->globalPos());
|
||||
} else {
|
||||
menu->exec(e->globalPos());
|
||||
}
|
||||
foreach(hd, allHeaders) {
|
||||
if (hd->action)
|
||||
hd->show = hd->action->isChecked();
|
||||
shown += hd->show ? 1 : 0;
|
||||
hd->action = NULL;
|
||||
}
|
||||
if (!shown)
|
||||
allHeaders[0]->show = true;
|
||||
delete menu;
|
||||
if (parent)
|
||||
delete parent;
|
||||
showHideSections();
|
||||
}
|
||||
|
||||
void XcaTreeView::showContextMenu(QContextMenuEvent *e,
|
||||
const QModelIndex &idx)
|
||||
{
|
||||
QMenu *menu = new QMenu(mainwin);
|
||||
QMenu *subExport = NULL;
|
||||
QModelIndexList indexes = getSelectedIndexes();
|
||||
QModelIndex index;
|
||||
|
||||
index = idx.isValid() ? idx : currentIndex();
|
||||
menu->addAction(tr("New"), this, SLOT(newItem()));
|
||||
menu->addAction(tr("Import"), this, SLOT(load()));
|
||||
menu->addAction(tr("Paste PEM data"), mainwin, SLOT(pastePem()));
|
||||
|
||||
if (indexes.size() == 1)
|
||||
menu->addAction(tr("Rename"), this, SLOT(editIdx()));
|
||||
|
||||
if (indexes.size() > 0) {
|
||||
menu->addAction(tr("Delete"), this, SLOT(deleteItems()));
|
||||
subExport = menu->addMenu(tr("Export"));
|
||||
subExport->addAction(tr("Clipboard"), this,
|
||||
SLOT(pem2clipboard()));
|
||||
subExport->addAction(tr("File"), this, SLOT(storeItems()));
|
||||
}
|
||||
|
||||
fillContextMenu(menu, subExport, index, indexes);
|
||||
|
||||
contextMenu(e, menu);
|
||||
}
|
||||
|
||||
@ -8,27 +8,14 @@
|
||||
#ifndef __XCATREEVIEW_H
|
||||
#define __XCATREEVIEW_H
|
||||
|
||||
#include "lib/db_base.h"
|
||||
#include <QtGui/QTreeView>
|
||||
#include <QtGui/QItemSelectionModel>
|
||||
#include <QtGui/QSortFilterProxyModel>
|
||||
#include <QtGui/QHeaderView>
|
||||
#include "lib/db_base.h"
|
||||
|
||||
class db_base;
|
||||
|
||||
class XcaHeaderView: public QHeaderView
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
XcaHeaderView()
|
||||
:QHeaderView(Qt::Horizontal)
|
||||
{
|
||||
setMovable(true);
|
||||
}
|
||||
void contextMenuEvent(QContextMenuEvent *e);
|
||||
public slots:
|
||||
void resetMoves();
|
||||
};
|
||||
class MainWindow;
|
||||
class QLineEdit;
|
||||
|
||||
class XcaTreeView: public QTreeView
|
||||
{
|
||||
@ -36,33 +23,38 @@ class XcaTreeView: public QTreeView
|
||||
protected:
|
||||
db_base *basemodel;
|
||||
QSortFilterProxyModel *proxy;
|
||||
MainWindow *mainwin;
|
||||
|
||||
public:
|
||||
XcaTreeView(QWidget *parent = 0);
|
||||
~XcaTreeView();
|
||||
virtual ~XcaTreeView();
|
||||
void contextMenuEvent(QContextMenuEvent *e);
|
||||
void setModel(QAbstractItemModel *model);
|
||||
virtual void setModel(QAbstractItemModel *model=NULL);
|
||||
void setMainwin(MainWindow *mw, QLineEdit *filter);
|
||||
QModelIndex getIndex(const QModelIndex &index);
|
||||
QModelIndex getProxyIndex(const QModelIndex &index);
|
||||
QModelIndexList getSelectedIndexes();
|
||||
void headerEvent(QContextMenuEvent *e, int col);
|
||||
QModelIndex currentIndex();
|
||||
void showContextMenu(QContextMenuEvent *e,
|
||||
const QModelIndex &index);
|
||||
virtual void fillContextMenu(QMenu *menu, QMenu *subExport,
|
||||
const QModelIndex &index, QModelIndexList indexes) {}
|
||||
void contextMenu(QContextMenuEvent *e,
|
||||
QMenu *parent = NULL, int sect = -1);
|
||||
|
||||
public slots:
|
||||
void showHideSections();
|
||||
void sectionMoved(int idx, int oldI, int newI);
|
||||
void columnsResize();
|
||||
void editIdx(const QModelIndex &idx);
|
||||
void editIdx();
|
||||
void setFilter(const QString &pattern);
|
||||
void deleteItems(void);
|
||||
void storeItems(void);
|
||||
void showItems(void);
|
||||
void newItem(void);
|
||||
void doubleClick(const QModelIndex &m);
|
||||
void load(void);
|
||||
void pem2clipboard(void);
|
||||
};
|
||||
|
||||
class XcaProxyModel: public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
XcaProxyModel(QWidget *parent = 0);
|
||||
bool lessThan(const QModelIndex &left, const QModelIndex &right) const;
|
||||
bool filterAcceptsRow(int sourceRow,
|
||||
const QModelIndex &sourceParent) const;
|
||||
QVariant data(const QModelIndex &index, int role) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
18
xca.pro
18
xca.pro
@ -82,7 +82,14 @@ HEADERS += local.h \
|
||||
widgets/validity.h \
|
||||
widgets/SearchPkcs11.h \
|
||||
widgets/RevocationList.h \
|
||||
widgets/XcaTreeView.h
|
||||
widgets/XcaTreeView.h \
|
||||
widgets/CertTreeView.h \
|
||||
widgets/KeyTreeView.h \
|
||||
widgets/ReqTreeView.h \
|
||||
widgets/TempTreeView.h \
|
||||
widgets/X509SuperTreeView.h \
|
||||
widgets/XcaHeaderView.h \
|
||||
widgets/XcaProxyModel.h
|
||||
|
||||
FORMS += ui/About.ui \
|
||||
ui/CaProperties.ui \
|
||||
@ -168,6 +175,13 @@ SOURCES += lib/asn1int.cpp \
|
||||
widgets/validity.cpp \
|
||||
widgets/SearchPkcs11.cpp \
|
||||
widgets/RevocationList.cpp \
|
||||
widgets/XcaTreeView.cpp
|
||||
widgets/XcaTreeView.cpp \
|
||||
widgets/CertTreeView.cpp \
|
||||
widgets/KeyTreeView.cpp \
|
||||
widgets/ReqTreeView.cpp \
|
||||
widgets/TempTreeView.cpp \
|
||||
widgets/X509SuperTreeView.cpp \
|
||||
widgets/XcaHeaderView.cpp \
|
||||
widgets/XcaProxyModel.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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user