Skip to content

Commit

Permalink
Remove Gemalto card support
Browse files Browse the repository at this point in the history
IB-7847

Signed-off-by: Raul Metsma <[email protected]>
  • Loading branch information
metsma committed Nov 30, 2023
1 parent 13f107a commit 3e810f9
Show file tree
Hide file tree
Showing 17 changed files with 57 additions and 422 deletions.
4 changes: 2 additions & 2 deletions client/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ if(NOT BUILD_DATE)
endif()

if(${QT_VERSION_MAJOR} STREQUAL "6")
find_package(Qt6 COMPONENTS Core5Compat SvgWidgets REQUIRED)
target_link_libraries(${PROJECT_NAME} Qt6::Core5Compat Qt6::SvgWidgets)
find_package(Qt6 COMPONENTS SvgWidgets REQUIRED)
target_link_libraries(${PROJECT_NAME} Qt6::SvgWidgets)
endif()

set_target_properties(${PROJECT_NAME} PROPERTIES
Expand Down
7 changes: 0 additions & 7 deletions client/CryptoDoc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,14 +226,7 @@ CKey::CKey(const QSslCertificate &c)
QString sn = c.subjectInfo("SN");
if(!gn.isEmpty() || !sn.isEmpty())
cn = QStringLiteral("%1 %2 %3").arg(gn, sn, c.personalCode());
QString o = c.subjectInfo(QSslCertificate::Organization);

static const QRegularExpression rx(QStringLiteral("ESTEID \\((.*)\\)"));
QRegularExpressionMatch match = rx.match(o);
if(match.hasMatch())
return QStringLiteral("%1 %2").arg(cn, match.captured(1));
if(o == QLatin1String("ESTEID"))
return QStringLiteral("%1 %2").arg(cn, CryptoDoc::tr("ID-CARD"));
int certType = c.type();
if(certType & SslCertificate::EResidentSubType)
return QStringLiteral("%1 %2").arg(cn, CryptoDoc::tr("Digi-ID E-RESIDENT"));
Expand Down
26 changes: 1 addition & 25 deletions client/Diagnostics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,31 +131,7 @@ void Diagnostics::generalInfo(QTextStream &s)
s << "<br />";
return r;
};
if(printAID(QStringLiteral("AID35"), APDU("00A40400 0F D23300000045737445494420763335")) ||
printAID(QStringLiteral("UPDATER_AID"), APDU("00A40400 0A D2330000005550443101")))
{
reader.transfer(APDU("00A4000C"));
reader.transfer(APDU("00A4010C 02 EEEE"));
reader.transfer(APDU("00A4020C 02 5044"));
QByteArray row = APDU("00B20004 00");
row[2] = 0x07; // read card id
s << "ID - " << reader.transfer(row).data << "<br />";

QString appletVersion;
if(QPCSCReader::Result data = reader.transfer(APDU("00CA0100 00")))
{
for(int i = 0; i < data.data.size(); ++i)
{
if(i == 0)
appletVersion = QString::number(quint8(data.data[i]));
else
appletVersion += QStringLiteral(".%1").arg(quint8(data.data[i]));
}
}
if(!appletVersion.isEmpty())
s << tr("Applet version") << ": " << appletVersion << "<br />";
}
else if(printAID(QStringLiteral("AID_IDEMIA"), APDU("00A40400 10 A000000077010800070000FE00000100")) ||
if(printAID(QStringLiteral("AID_IDEMIA"), APDU("00A40400 10 A000000077010800070000FE00000100")) ||
printAID(QStringLiteral("AID_OT"), APDU("00A4040C 0D E828BD080FF2504F5420415750")) ||
printAID(QStringLiteral("AID_QSCD"), APDU("00A4040C 10 51534344204170706C69636174696F6E")))
{
Expand Down
7 changes: 1 addition & 6 deletions client/MainWindow_MyEID.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ bool MainWindow::validateCardError(QSmartCardData::PinType type, QSmartCardData:

void MainWindow::showNotification( const QString &msg, bool isSuccess )
{
FadeInNotification* notification = new FadeInNotification(this,
auto *notification = new FadeInNotification(this,
isSuccess ? QStringLiteral("#ffffff") : QStringLiteral("#353739"),
isSuccess ? QStringLiteral("#498526") : QStringLiteral("#F8DDA7"), 110);
notification->start(msg, 750, 3000, 1200);
Expand Down Expand Up @@ -182,11 +182,6 @@ void MainWindow::updateCardWarnings(const QSmartCardData &data)
ui->myEid->invalidIcon(true);
warnings->showWarning(WarningText(WarningType::CertExpiredWarning));
}
else if(data.authCert().publicKey().algorithm() == QSsl::Rsa)
{
ui->myEid->invalidIcon(true);
warnings->showWarning(WarningText(WarningType::CertRevokedWarning));
}
else if(expiresIn <= 105 * DAY)
{
ui->myEid->warningIcon(true);
Expand Down
187 changes: 1 addition & 186 deletions client/QSmartCard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
#include <QtCore/QScopedPointer>
#include <QtCore/QTimer>
#include <QtNetwork/QSslKey>
#include <QTextCodec>

Q_LOGGING_CATEGORY(CLog, "qdigidoc4.QSmartCard")

Expand Down Expand Up @@ -65,7 +64,6 @@ QVariant QSmartCardData::data(PersonalDataType type) const
SslCertificate QSmartCardData::authCert() const { return d->authCert; }
SslCertificate QSmartCardData::signCert() const { return d->signCert; }
quint8 QSmartCardData::retryCount(PinType type) const { return d->retry.value(type); }
ulong QSmartCardData::usageCount(PinType type) const { return d->usage.value(type); }

quint8 QSmartCardData::minPinLen(QSmartCardData::PinType type)
{
Expand Down Expand Up @@ -114,184 +112,6 @@ QPCSCReader::Result Card::transfer(QPCSCReader *reader, bool verify, const QByte



const QByteArray EstEIDCard::ESTEIDDF = APDU("00A4010C 02 EEEE");
const QByteArray EstEIDCard::PERSONALDATA = APDU("00A4020C 02 5044");
const QTextCodec* EstEIDCard::codec = QTextCodec::codecForName("Windows-1252");

QPCSCReader::Result EstEIDCard::change(QPCSCReader *reader, QSmartCardData::PinType type, const QString &pin_, const QString &newpin_) const
{
QByteArray cmd = CHANGE;
QByteArray newpin = newpin_.toUtf8();
QByteArray pin = pin_.toUtf8();
cmd[3] = char(type == QSmartCardData::PukType ? 0 : type);
cmd[4] = char(pin.size() + newpin.size());
return transfer(reader, false, cmd + pin + newpin, type, quint8(pin.size()), true);
}

bool EstEIDCard::loadPerso(QPCSCReader *reader, QSmartCardDataPrivate *d) const
{
static const QByteArray AUTHCERT = APDU("00A40200 02 AACE");
static const QByteArray SIGNCERT = APDU("00A40200 02 DDCE");

if(reader->transfer(MASTER_FILE) &&
reader->transfer(ESTEIDDF) &&
d->data.isEmpty() && reader->transfer(PERSONALDATA))
{
QByteArray cmd = READRECORD;
for(char data = QSmartCardData::SurName; data != QSmartCardData::Comment4; ++data)
{
cmd[2] = data;
QPCSCReader::Result result = reader->transfer(cmd);
if(!result)
return false;
QString record = codec->toUnicode(result.data.trimmed());
if(record == QChar(0))
record.clear();
switch(data)
{
case QSmartCardData::BirthDate:
case QSmartCardData::IssueDate:
d->data[QSmartCardData::PersonalDataType(data)] = QDate::fromString(record, QStringLiteral("dd.MM.yyyy"));
break;
case QSmartCardData::Expiry:
d->data[QSmartCardData::PersonalDataType(data)] = QDateTime::fromString(record, QStringLiteral("dd.MM.yyyy")).addDays(1).addSecs(-1);
break;
default:
d->data[QSmartCardData::PersonalDataType(data)] = record;
break;
}
}
}
bool readFailed = false;
auto readCert = [&](const QByteArray &file) {
// Workaround some cards, add Le to end
QPCSCReader::Result data = reader->transfer(file + APDU(reader->protocol() == QPCSCReader::T1 ? "00" : ""));
if(!data)
return QSslCertificate();
QHash<quint8,QByteArray> fci = QSmartCard::parseFCI(data.data);
int size = fci.contains(0x85) ? quint8(fci[0x85][0]) << 8 | quint8(fci[0x85][1]) : 0x0600;
QByteArray cert;
QByteArray cmd = READBINARY;
while(cert.size() < size)
{
cmd[2] = char(cert.size() >> 8);
cmd[3] = char(cert.size());
data = reader->transfer(cmd);
if(!data)
{
readFailed = true;
return QSslCertificate();
}
cert += data.data;
}
return QSslCertificate(cert, QSsl::Der);
};
if(d->authCert.isNull())
d->authCert = readCert(AUTHCERT);
if(d->signCert.isNull())
d->signCert = readCert(SIGNCERT);
if(readFailed)
return false;
d->data[QSmartCardData::Email] = d->authCert.subjectAlternativeNames().values(QSsl::EmailEntry).value(0);
return updateCounters(reader, d);
}

QPCSCReader::Result EstEIDCard::replace(QPCSCReader *reader, QSmartCardData::PinType type, const QString &puk_, const QString &pin_) const
{
QPCSCReader::Result result;
if(!reader->isPinPad()) //Verify PUK. Not for pinpad.
{
result = verify(reader, QSmartCardData::PukType, puk_);
if(!result)
return result;
}

// Replace PIN with PUK
QByteArray pin = pin_.toUtf8();
QByteArray puk = puk_.toUtf8();
QByteArray cmd = Card::REPLACE;
cmd[3] = type;
cmd[4] = char(puk.size() + pin.size());
return transfer(reader, false, cmd + puk + pin, type, 0, true);
}

QByteArray EstEIDCard::sign(QPCSCReader *reader, const QByteArray &dgst) const
{
if(!reader->transfer(APDU("0022F301")) || // 00")) || // Compatibilty for some cards // SECENV1
!reader->transfer(APDU("002241B8 02 8300"))) //Key reference, 8303801100
return {};
QByteArray cmd = MUTUAL_AUTH;
cmd[4] = char(dgst.size());
cmd.insert(5, dgst);
return reader->transfer(cmd).data;
}

bool EstEIDCard::updateCounters(QPCSCReader *reader, QSmartCardDataPrivate *d) const
{
static const QByteArray KEYPOINTER = APDU("00A4020C 02 0033");
static const QByteArray KEYUSAGE = APDU("00A4020C 02 0013");
static const QByteArray PINRETRY = APDU("00A4020C 02 0016");

if(!reader->transfer(MASTER_FILE) ||
!reader->transfer(PINRETRY))
return false;

QByteArray cmd = READRECORD;
for(int i = QSmartCardData::Pin1Type; i <= QSmartCardData::PukType; ++i)
{
cmd[2] = char(i);
QPCSCReader::Result data = reader->transfer(cmd);
if(!data)
return false;
d->retry[QSmartCardData::PinType(i)] = quint8(data.data[5]);
}

if(!reader->transfer(ESTEIDDF) ||
!reader->transfer(KEYPOINTER))
return false;

cmd[2] = 1;
QPCSCReader::Result data = reader->transfer(cmd);
if(!data)
return false;

/*
* SIGN1 0100 1
* SIGN2 0200 2
* AUTH1 1100 3
* AUTH2 1200 4
*/
quint8 signkey = data.data.at(0x13) == 0x01 && data.data.at(0x14) == 0x00 ? 1 : 2;
quint8 authkey = data.data.at(0x09) == 0x11 && data.data.at(0x0A) == 0x00 ? 3 : 4;

if(!reader->transfer(KEYUSAGE))
return false;

cmd[2] = char(authkey);
data = reader->transfer(cmd);
if(!data)
return false;
d->usage[QSmartCardData::Pin1Type] = 0xFFFFFF - ((quint8(data.data[12]) << 16) + (quint8(data.data[13]) << 8) + quint8(data.data[14]));

cmd[2] = char(signkey);
data = reader->transfer(cmd);
if(!data)
return false;
d->usage[QSmartCardData::Pin2Type] = 0xFFFFFF - ((quint8(data.data[12]) << 16) + (quint8(data.data[13]) << 8) + quint8(data.data[14]));
return true;
}

QPCSCReader::Result EstEIDCard::verify(QPCSCReader *reader, QSmartCardData::PinType type, const QString &pin_) const
{
QByteArray pin = pin_.toUtf8();
QByteArray cmd = VERIFY;
cmd[3] = char(type == QSmartCardData::PukType ? 0 : type);
cmd[4] = char(pin.size());
return transfer(reader, true, cmd + pin, type, 0, true);
}



const QByteArray IDEMIACard::AID = APDU("00A40400 10 A000000077010800070000FE00000100");
const QByteArray IDEMIACard::AID_OT = APDU("00A4040C 0D E828BD080FF2504F5420415750");
const QByteArray IDEMIACard::AID_QSCD = APDU("00A4040C 10 51534344204170706C69636174696F6E");
Expand Down Expand Up @@ -452,8 +272,6 @@ QByteArray IDEMIACard::sign(QPCSCReader *reader, const QByteArray &dgst) const

bool IDEMIACard::updateCounters(QPCSCReader *reader, QSmartCardDataPrivate *d) const
{
d->usage[QSmartCardData::Pin1Type] = 0;
d->usage[QSmartCardData::Pin2Type] = 0;
reader->transfer(AID);
if(auto data = reader->transfer(APDU("00CB3FFF 0A 4D087006BF810102A08000")))
d->retry[QSmartCardData::Pin1Type] = quint8(data.data[13]);
Expand Down Expand Up @@ -684,10 +502,7 @@ void QSmartCard::reloadCard(const TokenData &token)
t->reader = selectedReader->name();
t->pinpad = selectedReader->isPinPad();
delete d->card;
if(IDEMIACard::isSupported(selectedReader->atr()))
d->card = new IDEMIACard();
else
d->card = new EstEIDCard();
d->card = new IDEMIACard();
if(d->card->loadPerso(selectedReader.data(), t))
{
d->t.d = t;
Expand Down
4 changes: 2 additions & 2 deletions client/QSmartCard.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ class QSmartCardData
SslCertificate authCert() const;
SslCertificate signCert() const;
quint8 retryCount( PinType type ) const;
ulong usageCount( PinType type ) const;

static quint8 minPinLen(QSmartCardData::PinType type);
static QString typeString( PinType type );
Expand Down Expand Up @@ -106,7 +105,7 @@ class QSmartCard: public QObject
};

explicit QSmartCard(QObject *parent = nullptr);
~QSmartCard();
~QSmartCard() override;

ErrorType change( QSmartCardData::PinType type, QWidget* parent, const QString &newpin, const QString &pin, const QString &title, const QString &bodyText );
QSmartCardData data() const;
Expand All @@ -123,6 +122,7 @@ class QSmartCard: public QObject
void dataChanged(const QSmartCardData &data);

private:
Q_DISABLE_COPY_MOVE(QSmartCard)
void reload();

class Private;
Expand Down
20 changes: 0 additions & 20 deletions client/QSmartCard_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@

#define APDU QByteArray::fromHex

class QTextCodec;

class Card
{
public:
Expand All @@ -54,23 +52,6 @@ class Card
static const QByteArray VERIFY;
};

class EstEIDCard: public Card
{
public:
QPCSCReader::Result change(QPCSCReader *reader, QSmartCardData::PinType type, const QString &pin, const QString &newpin) const final;
bool loadPerso(QPCSCReader *reader, QSmartCardDataPrivate *d) const final;
QPCSCReader::Result replace(QPCSCReader *reader, QSmartCardData::PinType type, const QString &puk, const QString &pin) const final;
QByteArray sign(QPCSCReader *reader, const QByteArray &dgst) const final;
bool updateCounters(QPCSCReader *reader, QSmartCardDataPrivate *d) const final;
QPCSCReader::Result verify(QPCSCReader *reader, QSmartCardData::PinType type, const QString &pin) const final;

static QString cardNR(QPCSCReader *reader);

static const QTextCodec *codec;
static const QByteArray ESTEIDDF;
static const QByteArray PERSONALDATA;
};

class IDEMIACard: public Card
{
public:
Expand Down Expand Up @@ -107,6 +88,5 @@ class QSmartCardDataPrivate: public QSharedData
QHash<QSmartCardData::PersonalDataType,QVariant> data;
SslCertificate authCert, signCert;
QHash<QSmartCardData::PinType,quint8> retry;
QHash<QSmartCardData::PinType,ulong> usage;
bool pinpad = false;
};
1 change: 0 additions & 1 deletion client/common_enums.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ enum WarningType {

CertExpiredWarning,
CertExpiryWarning,
CertRevokedWarning,
UnblockPin1Warning,
UnblockPin2Warning,

Expand Down
5 changes: 2 additions & 3 deletions client/dialogs/SettingsDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,15 +238,14 @@ SettingsDialog::SettingsDialog(int page, QWidget *parent)
});
#ifdef Q_OS_WIN
connect(ui->btnNavFromHistory, &QPushButton::clicked, this, [this] {
// remove certificates (having %ESTEID% text) from browsing history of Internet Explorer and/or Google Chrome, and do it for all users.
// remove certificates from browsing history of Internet Explorer and/or Google Chrome, and do it for all users.
QList<TokenData> cache = qApp->signer()->cache();
CertStore s;
for(const QSslCertificate &c: s.list())
{
if(std::any_of(cache.cbegin(), cache.cend(), [&](const TokenData &token) { return token.cert() == c; }))
continue;
if(c.subjectInfo(QSslCertificate::Organization).join(QString()).contains(QStringLiteral("ESTEID"), Qt::CaseInsensitive) ||
c.issuerInfo(QSslCertificate::CommonName).join(QString()).contains(QStringLiteral("KLASS3-SK"), Qt::CaseInsensitive) ||
if(c.issuerInfo(QSslCertificate::CommonName).join(QString()).contains(QStringLiteral("KLASS3-SK"), Qt::CaseInsensitive) ||
c.issuerInfo(QSslCertificate::Organization).contains(QStringLiteral("SK ID Solutions AS"), Qt::CaseInsensitive))
s.remove( c );
}
Expand Down
Loading

0 comments on commit 3e810f9

Please sign in to comment.