Page MenuHome GnuPG

No OneTemporary

diff --git a/src/smartcard/p15card.cpp b/src/smartcard/p15card.cpp
index 5cd724e0c..027d9f558 100644
--- a/src/smartcard/p15card.cpp
+++ b/src/smartcard/p15card.cpp
@@ -1,82 +1,82 @@
/* smartcard/p15card.cpp
This file is part of Kleopatra, the KDE keymanager
- SPDX-FileCopyrightText: 2020 g10 Code GmbH
- SPDX-FileContributor: Andre Heinecke <aheinecke@ingo-kloecker.de>
+ SPDX-FileCopyrightText: 2021 g10 Code GmbH
+ SPDX-FileContributor: Andre Heinecke <aheinecke@g10code.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "p15card.h"
#include "kleopatra_debug.h"
using namespace Kleo;
using namespace Kleo::SmartCard;
// static
const std::string P15Card::AppName = "p15";
P15Card::P15Card(const Card &card)
: Card(card)
{
setAppName(AppName);
}
std::string P15Card::appKeyFingerprint(const std::string &appKeyRef) const
{
return mMetaInfo.value("KLEO-FPR-" + appKeyRef);
}
void P15Card::setCardInfo(const std::vector< std::pair<std::string, std::string> > &infos)
{
// XXX: This is a copy of OpenPGPCard::setCardInfo
qCDebug(KLEOPATRA_LOG) << "Card" << serialNumber().c_str() << "info:";
for (const auto &pair: infos) {
qCDebug(KLEOPATRA_LOG) << pair.first.c_str() << ":" << pair.second.c_str();
if (parseCardInfo(pair.first, pair.second)) {
continue;
}
if (pair.first == "KEY-FPR") {
const auto values = QString::fromStdString(pair.second).split(QLatin1Char(' '));
if (values.size() < 2) {
qCWarning(KLEOPATRA_LOG) << "Invalid entry.";
setStatus(Card::CardError);
continue;
}
const auto keyNumber = values[0];
const std::string keyRef = "OPENPGP." + keyNumber.toStdString();
const auto fpr = values[1].toStdString();
if (keyNumber == QLatin1Char('1') || keyNumber == QLatin1Char('2') || keyNumber == QLatin1Char('3')) {
mMetaInfo.insert("KLEO-FPR-" + keyRef, fpr);
} else {
// Maybe more keyslots in the future?
qCDebug(KLEOPATRA_LOG) << "Unhandled keyslot";
}
} else {
mMetaInfo.insert(pair.first, pair.second);
}
}
}
void P15Card::setManufacturer(const std::string &manufacturer)
{
mManufacturer = manufacturer;
}
std::string P15Card::manufacturer() const
{
return mManufacturer;
}
bool P15Card::operator == (const Card& rhs) const
{
const P15Card *other = dynamic_cast<const P15Card *>(&rhs);
if (!other) {
return false;
}
return Card::operator ==(rhs)
&& mMetaInfo == other->mMetaInfo
&& mManufacturer == other->mManufacturer;
}
diff --git a/src/smartcard/p15card.h b/src/smartcard/p15card.h
index 742b59a85..3d0b21cd7 100644
--- a/src/smartcard/p15card.h
+++ b/src/smartcard/p15card.h
@@ -1,57 +1,57 @@
-/* smartcard/pivcard.h
+/* smartcard/p15card.h
This file is part of Kleopatra, the KDE keymanager
- SPDX-FileCopyrightText: 2020 g10 Code GmbH
- SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
+ SPDX-FileCopyrightText: 2021 g10 Code GmbH
+ SPDX-FileContributor: Andre Heinecke <aheinecke@g10code.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include "card.h"
#include <QMap>
namespace Kleo
{
namespace SmartCard
{
/** Class to work with PKCS#15 smartcards or compatible tokens.
*
* A PKCS#15 card is pretty generic and there is no real standard
* for them. It all depends on the Apps running on the cards. This
* mostly tries to leave it to GnuPG to determine if there are usable
* things on the card. The generic info on all keys on the card is
* accessible through keyInfo from the parent class.
*
* The specialization is required for specific app support.
**/
class P15Card: public Card
{
public:
explicit P15Card(const Card &card);
static const std::string AppName;
void setAppKeyRef(const std::string &appKeyRef,
const std::string &value);
std::string appKeyRef(const std::string &appKeyRef) const;
/* Obtain an application specific fingerprint for a key
* stored on this card.
* e.g. An App Key Ref would be
* OpenPGPCard::pgpSigKeyRef */
std::string appKeyFingerprint(const std::string &appKeyRef) const;
void setCardInfo(const std::vector< std::pair<std::string, std::string> > &infos);
void setManufacturer(const std::string &manufacturer);
std::string manufacturer() const;
bool operator == (const Card& other) const override;
private:
QMap <std::string, std::string> mMetaInfo;
std::string mManufacturer;
};
} // namespace Smartcard
} // namespace Kleopatra
diff --git a/src/view/p15cardwidget.cpp b/src/view/p15cardwidget.cpp
index 61452ef56..0c38d4944 100644
--- a/src/view/p15cardwidget.cpp
+++ b/src/view/p15cardwidget.cpp
@@ -1,230 +1,230 @@
/* view/p15cardwiget.cpp
This file is part of Kleopatra, the KDE keymanager
- SPDX-FileCopyrightText: 2020 g10 Code GmbH
+ SPDX-FileCopyrightText: 2021 g10 Code GmbH
SPDX-FileContributor: Andre Heinecke <aheinecke@g10code.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "p15cardwidget.h"
#include "smartcard/p15card.h"
#include "smartcard/openpgpcard.h"
#include "smartcard/readerstatus.h"
#include <QVBoxLayout>
#include <QGridLayout>
#include <QScrollArea>
#include <QStringList>
#include <KLocalizedString>
#include <KSeparator>
#include <Libkleo/KeyCache>
#include <Libkleo/Formatting>
#include <QGpgME/Protocol>
#include <QGpgME/KeyListJob>
#include <QGpgME/ImportFromKeyserverJob>
#include <QGpgME/CryptoConfig>
#include <gpgme++/keylistresult.h>
#include <gpgme++/importresult.h>
#include <Libkleo/GnuPG>
#include "kleopatra_debug.h"
using namespace Kleo;
using namespace Kleo::SmartCard;
P15CardWidget::P15CardWidget(QWidget *parent)
: QWidget(parent)
, mSerialNumber(new QLabel(this))
, mVersionLabel(new QLabel(this))
, mSigFprLabel(new QLabel(this))
, mEncFprLabel(new QLabel(this))
, mStatusLabel(new QLabel(this))
{
// Set up the scroll area
auto myLayout = new QVBoxLayout(this);
myLayout->setContentsMargins(0, 0, 0, 0);
auto area = new QScrollArea;
area->setFrameShape(QFrame::NoFrame);
area->setWidgetResizable(true);
myLayout->addWidget(area);
auto areaWidget = new QWidget;
area->setWidget(areaWidget);
auto areaVLay = new QVBoxLayout(areaWidget);
auto cardInfoGrid = new QGridLayout;
{
int row = 0;
// Version and Serialnumber
cardInfoGrid->addWidget(mVersionLabel, row++, 0, 1, 2);
mVersionLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
cardInfoGrid->addWidget(new QLabel(i18n("Serial number:")), row, 0);
cardInfoGrid->addWidget(mSerialNumber, row++, 1);
mSerialNumber->setTextInteractionFlags(Qt::TextBrowserInteraction);
cardInfoGrid->setColumnStretch(cardInfoGrid->columnCount(), 1);
}
areaVLay->addLayout(cardInfoGrid);
areaVLay->addWidget(mStatusLabel);
mStatusLabel->setVisible(false);
areaVLay->addWidget(new KSeparator(Qt::Horizontal));
areaVLay->addWidget(new QLabel(QStringLiteral("<b>%1</b>").arg(i18n("OpenPGP keys:"))));
areaVLay->addWidget(mSigFprLabel);
areaVLay->addWidget(mEncFprLabel);
areaVLay->addWidget(new KSeparator(Qt::Horizontal));
areaVLay->addStretch(1);
}
P15CardWidget::~P15CardWidget()
{
}
void P15CardWidget::searchPGPFpr(const std::string &fpr)
{
/* Only do auto import from LDAP */
auto conf = QGpgME::cryptoConfig();
Q_ASSERT (conf);
const QString cmp = engineIsVersion(2, 3, 0) ? QStringLiteral("dirmngr") : QStringLiteral("gpg");
const auto entry = conf->entry(cmp, QStringLiteral("Keyserver"), QStringLiteral("keyserver"));
if (!entry || !entry->stringValue().startsWith(QStringLiteral("ldap"))) {
return;
}
static std::vector<std::string> fprs;
if (fpr.empty() || std::find(fprs.begin(), fprs.end(), fpr) != fprs.end()) {
qCDebug(KLEOPATRA_LOG) << "Already looked for " << fpr.c_str() << "on ldap server";
return;
}
mStatusLabel->setText(i18n("Searching in directory service..."));
mStatusLabel->setVisible(true);
fprs.push_back (fpr);
qCDebug(KLEOPATRA_LOG) << "Looking for:" << fpr.c_str() << "on ldap server";
QGpgME::KeyListJob *job = QGpgME::openpgp()->keyListJob(true);
connect(KeyCache::instance().get(), &KeyCache::keysMayHaveChanged, this, [this, fpr] () {
qCDebug(KLEOPATRA_LOG) << "Updating key info after changes";
ReaderStatus::mutableInstance()->updateStatus();
updateSigKeyWidgets(fpr);
});
connect(job, &QGpgME::KeyListJob::result, job, [this](GpgME::KeyListResult, std::vector<GpgME::Key> keys, QString, GpgME::Error) {
if (keys.size() == 1) {
auto importJob = QGpgME::openpgp()->importFromKeyserverJob();
qCDebug(KLEOPATRA_LOG) << "Importing: " << keys[0].primaryFingerprint();
connect(importJob, &QGpgME::ImportFromKeyserverJob::result, importJob, [this](GpgME::ImportResult, QString, GpgME::Error) {
qCDebug(KLEOPATRA_LOG) << "import job done";
mStatusLabel->setText(i18n("Automatic import finished."));
});
importJob->start(keys);
} else if (keys.size() > 1) {
qCDebug(KLEOPATRA_LOG) << "Multiple keys found on server";
mStatusLabel->setText(i18n("Error multiple keys found on server."));
} else {
qCDebug(KLEOPATRA_LOG) << "No key found";
mStatusLabel->setText(i18n("Key not found in directory service."));
}
});
job->start(QStringList() << QString::fromStdString(fpr));
}
void P15CardWidget::updateSigKeyWidgets(const std::string &fpr)
{
std::string keyid = fpr;
if (!keyid.empty()) {
QString text = i18n("Signing key:") +
QStringLiteral("\t%1 (%2)")
.arg(Formatting::prettyID(keyid.c_str()));
text += QStringLiteral("<br/><br/>");
keyid.erase(0, keyid.size() - 16);
const auto subkeys = KeyCache::instance()->findSubkeysByKeyID({keyid});
if (subkeys.empty() || subkeys[0].isNull()) {
text += i18n("Public key not found.");
} else {
QStringList toolTips;
toolTips.reserve(subkeys.size());
for (const auto &sub: subkeys) {
// Yep you can have one subkey associated with multiple
// primary keys.
toolTips << Formatting::toolTip(sub.parent(), Formatting::Validity |
Formatting::ExpiryDates |
Formatting::UserIDs |
Formatting::Fingerprint);
}
text += toolTips.join(QLatin1String("<br/>"));
}
mSigFprLabel->setText(text);
} else {
mSigFprLabel->setVisible(false);
}
}
void P15CardWidget::setCard(const P15Card *card)
{
mCardSerialNumber = card->serialNumber();
mVersionLabel->setText(i18nc("%1 is a smartcard manufacturer", "%1 PKCS#15 card",
QString::fromStdString(card->manufacturer())));
mSerialNumber->setText(card->displaySerialNumber());
mSerialNumber->setToolTip(QString::fromStdString(card->serialNumber()));
const auto sigInfo = card->keyInfo(card->signingKeyRef());
if (!sigInfo.grip.empty()) {
const auto key = KeyCache::instance()->findSubkeyByKeyGrip(sigInfo.grip, GpgME::OpenPGP).parent();
if (key.isNull()) {
qCDebug(KLEOPATRA_LOG) << "Failed to find key for grip:" << sigInfo.grip.c_str();
const auto pgpSigFpr = card->appKeyFingerprint(OpenPGPCard::pgpSigKeyRef());
if (!pgpSigFpr.empty()) {
qCDebug(KLEOPATRA_LOG) << "Should be pgp key:" << pgpSigFpr.c_str();
searchPGPFpr(pgpSigFpr);
}
} else {
mStatusLabel->setVisible(false);
}
}
std::string keyid = card->appKeyFingerprint(OpenPGPCard::pgpSigKeyRef());
updateSigKeyWidgets(keyid);
keyid = card->appKeyFingerprint(OpenPGPCard::pgpEncKeyRef());
if (!keyid.empty()) {
mEncFprLabel->setText(i18n("Encryption key:") +
QStringLiteral(" %1 (%2)")
.arg(Formatting::prettyID(keyid.c_str()))
.arg(QString::fromStdString(card->encryptionKeyRef())));
keyid.erase(0, keyid.size() - 16);
const auto subkeys = KeyCache::instance()->findSubkeysByKeyID({keyid});
if (subkeys.empty() || subkeys[0].isNull()) {
mEncFprLabel->setToolTip(i18n("Public key not found."));
} else {
QStringList toolTips;
toolTips.reserve(subkeys.size());
for (const auto &sub: subkeys) {
// Yep you can have one subkey associated with multiple
// primary keys.
toolTips << Formatting::toolTip(sub.parent(), Formatting::Validity |
Formatting::StorageLocation |
Formatting::ExpiryDates |
Formatting::UserIDs |
Formatting::Fingerprint);
}
mEncFprLabel->setToolTip(toolTips.join(QLatin1String("<br/>")));
}
} else {
mEncFprLabel->setVisible(false);
}
// updateKeyWidgets(OpenPGPCard::pgpSigKeyRef(), card);
// updateKeyWidgets(OpenPGPCard::pgpEncKeyRef(), card);
}
diff --git a/src/view/p15cardwidget.h b/src/view/p15cardwidget.h
index cf5c7c099..9f596359c 100644
--- a/src/view/p15cardwidget.h
+++ b/src/view/p15cardwidget.h
@@ -1,43 +1,44 @@
/* view/p15cardwiget.h
This file is part of Kleopatra, the KDE keymanager
- SPDX-FileCopyrightText: 2020 g10 Code GmbH
+ SPDX-FileCopyrightText: 2021 g10 Code GmbH
SPDX-FileContributor: Andre Heinecke <aheinecke@g10code.com>
+
SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include <QWidget>
#include <QLabel>
class QLabel;
namespace Kleo
{
namespace SmartCard
{
struct KeyPairInfo;
class P15Card;
} // namespace SmartCard
class P15CardWidget: public QWidget
{
Q_OBJECT
public:
explicit P15CardWidget(QWidget *parent = nullptr);
~P15CardWidget();
void setCard(const SmartCard::P15Card* card);
private:
void searchPGPFpr(const std::string &fpr);
void updateSigKeyWidgets(const std::string &keyid);
std::string mCardSerialNumber;
QLabel *mSerialNumber = nullptr;
QLabel *mVersionLabel = nullptr;
QLabel *mSigFprLabel = nullptr;
QLabel *mEncFprLabel = nullptr;
QLabel *mStatusLabel = nullptr;
};
}

File Metadata

Mime Type
text/x-diff
Expires
Mon, Dec 23, 1:15 PM (12 m, 34 s)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
69/82/1a6a331b716563dc7dcaa0eeef71

Event Timeline