Skip to content

Commit 308ba75

Browse files
committed
Thales cards do not return Card NR anymore
IB-8696 Signed-off-by: Raul Metsma <[email protected]>
1 parent a3955d7 commit 308ba75

File tree

11 files changed

+66
-114
lines changed

11 files changed

+66
-114
lines changed

client/Diagnostics.cpp

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -109,14 +109,7 @@ void Diagnostics::generalInfo(QTextStream &s)
109109
if( !reader.isPresent() )
110110
continue;
111111

112-
reader.reconnect( QPCSCReader::UnpowerCard );
113-
QString cold = reader.atr();
114-
reader.reconnect( QPCSCReader::ResetCard );
115-
QString warm = reader.atr();
116-
117-
s << "ATR cold - " << cold << "<br />"
118-
<< "ATR warm - " << warm << "<br />";
119-
112+
s << "ATR - " << reader.atr() << "<br />";
120113
reader.beginTransaction();
121114
constexpr auto APDU = &QByteArray::fromHex;
122115
auto printAID = [&](const QLatin1String &label, const QByteArray &apdu)

client/MainWindow.cpp

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -86,18 +86,16 @@ MainWindow::MainWindow( QWidget *parent )
8686

8787
// Refresh ID card info in card widget
8888
connect(qApp->signer(), &QSigner::cacheChanged, this, &MainWindow::updateSelector);
89-
connect(&QPCSC::instance(), &QPCSC::statusChanged, this, &MainWindow::updateSelector);
9089
connect(qApp->signer(), &QSigner::signDataChanged, this, [this](const TokenData &token) {
91-
updateSelectorData(token);
90+
updateSelector();
9291
updateMyEID(token);
9392
ui->signContainerPage->cardChanged(token.cert(), token.data(QStringLiteral("blocked")).toBool());
9493
});
9594
connect(qApp->signer(), &QSigner::authDataChanged, this, [this](const TokenData &token) {
96-
updateSelectorData(token);
95+
updateSelector();
9796
updateMyEID(token);
9897
ui->cryptoContainerPage->cardChanged(token.cert(), token.data(QStringLiteral("blocked")).toBool());
9998
});
100-
QPCSC::instance().start();
10199

102100
// Refresh card info on "My EID" page
103101
connect(qApp->signer()->smartcard(), &QSmartCard::dataChanged, this, &MainWindow::updateMyEid);
@@ -124,7 +122,7 @@ MainWindow::MainWindow( QWidget *parent )
124122
connect(ui->accordion, &Accordion::changePinClicked, this, &MainWindow::changePinClicked);
125123
connect(ui->cardInfo, &CardWidget::selected, ui->selector, &QToolButton::toggle);
126124

127-
updateSelectorData(qApp->signer()->tokensign());
125+
updateSelector();
128126
updateMyEID(qApp->signer()->tokensign());
129127
ui->signContainerPage->cardChanged(qApp->signer()->tokensign().cert());
130128
ui->cryptoContainerPage->cardChanged(qApp->signer()->tokenauth().cert());
@@ -885,11 +883,7 @@ bool MainWindow::wrapContainer(bool signing)
885883

886884
void MainWindow::updateSelector()
887885
{
888-
updateSelectorData({});
889-
}
890-
891-
void MainWindow::updateSelectorData(TokenData data)
892-
{
886+
TokenData selected;
893887
enum Filter: uint8_t {
894888
Signing,
895889
Decrypting,
@@ -899,24 +893,24 @@ void MainWindow::updateSelectorData(TokenData data)
899893
{
900894
case SignIntro:
901895
case SignDetails:
902-
if(data.isNull()) data = qApp->signer()->tokensign();
896+
selected = qApp->signer()->tokensign();
903897
filter = Signing;
904898
break;
905899
case CryptoIntro:
906900
case CryptoDetails:
907-
if(data.isNull()) data = qApp->signer()->tokenauth();
901+
selected = qApp->signer()->tokenauth();
908902
filter = Decrypting;
909903
break;
910904
case MyEid:
911905
default:
912-
if(data.isNull()) data = qApp->signer()->smartcard()->tokenData();
906+
selected = qApp->signer()->smartcard()->tokenData();
913907
filter = MyEID;
914908
break;
915909
}
916910
QVector<TokenData> list;
917911
for(const TokenData &token: qApp->signer()->cache())
918912
{
919-
if(token.card() == data.card())
913+
if(token.card() == selected.card())
920914
continue;
921915
if(std::any_of(list.cbegin(), list.cend(), [token](const TokenData &item) { return token.card() == item.card(); }))
922916
continue;
@@ -935,7 +929,7 @@ void MainWindow::updateSelectorData(TokenData data)
935929
ui->selector->setChecked(false);
936930
ui->cardInfo->setVisible(ui->noCardInfo->isHidden());
937931
ui->cardInfo->setCursor(ui->selector->isVisible() ? Qt::PointingHandCursor : Qt::ArrowCursor);
938-
ui->cardInfo->update(data, list.size() > 1);
932+
ui->cardInfo->update(selected, list.size() > 1);
939933
if (!QPCSC::instance().serviceRunning())
940934
ui->noCardInfo->update(NoCardInfo::NoPCSC);
941935
else if(QPCSC::instance().readers().isEmpty())

client/MainWindow.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ class MainWindow final : public QWidget
8585
bool validateFiles(const QString &container, const QStringList &files);
8686
void showPinBlockedWarning(const QSmartCardData &data);
8787
void updateSelector();
88-
void updateSelectorData(TokenData data);
8988
void updateMyEID(const TokenData &t);
9089
void updateMyEid(const QSmartCardData &data);
9190
bool wrap(const QString& wrappedFile, bool enclose);

client/QCNG.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "SslCertificate.h"
2424
#include "TokenData.h"
2525

26+
#include <QtCore/QUuid>
2627
#include <QtCore/QLoggingCategory>
2728
#include <QtNetwork/QSslKey>
2829

@@ -220,7 +221,8 @@ QList<TokenData> QCNG::tokens() const
220221
if(QByteArray tmp = prop(key, NCRYPT_READER_PROPERTY); !tmp.isEmpty())
221222
reader = QString::fromUtf16((const char16_t*)tmp.data());
222223
}
223-
QString guid = prop(h, NCRYPT_SMARTCARD_GUID_PROPERTY).trimmed();
224+
QByteArray guidData = prop(h, NCRYPT_SMARTCARD_GUID_PROPERTY);
225+
QString guid = guidData[0] >= 0x20 && guidData[0] < 0x7F ? guidData.trimmed() : QUuid(*((GUID*)guidData.data())).toString(QUuid::WithBraces);
224226
TokenData &t = result.emplaceBack();
225227
t.setReader(reader);
226228
t.setCard(cert.type() & SslCertificate::EstEidType || cert.type() & SslCertificate::DigiIDType ?
@@ -232,7 +234,8 @@ QList<TokenData> QCNG::tokens() const
232234
qCWarning(CNG) << "key" << t.data(u"provider"_s)
233235
<< "spec" << t.data(u"spec"_s)
234236
<< "alg" << QStringView(keyname->pszAlgid)
235-
<< "flags" << keyname->dwFlags;
237+
<< "flags" << keyname->dwFlags
238+
<< t.card();
236239
if(cert.publicKey().algorithm() != QSsl::Rsa || reader.isEmpty())
237240
continue;
238241

client/QPCSC.cpp

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@
2727
#include <array>
2828
#include <cstring>
2929

30-
Q_LOGGING_CATEGORY(APDU,"QPCSC.APDU")
31-
Q_LOGGING_CATEGORY(SCard,"QPCSC.SCard")
30+
static Q_LOGGING_CATEGORY(APDU,"QPCSC.APDU")
31+
static Q_LOGGING_CATEGORY(SCard,"QPCSC.SCard")
3232

3333
static quint16 toUInt16(const QByteArray &data, int size)
3434
{
@@ -94,10 +94,12 @@ QPCSC::QPCSC()
9494
QPCSC::~QPCSC()
9595
{
9696
requestInterruption();
97+
d->sleepCond.wakeAll();
98+
if(d->thread)
99+
SC(Cancel, d->thread);
97100
wait();
98-
if( d->context )
101+
if(d->context)
99102
SC(ReleaseContext, d->context);
100-
qDeleteAll(d->lock);
101103
delete d;
102104
}
103105

@@ -138,23 +140,30 @@ void QPCSC::run()
138140
std::vector<SCARD_READERSTATE> list;
139141
while(!isInterruptionRequested())
140142
{
141-
if(!pcsc.serviceRunning())
142-
{
143-
sleep(5);
144-
continue;
145-
}
146143
// "\\?PnP?\Notification" does not work on macOS
147144
QByteArray data = pcsc.rawReaders();
148145
if(data.isEmpty())
149146
{
150-
sleep(5);
147+
QMutexLocker locker(&d->sleepMutex);
148+
if (isInterruptionRequested())
149+
break;
150+
d->sleepCond.wait(&d->sleepMutex, 5000);
151151
continue;
152152
}
153153
for(const char *name = data.constData(); *name; name += strlen(name) + 1)
154154
{
155155
if(std::none_of(list.cbegin(), list.cend(), [&name](const SCARD_READERSTATE &state) { return strcmp(state.szReader, name) == 0; }))
156156
list.push_back({ strdup(name), nullptr, 0, 0, 0, {} });
157157
}
158+
if(list.empty())
159+
{
160+
QMutexLocker locker(&d->sleepMutex);
161+
if (isInterruptionRequested())
162+
break;
163+
d->sleepCond.wait(&d->sleepMutex, 5000);
164+
continue;
165+
}
166+
d->thread = pcsc.d->context;
158167
if(SC(GetStatusChange, pcsc.d->context, 5*1000U, list.data(), DWORD(list.size())) != SCARD_S_SUCCESS)
159168
continue;
160169
for(auto i = list.begin(); i != list.end(); )
@@ -176,6 +185,7 @@ void QPCSC::run()
176185
++i;
177186
}
178187
}
188+
d->thread = {};
179189
}
180190

181191
bool QPCSC::serviceRunning() const
@@ -191,9 +201,6 @@ bool QPCSC::serviceRunning() const
191201
QPCSCReader::QPCSCReader( const QString &reader, QPCSC *parent )
192202
: d(new Private)
193203
{
194-
if(!parent->d->lock.contains(reader))
195-
parent->d->lock[reader] = new QMutex();
196-
parent->d->lock[reader]->lock();
197204
d->d = parent->d;
198205
d->reader = reader.toUtf8();
199206
d->state.szReader = d->reader.constData();
@@ -203,7 +210,6 @@ QPCSCReader::QPCSCReader( const QString &reader, QPCSC *parent )
203210
QPCSCReader::~QPCSCReader()
204211
{
205212
disconnect();
206-
d->d->lock[d->reader]->unlock();
207213
delete d;
208214
}
209215

@@ -218,15 +224,10 @@ bool QPCSCReader::beginTransaction()
218224
}
219225

220226
bool QPCSCReader::connect(Connect connect, Mode mode)
221-
{
222-
return connectEx(connect, mode) == SCARD_S_SUCCESS;
223-
}
224-
225-
quint32 QPCSCReader::connectEx(Connect connect, Mode mode)
226227
{
227228
LONG err = SC(Connect, d->d->context, d->state.szReader, connect, mode, &d->card, &d->io.dwProtocol);
228229
updateState();
229-
return quint32(err);
230+
return err == SCARD_S_SUCCESS;
230231
}
231232

232233
void QPCSCReader::disconnect( Reset reset )
@@ -290,15 +291,6 @@ QHash<QPCSCReader::Properties, int> QPCSCReader::properties() const
290291
return properties;
291292
}
292293

293-
bool QPCSCReader::reconnect( Reset reset, Mode mode )
294-
{
295-
if( !d->card )
296-
return false;
297-
LONG err = SC(Reconnect, d->card, DWORD(SCARD_SHARE_SHARED), mode, reset, &d->io.dwProtocol);
298-
updateState();
299-
return err == SCARD_S_SUCCESS;
300-
}
301-
302294
QStringList QPCSCReader::state() const
303295
{
304296
return stateToString(d->state.dwEventState);

client/QPCSC.h

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class QPCSC final: public QThread
4444
QByteArray rawReaders() const;
4545
void run() final;
4646

47-
class Private;
47+
struct Private;
4848
Private *d;
4949

5050
friend class QPCSCReader;
@@ -61,7 +61,7 @@ class QPCSCReader final: public QObject
6161
constexpr operator bool() const { return SW == 0x9000; }
6262
};
6363

64-
enum Properties {
64+
enum Properties : quint8 {
6565
wLcdLayout = 0x01,
6666
bEntryValidationCondition = 0x02,
6767
bTimeOut2 = 0x03,
@@ -76,21 +76,20 @@ class QPCSCReader final: public QObject
7676
wIdProduct = 0x0C
7777
};
7878

79-
enum Connect {
79+
enum Connect : quint8 {
8080
Exclusive = 1,
8181
Shared = 2,
8282
Direct = 3
8383
};
8484

85-
enum Reset
86-
{
85+
enum Reset : quint8 {
8786
LeaveCard = 0,
8887
ResetCard = 1,
8988
UnpowerCard = 2,
9089
EjectCard = 3
9190
};
9291

93-
enum Mode {
92+
enum Mode : quint8 {
9493
Undefined = 0,
9594
T0 = 1,
9695
T1 = 2
@@ -105,20 +104,19 @@ class QPCSCReader final: public QObject
105104
QString name() const;
106105
QHash<Properties,int> properties() const;
107106
QStringList state() const;
108-
bool updateState( quint32 msec = 0 );
109107

110108
bool connect( Connect connect = Shared, Mode mode = Mode(T0|T1) );
111-
quint32 connectEx( Connect connect = Shared, Mode mode = Mode(T0|T1) );
112109
void disconnect( Reset reset = LeaveCard );
113-
bool reconnect( Reset reset = LeaveCard, Mode mode = Mode(T0|T1) );
114110
bool beginTransaction();
115111
bool endTransaction( Reset reset = LeaveCard );
116112
Result transfer( const QByteArray &apdu ) const;
117113
Result transferCTL(const QByteArray &apdu, bool verify, quint16 lang = 0,
118114
quint8 minlen = 4, quint8 newPINOffset = 0, bool requestCurrentPIN = true) const;
119115

120116
private:
117+
bool updateState( quint32 msec = 0 );
118+
121119
Q_DISABLE_COPY(QPCSCReader)
122-
class Private;
120+
struct Private;
123121
Private *d;
124122
};

client/QPCSC_p.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
#include <QtCore/QHash>
2525
#include <QtCore/QMutex>
26+
#include <QtCore/QWaitCondition>
2627

2728
#ifdef Q_OS_WIN
2829
#undef UNICODE
@@ -178,16 +179,16 @@ struct DISPLAY_PROPERTIES_STRUCTURE
178179

179180
#pragma pack(pop)
180181

181-
class QPCSC::Private
182+
struct QPCSC::Private
182183
{
183-
public:
184184
SCARDCONTEXT context {};
185-
QHash<QString,QMutex*> lock;
185+
SCARDCONTEXT thread {};
186+
QMutex sleepMutex;
187+
QWaitCondition sleepCond;
186188
};
187189

188-
class QPCSCReader::Private
190+
struct QPCSCReader::Private
189191
{
190-
public:
191192
QHash<DRIVER_FEATURES,quint32> features();
192193

193194
QPCSC::Private *d {};

0 commit comments

Comments
 (0)