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; } }
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; }
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; }
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() ); }