Commit 7ba9c16d authored by Ingo Klöcker's avatar Ingo Klöcker
Browse files

Clean up/modernize Card and its subclasses a bit

In particular, add constructors for converting a Card to the specific
Card subclasses. This ensures that all state already set on a Card is
copied to the specific subclass when we construct it. Previously, we
copied the serial number (but no other state) manually.

Card:
* Document that Card represents one of possibly many applications on
  a smartcard
* Make setAppName() protected since it's only supposed to be called by
  the subclasses during initialization
* Remove unused (and obsolete) mSlot, slot(), setSlot()
* Initialize member variables in class definition

NetKeyCard, OpenPGPCard, PIVCard:
* Remove default constructors and unused constructors from serial number
* Add constructors for converting a Card to the specific Card subclasses
parent 1af4827e
......@@ -8,15 +8,17 @@
*/
#include "card.h"
#include "readerstatus.h"
using namespace Kleo;
using namespace Kleo::SmartCard;
Card::Card(): mCanLearn(false),
mHasNullPin(false),
mStatus(Status::NoCard),
mAppVersion(-1)
Card::Card()
{
}
Card::~Card()
{
}
......@@ -70,16 +72,6 @@ void Card::setPinStates(const std::vector<PinState> &pinStates)
mPinStates = pinStates;
}
void Card::setSlot(int slot)
{
mSlot = slot;
}
int Card::slot() const
{
return mSlot;
}
bool Card::hasNullPin() const
{
return mHasNullPin;
......@@ -100,19 +92,18 @@ void Card::setCanLearnKeys(bool value)
mCanLearn = value;
}
bool Card::operator == (const Card& other) const
bool Card::operator == (const Card &other) const
{
return mStatus == other.status()
&& mSerialNumber == other.serialNumber()
&& mAppName == other.appName()
&& mAppVersion == other.appVersion()
&& mPinStates == other.pinStates()
&& mSlot == other.slot()
&& mCanLearn == other.canLearnKeys()
&& mHasNullPin == other.hasNullPin();
}
bool Card::operator != (const Card& other) const
bool Card::operator != (const Card &other) const
{
return !operator==(other);
}
......
......@@ -9,8 +9,8 @@
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <vector>
#include <string>
#include <vector>
#include <QString>
......@@ -18,7 +18,7 @@ namespace Kleo
{
namespace SmartCard
{
/** Class to work with Smartcards or other Hardware tokens. */
/** Class representing an application on a smartcard or similar hardware token. */
class Card
{
public:
......@@ -46,10 +46,10 @@ public:
};
Card();
virtual ~Card() {}
virtual ~Card();
virtual bool operator == (const Card& other) const;
bool operator != (const Card& other) const;
virtual bool operator == (const Card &other) const;
bool operator != (const Card &other) const;
void setStatus(Status s);
Status status() const;
......@@ -58,7 +58,6 @@ public:
std::string serialNumber() const;
std::string appName() const;
void setAppName(const std::string &name);
void setAppVersion(int version);
int appVersion() const;
......@@ -66,9 +65,6 @@ public:
std::vector<PinState> pinStates() const;
void setPinStates(const std::vector<PinState> &pinStates);
void setSlot(int slot);
int slot() const;
bool hasNullPin() const;
void setHasNullPin(bool value);
......@@ -78,15 +74,17 @@ public:
QString errorMsg() const;
void setErrorMsg(const QString &msg);
protected:
void setAppName(const std::string &name);
private:
bool mCanLearn;
bool mHasNullPin;
Status mStatus;
bool mCanLearn = false;
bool mHasNullPin = false;
Status mStatus = NoCard;
std::string mSerialNumber;
std::string mAppName;
int mAppVersion;
int mAppVersion = -1;
std::vector<PinState> mPinStates;
int mSlot;
QString mErrMsg;
};
} // namespace Smartcard
......
......@@ -51,7 +51,8 @@ static GpgME::Key parse_keypairinfo_and_lookup_key(GpgME::Context *ctx, const st
} // namespace
NetKeyCard::NetKeyCard()
NetKeyCard::NetKeyCard(const Card &card)
: Card(card)
{
setAppName(AppName);
}
......
......@@ -21,7 +21,7 @@ namespace SmartCard
class NetKeyCard: public Card
{
public:
NetKeyCard();
explicit NetKeyCard(const Card &card);
static const std::string AppName;
......
......@@ -29,16 +29,12 @@ using namespace Kleo::SmartCard;
// static
const std::string OpenPGPCard::AppName = "openpgp";
OpenPGPCard::OpenPGPCard()
OpenPGPCard::OpenPGPCard(const Card &card)
: Card(card)
{
setAppName(AppName);
}
OpenPGPCard::OpenPGPCard(const std::string &serialno): OpenPGPCard()
{
setSerialNumber(serialno);
}
// static
std::string OpenPGPCard::pinKeyRef()
{
......
......@@ -21,8 +21,7 @@ namespace SmartCard
class OpenPGPCard: public Card
{
public:
OpenPGPCard();
OpenPGPCard(const std::string &serialno);
explicit OpenPGPCard(const Card &card);
static const std::string AppName;
......
......@@ -21,16 +21,12 @@ using namespace Kleo::SmartCard;
// static
const std::string PIVCard::AppName = "piv";
PIVCard::PIVCard()
PIVCard::PIVCard(const Card &card)
: Card(card)
{
setAppName(AppName);
}
PIVCard::PIVCard(const std::string &serialno): PIVCard()
{
setSerialNumber(serialno);
}
// static
std::string PIVCard::pivAuthenticationKeyRef()
{
......
......@@ -21,8 +21,7 @@ namespace SmartCard
class PIVCard: public Card
{
public:
PIVCard();
PIVCard(const std::string &serialno);
explicit PIVCard(const Card &card);
static const std::string AppName;
......
......@@ -333,13 +333,12 @@ static const std::string get_manufacturer(std::shared_ptr<Context> &gpgAgent, Er
static void handle_openpgp_card(std::shared_ptr<Card> &ci, std::shared_ptr<Context> &gpg_agent)
{
Error err;
auto ret = new OpenPGPCard();
ret->setSerialNumber(ci->serialNumber());
auto pgpCard = new OpenPGPCard(*ci);
ret->setManufacturer(get_manufacturer(gpg_agent, err));
pgpCard->setManufacturer(get_manufacturer(gpg_agent, err));
if (err.code()) {
// fallback, e.g. if gpg does not yet support querying for the MANUFACTURER attribute
ret->setManufacturer(get_openpgp_card_manufacturer_from_serial_number(ci->serialNumber()));
pgpCard->setManufacturer(get_openpgp_card_manufacturer_from_serial_number(ci->serialNumber()));
}
const auto info = gpgagent_statuslines(gpg_agent, "SCD LEARN --keypairinfo", err);
......@@ -347,8 +346,8 @@ static void handle_openpgp_card(std::shared_ptr<Card> &ci, std::shared_ptr<Conte
ci->setStatus(Card::CardError);
return;
}
ret->setKeyPairInfo(info);
ci.reset(ret);
pgpCard->setKeyPairInfo(info);
ci.reset(pgpCard);
}
static void readKeyPairInfoFromPIVCard(const std::string &keyRef, PIVCard *pivCard, const std::shared_ptr<Context> &gpg_agent)
......@@ -397,8 +396,7 @@ static void readCertificateFromPIVCard(const std::string &keyRef, PIVCard *pivCa
static void handle_piv_card(std::shared_ptr<Card> &ci, std::shared_ptr<Context> &gpg_agent)
{
Error err;
auto pivCard = new PIVCard();
pivCard->setSerialNumber(ci->serialNumber());
auto pivCard = new PIVCard(*ci);
const auto displaySerialnumber = scd_getattr_status(gpg_agent, "$DISPSERIALNO", err);
if (err) {
......@@ -427,8 +425,7 @@ static void handle_piv_card(std::shared_ptr<Card> &ci, std::shared_ptr<Context>
static void handle_netkey_card(std::shared_ptr<Card> &ci, std::shared_ptr<Context> &gpg_agent)
{
Error err;
auto nkCard = new NetKeyCard();
nkCard->setSerialNumber(ci->serialNumber());
auto nkCard = new NetKeyCard(*ci);
ci.reset(nkCard);
ci->setAppVersion(parse_app_version(scd_getattr_status(gpg_agent, "NKS-VERSION", err)));
......@@ -533,18 +530,17 @@ static std::shared_ptr<Card> get_card_status(const std::string &serialNumber, co
}
ci->setSerialNumber(serialNumber);
ci->setAppName(appName);
// Handle different card types
if (ci->appName() == NetKeyCard::AppName) {
if (appName == NetKeyCard::AppName) {
qCDebug(KLEOPATRA_LOG) << "get_card_status: found Netkey card" << ci->serialNumber().c_str() << "end";
handle_netkey_card(ci, gpg_agent);
return ci;
} else if (ci->appName() == OpenPGPCard::AppName) {
} else if (appName == OpenPGPCard::AppName) {
qCDebug(KLEOPATRA_LOG) << "get_card_status: found OpenPGP card" << ci->serialNumber().c_str() << "end";
handle_openpgp_card(ci, gpg_agent);
return ci;
} else if (ci->appName() == PIVCard::AppName) {
} else if (appName == PIVCard::AppName) {
qCDebug(KLEOPATRA_LOG) << "get_card_status: found PIV card" << ci->serialNumber().c_str() << "end";
handle_piv_card(ci, gpg_agent);
return ci;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment