Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F18826278
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
17 KB
Subscribers
None
View Options
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
Details
Attached
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
Attached To
rKLEOPATRA Kleopatra
Event Timeline
Log In to Comment