xca/widgets/KeyTreeView.cpp
Christian Hohnstädt 13b0992780 Set Key export format separately via context menu
The popping up query dialog during PEM export via Drag&Drop
and Ctrl-C during Key export was pretty annoying.
2021-10-24 14:41:25 +02:00

224 lines
4.8 KiB
C++

/* vi: set sw=4 ts=4:
*
* Copyright (C) 2020 Christian Hohnstaedt.
*
* All rights reserved.
*/
#include "lib/pki_scard.h"
#include "KeyTreeView.h"
#include "MainWindow.h"
#include "KeyDetail.h"
#include "NewKey.h"
#include "XcaWarning.h"
#include <QAbstractItemView>
#include <QMenu>
void KeyTreeView::fillContextMenu(QMenu *menu, QMenu *subExport,
const QModelIndex &index, QModelIndexList indexes)
{
QMenu *clipboard;
QAction *a;
bool multi = indexes.size() > 1;
QActionGroup *group = new QActionGroup(menu);
pki_key *key = db_base::fromIndex<pki_key>(index);
int exp_type = Settings["KeyFormat"];
clipboard = menu->addMenu(tr("Clipboard format"));
/* The evil copy & paster striked again */
a = clipboard->addAction(tr("PEM public"));
a->setData(QVariant(exportType::PEM_key));
a->setCheckable(true);
a->setChecked(exp_type == exportType::PEM_key);
group->addAction(a);
a = clipboard->addAction(tr("PEM private"));
a->setData(QVariant(exportType::PEM_private));
a->setCheckable(true);
a->setChecked(exp_type == exportType::PEM_private);
group->addAction(a);
a = clipboard->addAction(tr("PKCS#8"));
a->setData(QVariant(exportType::PKCS8));
a->setCheckable(true);
a->setChecked(exp_type == exportType::PKCS8);
group->addAction(a);
connect(group, SIGNAL(triggered(QAction*)),
this, SLOT(clipboardFormat(QAction*)));
if (indexes.size() == 0 || !key)
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;
default:
break;
}
}
if (!pkcs11::libraries.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 if (subExport) {
subExport->addAction(tr("Security token"),
this, SLOT(toToken()));
}
}
void KeyTreeView::setOwnPass()
{
if (!basemodel)
return;
try {
keys()->setOwnPass(currentIndex(), pki_key::ptPrivate);
} catch (errorEx &err) {
XCA_ERROR(err);
}
}
void KeyTreeView::resetOwnPass()
{
if (!basemodel)
return;
try {
keys()->setOwnPass(currentIndex(), pki_key::ptCommon);
} catch (errorEx &err) {
XCA_ERROR(err);
}
}
void KeyTreeView::changePin()
{
pki_scard *scard;
QModelIndex currentIdx = currentIndex();
if (!currentIdx.isValid())
return;
scard = db_base::fromIndex<pki_scard>(currentIdx);
try {
if (!scard->isToken()) {
throw errorEx(tr("This is not a token"));
}
scard->changePin();
} catch (errorEx &err) {
XCA_ERROR(err);
}
}
void KeyTreeView::initPin()
{
pki_scard *scard;
QModelIndex currentIdx = currentIndex();
if (!currentIdx.isValid())
return;
scard = db_base::fromIndex<pki_scard>(currentIdx);
try {
if (!scard->isToken()) {
throw errorEx(tr("This is not a token"));
}
scard->initPin();
} catch (errorEx &err) {
XCA_ERROR(err);
}
}
void KeyTreeView::changeSoPin()
{
pki_scard *scard;
QModelIndex currentIdx = currentIndex();
if (!currentIdx.isValid())
return;
scard = db_base::fromIndex<pki_scard>(currentIdx);
try {
if (!scard->isToken()) {
throw errorEx(tr("This is not a token"));
}
scard->changeSoPin();
} catch (errorEx &err) {
XCA_ERROR(err);
}
}
void KeyTreeView::toToken()
{
QModelIndex currentIdx = currentIndex();
if (!currentIdx.isValid() || !basemodel)
return;
pki_key *key = db_base::fromIndex<pki_key>(currentIdx);
if (!key || !pkcs11::libraries.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());
card->pkiSource = key->pkiSource;
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) {
XCA_ERROR(err);
}
delete card;
}
void KeyTreeView::showPki(pki_base *pki)
{
pki_key *key = dynamic_cast<pki_key *>(pki);
KeyDetail::showKey(this, key);
}
void KeyTreeView::newItem() {
newItem("");
}
void KeyTreeView::newItem(const QString &name)
{
if (!basemodel)
return;
NewKey *dlg = new NewKey(this, name);
if (dlg->exec())
keys()->newKey(dlg->getKeyJob(), dlg->keyDesc->text());
delete dlg;
}
void KeyTreeView::clipboardFormat(QAction *a)
{
qWarning("pki_key::default_export_type: %d %d\n",
(int)Settings["KeyFormat"], a->data().toInt());
Settings["KeyFormat"] = a->data().toInt();
}