Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify APDU SW usage #1292

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions client/Diagnostics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@
#include <QtCore/QTextStream>
#include <QtNetwork/QSslCertificate>

#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
namespace Qt {
using ::hex;
}
#endif

void Diagnostics::generalInfo(QTextStream &s)
{
s << "<b>" << tr("Arguments:") << "</b> " << Application::arguments().join(' ') << "<br />"
Expand Down Expand Up @@ -122,10 +128,10 @@ void Diagnostics::generalInfo(QTextStream &s)
{
constexpr auto APDU = &QByteArray::fromHex;
QPCSCReader::Result r = reader.transfer(apdu);
s << label << ": " << r.SW.toHex();
if (r.SW == APDU("9000")) s << " (OK)";
if (r.SW == APDU("6A81")) s << " (Locked)";
if (r.SW == APDU("6A82")) s << " (Not found)";
s << label << ": " << Qt::hex << r.SW;
if (r.SW == 0x9000) s << " (OK)";
if (r.SW == 0x6A81) s << " (Locked)";
if (r.SW == 0x6A82) s << " (Not found)";
s << "<br />";
return r;
};
Expand Down
32 changes: 12 additions & 20 deletions client/QSmartCard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,6 @@ QString QSmartCardData::typeString(QSmartCardData::PinType type)
return {};
}

const QByteArray Card::MASTER_FILE = APDU("00A4000C");
const QByteArray Card::MUTUAL_AUTH = APDU("00880000 00 00");
const QByteArray Card::CHANGE = APDU("00240000 00");
const QByteArray Card::READBINARY = APDU("00B00000 00");
const QByteArray Card::REPLACE = APDU("002C0000 00");
Expand Down Expand Up @@ -129,7 +127,7 @@ QHash<quint8,QByteArray> Card::parseFCI(const QByteArray &data)



const QByteArray IDEMIACard::AID = APDU("00A40400 10 A000000077010800070000FE00000100");
const QByteArray IDEMIACard::AID = APDU("00A4040C 10 A000000077010800070000FE00000100");
const QByteArray IDEMIACard::AID_OT = APDU("00A4040C 0D E828BD080FF2504F5420415750");
const QByteArray IDEMIACard::AID_QSCD = APDU("00A4040C 10 51534344204170706C69636174696F6E");

Expand Down Expand Up @@ -163,10 +161,7 @@ bool IDEMIACard::isSupported(const QByteArray &atr)

bool IDEMIACard::loadPerso(QPCSCReader *reader, QSmartCardDataPrivate *d) const
{
if(!reader->transfer(AID) ||
!reader->transfer(MASTER_FILE))
return false;
if(d->data.isEmpty() && reader->transfer(APDU("00A4010C025000")))
if(d->data.isEmpty() && reader->transfer(APDU("00A4090C 04 3F00 5000")))
{
QByteArray cmd = APDU("00A4020C025001");
for(char data = 1; data <= 8; ++data)
Expand Down Expand Up @@ -203,15 +198,13 @@ bool IDEMIACard::loadPerso(QPCSCReader *reader, QSmartCardDataPrivate *d) const
}

bool readFailed = false;
auto readCert = [&](const QByteArray &file1, const QByteArray &file2) {
if(!reader->transfer(MASTER_FILE) || !reader->transfer(file1))
auto readCert = [&](const QByteArray &path) {
QPCSCReader::Result data = reader->transfer(path);
if(!data)
{
readFailed = true;
return QSslCertificate();
}
QPCSCReader::Result data = reader->transfer(file2);
if(!data)
return QSslCertificate();
QHash<quint8,QByteArray> fci = parseFCI(data.data);
int size = fci.contains(0x80) ? quint8(fci[0x80][0]) << 8 | quint8(fci[0x80][1]) : 0x0600;
QByteArray cert;
Expand All @@ -231,9 +224,9 @@ bool IDEMIACard::loadPerso(QPCSCReader *reader, QSmartCardDataPrivate *d) const
return QSslCertificate(cert, QSsl::Der);
};
if(d->authCert.isNull())
d->authCert = readCert(APDU("00A4010C02ADF1"), APDU("00A4020402340100"));
d->authCert = readCert(APDU("00A40904 06 3F00 ADF1 3401 00"));
if(d->signCert.isNull())
d->signCert = readCert(APDU("00A4010C02ADF2"), APDU("00A4020402341F00"));
d->signCert = readCert(APDU("00A40904 06 3F00 ADF2 341F 00"));

if(readFailed)
return false;
Expand Down Expand Up @@ -280,7 +273,7 @@ QByteArray IDEMIACard::sign(QPCSCReader *reader, const QByteArray &dgst) const
if(!reader->transfer(AID_OT) ||
!reader->transfer(APDU("002241A4 09 8004FF200800840181")))
return {};
QByteArray cmd = MUTUAL_AUTH;
QByteArray cmd = APDU("00880000 00 00");
cmd[4] = char(std::min<size_t>(size_t(dgst.size()), 0x30));
cmd.insert(5, dgst.left(0x30));
return reader->transfer(cmd).data;
Expand All @@ -289,12 +282,12 @@ QByteArray IDEMIACard::sign(QPCSCReader *reader, const QByteArray &dgst) const
bool IDEMIACard::updateCounters(QPCSCReader *reader, QSmartCardDataPrivate *d) const
{
reader->transfer(AID);
if(auto data = reader->transfer(APDU("00CB3FFF 0A 4D087006BF810102A08000")))
if(auto data = reader->transfer(APDU("00CB3FFF 0A 4D087006BF810102A080 00")))
d->retry[QSmartCardData::Pin1Type] = quint8(data.data[13]);
if(auto data = reader->transfer(APDU("00CB3FFF 0A 4D087006BF810202A08000")))
if(auto data = reader->transfer(APDU("00CB3FFF 0A 4D087006BF810202A080 00")))
d->retry[QSmartCardData::PukType] = quint8(data.data[13]);
reader->transfer(AID_QSCD);
if(auto data = reader->transfer(APDU("00CB3FFF 0A 4D087006BF810502A08000")))
if(auto data = reader->transfer(APDU("00CB3FFF 0A 4D087006BF810502A080 00")))
d->retry[QSmartCardData::Pin2Type] = quint8(data.data[13]);
return true;
}
Expand All @@ -314,7 +307,7 @@ QSmartCard::ErrorType QSmartCard::Private::handlePinResult(QPCSCReader *reader,
{
if(!response || forceUpdate)
card->updateCounters(reader, t.d);
switch((quint8(response.SW[0]) << 8) + quint8(response.SW[1]))
switch(response.SW)
{
case 0x9000: return QSmartCard::NoError;
case 0x63C0: return QSmartCard::BlockedError;//pin retry count 0
Expand Down Expand Up @@ -471,7 +464,6 @@ void QSmartCard::reloadCard(const TokenData &token, bool reloadCounters)
t = d->t.d;
t->reader = selectedReader->name();
t->pinpad = selectedReader->isPinPad();
d->card.reset();
d->card = std::make_unique<IDEMIACard>();
if(d->card->loadPerso(selectedReader.data(), t))
{
Expand Down
3 changes: 0 additions & 3 deletions client/QSmartCard_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ class Card

static QHash<quint8,QByteArray> parseFCI(const QByteArray &data);

static const QByteArray MASTER_FILE;
static const QByteArray MUTUAL_AUTH;
static const QByteArray CHANGE;
static const QByteArray READBINARY;
static const QByteArray REPLACE;
Expand All @@ -61,7 +59,6 @@ class IDEMIACard: public Card
QByteArray sign(QPCSCReader *reader, const QByteArray &dgst) const final;
bool updateCounters(QPCSCReader *reader, QSmartCardDataPrivate *d) const final;

static QString cardNR(QPCSCReader *reader);
static bool isSupported(const QByteArray &atr);
static QByteArray pinTemplate(const QString &pin);

Expand Down
2 changes: 1 addition & 1 deletion common
Submodule common updated 3 files
+22 −17 QPCSC.cpp
+2 −7 QPCSC.h
+8 −14 QPCSC_p.h
Loading