diff --git a/src/smartcard/card.cpp b/src/smartcard/card.cpp index 7a3b9e5ed..fadd9d0ae 100644 --- a/src/smartcard/card.cpp +++ b/src/smartcard/card.cpp @@ -1,312 +1,318 @@ /* 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); } 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(); } std::vector Card::pinStates() const { return mPinStates; } void Card::setPinStates(const std::vector &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 mStatus == other.status() && mSerialNumber == other.serialNumber() && mAppName == other.appName() && mAppVersion == other.appVersion() && mPinStates == other.pinStates() && mCanLearn == other.canLearnKeys() && mHasNullPin == other.hasNullPin() && 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 &infos) { mKeyInfos = infos; } const std::vector & 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> &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; } } -bool Card::parseCardInfo(const std::string &name, const std::string &value) +void Card::parseCardInfo(const std::string &name, const std::string &value) { if (name == "APPVERSION") { mAppVersion = parseHexEncodedVersionTuple(value); - return true; } else if (name == "CARDTYPE") { mCardType = value; - return true; } else if (name == "CARDVERSION") { mCardVersion = parseHexEncodedVersionTuple(value); - return true; } 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(' ')); - return true; } 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); } - return true; } 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; } - return true; } else { mCardInfo.insert({name, value}); } +} - return false; +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); } diff --git a/src/smartcard/card.h b/src/smartcard/card.h index a6d385b0b..77b748d0b 100644 --- a/src/smartcard/card.h +++ b/src/smartcard/card.h @@ -1,134 +1,138 @@ #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 #include #include #include 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; void setStatus(Status s); Status status() const; void setSerialNumber(const std::string &sn); std::string serialNumber() const; + void setCardInfo(const std::vector> &infos); + QString displaySerialNumber() const; void setDisplaySerialNumber(const QString &sn); std::string appName() const; void setAppVersion(int version); int appVersion() const; QString displayAppVersion() 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; std::vector pinStates() const; void setPinStates(const std::vector &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 & keyInfos() const; const KeyPairInfo & keyInfo(const std::string &keyRef) const; protected: void setAppName(const std::string &name); void setInitialKeyInfos(const std::vector &infos); - bool parseCardInfo(const std::string &name, const std::string &value); + 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::vector mPinStates; QString mErrMsg; std::vector mKeyInfos; std::multimap mCardInfo; }; } // namespace Smartcard } // namespace Kleopatra diff --git a/src/smartcard/netkeycard.cpp b/src/smartcard/netkeycard.cpp index 1cff2d51d..822dc2760 100644 --- a/src/smartcard/netkeycard.cpp +++ b/src/smartcard/netkeycard.cpp @@ -1,128 +1,123 @@ /* smartcard/netkeycard.cpp This file is part of Kleopatra, the KDE keymanager SPDX-FileCopyrightText: 2017 Intevation GmbH SPDX-License-Identifier: GPL-2.0-or-later */ #include "netkeycard.h" #include "keypairinfo.h" #include "kleopatra_debug.h" #include #include #include #include #include using namespace Kleo; using namespace Kleo::SmartCard; // static const std::string NetKeyCard::AppName = "nks"; namespace { static GpgME::Key lookup_key(GpgME::Context *ctx, const std::string &keyGrip) { if (!ctx || keyGrip.empty()) { return GpgME::Key(); } const std::string pattern = '&' + keyGrip; qCDebug(KLEOPATRA_LOG) << "parse_keypairinfo_and_lookup_key: pattern=" << pattern.c_str(); if (const auto err = ctx->startKeyListing(pattern.c_str())) { qCDebug(KLEOPATRA_LOG) << "parse_keypairinfo_and_lookup_key: startKeyListing failed:" << err.asString(); return GpgME::Key(); } GpgME::Error e; const auto key = ctx->nextKey(e); ctx->endKeyListing(); qCDebug(KLEOPATRA_LOG) << "parse_keypairinfo_and_lookup_key: e=" << e.code() << "; key.isNull()" << key.isNull(); return key; } } // namespace NetKeyCard::NetKeyCard(const Card &card) : Card(card) { setAppName(AppName); } // static std::string NetKeyCard::nksPinKeyRef() { return std::string("PW1.CH"); } // static std::string NetKeyCard::sigGPinKeyRef() { return std::string("PW1.CH.SIG"); } -void NetKeyCard::setCardInfo(const std::vector< std::pair > &infos) +void NetKeyCard::processCardInfo() { - 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); - } setKeyPairInfo(keyInfos()); } void NetKeyCard::setKeyPairInfo(const std::vector &infos) { // check that any of the keys are new const std::unique_ptr klc(GpgME::Context::createForProtocol(GpgME::CMS)); if (!klc.get()) { return; } klc->setKeyListMode(GpgME::Ephemeral); klc->addKeyListMode(GpgME::Validate); setCanLearnKeys(false); mKeys.clear(); for (const auto &info: infos) { const auto key = lookup_key(klc.get(), info.grip); if (key.isNull()) { setCanLearnKeys(true); } mKeys.push_back(key); } } // State 0 -> NKS PIN Retry counter // State 1 -> NKS PUK Retry counter // State 2 -> SigG PIN Retry counter // State 3 -> SigG PUK Retry counter bool NetKeyCard::hasNKSNullPin() const { const auto states = pinStates(); if (states.size() < 2) { qCWarning(KLEOPATRA_LOG) << "Invalid size of pin states:" << states.size(); return false; } return states[0] == Card::NullPin; } bool NetKeyCard::hasSigGNullPin() const { const auto states = pinStates(); if (states.size() < 4) { qCWarning(KLEOPATRA_LOG) << "Invalid size of pin states:" << states.size(); return false; } return states[2] == Card::NullPin; } std::vector NetKeyCard::keys() const { return mKeys; } diff --git a/src/smartcard/netkeycard.h b/src/smartcard/netkeycard.h index 2808bbb5a..d9bf29da6 100644 --- a/src/smartcard/netkeycard.h +++ b/src/smartcard/netkeycard.h @@ -1,47 +1,46 @@ #pragma once /* smartcard/netkeycard.h This file is part of Kleopatra, the KDE keymanager SPDX-FileCopyrightText: 2017 Intevation GmbH SPDX-License-Identifier: GPL-2.0-or-later */ #include "card.h" #include namespace Kleo { namespace SmartCard { struct KeyPairInfo; /** Class to work with NetKey smartcards or compatible tokens */ class NetKeyCard: public Card { public: explicit NetKeyCard(const Card &card); static const std::string AppName; static std::string nksPinKeyRef(); static std::string sigGPinKeyRef(); - void setCardInfo(const std::vector< std::pair > &infos); - bool hasSigGNullPin() const; bool hasNKSNullPin() const; std::vector keys() const; private: + void processCardInfo() override; void setKeyPairInfo(const std::vector &infos); private: std::vector mKeys; }; } // namespace Smartcard } // namespace Kleopatra diff --git a/src/smartcard/openpgpcard.cpp b/src/smartcard/openpgpcard.cpp index 262fd01c6..e85afa0a9 100644 --- a/src/smartcard/openpgpcard.cpp +++ b/src/smartcard/openpgpcard.cpp @@ -1,142 +1,131 @@ /* smartcard/openpgpcard.cpp This file is part of Kleopatra, the KDE keymanager SPDX-FileCopyrightText: 2017 Bundesamt für Sicherheit in der Informationstechnik SPDX-FileContributor: Intevation GmbH SPDX-FileCopyrightText: 2020 g10 Code GmbH SPDX-FileContributor: Ingo Klöcker SPDX-License-Identifier: GPL-2.0-or-later */ /* Code in this file is partly based on the GNU Privacy Assistant * (cm-openpgp.c) git rev. 0a78795146661234070681737b3e08228616441f * * Whis is: * SPDX-FileCopyrightText: 2008, 2009 g 10 Code GmbH * * And may be licensed under the GNU General Public License * as published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. */ #include "openpgpcard.h" #include #include "kleopatra_debug.h" using namespace Kleo; using namespace Kleo::SmartCard; // static const std::string OpenPGPCard::AppName = "openpgp"; OpenPGPCard::OpenPGPCard(const Card &card) : Card(card) { setAppName(AppName); setInitialKeyInfos(OpenPGPCard::supportedKeys()); } // static std::string OpenPGPCard::pgpSigKeyRef() { return std::string("OPENPGP.1"); } // static std::string OpenPGPCard::pgpEncKeyRef() { return std::string("OPENPGP.2"); } // static std::string OpenPGPCard::pgpAuthKeyRef() { return std::string("OPENPGP.3"); } // static std::string OpenPGPCard::pinKeyRef() { return std::string("OPENPGP.1"); } // static std::string OpenPGPCard::adminPinKeyRef() { return std::string("OPENPGP.3"); } // static std::string OpenPGPCard::resetCodeKeyRef() { return std::string("OPENPGP.2"); } // static const std::vector & OpenPGPCard::supportedKeys() { static const std::vector keyInfos = { {OpenPGPCard::pgpSigKeyRef(), "", "sc", "", ""}, {OpenPGPCard::pgpEncKeyRef(), "", "e", "", ""}, {OpenPGPCard::pgpAuthKeyRef(), "", "a", "", ""} }; return keyInfos; } // static QString OpenPGPCard::keyDisplayName(const std::string &keyRef) { static const QMap displayNames = { { OpenPGPCard::pgpSigKeyRef(), i18n("Signature") }, { OpenPGPCard::pgpEncKeyRef(), i18n("Encryption") }, { OpenPGPCard::pgpAuthKeyRef(), i18n("Authentication") } }; return displayNames.value(keyRef); } -void OpenPGPCard::setCardInfo(const std::vector< std::pair > &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(); - if (parseCardInfo(pair.first, pair.second)) { - continue; - } - } -} - std::string OpenPGPCard::keyFingerprint(const std::string &keyRef) const { return cardInfo("KLEO-FPR-" + keyRef); } bool OpenPGPCard::operator == (const Card& rhs) const { const auto other = dynamic_cast(&rhs); if (!other) { return false; } return Card::operator ==(rhs) && mManufacturer == other->mManufacturer; } void OpenPGPCard::setManufacturer(const std::string &manufacturer) { mManufacturer = manufacturer; } std::string OpenPGPCard::manufacturer() const { return mManufacturer; } std::string OpenPGPCard::pubkeyUrl() const { return cardInfo("PUBKEY-URL"); } diff --git a/src/smartcard/openpgpcard.h b/src/smartcard/openpgpcard.h index ee177d173..ae1b4641e 100644 --- a/src/smartcard/openpgpcard.h +++ b/src/smartcard/openpgpcard.h @@ -1,57 +1,55 @@ /* smartcard/openpgpcard.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-FileCopyrightText: 2020 g10 Code GmbH SPDX-FileContributor: Ingo Klöcker SPDX-License-Identifier: GPL-2.0-or-later */ #pragma once #include "card.h" namespace Kleo { namespace SmartCard { struct KeyPairInfo; /** Class to work with OpenPGP smartcards or compatible tokens */ class OpenPGPCard: public Card { public: explicit OpenPGPCard(const Card &card); static const std::string AppName; static std::string pgpSigKeyRef(); static std::string pgpEncKeyRef(); static std::string pgpAuthKeyRef(); static std::string pinKeyRef(); static std::string adminPinKeyRef(); static std::string resetCodeKeyRef(); static const std::vector & supportedKeys(); static QString keyDisplayName(const std::string &keyRef); - void setCardInfo(const std::vector< std::pair > &infos); - std::string keyFingerprint(const std::string &keyRef) const; bool operator == (const Card& other) const override; void setManufacturer(const std::string &manufacturer); std::string manufacturer() const; std::string pubkeyUrl() const; private: std::string mManufacturer; }; } // namespace Smartcard } // namespace Kleopatra diff --git a/src/smartcard/p15card.cpp b/src/smartcard/p15card.cpp index 681bdc0ee..3d6c7b3b4 100644 --- a/src/smartcard/p15card.cpp +++ b/src/smartcard/p15card.cpp @@ -1,62 +1,50 @@ /* smartcard/p15card.cpp This file is part of Kleopatra, the KDE keymanager SPDX-FileCopyrightText: 2021 g10 Code GmbH SPDX-FileContributor: Andre Heinecke 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 cardInfo("KLEO-FPR-" + appKeyRef); } -void P15Card::setCardInfo(const std::vector< std::pair > &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; - } - } -} - 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(&rhs); if (!other) { return false; } return Card::operator ==(rhs) && mManufacturer == other->mManufacturer; } diff --git a/src/smartcard/p15card.h b/src/smartcard/p15card.h index b23ce5c8f..1fe6ffcee 100644 --- a/src/smartcard/p15card.h +++ b/src/smartcard/p15card.h @@ -1,55 +1,54 @@ /* smartcard/p15card.h This file is part of Kleopatra, the KDE keymanager SPDX-FileCopyrightText: 2021 g10 Code GmbH SPDX-FileContributor: Andre Heinecke SPDX-License-Identifier: GPL-2.0-or-later */ #pragma once #include "card.h" 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 > &infos); void setManufacturer(const std::string &manufacturer); std::string manufacturer() const; bool operator == (const Card& other) const override; private: std::string mManufacturer; }; } // namespace Smartcard } // namespace Kleopatra diff --git a/src/smartcard/pivcard.cpp b/src/smartcard/pivcard.cpp index 5ca617313..c285203b5 100644 --- a/src/smartcard/pivcard.cpp +++ b/src/smartcard/pivcard.cpp @@ -1,146 +1,135 @@ /* smartcard/pivcard.cpp This file is part of Kleopatra, the KDE keymanager SPDX-FileCopyrightText: 2020 g10 Code GmbH SPDX-FileContributor: Ingo Klöcker SPDX-License-Identifier: GPL-2.0-or-later */ #include "pivcard.h" #include "keypairinfo.h" #include #include "kleopatra_debug.h" using namespace Kleo; using namespace Kleo::SmartCard; // static const std::string PIVCard::AppName = "piv"; PIVCard::PIVCard(const Card &card) : Card(card) { setAppName(AppName); setInitialKeyInfos(PIVCard::supportedKeys()); } // static std::string PIVCard::pivAuthenticationKeyRef() { return std::string("PIV.9A"); } // static std::string PIVCard::cardAuthenticationKeyRef() { return std::string("PIV.9E"); } // static std::string PIVCard::digitalSignatureKeyRef() { return std::string("PIV.9C"); } // static std::string PIVCard::keyManagementKeyRef() { return std::string("PIV.9D"); } // static std::string PIVCard::pinKeyRef() { return std::string("PIV.80"); } // static std::string PIVCard::pukKeyRef() { return std::string("PIV.81"); } // static const std::vector & PIVCard::supportedKeys() { static const std::vector keyInfos = { {PIVCard::pivAuthenticationKeyRef(), "", "a", "", ""}, {PIVCard::cardAuthenticationKeyRef(), "", "a", "", ""}, {PIVCard::digitalSignatureKeyRef(), "", "sc", "", ""}, {PIVCard::keyManagementKeyRef(), "", "e", "", ""} }; return keyInfos; } // static QString PIVCard::keyDisplayName(const std::string &keyRef) { static const QMap displayNames = { { PIVCard::pivAuthenticationKeyRef(), i18n("PIV Authentication Key") }, { PIVCard::cardAuthenticationKeyRef(), i18n("Card Authentication Key") }, { PIVCard::digitalSignatureKeyRef(), i18n("Digital Signature Key") }, { PIVCard::keyManagementKeyRef(), i18n("Key Management Key") }, }; return displayNames.value(keyRef); } // static std::vector< std::pair > PIVCard::supportedAlgorithms(const std::string &keyRef) { if (keyRef == PIVCard::keyManagementKeyRef()) { return { { "rsa2048", i18n("RSA key transport (2048 bits)") }, { "nistp256", i18n("ECDH (Curve P-256)") }, { "nistp384", i18n("ECDH (Curve P-384)") } }; } else if (keyRef == PIVCard::digitalSignatureKeyRef()) { return { { "rsa2048", i18n("RSA (2048 bits)") }, { "nistp256", i18n("ECDSA (Curve P-256)") }, { "nistp384", i18n("ECDSA (Curve P-384)") } }; } // NIST SP 800-78-4 does not allow Curve P-384 for PIV Authentication key or Card Authentication key return { { "rsa2048", i18n("RSA (2048 bits)") }, { "nistp256", i18n("ECDSA (Curve P-256)") }, }; } -void PIVCard::setCardInfo(const std::vector< std::pair > &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(); - if (parseCardInfo(pair.first, pair.second)) { - continue; - } - } -} - std::string PIVCard::keyAlgorithm(const std::string &keyRef) const { return cardInfo("KLEO-KEYALGO-" + keyRef); } void PIVCard::setKeyAlgorithm(const std::string &keyRef, const std::string &algorithm) { addCardInfo("KLEO-KEYALGO-" + keyRef, algorithm); } std::string PIVCard::certificateData(const std::string &keyRef) const { return cardInfo("KLEO-CERTIFICATE-" + keyRef); } void PIVCard::setCertificateData(const std::string &keyRef, const std::string &data) { addCardInfo("KLEO-CERTIFICATE-" + keyRef, data); } diff --git a/src/smartcard/pivcard.h b/src/smartcard/pivcard.h index 54e1b2454..5b0008ea9 100644 --- a/src/smartcard/pivcard.h +++ b/src/smartcard/pivcard.h @@ -1,49 +1,47 @@ /* smartcard/pivcard.h This file is part of Kleopatra, the KDE keymanager SPDX-FileCopyrightText: 2020 g10 Code GmbH SPDX-FileContributor: Ingo Klöcker SPDX-License-Identifier: GPL-2.0-or-later */ #pragma once #include "card.h" namespace Kleo { namespace SmartCard { struct KeyPairInfo; /** Class to work with PIV smartcards or compatible tokens */ class PIVCard: public Card { public: explicit PIVCard(const Card &card); static const std::string AppName; static std::string pivAuthenticationKeyRef(); static std::string cardAuthenticationKeyRef(); static std::string digitalSignatureKeyRef(); static std::string keyManagementKeyRef(); static std::string pinKeyRef(); static std::string pukKeyRef(); static const std::vector & supportedKeys(); static QString keyDisplayName(const std::string &keyRef); static std::vector< std::pair > supportedAlgorithms(const std::string &keyRef); - void setCardInfo(const std::vector< std::pair > &infos); - std::string keyAlgorithm(const std::string &keyRef) const; void setKeyAlgorithm(const std::string &keyRef, const std::string &algorithm); std::string certificateData(const std::string &keyRef) const; void setCertificateData(const std::string &keyRef, const std::string &data); }; } // namespace Smartcard } // namespace Kleopatra