3030#include < QtCore/QScopedPointer>
3131#include < QtNetwork/QSslKey>
3232
33- Q_LOGGING_CATEGORY (CLog, " qdigidoc4.QSmartCard" )
33+ static Q_LOGGING_CATEGORY (CLog, " qdigidoc4.QSmartCard" )
3434
3535QSmartCardData::QSmartCardData(): d(new QSmartCardDataPrivate) {}
3636QSmartCardData::QSmartCardData (const QSmartCardData &other) = default;
3737QSmartCardData::QSmartCardData (QSmartCardData &&other) noexcept = default;
38- QSmartCardData::~QSmartCardData () = default ;
38+ QSmartCardData::~QSmartCardData () noexcept = default ;
3939QSmartCardData& QSmartCardData::operator =(const QSmartCardData &other) = default ;
4040QSmartCardData& QSmartCardData::operator =(QSmartCardData &&other) noexcept = default ;
4141bool QSmartCardData::operator ==(const QSmartCardData &other) const
@@ -197,15 +197,14 @@ QPCSCReader::Result IDEMIACard::change(QPCSCReader *reader, QSmartCardData::PinT
197197 QByteArray pin = pinTemplate (pin_);
198198 switch (type) {
199199 case QSmartCardData::Pin1Type:
200- reader->transfer (AID);
201200 cmd[3 ] = 1 ;
202201 break ;
203202 case QSmartCardData::PukType:
204- reader->transfer (AID);
205203 cmd[3 ] = 2 ;
206204 break ;
207205 case QSmartCardData::Pin2Type:
208- reader->transfer (AID_QSCD);
206+ if (auto result = reader->transfer (AID_QSCD); !result)
207+ return result;
209208 cmd[3 ] = char (0x85 );
210209 break ;
211210 }
@@ -223,7 +222,8 @@ bool IDEMIACard::loadPerso(QPCSCReader *reader, QSmartCardDataPrivate *d) const
223222 if (d->data .isEmpty () && reader->transfer (APDU (" 00A4090C 04 3F00 5000" )))
224223 {
225224 QByteArray cmd = APDU (" 00A4020C 02 5001" );
226- for (char data = QSmartCardData::SurName; data <= QSmartCardData::Expiry; ++data)
225+ using enum QSmartCardData::PersonalDataType;
226+ for (char data = SurName; data <= Expiry; ++data)
227227 {
228228 cmd[6 ] = data;
229229 if (!reader->transfer (cmd))
@@ -236,19 +236,19 @@ bool IDEMIACard::loadPerso(QPCSCReader *reader, QSmartCardDataPrivate *d) const
236236 record.clear ();
237237 switch (data)
238238 {
239- case QSmartCardData:: SurName:
240- case QSmartCardData:: FirstName:
241- case QSmartCardData:: Citizen:
242- case QSmartCardData:: Id:
243- case QSmartCardData:: DocumentId:
239+ case SurName:
240+ case FirstName:
241+ case Citizen:
242+ case Id:
243+ case DocumentId:
244244 d->data [QSmartCardData::PersonalDataType (data)] = record;
245245 break ;
246- case QSmartCardData:: BirthDate:
246+ case BirthDate:
247247 if (!record.isEmpty ())
248- d->data [QSmartCardData:: BirthDate] = QDate::fromString (record.left (10 ), QStringLiteral (" dd MM yyyy" ));
248+ d->data [BirthDate] = QDate::fromString (record.left (10 ), QStringLiteral (" dd MM yyyy" ));
249249 break ;
250- case QSmartCardData:: Expiry:
251- d->data [QSmartCardData:: Expiry] = QDateTime::fromString (record, QStringLiteral (" dd MM yyyy" )).addDays (1 ).addSecs (-1 );
250+ case Expiry:
251+ d->data [Expiry] = QDateTime::fromString (record, QStringLiteral (" dd MM yyyy" )).addDays (1 ).addSecs (-1 );
252252 break ;
253253 default : break ;
254254 }
@@ -293,29 +293,29 @@ bool IDEMIACard::loadPerso(QPCSCReader *reader, QSmartCardDataPrivate *d) const
293293QByteArray IDEMIACard::pinTemplate (const QString &pin)
294294{
295295 QByteArray result = pin.toUtf8 ();
296+ #if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0)
297+ result.resize (12 , char (0xFF ));
298+ #else
296299 result += QByteArray (12 - result.size (), char (0xFF ));
300+ #endif
297301 return result;
298302}
299303
300304QPCSCReader::Result IDEMIACard::replace (QPCSCReader *reader, QSmartCardData::PinType type, const QString &puk_, const QString &pin_) const
301305{
302- auto result = reader->transfer (AID);
303- if (!result)
304- return result;
305-
306306 QByteArray puk = pinTemplate (puk_);
307307 QByteArray cmd = VERIFY;
308308 cmd[3 ] = 2 ;
309309 cmd[4 ] = char (puk.size ());
310- result = transfer (reader, true , cmd + puk, type, 0 , true );
311- if (!result)
310+ if (auto result = transfer (reader, true , cmd + puk, QSmartCardData::PukType, 0 , true ); !result)
312311 return result;
313312
314313 cmd = Card::REPLACE;
315314 cmd[2 ] = 2 ;
316315 if (type == QSmartCardData::Pin2Type)
317316 {
318- reader->transfer (IDEMIACard::AID_QSCD);
317+ if (auto result = reader->transfer (IDEMIACard::AID_QSCD); !result)
318+ return result;
319319 cmd[3 ] = char (0x85 );
320320 }
321321 else
@@ -325,17 +325,6 @@ QPCSCReader::Result IDEMIACard::replace(QPCSCReader *reader, QSmartCardData::Pin
325325 return transfer (reader, false , cmd + pin, type, 0 , false );
326326}
327327
328- QByteArray IDEMIACard::sign (QPCSCReader *reader, const QByteArray &dgst) const
329- {
330- if (!reader->transfer (AID_OT) ||
331- !reader->transfer (APDU (" 002241A4 09 8004FF200800840181" )))
332- return {};
333- QByteArray cmd = APDU (" 00880000 00 00" );
334- cmd[4 ] = char (std::min<size_t >(size_t (dgst.size ()), 0x30 ));
335- cmd.insert (5 , dgst.left (0x30 ));
336- return reader->transfer (cmd).data ;
337- }
338-
339328bool IDEMIACard::updateCounters (QPCSCReader *reader, QSmartCardDataPrivate *d) const
340329{
341330 reader->transfer (AID);
@@ -455,7 +444,11 @@ bool THALESCard::loadPerso(QPCSCReader *reader, QSmartCardDataPrivate *d) const
455444QByteArray THALESCard::pinTemplate (const QString &pin)
456445{
457446 QByteArray result = pin.toUtf8 ();
447+ #if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0)
448+ result.resize (12 , char (0x00 ));
449+ #else
458450 result += QByteArray (12 - result.size (), char (0x00 ));
451+ #endif
459452 return result;
460453}
461454
@@ -469,22 +462,6 @@ QPCSCReader::Result THALESCard::replace(QPCSCReader *reader, QSmartCardData::Pin
469462 return transfer (reader, false , cmd + puk + pin, type, quint8 (puk.size ()), true );
470463}
471464
472- QByteArray THALESCard::sign (QPCSCReader *reader, const QByteArray &dgst) const
473- {
474- if (!reader->transfer (APDU (" 002241B6 09 800154840101" )))
475- return {};
476-
477- QByteArray send {0x90 , char (dgst.size ())};
478- send.append (dgst);
479- send.insert (0 , char (send.size ()));
480- send.insert (0 , APDU (" 002A90A0" ));
481-
482- if (!reader->transfer (send))
483- return {};
484-
485- return reader->transfer (APDU (" 002A9E9A 00" )).data ;
486- }
487-
488465bool THALESCard::updateCounters (QPCSCReader *reader, QSmartCardDataPrivate *d) const
489466{
490467 auto apdu = APDU (" 00CB00FF 05 A003830180 00" );
@@ -506,18 +483,18 @@ bool THALESCard::updateCounters(QPCSCReader *reader, QSmartCardDataPrivate *d) c
506483
507484
508485
509- QSharedPointer <QPCSCReader> QSmartCard::Private::connect (const QString &reader)
486+ std::unique_ptr <QPCSCReader> QSmartCard::Private::connect (const QString &reader)
510487{
511488 qCDebug (CLog) << " Connecting to reader" << reader;
512- QSharedPointer<QPCSCReader> r ( new QPCSCReader (reader, &QPCSC::instance () ));
489+ auto r = std::make_unique< QPCSCReader> (reader, &QPCSC::instance ());
513490 if (!r->connect () || !r->beginTransaction ())
514- r.clear ();
491+ r.reset ();
515492 return r;
516493}
517494
518- QSmartCard::ErrorType QSmartCard::Private::handlePinResult (QPCSCReader *reader, const QPCSCReader::Result &response, bool forceUpdate )
495+ QSmartCard::ErrorType QSmartCard::Private::handlePinResult (QPCSCReader *reader, const QPCSCReader::Result &response)
519496{
520- if (!response || forceUpdate )
497+ if (!response)
521498 card->updateCounters (reader, t.d );
522499 switch (response.SW )
523500 {
@@ -546,90 +523,91 @@ QSmartCard::QSmartCard(QObject *parent)
546523{
547524}
548525
549- QSmartCard::~QSmartCard () = default ;
550-
551- QSmartCard::ErrorType QSmartCard::change (QSmartCardData::PinType type, QWidget* parent, const QString &newpin, const QString &pin, const QString &title, const QString &bodyText)
552- {
553- PinPopup::PinFlags flags = {};
554- switch (type)
555- {
556- case QSmartCardData::Pin1Type: flags = PinPopup::Pin1Type; break ;
557- case QSmartCardData::Pin2Type: flags = PinPopup::Pin2Type; break ;
558- case QSmartCardData::PukType: flags = PinPopup::PukType; break ;
559- default : return UnknownError;
560- }
561- QSharedPointer<QPCSCReader> reader (d->connect (d->t .reader ()));
562- if (!reader)
563- return UnknownError;
564-
565- QScopedPointer<PinPopup> p;
566- if (d->t .isPinpad ())
567- {
568- p.reset (new PinPopup (PinPopup::PinFlags (flags|PinPopup::PinpadChangeFlag), title, {}, parent, bodyText));
569- p->open ();
570- }
571- return d->handlePinResult (reader.data (), d->card ->change (reader.data (), type, pin, newpin), true );
572- }
526+ QSmartCard::~QSmartCard () noexcept = default ;
573527
574528QSmartCardData QSmartCard::data () const { return d->t ; }
575529
576530QSmartCard::ErrorType QSmartCard::pinChange (QSmartCardData::PinType type, QSmartCard::PinAction action, QWidget* parent)
577531{
578- QScopedPointer<PinUnblock> p ;
532+ std::unique_ptr<PinPopup,QScopedPointerDeleteLater> popup ;
579533 QByteArray oldPin, newPin;
580- QString title, textBody;
581534
582535 if (!d->t .isPinpad ())
583536 {
584- p. reset ( new PinUnblock (type, action, d->t .retryCount (type), d->t .data (QSmartCardData::BirthDate).toDate (),
585- d->t .data (QSmartCardData::Id).toString (), d->t .isPUKReplacable (), parent)) ;
586- if (!p-> exec ())
537+ PinUnblock p (type, action, d->t .retryCount (type), d->t .data (QSmartCardData::BirthDate).toDate (),
538+ d->t .data (QSmartCardData::Id).toString (), d->t .isPUKReplacable (), parent);
539+ if (!p. exec ())
587540 return CancelError;
588- oldPin = p-> firstCodeText ().toUtf8 ();
589- newPin = p-> newCodeText ().toUtf8 ();
541+ oldPin = p. firstCodeText ().toUtf8 ();
542+ newPin = p. newCodeText ().toUtf8 ();
590543 }
591544 else
592545 {
593546 SslCertificate cert = d->t .authCert ();
594- title = cert.toString (cert.showCN () ? QStringLiteral (" CN, serialNumber" ) : QStringLiteral (" GN SN, serialNumber" ));
595- textBody = tr (" To change %1 on a PinPad reader the old %1 code has to be entered first and then the new %1 code twice." ).arg (QSmartCardData::typeString (type));
547+ QString title = cert.toString (cert.showCN () ? QStringLiteral (" CN, serialNumber" ) : QStringLiteral (" GN SN, serialNumber" ));
548+ PinPopup::PinFlags flags = {};
549+ switch (type)
550+ {
551+ case QSmartCardData::Pin1Type: flags = PinPopup::Pin1Type; break ;
552+ case QSmartCardData::Pin2Type: flags = PinPopup::Pin2Type; break ;
553+ case QSmartCardData::PukType: flags = PinPopup::PukType; break ;
554+ default : return UnknownError;
555+ }
556+ popup.reset (new PinPopup (PinPopup::PinFlags (flags|PinPopup::PinpadChangeFlag), title, {}, parent,
557+ tr (" To change %1 on a PinPad reader the old %1 code has to be entered first and then the new %1 code twice." ).arg (QSmartCardData::typeString (type))));
558+ popup->open ();
596559 }
597- return change (type, parent, newPin, oldPin, title, textBody);
560+
561+ if (auto reader = Private::connect (d->t .reader ()))
562+ return d->handlePinResult (reader.get (), d->card ->change (reader.get (), type, oldPin, newPin));
563+ return UnknownError;
598564}
599565
600566QSmartCard::ErrorType QSmartCard::pinUnblock (QSmartCardData::PinType type, QSmartCard::PinAction action, QWidget* parent)
601567{
602- QScopedPointer<PinUnblock> p;
603- QByteArray puk, newPin;
604- QString title, textBody;
568+ std::unique_ptr<PinPopup,QScopedPointerDeleteLater> popup;
569+ QByteArray puk, pin;
605570
606571 if (!d->t .isPinpad ())
607572 {
608- p. reset ( new PinUnblock ( type, action,
609- d->t .retryCount (QSmartCardData::PukType), d-> t . data (QSmartCardData::BirthDate). toDate (), d-> t . data (QSmartCardData:: Id).toString (), d->t .isPUKReplacable (), parent) );
610- if (!p-> exec ())
573+ PinUnblock p ( type, action, d-> t . retryCount (QSmartCardData::PukType), d-> t . data (QSmartCardData::BirthDate). toDate () ,
574+ d->t .data (QSmartCardData::Id).toString (), d->t .isPUKReplacable (), parent);
575+ if (!p. exec ())
611576 return CancelError;
612- puk = p-> firstCodeText ().toUtf8 ();
613- newPin = p-> newCodeText ().toUtf8 ();
577+ puk = p. firstCodeText ().toUtf8 ();
578+ pin = p. newCodeText ().toUtf8 ();
614579 }
615580 else
616581 {
617582 SslCertificate cert = d->t .authCert ();
618- title = cert.toString (cert.showCN () ? QStringLiteral (" CN, serialNumber" ) : QStringLiteral (" GN SN, serialNumber" ));
583+ QString title = cert.toString (cert.showCN () ? QStringLiteral (" CN, serialNumber" ) : QStringLiteral (" GN SN, serialNumber" ));
584+ QString bodyText;
619585 switch (action)
620586 {
621587 case QSmartCard::ActivateWithPuk:
622588 case QSmartCard::ChangeWithPuk:
623- textBody = tr (" To change %1 code with the PUK code on a PinPad reader the PUK code has to be entered first and then the %1 code twice." ).arg (QSmartCardData::typeString (type));
589+ bodyText = tr (" To change %1 code with the PUK code on a PinPad reader the PUK code has to be entered first and then the %1 code twice." ).arg (QSmartCardData::typeString (type));
624590 break ;
625591 case QSmartCard::UnblockWithPuk:
626- textBody = tr (" To unblock the %1 code on a PinPad reader the PUK code has to be entered first and then the %1 code twice." ).arg (QSmartCardData::typeString (type));
592+ bodyText = tr (" To unblock the %1 code on a PinPad reader the PUK code has to be entered first and then the %1 code twice." ).arg (QSmartCardData::typeString (type));
627593 break ;
628594 default :
629595 break ;
630596 }
597+ PinPopup::PinFlags flags = {};
598+ switch (type)
599+ {
600+ case QSmartCardData::Pin1Type: flags = PinPopup::Pin1Type; break ;
601+ case QSmartCardData::Pin2Type: flags = PinPopup::Pin2Type; break ;
602+ default : return UnknownError;
603+ }
604+ popup.reset (new PinPopup (PinPopup::PinFlags (flags|PinPopup::PinpadChangeFlag), title, {}, parent, bodyText));
605+ popup->open ();
631606 }
632- return unblock (type, parent, newPin, puk, title, textBody);
607+
608+ if (auto reader = Private::connect (d->t .reader ()))
609+ return d->handlePinResult (reader.get (), d->card ->replace (reader.get (), type, puk, pin));
610+ return UnknownError;
633611}
634612
635613void QSmartCard::reloadCounters ()
@@ -663,25 +641,24 @@ void QSmartCard::reloadCard(const TokenData &token, bool reloadCounters)
663641 return ;
664642
665643 QString reader = token.reader ();
666- if (token.reader ().endsWith (QStringLiteral (" ..." ))) {
644+ if (token.reader ().endsWith (QLatin1String (" ..." ))) {
667645 for (const QString &test: QPCSC::instance ().readers ()) {
668646 if (test.startsWith (token.reader ().left (token.reader ().size () - 3 )))
669647 reader = test;
670648 }
671649 }
672650
673651 qCDebug (CLog) << " Read" << reader;
674- QScopedPointer<QPCSCReader> selectedReader ( new QPCSCReader (reader, & QPCSC::instance ()) );
675- if (!selectedReader-> connect () || !selectedReader-> beginTransaction () )
652+ auto selectedReader = Private::connect (reader );
653+ if (!selectedReader)
676654 return ;
677655
678- std::unique_ptr<Card> card;
679656 if (IDEMIACard::isSupported (selectedReader->atr ()))
680- card = std::make_unique<IDEMIACard>();
657+ d-> card = std::make_unique<IDEMIACard>();
681658 else if (THALESCard::isSupported (selectedReader->atr ()))
682- card = std::make_unique<THALESCard>();
659+ d-> card = std::make_unique<THALESCard>();
683660 else {
684- qDebug ( ) << " Unsupported card" ;
661+ qCDebug (CLog ) << " Unsupported card" ;
685662 return ;
686663 }
687664
@@ -690,36 +667,14 @@ void QSmartCard::reloadCard(const TokenData &token, bool reloadCounters)
690667 t = d->t .d ;
691668 t->reader = selectedReader->name ();
692669 t->pinpad = selectedReader->isPinPad ();
693- d->card = std::move (card);
694- if (d->card ->loadPerso (selectedReader.data (), t))
670+ if (d->card ->loadPerso (selectedReader.get (), t))
695671 {
696672 d->t .d = std::move (t);
697673 emit dataChanged (d->t );
698674 }
699675 else
700- qDebug ( ) << " Failed to read card info, try again next round" ;
676+ qCDebug (CLog ) << " Failed to read card info, try again next round" ;
701677}
702678
703679TokenData QSmartCard::tokenData () const { return d->token ; }
704680
705- QSmartCard::ErrorType QSmartCard::unblock (QSmartCardData::PinType type, QWidget* parent, const QString &pin, const QString &puk, const QString &title, const QString &bodyText)
706- {
707- PinPopup::PinFlags flags = {};
708- switch (type)
709- {
710- case QSmartCardData::Pin1Type: flags = PinPopup::Pin1Type; break ;
711- case QSmartCardData::Pin2Type: flags = PinPopup::Pin2Type; break ;
712- default : return UnknownError;
713- }
714- QSharedPointer<QPCSCReader> reader (d->connect (d->t .reader ()));
715- if (!reader)
716- return UnknownError;
717-
718- QScopedPointer<PinPopup> p;
719- if (d->t .isPinpad ())
720- {
721- p.reset (new PinPopup (PinPopup::PinFlags (flags|PinPopup::PinpadChangeFlag), title, {}, parent, bodyText));
722- p->open ();
723- }
724- return d->handlePinResult (reader.data (), d->card ->replace (reader.data (), type, puk, pin), true );
725- }
0 commit comments