void QSigner::emitDataChanged() { TokenData data; data.setCard( d->selectedCard ); data.setCards( d->cards.keys() ); data.setCert( d->cert ); data.setFlags( d->flags ); Q_EMIT dataChanged( data ); }
TEST(test_buffer, read_bytes_empty) { err_code_t err; DataBlock::setMinCapacity(5); BufferReader reader; TokenData td; reader.readBytes(err, 0, td); ASSERT_EQ(err, RET_OK); ASSERT_EQ(td.size(), 0); }
QString Common::tokenInfo( CertType type, const TokenData &data ) { QString content; QTextStream s( &content ); SslCertificate c( data.cert() ); s << "<table width=\"100%\"><tr><td>"; if( c.isTempel() ) { s << tr("Company") << ": <font color=\"black\">" << c.toString( "CN" ) << "</font><br />"; s << tr("Register code") << ": <font color=\"black\">" << c.subjectInfo( "serialNumber" ) << "</font><br />"; } else { s << tr("Name") << ": <font color=\"black\">" << c.toString( "GN SN" ) << "</font><br />"; s << tr("Personal code") << ": <font color=\"black\">" << c.subjectInfo( "serialNumber" ) << "</font><br />"; } s << tr("Card in reader") << ": <font color=\"black\">" << data.card() << "</font><br />"; bool willExpire = c.expiryDate().toLocalTime() <= QDateTime::currentDateTime().addDays( 105 ); s << (type == AuthCert ? tr("Auth certificate is") : tr("Sign certificate is") ) << " "; if( c.isValid() ) { s << "<font color=\"green\">" << tr("valid") << "</font>"; if( willExpire ) s << "<br /><font color=\"red\">" << tr("Your certificates will expire soon") << "</font>"; } else s << "<font color=\"red\">" << tr("expired") << "</font>"; if( data.flags() & TokenData::PinLocked ) s << "<br /><font color=\"red\">" << tr("PIN is locked") << "</font>"; s << "</td><td align=\"center\" width=\"75\">"; if( !c.isValid() || willExpire || data.flags() & TokenData::PinLocked ) { s << "<a href=\"openUtility\"><img src=\":/images/warning.png\"><br />" "<font color=\"red\">" << tr("Open utility") << "</font></a>"; } else if( c.isTempel() ) s << "<img src=\":/images/ico_stamp_blue_75.png\">"; else s << "<img src=\":/images/ico_person_blue_75.png\">"; s << "</td></tr></table>"; return content; }
TokenData QPKCS11::selectSlot( const QString &card, SslCertificate::KeyUsage usage ) { delete d->pslot; d->pslot = 0; TokenData t; t.setCard( card ); for( unsigned int i = 0; i < d->nslots; ++i ) { CK_TOKEN_INFO token; if( (d->err = d->f->C_GetTokenInfo( d->pslots[i], &token )) != CKR_OK || card != QByteArray( (const char*)token.serialNumber, 16 ).trimmed() ) continue; SslCertificate cert = d->readCert( d->pslots[i] ); if( !cert.keyUsage().keys().contains( usage ) ) continue; d->pslot = new CK_SLOT_ID( d->pslots[i] ); t.setCert( cert ); if( token.flags & CKF_SO_PIN_COUNT_LOW || token.flags & CKF_USER_PIN_COUNT_LOW ) t.setFlag( TokenData::PinCountLow ); if( token.flags & CKF_SO_PIN_FINAL_TRY || token.flags & CKF_USER_PIN_FINAL_TRY ) t.setFlag( TokenData::PinFinalTry ); if( token.flags & CKF_SO_PIN_LOCKED || token.flags & CKF_USER_PIN_LOCKED ) t.setFlag( TokenData::PinLocked ); break; } return t; }
TokenData QCSP::selectCert( const QString &cn, SslCertificate::KeyUsage usage ) { TokenData t; t.setCard( cn ); if( d->h ) CryptReleaseContext( d->h, 0 ); QPair<QString,QString> c = d->certs.value( cn ); if( !CryptAcquireContextW( &d->h, LPCWSTR(c.second.utf16()), LPCWSTR(c.first.utf16()), PROV_RSA_FULL, 0 ) ) return t; HCRYPTKEY key = 0; if( !CryptGetUserKey( d->h, usage == SslCertificate::NonRepudiation ? AT_SIGNATURE : AT_KEYEXCHANGE, &key ) ) return t; SslCertificate cert = QSslCertificate( d->keyParam( key, KP_CERTIFICATE, 0 ), QSsl::Der ); CryptDestroyKey( key ); if( cert.keyUsage().keys().contains( usage ) ) t.setCert( cert ); return t; }
QPKCS11::PinStatus QPKCS11::login( const TokenData &_t ) { CK_TOKEN_INFO token; if( !d->pslot || (d->err = d->f->C_GetTokenInfo( *(d->pslot), &token )) != CKR_OK ) return PinUnknown; if( !(token.flags & CKF_LOGIN_REQUIRED) ) return PinOK; TokenData t = _t; if( token.flags & CKF_SO_PIN_COUNT_LOW || token.flags & CKF_USER_PIN_COUNT_LOW ) t.setFlag( TokenData::PinCountLow ); if( token.flags & CKF_SO_PIN_FINAL_TRY || token.flags & CKF_USER_PIN_FINAL_TRY ) t.setFlag( TokenData::PinFinalTry ); if( token.flags & CKF_SO_PIN_LOCKED || token.flags & CKF_USER_PIN_LOCKED ) t.setFlag( TokenData::PinLocked ); if( d->session ) d->err = d->f->C_CloseSession( d->session ); d->session = 0; if( (d->err = d->f->C_OpenSession( *(d->pslot), CKF_SERIAL_SESSION, 0, 0, &d->session )) != CKR_OK ) return PinUnknown; bool pin2 = SslCertificate( t.cert() ).keyUsage().keys().contains( SslCertificate::NonRepudiation ); if( token.flags & CKF_PROTECTED_AUTHENTICATION_PATH ) { PinDialog p( pin2 ? PinDialog::Pin2PinpadType : PinDialog::Pin1PinpadType, t, qApp->activeWindow() ); QPKCS11Thread t( d ); connect( &t, SIGNAL(started()), &p, SIGNAL(startTimer()) ); p.open(); d->err = t.waitForDone(); } else { PinDialog p( pin2 ? PinDialog::Pin2Type : PinDialog::Pin1Type, t, qApp->activeWindow() ); if( !p.exec() ) return PinCanceled; QByteArray pin = p.text().toUtf8(); d->err = d->f->C_Login( d->session, CKU_USER, (unsigned char*)pin.constData(), pin.size() ); } switch( d->err ) { case CKR_OK: return PinOK; case CKR_CANCEL: case CKR_FUNCTION_CANCELED: return PinCanceled; case CKR_PIN_INCORRECT: return PinIncorrect; case CKR_PIN_LOCKED: return PinLocked; default: return PinUnknown; } }
PinDialog::PinDialog( PinFlags flags, const TokenData &t, QWidget *parent ) : QDialog( parent ) { SslCertificate c = t.cert(); init( flags, c.toString( c.showCN() ? "CN serialNumber" : "GN SN serialNumber" ), t.flags() ); }
bool AccessCert::download( bool noCard ) { if( noCard ) { QDesktopServices::openUrl( QUrl( tr("http://www.id.ee/kehtivuskinnitus") ) ); return false; } QMessageBox d( QMessageBox::Information, tr("Server access certificate"), tr("Hereby I agree to terms and conditions of validity confirmation service and " "will use the service in extent of 10 signatures per month. If you going to " "exceed the limit of 10 signatures per month or/and will use the service for " "commercial purposes, please refer to IT support of your company. Additional " "information is available from <a href=\"%1\">%1</a> or phone 1777") .arg( tr("http://www.id.ee/kehtivuskinnitus") ), QMessageBox::Help, m_parent ); d.addButton( tr("Agree"), QMessageBox::AcceptRole ); if( QLabel *label = d.findChild<QLabel*>() ) label->setOpenExternalLinks( true ); if( d.exec() == QMessageBox::Help ) { QDesktopServices::openUrl( QUrl( tr("http://www.id.ee/kehtivuskinnitus") ) ); return false; } QSigner *s = qApp->signer(); QPKCS11 *p = s->handle(); s->lock(); TokenData token; bool retry = false; do { retry = false; token = p->selectSlot( s->token().card(), SslCertificate::DataEncipherment ); QPKCS11::PinStatus status = p->login( token ); switch( status ) { case QPKCS11::PinOK: break; case QPKCS11::PinCanceled: s->unlock(); return false; case QPKCS11::PinIncorrect: showWarning( QPKCS11::errorString( status ) ); retry = true; break; default: showWarning( tr("Error downloading server access certificate!") + "\n" + QPKCS11::errorString( status ) ); s->unlock(); return false; } } while( retry ); QScopedPointer<SSLConnect> ssl( new SSLConnect ); ssl->setToken( token.cert(), p->key() ); QByteArray result = ssl->getUrl( SSLConnect::AccessCert ); if( !ssl->errorString().isEmpty() ) { showWarning( tr("Error downloading server access certificate!") + "\n" + ssl->errorString() ); return false; } s->unlock(); if( result.isEmpty() ) { showWarning( tr("Empty result!") ); return false; } QString status, cert, pass, message; QXmlStreamReader xml( result ); while( xml.readNext() != QXmlStreamReader::Invalid ) { if( !xml.isStartElement() ) continue; if( xml.name() == "StatusCode" ) status = xml.readElementText(); else if( xml.name() == "MessageToDisplay" ) message = xml.readElementText(); else if( xml.name() == "TokenData" ) cert = xml.readElementText(); else if( xml.name() == "TokenPassword" ) pass = xml.readElementText(); } if( status.isEmpty() ) { showWarning( tr("Error parsing server access certificate result!") ); return false; } switch( status.toInt() ) { case 1: //need to order cert manually from SK web QDesktopServices::openUrl( QUrl( tr("http://www.id.ee/kehtivuskinnitus") ) ); return false; case 2: //got error, show message from MessageToDisplay element showWarning( tr("Error downloading server access certificate!\n%1").arg( message ) ); return false; default: break; //ok } if ( cert.isEmpty() ) { showWarning( tr("Error reading server access certificate - empty content!") ); return false; } QString path = QDesktopServices::storageLocation( QDesktopServices::DataLocation ); if ( !QDir( path ).exists() ) QDir().mkpath( path ); QFile f( QString( "%1/%2.p12" ).arg( path, SslCertificate( qApp->signer()->token().cert() ).subjectInfo( "serialNumber" ) ) ); if ( !f.open( QIODevice::WriteOnly|QIODevice::Truncate ) ) { showWarning( tr("Failed to save server access certificate file to %1!\n%2") .arg( f.fileName() ) .arg( f.errorString() ) ); return false; } f.write( QByteArray::fromBase64( cert.toLatin1() ) ); Application::setConfValue( Application::PKCS12Cert, m_cert = QDir::toNativeSeparators( f.fileName() ) ); Application::setConfValue( Application::PKCS12Pass, m_pass = pass ); return true; }
bool AccessCert::download( bool noCard ) { if( noCard ) { QDesktopServices::openUrl( QUrl( tr("http://www.sk.ee/toend/") ) ); return false; } SslCertificate tempel( qApp->signer()->tokensign().cert() ); if( tempel.type() & SslCertificate::TempelType ) { setIcon( Information ); setText( tr("For getting server access certificate to Tempel contact <a href=\"mailto:[email protected]\">[email protected]</a>") ); return false; } setIcon( Information ); setText( tr("Hereby I agree to terms and conditions of validity confirmation service and " "will use the service in extent of 10 signatures per month. If you going to " "exceed the limit of 10 signatures per month or/and will use the service for " "commercial purposes, please refer to IT support of your company. Additional " "information is available from <a href=\"%1\">%1</a> or phone 1777") .arg( tr("http://www.id.ee/kehtivuskinnitus") ) ); setStandardButtons( Help ); QPushButton *agree = addButton( tr("Agree"), AcceptRole ); if( exec() == Help ) { QDesktopServices::openUrl( QUrl( tr("http://www.id.ee/kehtivuskinnitus") ) ); return false; } removeButton( agree ); QSigner *s = qApp->signer(); QPKCS11 *p = qobject_cast<QPKCS11*>(reinterpret_cast<QObject*>(s->handle())); #ifdef Q_OS_WIN QCNG *c = qobject_cast<QCNG*>(reinterpret_cast<QObject*>(s->handle())); if( !p && !c ) return false; #endif s->lock(); Qt::HANDLE key = 0; TokenData token; if( p ) { bool retry = false; do { retry = false; token.setCard( s->tokensign().card() ); Q_FOREACH( const TokenData &t, p->tokens() ) if( token.card() == t.card() && SslCertificate( t.cert() ).enhancedKeyUsage().contains( SslCertificate::ClientAuth ) ) token.setCert( t.cert() ); QPKCS11::PinStatus status = p->login( token ); switch( status ) { case QPKCS11::PinOK: break; case QPKCS11::PinCanceled: s->unlock(); return false; case QPKCS11::PinIncorrect: showWarning( QPKCS11::errorString( status ) ); retry = true; break; default: showWarning( tr("Error downloading server access certificate!") + "\n" + QPKCS11::errorString( status ) ); s->unlock(); return false; } } while( retry ); key = p->key(); } else {
QList<TokenData> QCNG::tokens() const { qWarning() << "Start enumerationg providers"; QHash<SslCertificate,QCNGCache> cache; DWORD count = 0; NCryptProviderName *names = nullptr; NCryptEnumStorageProviders( &count, &names, NCRYPT_SILENT_FLAG ); for( DWORD i = 0; i < count; ++i ) { qWarning() << "Found provider" << QString::fromWCharArray(names[i].pszName); if( wcscmp( names[i].pszName, MS_SMART_CARD_KEY_STORAGE_PROVIDER ) == 0 ) { for( const QString &reader: QPCSC::instance().readers() ) { qWarning() << reader; QString scope = QString(R"(\\.\%1\)").arg(reader); d->enumKeys( cache, names[i].pszName, LPCWSTR(scope.utf16()) ); } } else d->enumKeys( cache, names[i].pszName ); } NCryptFreeBuffer( names ); d->cache = cache; qWarning() << "End enumerationg providers"; QList<TokenData> result; for(QHash<SslCertificate,QCNGCache>::const_iterator i = cache.constBegin(); i != cache.constEnd(); ++i) { TokenData t; t.setCard(i.key().type() & SslCertificate::EstEidType || i.key().type() & SslCertificate::DigiIDType ? i.value().guid : i.key().subjectInfo(QSslCertificate::CommonName)); t.setCert(i.key()); result << t; } return result; } TokenData QCNG::selectCert( const SslCertificate &cert ) { qWarning() << "Select:" << cert.subjectInfo( "CN" ); if( !d->cache.contains( cert ) ) return TokenData(); d->selected = d->cache[cert]; qWarning() << "Found:" << d->selected.guid << d->selected.key; TokenData t; t.setCard( cert.type() & SslCertificate::EstEidType || cert.type() & SslCertificate::DigiIDType ? d->selected.guid : cert.subjectInfo( QSslCertificate::CommonName ) ); t.setCert( cert ); return t; } QByteArray QCNG::sign( int method, const QByteArray &digest ) const { d->err = PinUnknown; BCRYPT_PKCS1_PADDING_INFO padInfo = { NCRYPT_SHA256_ALGORITHM }; switch( method ) { case NID_sha224: padInfo.pszAlgId = L"SHA224"; break; case NID_sha256: padInfo.pszAlgId = NCRYPT_SHA256_ALGORITHM; break; case NID_sha384: padInfo.pszAlgId = NCRYPT_SHA384_ALGORITHM; break; case NID_sha512: padInfo.pszAlgId = NCRYPT_SHA512_ALGORITHM; break; case NID_md5_sha1: //padInfo.pszAlgId = L"SHAMD5"; break; default: break; } DWORD size = 0; QByteArray res; NCRYPT_KEY_HANDLE k = d->key(); QString algo(5, 0); SECURITY_STATUS err = NCryptGetProperty(k, NCRYPT_ALGORITHM_GROUP_PROPERTY, PBYTE(algo.data()), DWORD((algo.size() + 1) * 2), &size, 0); algo.resize(size/2 - 1); bool isRSA = algo == "RSA"; err = NCryptSignHash(k, isRSA ? &padInfo : nullptr, PBYTE(digest.constData()), DWORD(digest.size()), nullptr, 0, &size, isRSA ? BCRYPT_PAD_PKCS1 : 0); if(FAILED(err)) return res; res.resize(int(size)); err = NCryptSignHash(k, isRSA ? &padInfo : nullptr, PBYTE(digest.constData()), DWORD(digest.size()), PBYTE(res.data()), DWORD(res.size()), &size, isRSA ? BCRYPT_PAD_PKCS1 : 0); NCryptFreeObject( k ); switch( err ) { case ERROR_SUCCESS: d->err = PinOK; return res; case SCARD_W_CANCELLED_BY_USER: d->err = PinCanceled; break; default: res.clear(); break; } return res; }
TEST(test_buffer, fuzzy) { err_code_t err; DataBlock::setMinCapacity(5); BufferReader reader; TokenData td; DataBlock* dbPtr = NULL; // VALUE foo 10 0 24\r\n // \r\n // END\r\n // [] char str_list[][6] = {"VALUE", " foo ", "10 0 ", "24\r\n\r", "\nEND\r", "\n"}; for (int i = 0; i < 6; i++) { reader.write(str_list[i], strlen(str_list[i])); } uint64_t val, nBytes; reader.readUntil(err, ' ', td); ASSERT_EQ(err, RET_OK); ASSERT_EQ(td.size(), 1); ASSERT_EQ(td.front().offset, 0); ASSERT_EQ(td.front().size, 5); dbPtr = &*(td.front().iterator); dbPtr->release(td.front().size); ASSERT_N_STREQ((*dbPtr)[td.front().offset], "VALUE", 5); TEST_SKIP_BYTES_NO_THROW(1); td.clear(); reader.readUntil(err, ' ', td); ASSERT_EQ(err, RET_OK); ASSERT_EQ(td.size(), 1); ASSERT_EQ(td.front().offset, 1); ASSERT_EQ(td.front().size, 3); dbPtr = &*(td.front().iterator); dbPtr->release(td.front().size); ASSERT_N_STREQ((*dbPtr)[td.front().offset], "foo", 3); TEST_SKIP_BYTES_NO_THROW(1); td.clear(); TEST_READ_UNSIGNED_NO_THROW(val); ASSERT_EQ(val, 10); TEST_SKIP_BYTES_NO_THROW(1); TEST_READ_UNSIGNED_NO_THROW(nBytes); ASSERT_EQ(nBytes, 0); TEST_SKIP_BYTES_NO_THROW(1); TEST_READ_UNSIGNED_NO_THROW(val); ASSERT_EQ(val, 24); reader.readBytes(err, nBytes + 4, td); ASSERT_EQ(err, RET_OK); dbPtr = &*(td.front().iterator); dbPtr->release(td.front().size); // td.pop_front(); td.erase(td.begin()); dbPtr = &*(td.front().iterator); dbPtr->release(td.front().size); ASSERT_EQ(reader.peek(err, 0), 'E'); ASSERT_EQ(err, RET_OK); TEST_SKIP_BYTES_NO_THROW(5); }
TEST(test_buffer, read_bytes) { err_code_t err; DataBlock::setMinCapacity(5); BufferReader reader; TokenData td; DataBlock* dbPtr = NULL; reader.write(CSTR("12345"), 5); reader.write(CSTR("68964"), 5); reader.write(CSTR("\r\n"), 2); reader.readBytes(err, 6, td); ASSERT_EQ(err, RET_OK); ASSERT_EQ(td.size(), 2); ASSERT_EQ(td.front().size, 5); ASSERT_EQ(td.front().offset, 0); dbPtr = &*(td.front().iterator); dbPtr->release(td.front().size); ASSERT_N_STREQ((*dbPtr)[td.front().offset], "12345", 5); // td.pop_front(); td.erase(td.begin()); ASSERT_EQ(td.front().size, 1); ASSERT_EQ(td.front().offset, 0); dbPtr = &*(td.front().iterator); dbPtr->release(td.front().size); ASSERT_N_STREQ((*dbPtr)[td.front().offset], "6", 1); td.clear(); reader.readBytes(err, 4, td); ASSERT_EQ(err, RET_OK); ASSERT_EQ(td.size(), 1); ASSERT_EQ(td.front().size, 4); ASSERT_EQ(td.front().offset, 1); dbPtr = &*(td.front().iterator); dbPtr->release(td.front().size); ASSERT_N_STREQ((*dbPtr)[td.front().offset], "8964", 4); td.clear(); reader.readBytes(err, 2, td); ASSERT_EQ(err, RET_OK); ASSERT_EQ(td.size(), 1); ASSERT_EQ(td.front().size, 2); ASSERT_EQ(td.front().offset, 0); dbPtr = &*(td.front().iterator); dbPtr->release(td.front().size); ASSERT_N_STREQ((*dbPtr)[td.front().offset], "\r\n", 2); td.clear(); reader.readBytes(err, 2, td); ASSERT_EQ(err, RET_INCOMPLETE_BUFFER_ERR); td.clear(); reader.write(CSTR("syyin"), 5); reader.readBytes(err, 5, td); ASSERT_EQ(err, RET_OK); ASSERT_EQ(td.size(), 2); ASSERT_EQ(td.front().size, 3); ASSERT_EQ(td.front().offset, 2); dbPtr = &*(td.front().iterator); dbPtr->release(td.front().size); ASSERT_N_STREQ((*dbPtr)[td.front().offset], "syy", 3); // td.pop_front(); td.erase(td.begin()); ASSERT_EQ(td.front().size, 2); ASSERT_EQ(td.front().offset, 0); dbPtr = &*(td.front().iterator); dbPtr->release(td.front().size); ASSERT_N_STREQ((*dbPtr)[td.front().offset], "in", 2); }
TEST(test_buffer, read_until_across_block) { err_code_t err; DataBlock::setMinCapacity(5); // xi gu|a chi| guan|g le |aaaaa|aaaaa|aaa ! char str_list[][6] = {"xi gu", "a chi", " guan", "g le ", "aaaaa", "aaaaa", "aaa !"}; size_t i = 0; BufferReader reader; DataBlock* dbPtr = NULL; for (i = 0; i < 7; i++) { reader.write(str_list[i], 5); } size_t n_token = 7; TokenData* tokenDataPtr = new TokenData[n_token]; TokenData* tdPtr = NULL; for (i = 0; i < n_token - 1; i++) { reader.readUntil(err, ' ', tokenDataPtr[i]); ASSERT_EQ(err, RET_OK); EXPECT_EQ(reader.peek(err, 0), ' '); ASSERT_EQ(err, RET_OK); TEST_SKIP_BYTES_NO_THROW(1); } reader.readUntil(err, ' ', *(tokenDataPtr + n_token - 1)); ASSERT_EQ(err, RET_INCOMPLETE_BUFFER_ERR); // xi tdPtr = tokenDataPtr; ASSERT_EQ(tdPtr->size(), 1); ASSERT_EQ(tdPtr->front().size, 2); ASSERT_EQ(tdPtr->front().offset, 0); dbPtr = &*(tdPtr->front().iterator); dbPtr->release(tdPtr->front().size); ASSERT_N_STREQ((*dbPtr)[tdPtr->front().offset], "xi", 2); // gu|a tdPtr = tokenDataPtr + 1; ASSERT_EQ(tdPtr->size(), 2); ASSERT_EQ(tdPtr->front().size, 2); ASSERT_EQ(tdPtr->front().offset, 3); dbPtr = &*(tdPtr->front().iterator); dbPtr->release(tdPtr->front().size); ASSERT_N_STREQ((*dbPtr)[tdPtr->front().offset], "gu", 2); // tdPtr->pop_front(); tdPtr->erase(tdPtr->begin()); ASSERT_EQ(tdPtr->front().size, 1); ASSERT_EQ(tdPtr->front().offset, 0); dbPtr = &*(tdPtr->front().iterator); dbPtr->release(tdPtr->front().size); ASSERT_N_STREQ((*dbPtr)[tdPtr->front().offset], "a", 1); // chi tdPtr = tokenDataPtr + 2; ASSERT_EQ(tdPtr->size(), 1); ASSERT_EQ(tdPtr->front().size, 3); ASSERT_EQ(tdPtr->front().offset, 2); dbPtr = &*(tdPtr->front().iterator); dbPtr->release(tdPtr->front().size); ASSERT_N_STREQ((*dbPtr)[tdPtr->front().offset], "chi", 3); // guan|g tdPtr = tokenDataPtr + 3; ASSERT_EQ(tdPtr->size(), 2); ASSERT_EQ(tdPtr->front().size, 4); ASSERT_EQ(tdPtr->front().offset, 1); dbPtr = &*(tdPtr->front().iterator); dbPtr->release(tdPtr->front().size); ASSERT_N_STREQ((*dbPtr)[tdPtr->front().offset], "guan", 4); // tdPtr->pop_front(); tdPtr->erase(tdPtr->begin()); ASSERT_EQ(tdPtr->front().size, 1); ASSERT_EQ(tdPtr->front().offset, 0); dbPtr = &*(tdPtr->front().iterator); dbPtr->release(tdPtr->front().size); ASSERT_N_STREQ((*dbPtr)[tdPtr->front().offset], "g", 1); // le tdPtr = tokenDataPtr + 4; ASSERT_EQ(tdPtr->size(), 1); ASSERT_EQ(tdPtr->front().size, 2); ASSERT_EQ(tdPtr->front().offset, 2); dbPtr = &*(tdPtr->front().iterator); dbPtr->release(tdPtr->front().size); ASSERT_N_STREQ((*dbPtr)[tdPtr->front().offset], "le", 2); // aaaaa|aaaaa|aaa tdPtr = tokenDataPtr + 5; ASSERT_EQ(tdPtr->size(), 3); ASSERT_EQ(tdPtr->front().size, 5); ASSERT_EQ(tdPtr->front().offset, 0); dbPtr = &*(tdPtr->front().iterator); dbPtr->release(tdPtr->front().size); ASSERT_N_STREQ((*dbPtr)[tdPtr->front().offset], "aaaaa", 5); // tdPtr->pop_front(); tdPtr->erase(tdPtr->begin()); ASSERT_EQ(tdPtr->front().size, 5); ASSERT_EQ(tdPtr->front().offset, 0); dbPtr = &*(tdPtr->front().iterator); dbPtr->release(tdPtr->front().size); ASSERT_N_STREQ((*dbPtr)[tdPtr->front().offset], "aaaaa", 5); // tdPtr->pop_front(); tdPtr->erase(tdPtr->begin()); ASSERT_EQ(tdPtr->front().size, 3); ASSERT_EQ(tdPtr->front().offset, 0); dbPtr = &*(tdPtr->front().iterator); dbPtr->release(tdPtr->front().size); ASSERT_N_STREQ((*dbPtr)[tdPtr->front().offset], "aaa", 3); ASSERT_EQ(reader.peek(err, 0), '!'); ASSERT_EQ(err, RET_OK); TEST_SKIP_BYTES_NO_THROW(1); delete[] tokenDataPtr; }
PinDialog::PinDialog( PinType type, const TokenData &t, QWidget *parent ) { SslCertificate c = t.cert(); init( type, c.toString( c.isTempel() ? "CN serialNumber" : "GN SN serialNumber" ), t.flags() ); }