@@ -92,9 +92,12 @@ const QByteArray Card::READBINARY = APDU("00B00000 00");
9292const QByteArray Card::REPLACE = APDU(" 002C0000 00" );
9393const QByteArray Card::VERIFY = APDU(" 00200000 00" );
9494
95- QPCSCReader::Result Card::transfer (QPCSCReader *reader, bool verify, const QByteArray &apdu,
95+ QPCSCReader::Result Card::transfer (QPCSCReader *reader, bool verify, QByteArray & &apdu,
9696 QSmartCardData::PinType type, quint8 newPINOffset, bool requestCurrentPIN)
9797{
98+ auto clean = qScopeGuard ([&apdu] {
99+ apdu.fill (' 0' );
100+ });
98101 if (!reader->isPinPad ())
99102 return reader->transfer (apdu);
100103 quint16 language = 0x0000 ;
@@ -119,6 +122,17 @@ QByteArrayView Card::parseFCI(QByteArrayView data, quint8 expectedTag)
119122 return {};
120123}
121124
125+ QByteArray Card::pinTemplate (const QString &data) const
126+ {
127+ QByteArray pin = data.toUtf8 ();
128+ #if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0)
129+ pin.resize (12 , fillChar);
130+ #else
131+ pin += QByteArray (12 - pin.size (), fillChar);
132+ #endif
133+ return pin;
134+ }
135+
122136struct TLV
123137{
124138 quint32 tag {};
@@ -191,11 +205,9 @@ const QByteArray IDEMIACard::AID_QSCD = APDU("00A4040C 10 51534344204170706C6963
191205const QByteArray IDEMIACard::ATR_COSMO8 = QByteArrayLiteral(" 3BDB960080B1FE451F830012233F536549440F9000F1" );
192206const QByteArray IDEMIACard::ATR_COSMOX = QByteArrayLiteral(" 3BDC960080B1FE451F830012233F54654944320F9000C3" );
193207
194- QPCSCReader::Result IDEMIACard::change (QPCSCReader *reader, QSmartCardData::PinType type, QByteArray && pin, QByteArray & &newpin) const
208+ QPCSCReader::Result IDEMIACard::change (QPCSCReader *reader, QSmartCardData::PinType type, const QByteArray &pin, const QByteArray &newpin) const
195209{
196210 QByteArray cmd = CHANGE;
197- newpin = pinTemplate (std::move (newpin));
198- pin = pinTemplate (std::move (pin));
199211 switch (type) {
200212 case QSmartCardData::Pin1Type:
201213 cmd[3 ] = 1 ;
@@ -210,7 +222,9 @@ QPCSCReader::Result IDEMIACard::change(QPCSCReader *reader, QSmartCardData::PinT
210222 break ;
211223 }
212224 cmd[4 ] = char (pin.size () + newpin.size ());
213- return transfer (reader, false , cmd + pin + newpin, type, quint8 (pin.size ()), true );
225+ cmd += pin;
226+ cmd += newpin;
227+ return transfer (reader, false , std::move (cmd), type, quint8 (pin.size ()), true );
214228}
215229
216230bool IDEMIACard::isSupported (const QByteArray &atr)
@@ -291,23 +305,13 @@ bool IDEMIACard::loadPerso(QPCSCReader *reader, QSmartCardDataPrivate *d) const
291305 return updateCounters (reader, d);
292306}
293307
294- QByteArray IDEMIACard::pinTemplate (QByteArray &&pin)
295- {
296- #if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0)
297- pin.resize (12 , char (0xFF ));
298- #else
299- pin += QByteArray (12 - pin.size (), char (0xFF ));
300- #endif
301- return std::move (pin);
302- }
303-
304- QPCSCReader::Result IDEMIACard::replace (QPCSCReader *reader, QSmartCardData::PinType type, QByteArray &&puk, QByteArray &&pin) const
308+ QPCSCReader::Result IDEMIACard::replace (QPCSCReader *reader, QSmartCardData::PinType type, const QByteArray &puk, const QByteArray &pin) const
305309{
306- puk = pinTemplate (std::move (puk));
307310 QByteArray cmd = VERIFY;
308311 cmd[3 ] = 2 ;
309312 cmd[4 ] = char (puk.size ());
310- if (auto result = transfer (reader, true , cmd + puk, QSmartCardData::PukType, 0 , true ); !result)
313+ cmd += puk;
314+ if (auto result = transfer (reader, true , std::move (cmd), QSmartCardData::PukType, 0 , true ); !result)
311315 return result;
312316
313317 cmd = Card::REPLACE;
@@ -320,9 +324,9 @@ QPCSCReader::Result IDEMIACard::replace(QPCSCReader *reader, QSmartCardData::Pin
320324 }
321325 else
322326 cmd[3 ] = char (type);
323- pin = pinTemplate (std::move (pin));
324327 cmd[4 ] = char (pin.size ());
325- return transfer (reader, false , cmd + pin, type, 0 , false );
328+ cmd += pin;
329+ return transfer (reader, false , std::move (cmd), type, 0 , false );
326330}
327331
328332bool IDEMIACard::updateCounters (QPCSCReader *reader, QSmartCardDataPrivate *d) const
@@ -351,14 +355,14 @@ bool IDEMIACard::updateCounters(QPCSCReader *reader, QSmartCardDataPrivate *d) c
351355
352356const QByteArray THALESCard::AID = APDU(" 00A4040C 0C A000000063504B43532D3135" );
353357
354- QPCSCReader::Result THALESCard::change (QPCSCReader *reader, QSmartCardData::PinType type, QByteArray && pin, QByteArray & &newpin) const
358+ QPCSCReader::Result THALESCard::change (QPCSCReader *reader, QSmartCardData::PinType type, const QByteArray &pin, const QByteArray &newpin) const
355359{
356360 QByteArray cmd = CHANGE;
357- newpin = pinTemplate (std::move (newpin));
358- pin = pinTemplate (std::move (pin));
359361 cmd[3 ] = char (0x80 | type);
360362 cmd[4 ] = char (pin.size () + newpin.size ());
361- return transfer (reader, false , cmd + pin + newpin, type, quint8 (pin.size ()), true );
363+ cmd += pin;
364+ cmd += newpin;
365+ return transfer (reader, false , std::move (cmd), type, quint8 (pin.size ()), true );
362366}
363367
364368bool THALESCard::isSupported (const QByteArray &atr)
@@ -441,25 +445,14 @@ bool THALESCard::loadPerso(QPCSCReader *reader, QSmartCardDataPrivate *d) const
441445 return updateCounters (reader, d);
442446}
443447
444- QByteArray THALESCard::pinTemplate (const QString &pin)
445- {
446- QByteArray result = pin.toUtf8 ();
447- #if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0)
448- result.resize (12 , char (0x00 ));
449- #else
450- result += QByteArray (12 - result.size (), char (0x00 ));
451- #endif
452- return result;
453- }
454-
455- QPCSCReader::Result THALESCard::replace (QPCSCReader *reader, QSmartCardData::PinType type, QByteArray &&puk, QByteArray &&pin) const
448+ QPCSCReader::Result THALESCard::replace (QPCSCReader *reader, QSmartCardData::PinType type, const QByteArray &puk, const QByteArray &pin) const
456449{
457- puk = pinTemplate (std::move (puk));
458- pin = pinTemplate (std::move (pin));
459450 QByteArray cmd = REPLACE;
460451 cmd[3 ] = char (0x80 | type);
461452 cmd[4 ] = char (puk.size () + pin.size ());
462- return transfer (reader, false , cmd + puk + pin, type, quint8 (puk.size ()), true );
453+ cmd += puk;
454+ cmd += pin;
455+ return transfer (reader, false , std::move (cmd), type, quint8 (puk.size ()), true );
463456}
464457
465458bool THALESCard::updateCounters (QPCSCReader *reader, QSmartCardDataPrivate *d) const
@@ -533,16 +526,31 @@ bool QSmartCard::pinChange(QSmartCardData::PinType type, QSmartCard::PinAction a
533526 }
534527 popup.reset (new PinPopup (src, flags, d->t .authCert (), parent, bodyText));
535528 popup->open ();
529+ oldPin = d->card ->pinTemplate ({});
530+ newPin = d->card ->pinTemplate ({});
536531 }
537532 else
538533 {
539534 PinUnblock p (type, action, d->t .retryCount (src), d->t .data (QSmartCardData::BirthDate).toDate (),
540535 d->t .data (QSmartCardData::Id).toString (), d->t .isPUKReplacable (), parent);
541536 if (!p.exec ())
542537 return false ;
543- oldPin = p.firstCodeText ().toUtf8 ();
544- newPin = p.newCodeText ().toUtf8 ();
538+ QString oldPinString = p.firstCodeText ();
539+ QString newPinString = p.newCodeText ();
540+ oldPin = d->card ->pinTemplate (oldPinString);
541+ newPin = d->card ->pinTemplate (newPinString);
542+ // Try to clean QLineEdit internal PIN copy using constData that does not detach memory
543+ auto chars = const_cast <QChar*>(oldPinString.constData ());
544+ for (int i = 0 ; i < oldPinString.length (); ++i)
545+ chars[i] = ' \0 ' ;
546+ chars = const_cast <QChar*>(newPinString.constData ());
547+ for (int i = 0 ; i < newPinString.length (); ++i)
548+ chars[i] = ' \0 ' ;
545549 }
550+ auto clean = qScopeGuard ([&oldPin, &newPin] {
551+ oldPin.fill (' \0 ' );
552+ newPin.fill (' \0 ' );
553+ });
546554
547555 QPCSCReader reader (d->t .reader (), &QPCSC::instance ());
548556 if (!reader.connect ())
@@ -551,8 +559,8 @@ bool QSmartCard::pinChange(QSmartCardData::PinType type, QSmartCard::PinAction a
551559 return false ;
552560 }
553561 auto response = action == QSmartCard::ChangeWithPin || action == QSmartCard::ActivateWithPin ?
554- d->card ->change (&reader, type, std::move ( oldPin), std::move ( newPin) ) :
555- d->card ->replace (&reader, type, std::move ( oldPin), std::move ( newPin) );
562+ d->card ->change (&reader, type, oldPin, newPin) :
563+ d->card ->replace (&reader, type, oldPin, newPin);
556564 switch (response.SW )
557565 {
558566 case 0x9000 :
0 commit comments