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

Take manufacturer from card info if available

Card:
* Parse MANUFACTURER card info value
* Add possibility to set manufacturer (e.g. for old versions of gpg)

OpenPGPCard, P15Card:
* Remove manufacturer
* Remove now obsolete overrides of operator==

ReaderStatus:
* Use fallback for guessing the OpenPGP card manufacturer from the
  serial number, if MANUFACTURER isn't included in card info
* For PKCS#15 cards this fallback isn't necessary

GnuPG-bug-id: 4876
parent 5e08d5d5
......@@ -101,6 +101,20 @@ 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;
......@@ -286,6 +300,17 @@ void Card::parseCardInfo(const std::string &name, const std::string &value)
// 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});
}
......
......@@ -71,6 +71,9 @@ public:
int appVersion() const;
QString displayAppVersion() const;
void setManufacturer(const std::string &manufacturer);
std::string manufacturer() const;
std::string cardType() const;
int cardVersion() const;
......
......@@ -104,27 +104,6 @@ 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<const OpenPGPCard *>(&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");
......
......@@ -39,15 +39,7 @@ public:
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
......
......@@ -27,24 +27,3 @@ std::string P15Card::appKeyFingerprint(const std::string &appKeyRef) const
{
return cardInfo("KLEO-FPR-" + appKeyRef);
}
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<const P15Card *>(&rhs);
if (!other) {
return false;
}
return Card::operator ==(rhs)
&& mManufacturer == other->mManufacturer;
}
......@@ -40,14 +40,6 @@ public:
* e.g. An App Key Ref would be
* OpenPGPCard::pgpSigKeyRef */
std::string appKeyFingerprint(const std::string &appKeyRef) const;
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
......
......@@ -366,30 +366,6 @@ static const char * get_openpgp_card_manufacturer_from_serial_number(const std::
}
}
static const std::string get_manufacturer(std::shared_ptr<Context> &gpgAgent, Error &err)
{
// The result of SCD GETATTR 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
const auto manufacturerIdAndName = scd_getattr_status(gpgAgent, "MANUFACTURER", err);
if (err.code()) {
if (err.code() == GPG_ERR_INV_NAME) {
qCDebug(KLEOPATRA_LOG) << "get_manufacturer(): Querying for attribute MANUFACTURER not yet supported; needs GnuPG 2.2.21+";
} else {
qCWarning(KLEOPATRA_LOG) << "Running SCD GETATTR MANUFACTURER failed:" << err;
}
return std::string();
}
const auto startOfManufacturerName = manufacturerIdAndName.find(' ');
if (startOfManufacturerName == std::string::npos) {
// only ID without manufacturer name
return "unknown";
}
const auto manufacturerName = manufacturerIdAndName.substr(startOfManufacturerName + 1);
return manufacturerName;
}
static bool isOpenPGPCardSerialNumber(const std::string &serialNumber)
{
return serialNumber.size() == 32 && serialNumber.substr(0, 12) == "D27600012401";
......@@ -428,12 +404,6 @@ static void handle_openpgp_card(std::shared_ptr<Card> &ci, std::shared_ptr<Conte
Error err;
auto pgpCard = new OpenPGPCard(*ci);
pgpCard->setManufacturer(get_manufacturer(gpg_agent, err));
if (err.code()) {
// fallback, e.g. if gpg does not yet support querying for the MANUFACTURER attribute
pgpCard->setManufacturer(get_openpgp_card_manufacturer_from_serial_number(ci->serialNumber()));
}
const auto info = gpgagent_statuslines(gpg_agent, "SCD LEARN --force", err);
if (err.code()) {
ci->setStatus(Card::CardError);
......@@ -441,6 +411,11 @@ static void handle_openpgp_card(std::shared_ptr<Card> &ci, std::shared_ptr<Conte
}
pgpCard->setCardInfo(info);
if (pgpCard->manufacturer().empty()) {
// fallback in case MANUFACTURER is not yet included in the card info
pgpCard->setManufacturer(get_openpgp_card_manufacturer_from_serial_number(ci->serialNumber()));
}
setDisplaySerialNumber(pgpCard, gpg_agent);
ci.reset(pgpCard);
......@@ -531,7 +506,6 @@ static void handle_p15_card(std::shared_ptr<Card> &ci, std::shared_ptr<Context>
gpgagent_statuslines(gpg_agent, "READKEY --card --no-data -- $ENCRKEYID", err);
p15Card->setCardInfo(info);
p15Card->setManufacturer(get_manufacturer(gpg_agent, err));
setDisplaySerialNumber(p15Card, gpg_agent);
......
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