예제 #1
0
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 );
}
예제 #2
0
파일: test_buffer.cpp 프로젝트: Abioy/libmc
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);
}
예제 #3
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;
}
예제 #4
0
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;
}
예제 #5
0
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;
}
예제 #6
0
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;
	}
}
예제 #7
0
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() );
}
예제 #8
0
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;
}
예제 #9
0
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
	{
예제 #10
0
파일: QCNG.cpp 프로젝트: open-eid/qdigidoc
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;
}
예제 #11
0
파일: test_buffer.cpp 프로젝트: Abioy/libmc
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);
}
예제 #12
0
파일: test_buffer.cpp 프로젝트: Abioy/libmc
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);
}
예제 #13
0
파일: test_buffer.cpp 프로젝트: Abioy/libmc
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;
}
예제 #14
0
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() );
}