Exemplo n.º 1
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;
}
Exemplo n.º 2
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 );
}
Exemplo n.º 3
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;
}
Exemplo n.º 4
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
	{
Exemplo n.º 5
0
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;
}