xca/widgets/ImportMulti.cpp
Christian Hohnstaedt 4b3ee2c705 Switch database format to SQL(ite)
This is a large squash of many small commits.

Allow porting data from the legacy format to SQL.
Store Binaries base64 encoded and use db->transaction
Update password hash to be 8000 x SHA512 with 8 byte Salt
Add revocations table and fixup CRL generation
Add comment and insertion date columns

Fix column saving, remove trust, add XcaDialog
Allow changing the internal name and comment in Cert/Req details view
Extend Comment functionality, Replace About.ui by XcaDialog.ui
2018-03-05 07:42:36 +01:00

360 lines
8.0 KiB
C++

/* vi: set sw=4 ts=4:
*
* Copyright (C) 2001 - 2014 Christian Hohnstaedt.
*
* All rights reserved.
*/
#include "ImportMulti.h"
#include "MainWindow.h"
#include "lib/pki_base.h"
#include "lib/pki_pkcs7.h"
#include "lib/pki_pkcs12.h"
#include "lib/pki_crl.h"
#include "lib/pki_multi.h"
#include "lib/pki_scard.h"
#include "lib/pki_evp.h"
#include "widgets/CrlDetail.h"
#include "widgets/CertDetail.h"
#include "widgets/KeyDetail.h"
#include <QPushButton>
#include <QMessageBox>
#include <QLabel>
#include <QInputDialog>
#include <QUrl>
#include <QMimeData>
ImportMulti::ImportMulti(MainWindow *parent)
:QDialog(parent)
{
mainwin = parent;
setupUi(this);
setWindowTitle(XCA_TITLE);
image->setPixmap(*MainWindow::certImg);
listView->setEditTriggers(QAbstractItemView::NoEditTriggers);
mcont = new db_token(parent);
listView->setModel(mcont);
listView->setIconSize(pki_evp::icon[0]->size());
listView->setSelectionMode(QAbstractItemView::ExtendedSelection);
connect( listView, SIGNAL(doubleClicked(const QModelIndex &)),
this, SLOT(on_butDetails_clicked()));
deleteToken->hide();
renameToken->hide();
slotInfo->hide();
setAcceptDrops(true);
}
void ImportMulti::tokenInfo(slotid s)
{
slot = s;
mcont->setSlot(slot);
deleteToken->show();
renameToken->show();
slotInfo->show();
listView->setEditTriggers(QAbstractItemView::EditKeyPressed);
pkcs11 p11;
QString info = p11.driverInfo(slot);
tkInfo ti = p11.tokenInfo(slot);
info += tr("\nName: %1\nModel: %2\nSerial: %3").
arg(ti.label()).arg(ti.model()).arg(ti.serial());
slotInfo->setText(info);
image->setPixmap(*MainWindow::scardImg);
heading->setText(tr("Manage security token"));
setAcceptDrops(false);
}
void ImportMulti::addItem(pki_base *pki)
{
if (!pki)
return;
QString cn = pki->getClassName();
if (cn == "pki_x509" || cn == "pki_evp" || cn == "pki_x509req" ||
cn == "pki_crl" || cn == "pki_temp" || cn == "pki_scard")
{
mcont->inToCont(pki);
}
else if (cn == "pki_pkcs7") {
pki_pkcs7 *p7 = ( pki_pkcs7 *)pki;
for (int i=0; i<p7->numCert(); i++) {
addItem(p7->getCert(i));
}
delete p7;
}
else if (cn == "pki_pkcs12") {
pki_pkcs12 *p12 = ( pki_pkcs12 *)pki;
addItem(p12->getKey());
addItem(p12->getCert());
for (int i=0; i<p12->numCa(); i++) {
addItem(p12->getCa(i));
}
delete p12;
}
else if (cn == "pki_multi") {
pki_multi *pm = (pki_multi*)pki;
pki_base *inner;
while ((inner = pm->pull()))
addItem(inner);
delete pm;
}
else {
XCA_WARN(tr("The type of the item '%1' is not recognized").
arg(cn));
}
}
void ImportMulti::dragEnterEvent(QDragEnterEvent *event)
{
if (event->mimeData()->hasUrls())
event->acceptProposedAction();
}
void ImportMulti::dropEvent(QDropEvent *event)
{
QList<QUrl> urls = event->mimeData()->urls();
QUrl u;
QStringList failed;
pki_multi *pki = new pki_multi();
foreach(u, urls) {
QString s = u.toLocalFile();
int count = pki->count();
pki->probeAnything(s);
if (pki->count() == count)
failed << s;
}
importError(failed);
addItem(pki);
event->acceptProposedAction();
}
void ImportMulti::on_butRemove_clicked()
{
QItemSelectionModel *selectionModel = listView->selectionModel();
QModelIndexList indexes = selectionModel->selectedIndexes();
QModelIndex index;
QString items;
foreach(index, indexes) {
if (index.column() != 0)
continue;
mcont->remFromCont(index);
pki_base *pki = static_cast<pki_base*>(index.internalPointer());
delete pki;
}
}
void ImportMulti::on_butOk_clicked()
{
while (mcont->rootItem->childCount()) {
QModelIndex idx = mcont->index(0, 0, QModelIndex());
import(idx);
}
accept();
}
void ImportMulti::on_butImport_clicked()
{
QItemSelectionModel *selectionModel = listView->selectionModel();
QModelIndexList indexes = selectionModel->selectedIndexes();
QModelIndex index;
foreach(index, indexes) {
if (index.column() != 0)
continue;
import(index);
}
}
void ImportMulti::on_deleteToken_clicked()
{
QItemSelectionModel *selectionModel = listView->selectionModel();
QModelIndexList indexes = selectionModel->selectedIndexes();
QModelIndex index;
QString items;
foreach(index, indexes) {
if (index.column() != 0)
continue;
pki_base *pki = static_cast<pki_base*>(index.internalPointer());
try {
pki->deleteFromToken(slot);
mcont->remFromCont(index);
delete pki;
} catch (errorEx &err) {
mainwin->Error(err);
}
}
}
void ImportMulti::on_renameToken_clicked()
{
QItemSelectionModel *selectionModel = listView->selectionModel();
QModelIndexList indexes = selectionModel->selectedIndexes();
QModelIndex index;
QString items;
foreach(index, indexes) {
if (index.column() != 0)
continue;
listView->edit(index);
break;
}
}
static db_base *select_db(QString cn)
{
if (cn == "pki_x509")
return MainWindow::certs;
if (cn == "pki_evp")
return MainWindow::keys;
if (cn == "pki_scard")
return MainWindow::keys;
if (cn == "pki_x509req")
return MainWindow::reqs;
if (cn == "pki_crl")
return MainWindow::crls;
if (cn == "pki_temp")
return MainWindow::temps;
return NULL;
}
pki_base *ImportMulti::import(QModelIndex &idx)
{
pki_base *pki = static_cast<pki_base*>(idx.internalPointer());
db_base *db;
if (!pki)
return NULL;
if (!mainwin->keys) {
mainwin->load_database();
}
QString cn = pki->getClassName();
mcont->remFromCont(idx);
if (!mainwin->keys) {
delete pki;
return NULL;
}
if (cn == "pki_evp")
((pki_evp*)pki)->setOwnPass(pki_evp::ptCommon);
db = select_db(cn);
if (!db) {
XCA_WARN(tr("The type of the item '%1' is not recognized").
arg(cn));
delete pki;
return NULL;
}
return db->insert(pki);
}
void ImportMulti::on_butDetails_clicked()
{
QItemSelectionModel *selectionModel = listView->selectionModel();
QModelIndex index;
if (!selectionModel->selectedIndexes().count())
return;
index = selectionModel->selectedIndexes().first();
pki_base *pki = static_cast<pki_base*>(index.internalPointer());
if (!pki)
return;
QString cn = pki->getClassName();
try {
if (cn == "pki_x509"){
CertDetail *dlg;
dlg = new CertDetail(mainwin);
dlg->setCert((pki_x509 *)pki);
dlg->exec();
delete dlg;
} else if (cn == "pki_evp" || cn == "pki_scard") {
KeyDetail *dlg;
dlg = new KeyDetail(mainwin);
dlg->setKey((pki_key *)pki);
dlg->exec();
delete dlg;
} else if (cn == "pki_x509req") {
CertDetail *dlg;
dlg = new CertDetail(mainwin);
dlg->setReq((pki_x509req *)pki);
dlg->exec();
delete dlg;
} else if (cn == "pki_crl") {
CrlDetail *dlg;
dlg = new CrlDetail(mainwin);
dlg->setCrl((pki_crl *)pki);
dlg->exec();
delete dlg;
} else if (cn == "pki_temp") {
XCA_WARN(tr("Details of the item '%1' cannot be shown").
arg(cn));
} else
XCA_WARN(tr("The type of the item '%1' is not recognized").arg(cn));
}
catch (errorEx &err) {
mainwin->Error(err);
}
}
ImportMulti::~ImportMulti()
{
QModelIndex idx = listView->currentIndex();
while (idx != QModelIndex()) {
mcont->remFromCont(idx);
pki_base *pki = static_cast<pki_base*>(idx.internalPointer());
delete pki;
idx = listView->currentIndex();
}
listView->setModel(NULL);
delete mcont;
}
int ImportMulti::entries()
{
return mcont->rootItem->childCount();
}
void ImportMulti::importError(QStringList failed)
{
if (failed.count() == 1) {
XCA_INFO(tr("The file '%1' did not contain PKI data").
arg(failed[0]));
} else if (failed.count() > 1) {
XCA_INFO(tr("The %1 files: '%2' did not contain PKI data").
arg(failed.count()).
arg(failed.join("', '")));
}
}
void ImportMulti::execute(int force, QStringList failed)
{
importError(failed);
/* if there is nothing to import don't pop up */
if (entries() == 0) {
accept();
return;
}
/* if there is only 1 item and force is 0 import it silently */
if (entries() == 1 && force == 0) {
QModelIndex idx = mcont->index(0, 0, QModelIndex());
pki_base *pki = import(idx);
if (pki && !pki_base::suppress_messages)
XCA_INFO(pki->getMsg(pki_base::msg_import).
arg(pki->getIntName()));
accept();
return;
}
/* the behaviour for more than one item */
exec();
}