Page MenuHome GnuPG

No OneTemporary

diff --git a/src/smartcard/card.cpp b/src/smartcard/card.cpp
index cd35fbe16..c1bcecd8c 100644
--- a/src/smartcard/card.cpp
+++ b/src/smartcard/card.cpp
@@ -1,371 +1,346 @@
/* smartcard/card.h
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2017 Bundesamt für Sicherheit in der Informationstechnik
SPDX-FileContributor: Intevation GmbH
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "card.h"
#include "readerstatus.h"
#include "kleopatra_debug.h"
using namespace Kleo;
using namespace Kleo::SmartCard;
namespace {
static QString formatVersion(int value)
{
if (value < 0) {
return QString();
}
const unsigned int a = ((value >> 24) & 0xff);
const unsigned int b = ((value >> 16) & 0xff);
const unsigned int c = ((value >> 8) & 0xff);
const unsigned int d = ((value ) & 0xff);
if (a) {
return QStringLiteral("%1.%2.%3.%4").arg(QString::number(a), QString::number(b), QString::number(c), QString::number(d));
} else if (b) {
return QStringLiteral("%1.%2.%3").arg(QString::number(b), QString::number(c), QString::number(d));
} else if (c) {
return QStringLiteral("%1.%2").arg(QString::number(c), QString::number(d));
}
return QString::number(d);
}
}
Card::Card()
{
}
Card::~Card()
{
}
void Card::setStatus(Status s)
{
mStatus = s;
}
Card::Status Card::status() const
{
return mStatus;
}
void Card::setSerialNumber(const std::string &sn)
{
mSerialNumber = sn;
}
std::string Card::serialNumber() const
{
return mSerialNumber;
}
QString Card::displaySerialNumber() const
{
return mDisplaySerialNumber;
}
void Card::setDisplaySerialNumber(const QString &serialNumber)
{
mDisplaySerialNumber = serialNumber;
}
std::string Card::appName() const
{
return mAppName;
}
void Card::setAppName(const std::string &name)
{
mAppName = name;
}
void Card::setAppVersion(int version)
{
mAppVersion = version;
}
int Card::appVersion() const
{
return mAppVersion;
}
QString Card::displayAppVersion() const
{
return formatVersion(mAppVersion);
}
void Card::setManufacturer(const std::string &value)
{
if (!manufacturer().empty()) {
qCDebug(KLEOPATRA_LOG) << "Card manufacturer is already set; overwriting existing value";
mCardInfo.erase("MANUFACTURER");
}
mCardInfo.insert({"MANUFACTURER", value});
}
std::string Card::manufacturer() const
{
return cardInfo("MANUFACTURER");
}
std::string Card::cardType() const
{
return mCardType;
}
int Card::cardVersion() const
{
return mCardVersion;
}
QString Card::displayCardVersion() const
{
return formatVersion(mCardVersion);
}
QString Card::cardHolder() const
{
return mCardHolder;
}
void Card::setSigningKeyRef(const std::string &keyRef)
{
mSigningKeyRef = keyRef;
}
std::string Card::signingKeyRef() const
{
return mSigningKeyRef;
}
bool Card::hasSigningKey() const
{
return !keyInfo(mSigningKeyRef).grip.empty();
}
void Card::setEncryptionKeyRef(const std::string &keyRef)
{
mEncryptionKeyRef = keyRef;
}
std::string Card::encryptionKeyRef() const
{
return mEncryptionKeyRef;
}
bool Card::hasEncryptionKey() const
{
return !keyInfo(mEncryptionKeyRef).grip.empty();
}
void Card::setAuthenticationKeyRef(const std::string &keyRef)
{
mAuthenticationKeyRef = keyRef;
}
std::string Card::authenticationKeyRef() const
{
return mAuthenticationKeyRef;
}
bool Card::hasAuthenticationKey() const
{
return !keyInfo(mAuthenticationKeyRef).grip.empty();
}
std::vector<Card::PinState> Card::pinStates() const
{
return mPinStates;
}
void Card::setPinStates(const std::vector<PinState> &pinStates)
{
mPinStates = pinStates;
}
bool Card::hasNullPin() const
{
return mHasNullPin;
}
void Card::setHasNullPin(bool value)
{
mHasNullPin = value;
}
bool Card::canLearnKeys() const
{
return mCanLearn;
}
void Card::setCanLearnKeys(bool value)
{
mCanLearn = value;
}
-bool Card::operator == (const Card &other) const
-{
- return mCanLearn == other.mCanLearn
- && mHasNullPin == other.mHasNullPin
- && mStatus == other.mStatus
- && mSerialNumber == other.mSerialNumber
- && mAppName == other.mAppName
- && mAppVersion == other.mAppVersion
- && mCardType == other.mCardType
- && mCardVersion == other.mCardVersion
- && mCardHolder == other.mCardHolder
- && mSigningKeyRef == other.mSigningKeyRef
- && mEncryptionKeyRef == other.mEncryptionKeyRef
- && mAuthenticationKeyRef == other.mAuthenticationKeyRef
- && mPinStates == other.mPinStates
- && mErrMsg == other.mErrMsg
- && mKeyInfos == other.mKeyInfos
- && mCardInfo == other.mCardInfo;
-}
-
-bool Card::operator != (const Card &other) const
-{
- return !operator==(other);
-}
-
void Card::setErrorMsg(const QString &msg)
{
mErrMsg = msg;
}
QString Card::errorMsg() const
{
return mErrMsg;
}
void Card::setInitialKeyInfos(const std::vector<KeyPairInfo> &infos)
{
mKeyInfos = infos;
}
const std::vector<KeyPairInfo> & Card::keyInfos() const
{
return mKeyInfos;
}
const KeyPairInfo & Card::keyInfo(const std::string &keyRef) const
{
static const KeyPairInfo nullKey;
for (const KeyPairInfo &k : mKeyInfos) {
if (k.keyRef == keyRef) {
return k;
}
}
return nullKey;
}
void Card::setCardInfo(const std::vector<std::pair<std::string, std::string>> &infos)
{
qCDebug(KLEOPATRA_LOG) << "Card" << serialNumber().c_str() << "info:";
for (const auto &pair: infos) {
qCDebug(KLEOPATRA_LOG) << pair.first.c_str() << ":" << pair.second.c_str();
parseCardInfo(pair.first, pair.second);
}
processCardInfo();
}
namespace {
static int parseHexEncodedVersionTuple(const std::string &s) {
// s is a hex-encoded, unsigned int-packed version tuple,
// i.e. each byte represents one part of the version tuple
bool ok;
const auto version = QByteArray::fromStdString(s).toUInt(&ok, 16);
return ok ? version : -1;
}
}
void Card::parseCardInfo(const std::string &name, const std::string &value)
{
if (name == "APPVERSION") {
mAppVersion = parseHexEncodedVersionTuple(value);
} else if (name == "CARDTYPE") {
mCardType = value;
} else if (name == "CARDVERSION") {
mCardVersion = parseHexEncodedVersionTuple(value);
} else if (name == "DISP-NAME") {
auto list = QString::fromUtf8(QByteArray::fromStdString(value)).
split(QStringLiteral("<<"), Qt::SkipEmptyParts);
std::reverse(list.begin(), list.end());
mCardHolder = list.join(QLatin1Char(' ')).replace(QLatin1Char('<'), QLatin1Char(' '));
} else if (name == "KEYPAIRINFO") {
const KeyPairInfo info = KeyPairInfo::fromStatusLine(value);
if (info.grip.empty()) {
qCWarning(KLEOPATRA_LOG) << "Invalid KEYPAIRINFO status line" << QString::fromStdString(value);
setStatus(Card::CardError);
} else {
updateKeyInfo(info);
}
} else if (name == "KEY-FPR") {
// handle OpenPGP key fingerprints
const auto values = QString::fromStdString(value).split(QLatin1Char(' '));
if (values.size() < 2) {
qCWarning(KLEOPATRA_LOG) << "Invalid KEY-FPR status line" << QString::fromStdString(value);
setStatus(Card::CardError);
}
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')) {
addCardInfo("KLEO-FPR-" + keyRef, fpr);
} else {
// Maybe more keyslots in the future?
qCDebug(KLEOPATRA_LOG) << "Unhandled keyslot" << keyNumber;
}
} else if (name == "MANUFACTURER") {
// the value of MANUFACTURER is the manufacturer ID as unsigned number
// optionally followed by the name of the manufacturer, e.g.
// 6 Yubico
// 65534 unmanaged S/N range
// for PKCS#15 cards the manufacturer ID is always 0, e.g.
// 0 www.atos.net/cardos [R&S]
const auto startOfManufacturerName = value.find(' ');
if (startOfManufacturerName != std::string::npos) {
addCardInfo(name, value.substr(startOfManufacturerName + 1));
}
} else {
mCardInfo.insert({name, value});
}
}
void Card::processCardInfo()
{
}
void Card::addCardInfo(const std::string &name, const std::string &value)
{
mCardInfo.insert({name, value});
}
std::string Card::cardInfo(const std::string &name) const
{
const auto range = mCardInfo.equal_range(name);
return range.first != range.second ? range.first->second : std::string();
}
void Card::updateKeyInfo(const KeyPairInfo& keyPairInfo)
{
for (KeyPairInfo &k : mKeyInfos) {
if (k.keyRef == keyPairInfo.keyRef) {
k.update(keyPairInfo);
return;
}
}
mKeyInfos.push_back(keyPairInfo);
}
std::string Card::keyFingerprint(const std::string &keyRef) const
{
return cardInfo("KLEO-FPR-" + keyRef);
}
diff --git a/src/smartcard/card.h b/src/smartcard/card.h
index f65fa75a9..368304f45 100644
--- a/src/smartcard/card.h
+++ b/src/smartcard/card.h
@@ -1,148 +1,147 @@
#pragma once
/* smartcard/card.h
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2017 Bundesamt für Sicherheit in der Informationstechnik
SPDX-FileContributor: Intevation GmbH
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "keypairinfo.h"
#include <map>
#include <string>
#include <vector>
#include <QString>
namespace Kleo
{
namespace SmartCard
{
/** Class representing an application on a smartcard or similar hardware token. */
class Card
{
public:
enum PinState {
UnknownPinState,
NullPin,
PinBlocked,
NoPin,
PinOk,
NumPinStates
};
enum Status {
NoCard,
CardPresent,
CardActive,
CardUsable,
_NumScdStates,
CardError = _NumScdStates,
NumStates
};
Card();
virtual ~Card();
- virtual bool operator == (const Card &other) const;
- bool operator != (const Card &other) const;
+ bool operator==(const Card &) const = default;
void setStatus(Status s);
Status status() const;
void setSerialNumber(const std::string &sn);
std::string serialNumber() const;
void setCardInfo(const std::vector<std::pair<std::string, std::string>> &infos);
QString displaySerialNumber() const;
void setDisplaySerialNumber(const QString &sn);
std::string appName() const;
void setAppVersion(int version);
int appVersion() const;
QString displayAppVersion() const;
void setManufacturer(const std::string &manufacturer);
std::string manufacturer() const;
std::string cardType() const;
int cardVersion() const;
QString displayCardVersion() const;
QString cardHolder() const;
void setSigningKeyRef(const std::string &keyRef);
std::string signingKeyRef() const;
bool hasSigningKey() const;
void setEncryptionKeyRef(const std::string &keyRef);
std::string encryptionKeyRef() const;
bool hasEncryptionKey() const;
void setAuthenticationKeyRef(const std::string &keyRef);
std::string authenticationKeyRef() const;
bool hasAuthenticationKey() const;
std::vector<PinState> pinStates() const;
void setPinStates(const std::vector<PinState> &pinStates);
bool hasNullPin() const;
void setHasNullPin(bool value);
bool canLearnKeys() const;
void setCanLearnKeys(bool value);
QString errorMsg() const;
void setErrorMsg(const QString &msg);
const std::vector<KeyPairInfo> & keyInfos() const;
const KeyPairInfo & keyInfo(const std::string &keyRef) const;
std::string keyFingerprint(const std::string &keyRef) const;
protected:
void setAppName(const std::string &name);
void setInitialKeyInfos(const std::vector<KeyPairInfo> &infos);
virtual void processCardInfo();
void addCardInfo(const std::string &name, const std::string &value);
std::string cardInfo(const std::string &name) const;
private:
void parseCardInfo(const std::string &name, const std::string &value);
void updateKeyInfo(const KeyPairInfo &keyPairInfo);
private:
bool mCanLearn = false;
bool mHasNullPin = false;
Status mStatus = NoCard;
std::string mSerialNumber;
QString mDisplaySerialNumber;
std::string mAppName;
int mAppVersion = -1;
std::string mCardType;
int mCardVersion = -1;
QString mCardHolder;
std::string mSigningKeyRef;
std::string mEncryptionKeyRef;
std::string mAuthenticationKeyRef;
std::vector<PinState> mPinStates;
QString mErrMsg;
std::vector<KeyPairInfo> mKeyInfos;
std::multimap<std::string, std::string> mCardInfo;
};
} // namespace Smartcard
} // namespace Kleopatra
diff --git a/src/smartcard/keypairinfo.cpp b/src/smartcard/keypairinfo.cpp
index f9db8eada..602ddfd87 100644
--- a/src/smartcard/keypairinfo.cpp
+++ b/src/smartcard/keypairinfo.cpp
@@ -1,100 +1,84 @@
/* smartcard/keypairinfo.cpp
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-License-Identifier: GPL-2.0-or-later
*/
#include "keypairinfo.h"
#include <QString>
#include <QStringList>
using namespace Kleo::SmartCard;
// static
KeyPairInfo KeyPairInfo::fromStatusLine(const std::string &s) {
// The format of a KEYPAIRINFO line is
// KEYPAIRINFO <hexgrip> <keyref> [usage] [keytime] [algostr]
// The string s does not contain the leading "KEYPAIRINFO ".
KeyPairInfo info;
const auto values = QString::fromStdString(s).split(QLatin1Char(' '));
if (values.size() < 2) {
return info;
}
info.grip = values[0].toStdString();
info.keyRef = values[1].toStdString();
if (values.size() >= 3) {
info.usage = values[2].toStdString();
}
if (values.size() >= 4) {
info.keyTime = values[3].toStdString();
}
if (values.size() >= 5) {
info.algorithm = values[4].toStdString();
}
return info;
}
bool KeyPairInfo::canAuthenticate() const
{
return usage.find('a') != std::string::npos;
}
bool KeyPairInfo::canCertify() const
{
return usage.find('c') != std::string::npos;
}
bool KeyPairInfo::canEncrypt() const
{
return usage.find('e') != std::string::npos;
}
bool KeyPairInfo::canSign() const
{
return usage.find('s') != std::string::npos;
}
void KeyPairInfo::update(const KeyPairInfo &other)
{
Q_ASSERT(keyRef == other.keyRef);
if (keyRef != other.keyRef) {
return;
}
if (grip != other.grip) {
// reset all infos if the grip changed
grip = other.grip;
usage = std::string();
keyTime = std::string();
algorithm = std::string();
}
// now update all infos from other's infos unless other's infos are empty or not specified
if (!other.usage.empty() && other.usage != "-") {
usage = other.usage;
}
if (!other.keyTime.empty() && other.keyTime != "-") {
keyTime = other.keyTime;
}
if (!other.algorithm.empty() && other.algorithm != "-") {
algorithm = other.algorithm;
}
}
-
-// C++20: Replace with defaulted equality operator
-bool KeyPairInfo::operator==(const KeyPairInfo &other) const
-{
- return keyRef == other.keyRef
- && grip == other.grip
- && usage == other.usage
- && keyTime == other.keyTime
- && algorithm == other.algorithm;
-}
-
-// C++20: Remove
-bool KeyPairInfo::operator!=(const KeyPairInfo &other) const
-{
- return !operator==(other);
-}
diff --git a/src/smartcard/keypairinfo.h b/src/smartcard/keypairinfo.h
index 13ac732a6..fac73c6bc 100644
--- a/src/smartcard/keypairinfo.h
+++ b/src/smartcard/keypairinfo.h
@@ -1,38 +1,37 @@
/* smartcard/keypairinfo.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-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include <string>
namespace Kleo
{
namespace SmartCard
{
struct KeyPairInfo {
static KeyPairInfo fromStatusLine(const std::string &s);
bool canAuthenticate() const;
bool canCertify() const;
bool canEncrypt() const;
bool canSign() const;
void update(const KeyPairInfo &other);
- bool operator==(const KeyPairInfo &other) const;
- bool operator!=(const KeyPairInfo &other) const;
+ bool operator==(const KeyPairInfo &) const = default;
std::string keyRef;
std::string grip;
std::string usage;
std::string keyTime;
std::string algorithm;
};
} // namespace Smartcard
} // namespace Kleopatra

File Metadata

Mime Type
text/x-diff
Expires
Mon, Dec 23, 4:59 PM (11 h, 26 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
c0/52/f2020a39bc317e0cacd3e5fe0daf

Event Timeline