mirror of
https://github.com/chris2511/xca.git
synced 2026-09-12 19:51:05 +05:00
Collect all export formats in pki_export. Each export format has assigned acouple of flags, indicating, whether they are text, concatenateable, encrypted, usable for multiple selections or only for a single item.
236 lines
5.0 KiB
C++
236 lines
5.0 KiB
C++
/* vi: set sw=4 ts=4:
|
|
*
|
|
* Copyright (C) 2020 Christian Hohnstaedt.
|
|
*
|
|
* All rights reserved.
|
|
*/
|
|
|
|
#include "lib/pki_scard.h"
|
|
#include "lib/load_obj.h"
|
|
#include "KeyTreeView.h"
|
|
#include "MainWindow.h"
|
|
#include "KeyDetail.h"
|
|
#include "NewKey.h"
|
|
#include "ExportDialog.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"];
|
|
const pki_export *x;
|
|
|
|
clipboard = menu->addMenu(tr("Clipboard format"));
|
|
foreach(x, pki_export::select(asym_key, 0)) {
|
|
if (!(x->flags & F_CLIPBOARD))
|
|
continue;
|
|
qWarning() << "CLIPBOARD" << x->id << x->desc;
|
|
a = clipboard->addAction(x->desc);
|
|
a->setData(x->id);
|
|
a->setCheckable(true);
|
|
a->setChecked(exp_type == x->id);
|
|
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)
|
|
{
|
|
Settings["KeyFormat"] = a->data().toInt();
|
|
}
|
|
|
|
void KeyTreeView::load(void)
|
|
{
|
|
load_key l;
|
|
load_default(&l);
|
|
}
|
|
|
|
ExportDialog *KeyTreeView::exportDialog(const QModelIndexList &indexes)
|
|
{
|
|
if (indexes.size() == 0)
|
|
return NULL;
|
|
pki_key *key = db_base::fromIndex<pki_key>(indexes[0]);
|
|
return new ExportDialog(this,
|
|
tr("Export public key [%1]").arg(key->getTypeString()),
|
|
tr("Private Keys ( *.pem *.der *.pk8 );; "
|
|
"SSH Public Keys ( *.pub )"), indexes,
|
|
QPixmap(key->isToken() ? ":scardImg" : ":keyImg"),
|
|
pki_export::select(asym_key, basemodel->exportFlags(indexes)),
|
|
"keyexport");
|
|
}
|