diff --git a/src/smartcard/openpgpcard.cpp b/src/smartcard/openpgpcard.cpp index cf3c14c71..aa057901b 100644 --- a/src/smartcard/openpgpcard.cpp +++ b/src/smartcard/openpgpcard.cpp @@ -1,105 +1,163 @@ /* 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-FileCopyrightText: 2020, 2022 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 "algorithminfo.h" + +#include + #include #include "kleopatra_debug.h" using namespace Kleo; using namespace Kleo::SmartCard; +static QDebug operator<<(QDebug s, const std::string &string) +{ + return s << QString::fromStdString(string); +} + // 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::setSupportedAlgorithms(const std::vector &algorithms) +{ + const static std::vector allowedAlgorithms = { + "brainpoolP256r1", + "brainpoolP384r1", + "brainpoolP512r1", + "curve25519", + "nistp256", + "nistp384", + "nistp521", + "rsa2048", + "rsa3072", + "rsa4096", + }; + mAlgorithms.clear(); + std::copy_if(algorithms.begin(), algorithms.end(), std::back_inserter(mAlgorithms), [](const auto &algo) { + return Kleo::contains(allowedAlgorithms, algo); + }); + if (mAlgorithms.size() < algorithms.size()) { + qWarning(KLEOPATRA_LOG).nospace() << "OpenPGPCard::" << __func__ << " Invalid algorithm in " << algorithms + << " (allowed algorithms: " << allowedAlgorithms << ")"; + } +} + std::string OpenPGPCard::pubkeyUrl() const { return cardInfo("PUBKEY-URL"); } + +std::vector OpenPGPCard::supportedAlgorithms(const std::string &keyRef) +{ + const static std::map displayNames = { + { "brainpoolP256r1", i18nc("@info", "ECC (Brainpool P-256)") }, + { "brainpoolP384r1", i18nc("@info", "ECC (Brainpool P-384)") }, + { "brainpoolP512r1", i18nc("@info", "ECC (Brainpool P-512)") }, + { "curve25519", i18nc("@info", "ECC (Curve 25519)") }, + { "nistp256", i18nc("@info", "ECC (NIST P-256)") }, + { "nistp384", i18nc("@info", "ECC (NIST P-384)") }, + { "nistp521", i18nc("@info", "ECC (NIST P-521)") }, + { "rsa2048", i18nc("@info", "RSA 2048") }, + { "rsa3072", i18nc("@info", "RSA 3072") }, + { "rsa4096", i18nc("@info", "RSA 4096") }, + }; + const std::string curve25519Algo = keyRef == OpenPGPCard::pgpEncKeyRef() ? "cv25519" : "ed25519"; + std::vector algos; + std::transform(mAlgorithms.cbegin(), mAlgorithms.cend(), std::back_inserter(algos), [curve25519Algo](const auto &algo) { + if (algo == "curve25519") { + return AlgorithmInfo{curve25519Algo, displayNames.at(algo)}; + } + return AlgorithmInfo{algo, displayNames.at(algo)}; + }); + return algos; +} diff --git a/src/smartcard/openpgpcard.h b/src/smartcard/openpgpcard.h index af8b2fada..c5ceca4c2 100644 --- a/src/smartcard/openpgpcard.h +++ b/src/smartcard/openpgpcard.h @@ -1,45 +1,68 @@ /* 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-FileCopyrightText: 2020, 2022 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 AlgorithmInfo; 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); + /** + * Sets the algorithms supported by this smart card to \p algorithms. + * The following values for algorithms are allowed: + * brainpoolP256r1, brainpoolP384r1, brainpoolP512r1, + * curve25519, + * nistp256, nistp384, nistp521, + * rsa2048, rsa3072, rsa4096. + */ + void setSupportedAlgorithms(const std::vector &algorithms); + std::string pubkeyUrl() const; + + /** + * Returns a list of algorithm names and corresponding display names suitable + * for the card slot specified by \p keyRef. + * + * \note For Curve25519, depending on the given card slot, either "ed25519" + * or "cv25519" is returned as algorithm ID. + */ + std::vector supportedAlgorithms(const std::string &keyRef); + +private: + std::vector mAlgorithms; }; } // namespace Smartcard } // namespace Kleopatra