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; }
void QSigner::selectCert( const QString &card ) { d->selectedCard = card; d->sign = QSslCertificate(); Q_EMIT dataChanged( d->cards.keys(), d->selectedCard, d->sign ); PKCS11_CERT* certs; unsigned int numberOfCerts; for( unsigned int i = 0; i < d->slotCount; ++i ) { PKCS11_SLOT* slot = &d->slots[i]; if( !slot->token || d->selectedCard != QByteArray( (const char*)slot->token->serialnr, 16 ).trimmed() || PKCS11_enumerate_certs( slot->token, &certs, &numberOfCerts ) || numberOfCerts <= 0 ) continue; SslCertificate cert = SslCertificate::fromX509( Qt::HANDLE((&certs[0])->x509) ); if( cert.keyUsage().keys().contains( SslCertificate::NonRepudiation ) ) { d->sign = cert; d->cards[d->selectedCard] = i; break; } } Q_EMIT dataChanged( d->cards.keys(), d->selectedCard, d->sign ); }
void SignatureWidget::link( const QString &url ) { if( url == "details" ) (new SignatureDialog( s, qApp->activeWindow() ))->show(); else if( url == "remove" ) { SslCertificate c = s.cert(); QString msg = tr("Remove signature %1") .arg( c.toString( c.showCN() ? "CN serialNumber" : "GN SN serialNumber" ) ); QMessageBox::StandardButton b = QMessageBox::warning( qApp->activeWindow(), msg, msg, QMessageBox::Ok|QMessageBox::Cancel, QMessageBox::Cancel ); if( b == QMessageBox::Ok ) Q_EMIT removeSignature( num ); } }
bool SslContext::UseCertificate(String certdata, String pkeydata, bool cert_asn1) { ASSERT(ssl_ctx); if(IsNull(certdata) || IsNull(pkeydata)) return false; SslCertificate cert; SslKey pkey; if(!cert.Load(certdata, cert_asn1) || !pkey.Load(pkeydata)) return false; if(!SSL_CTX_use_certificate(ssl_ctx, cert) || !SSL_CTX_use_PrivateKey(ssl_ctx, pkey)) return false; if(!SSL_CTX_check_private_key(ssl_ctx)) return false; return true; }
void QSigner::selectCert( const QString &card ) { d->selectedCard = card; d->flags = 0; d->cert = QSslCertificate(); emitDataChanged(); if( d->slotCount ) { PKCS11_release_all_slots( d->handle, d->slots, d->slotCount ); d->slotCount = 0; } if( PKCS11_enumerate_slots( d->handle, &d->slots, &d->slotCount ) || d->cards[card] >= d->slotCount || !(d->slot = &d->slots[d->cards[card]]) ) return; PKCS11_CERT* certs; unsigned int numberOfCerts; for( unsigned int i = 0; i < d->slotCount; ++i ) { if( !d->slot->token || d->selectedCard != QByteArray( (const char*)d->slot->token->serialnr, 16 ).trimmed() || PKCS11_enumerate_certs( d->slot->token, &certs, &numberOfCerts ) || numberOfCerts <= 0 ) continue; SslCertificate cert = SslCertificate::fromX509( Qt::HANDLE((&certs[0])->x509) ); if( cert.keyUsage().keys().contains( SslCertificate::NonRepudiation ) ) { d->cert = cert; d->cards[d->selectedCard] = i; #ifdef LIBP11_TOKEN_FLAGS if( d->slot->token->userPinCountLow || d->slot->token->soPinCountLow ) d->flags |= TokenData::PinCountLow; if( d->slot->token->userPinFinalTry || d->slot->token->soPinFinalTry ) d->flags |= TokenData::PinFinalTry; if( d->slot->token->userPinLocked || d->slot->token->soPinLocked ) d->flags |= TokenData::PinLocked; #endif break; } } emitDataChanged(); }
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; }
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() ); }
void CertificateDialog::setCertificate( const QSslCertificate &cert ) { d->cert = cert; SslCertificate c = cert; QString i; QTextStream s( &i ); s << "<b>" << tr("Certificate Information") << "</b><br />"; s << "<hr>"; s << "<b>" << tr("This certificate is intended for following purpose(s):") << "</b>"; s << "<ul>"; Q_FOREACH( const QString &ext, c.enhancedKeyUsage() ) s << "<li>" << ext << "</li>"; s << "</ul>"; s << "<br /><br /><br /><br />"; //s << tr("* Refer to the certification authority's statement for details.") << "<br />"; s << "<hr>"; s << "<p style='margin-left: 30px;'>"; s << "<b>" << tr("Issued to:") << "</b> " << c.subjectInfo( QSslCertificate::CommonName ); s << "<br /><br /><br />"; s << "<b>" << tr("Issued by:") << "</b> " << c.issuerInfo( QSslCertificate::CommonName ); s << "<br /><br /><br />"; s << "<b>" << tr("Valid from") << "</b> " << c.effectiveDate().toLocalTime().toString( "dd.MM.yyyy" ) << " "; s << "<b>" << tr("to") << "</b> "<< c.expiryDate().toLocalTime().toString( "dd.MM.yyyy" ); s << "</p>"; d->info->setHtml( i ); d->addItem( tr("Version"), "V" + c.version() ); d->addItem( tr("Serial number"), QString( "%1 (0x%2)" ) .arg( c.serialNumber().constData() ) .arg( QString::number( c.serialNumber().toInt(), 16 ) ) ); d->addItem( tr("Signature algorithm"), c.signatureAlgorithm() ); QStringList text, textExt; Q_FOREACH( const QByteArray &subject, QList<QByteArray>() << "CN" << "OU" << "O" << "C" ) { const QString &data = c.issuerInfo( subject ); if( data.isEmpty() ) continue; text << data; textExt << QString( "%1 = %2" ).arg( subject.constData() ).arg( data ); } d->addItem( tr("Issuer"), text.join( ", " ), textExt.join( "\n" ) ); d->addItem( tr("Valid from"), c.effectiveDate().toLocalTime().toString( "dd.MM.yyyy hh:mm:ss" ) ); d->addItem( tr("Vaild to"), c.expiryDate().toLocalTime().toString( "dd.MM.yyyy hh:mm:ss" ) ); text.clear(); textExt.clear(); Q_FOREACH( const QByteArray &subject, QList<QByteArray>() << "serialNumber" << "GN" << "SN" << "CN" << "OU" << "O" << "C" ) { const QString &data = c.subjectInfo( subject ); if( data.isEmpty() ) continue; text << data; textExt << QString( "%1 = %2" ).arg( subject.constData() ).arg( data ); } d->addItem( tr("Subject"), text.join( ", " ), textExt.join( "\n" ) ); d->addItem( tr("Public key"), QString("%1 (%2)") .arg( c.publicKey().algorithm() == QSsl::Rsa ? "RSA" : "DSA" ) .arg( d->keyLenght( c.publicKey() ) ), c.toHex( c.publicKey().toDer() ) ); QStringList enhancedKeyUsage = c.enhancedKeyUsage().values(); if( !enhancedKeyUsage.isEmpty() ) d->addItem( tr("Enhanched key usage"), enhancedKeyUsage.join( ", " ), enhancedKeyUsage.join( "\n" ) ); QStringList policies = c.policies(); if( !policies.isEmpty() ) d->addItem( tr("Certificate policies"), policies.join( ", " ) ); d->addItem( tr("Authority key identifier"), c.toHex( c.authorityKeyIdentifier() ) ); d->addItem( tr("Subject key identifier"), c.toHex( c.subjectKeyIdentifier() ) ); QStringList keyUsage = c.keyUsage().values(); if( !keyUsage.isEmpty() ) d->addItem( tr("Key usage"), keyUsage.join( ", " ), keyUsage.join( "\n" ) ); }
SignatureWidget::SignatureWidget( const DigiDocSignature &signature, unsigned int signnum, QWidget *parent ) : QLabel( parent ) , num( signnum ) , s( signature ) { setSizePolicy( QSizePolicy::Ignored, QSizePolicy::Preferred ); setWordWrap( true ); const SslCertificate cert = s.cert(); QString content; QTextStream st( &content ); if( cert.isTempel() ) st << "<img src=\":/images/ico_stamp_blue_16.png\">"; else st << "<img src=\":/images/ico_person_blue_16.png\">"; st << "<b>" << Qt::escape( cert.toString( cert.showCN() ? "CN" : "GN SN" ) ) << "</b>"; QString tooltip; QTextStream t( &tooltip ); QDateTime date = s.dateTime(); if( !s.location().isEmpty() ) { st << "<br />" << Qt::escape( s.location() ); t << Qt::escape( s.location() ) << "<br />"; } if( !s.role().isEmpty() ) { st << "<br />" << Qt::escape( s.role() ); t << Qt::escape( s.role() ) << "<br />"; } if( !date.isNull() ) { st << "<br />" << tr("Signed on") << " " << SslCertificate::formatDate( date, "dd. MMMM yyyy" ) << " " << tr("time") << " " << date.toString( "hh:mm" ); t << tr("Signed on") << " " << SslCertificate::formatDate( date, "dd. MMMM yyyy" ) << " " << tr("time") << " " << date.toString( "hh:mm" ); } setToolTip( tooltip ); st << "<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\"><tr>"; st << "<td>" << tr("Signature is") << " "; switch( s.validate() ) { case DigiDocSignature::Valid: st << "<font color=\"green\">" << tr("valid"); break; case DigiDocSignature::Invalid: st << "<font color=\"red\">" << tr("not valid"); break; case DigiDocSignature::Unknown: st << "<font color=\"red\">" << tr("unknown"); break; } if( signature.isTest() ) st << " (" << tr("Test signature") << ")"; st << "</font>"; st << "</td><td align=\"right\">"; st << "<a href=\"details\">" << tr("Show details") << "</a>"; st << "</td></tr><tr><td></td>"; st << "<td align=\"right\">"; st << "<a href=\"remove\">" << tr("Remove") << "</a>"; st << "</td></tr></table>"; setText( content ); connect( this, SIGNAL(linkActivated(QString)), SLOT(link(QString)) ); }
SignatureDialog::SignatureDialog( const DigiDocSignature &signature, QWidget *parent ) : QWidget( parent ) , s( signature ) , d( new SignatureDialogPrivate ) { d->setupUi( this ); setAttribute( Qt::WA_DeleteOnClose ); setWindowFlags( Qt::Sheet ); const SslCertificate c = s.cert(); QString titleText = c.toString( c.showCN() ? "CN serialNumber" : "GN SN serialNumber" ); d->title->setText( titleText ); setWindowTitle( titleText ); QString msg; QTextStream st( &msg ); switch( s.validate() ) { case DigiDocSignature::Valid: st << tr("Signature is valid"); break; case DigiDocSignature::Invalid: st << "<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\"><tr>" << "<td>" << tr("Signature is not valid") << "</td>" << "<td align=\"right\"><a href=\"help\">" << tr("Help") << "</a></td>" << "</tr></table>" << "(" << (s.lastError().isEmpty() ? tr("Unknown error") : s.lastError()) << ")"; break; case DigiDocSignature::Unknown: st << "<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\"><tr>" << "<td>" << tr("Signature status unknown") << "</td>" << "<td align=\"right\"><a href=\"help\">" << tr("Help") << "</a></td>" << "</tr></table>" << "(" << (s.lastError().isEmpty() ? tr("Unknown error") : s.lastError()) << ")"; break; } d->error->setText( msg ); const QStringList l = s.locations(); d->signerCity->setText( l.value( 0 ) ); d->signerState->setText( l.value( 1 ) ); d->signerZip->setText( l.value( 2 ) ); d->signerCountry->setText( l.value( 3 ) ); QStringList roles = s.roles(); d->signerRole->setText( roles.value(0) ); if( s.type() == DigiDocSignature::DDocType ) delete d->signerResolution; else d->signerResolution->setText( roles.value(1) ); // Certificate info QTreeWidget *t = d->signatureView; addItem( t, tr("Signing time"), s.dateTime().toString( "dd.MM.yyyy hh:mm:ss" ) ); addItem( t, tr("Signature type"), c.publicKey().algorithm() == QSsl::Rsa ? "RSA" : "DSA" ); addItem( t, tr("Signature format"), s.mediaType() ); addItem( t, tr("Signed file count"), QString::number( s.parent()->documentModel()->rowCount() ) ); addItem( t, tr("Certificate serialnumber"), c.serialNumber() ); addItem( t, tr("Certificate valid at"), c.effectiveDate().toLocalTime().toString( "dd.MM.yyyy" ) ); addItem( t, tr("Certificate valid until"), c.expiryDate().toLocalTime().toString( "dd.MM.yyyy" ) ); addItem( t, tr("Certificate issuer"), c.issuerInfo( QSslCertificate::CommonName ) ); t->resizeColumnToContents( 0 ); // OCSP info if( s.type() == DigiDocSignature::DDocType || s.type() == DigiDocSignature::TMType ) { SslCertificate ocsp = s.ocspCert(); addItem( d->ocspView, tr("Certificate issuer"), ocsp.issuerInfo( QSslCertificate::CommonName ) ); addItem( d->ocspView, tr("Certificate serialnumber"), ocsp.serialNumber() ); addItem( d->ocspView, tr("Time"), s.dateTime().toString( "dd.MM.yyyy hh:mm:ss" ) ); addItem( d->ocspView, tr("Hash value of validity confirmation"), ocsp.toHex( s.digestValue() ) ); d->ocspView->resizeColumnToContents( 0 ); } else d->tabWidget->removeTab( 2 ); }
SignatureDialog::SignatureDialog( const DigiDocSignature &signature, QWidget *parent ) : QDialog( parent ) , s( signature ) , d( new SignatureDialogPrivate ) { d->setupUi( this ); d->error->hide(); setAttribute( Qt::WA_DeleteOnClose ); const SslCertificate c = s.cert(); #define addCertButton(cert, button) if(!cert.isNull()) \ d->buttonBox->addButton(button, QDialogButtonBox::ActionRole)->setProperty("cert", QVariant::fromValue(cert)); addCertButton(s.cert(), tr("Show signer's certificate")); addCertButton(s.ocspCert(), tr("Show OCSP certificate")); addCertButton(s.tsaCert(), tr("Show TSA certificate")); addCertButton(qApp->confValue( Application::TSLCert ).value<QSslCertificate>(), tr("Show TSL certificate")); QString status; switch( s.validate() ) { case DigiDocSignature::Valid: status = tr("Signature is valid"); break; case DigiDocSignature::Warning: status = QString("%1 (%2)").arg( tr("Signature is valid"), tr("Warnings") ); if( !s.lastError().isEmpty() ) d->error->setPlainText( s.lastError() ); if( s.warning() & DigiDocSignature::WrongNameSpace ) { d->info->setText( tr( "This Digidoc document has not been created according to specification, " "but the digital signature is legally valid. Please inform the document creator " "of this issue. <a href='http://www.id.ee/?id=36511'>Additional information</a>.") ); } if( s.warning() & DigiDocSignature::DigestWeak ) { d->info->setText( tr( "The current BDOC container uses weaker encryption method than officialy accepted in Estonia.") ); } break; case DigiDocSignature::Test: status = QString("%1 (%2)").arg( tr("Signature is valid"), tr("Test signature") ); if( !s.lastError().isEmpty() ) d->error->setPlainText( s.lastError() ); d->info->setText( tr( "Test signature is signed with test certificates that are similar to the " "certificates of real tokens, but digital signatures with legal force cannot " "be given with them as there is no actual owner of the card. " "<a href='http://www.id.ee/index.php?id=30494'>Additional information</a>.") ); break; case DigiDocSignature::Invalid: status = tr("Signature is not valid"); d->error->setPlainText( s.lastError().isEmpty() ? tr("Unknown error") : s.lastError() ); d->info->setText( tr( "This is an invalid signature or malformed digitally signed file. The signature is not valid.") ); break; case DigiDocSignature::Unknown: status = tr("Signature status unknown"); d->error->setPlainText( s.lastError().isEmpty() ? tr("Unknown error") : s.lastError() ); d->info->setText( tr( "Signature status is displayed unknown if you don't have all validity confirmation service " "certificates and/or certificate authority certificates installed into your computer. " "<a href='http://www.id.ee/index.php?id=35941'>Additional information</a>.") ); break; } if( d->error->toPlainText().isEmpty() && d->info->text().isEmpty() ) d->tabWidget->removeTab( 0 ); else d->buttonBox->addButton( QDialogButtonBox::Help ); d->title->setText( c.toString( c.showCN() ? "CN serialNumber" : "GN SN serialNumber" ) + "\n" + status ); setWindowTitle( c.toString( c.showCN() ? "CN serialNumber" : "GN SN serialNumber" ) + " - " + status ); const QStringList l = s.locations(); d->signerCity->setText( l.value( 0 ) ); d->signerState->setText( l.value( 1 ) ); d->signerZip->setText( l.value( 2 ) ); d->signerCountry->setText( l.value( 3 ) ); Q_FOREACH( const QString &role, s.roles() ) { QLineEdit *line = new QLineEdit( role, d->signerRoleGroup ); line->setReadOnly( true ); d->signerRoleGroupLayout->addRow( line ); } // Certificate info QTreeWidget *t = d->signatureView; t->header()->setResizeMode( 0, QHeaderView::ResizeToContents ); addItem( t, tr("TSL URL"), qApp->confValue( Application::TSLUrl ).toString() ); addItem( t, tr("Signer's computer time (UTC)"), DateTime( s.signTime() ).toStringZ( "dd.MM.yyyy hh:mm:ss" ) ); addItem( t, tr("Signature method"), s.signatureMethod() ); addItem( t, tr("Container format"), s.parent()->mediaType() ); if( s.type() != DigiDocSignature::DDocType ) addItem( t, tr("Signature format"), s.profile() ); if( !s.policy().isEmpty() ) { #define toVer(X) (X)->toUInt() - 1 QStringList ver = s.policy().split( "." ); if( ver.size() >= 3 ) addItem( t, tr("Signature policy"), QString("%1.%2.%3").arg( toVer(ver.end()-3) ).arg( toVer(ver.end()-2) ).arg( toVer(ver.end()-1) ) ); else addItem( t, tr("Signature policy"), s.policy() ); } addItem( t, tr("Signed file count"), QString::number( s.parent()->documentModel()->rowCount() ) ); addItem( t, tr("Signer Certificate issuer"), c.issuerInfo( QSslCertificate::CommonName ) ); if( !s.spuri().isEmpty() ) addItem( t, "SPUri", s.spuri() ); // OCSP info switch( s.type() ) { case DigiDocSignature::TSType: { addItem( t, tr("Signature Timestamp"), DateTime( s.tsaTime().toLocalTime() ).toStringZ( "dd.MM.yyyy hh:mm:ss" )); addItem( t, tr("Signature Timestamp") + " (UTC)", DateTime( s.tsaTime() ).toStringZ( "dd.MM.yyyy hh:mm:ss" ) ); addItem( t, tr("TSA Certificate issuer"), SslCertificate(s.tsaCert()).issuerInfo( QSslCertificate::CommonName ) ); } //Fall through to OCSP info case DigiDocSignature::DDocType: case DigiDocSignature::TMType: { SslCertificate ocsp = s.ocspCert(); addItem( t, tr("OCSP Certificate issuer"), ocsp.issuerInfo( QSslCertificate::CommonName ) ); addItem( t, tr("OCSP time"), DateTime( s.ocspTime().toLocalTime() ).toStringZ( "dd.MM.yyyy hh:mm:ss" ) ); addItem( t, tr("OCSP time") + " (UTC)", DateTime( s.ocspTime() ).toStringZ( "dd.MM.yyyy hh:mm:ss" ) ); addItem( t, tr("Hash value of signature"), SslCertificate::toHex( s.ocspNonce() ) ); break; } default: break; } }
PrintSheet::PrintSheet( DigiDoc *doc, QPrinter *printer ) : QPainter( printer ) , p( printer ) { printer->setOrientation( QPrinter::Portrait ); left = p->pageRect().left(); margin = left; right = p->pageRect().right() - 2*margin; top = p->pageRect().top(); bottom = p->pageRect().y() + p->pageRect().height() - 2*margin; #ifdef Q_OS_MAC scale( 0.8, 0.8 ); right /= 0.8; bottom /= 0.8; #endif QFont text = font(); text.setFamily( "Arial, Liberation Sans, Helvetica, sans-serif" ); text.setPixelSize( 12 ); QFont head = text; QFont sHead = text; head.setPixelSize( 28 ); sHead.setPixelSize( 18 ); QPen oPen = pen(); QPen sPen = pen(); QPen hPen = pen(); hPen.setWidth( 2 ); sPen.setWidth( 1 ); sPen.setStyle( Qt::DotLine ); setFont( head ); QRect rect( left, top, right, 60 ); drawText( rect, Qt::TextWordWrap, tr("VALIDITY CONFIRMATION SHEET"), &rect ); setPen( hPen ); drawLine( left, rect.bottom(), right, rect.bottom() ); top += rect.height() + 30; setFont( sHead ); drawText( left, top, tr("SIGNED FILES") ); setPen( sPen ); drawLine( left, top+3, right, top+3 ); top += 30; setFont( text ); setPen( oPen ); drawText( left, top, tr("FILE NAME") ); drawText( right-150, top, tr("FILE SIZE") ); for( int i = 0; i < doc->documentModel()->rowCount(); ++i ) { int fileHeight = drawTextRect( QRect( left, top+5, right - left - 150, 20 ), doc->documentModel()->index( i, 0 ).data().toString() ); drawTextRect( QRect( right-150, top+5, 150, fileHeight ), doc->documentModel()->index( i, 2 ).data().toString() ); top += fileHeight; newPage( 50 ); } top += 35; newPage( 50 ); setFont( sHead ); drawText( left, top, tr("SIGNERS") ); setPen( sPen ); drawLine( left, top+3, right, top+3 ); top += 30; setFont( text ); setPen( oPen ); int i = 1; Q_FOREACH( const DigiDocSignature &sig, doc->signatures() ) { const SslCertificate cert = sig.cert(); bool tempel = cert.isTempel(); newPage( 50 ); drawText( left, top, tr("NO.") ); drawText( left+40, top, tempel ? tr( "COMPANY" ) : tr( "NAME" ) ); drawText( right-300, top, tempel ? tr("REGISTER CODE") : tr("PERSONAL CODE") ); drawText( right-170, top, tr("TIME") ); top += 5; int nameHeight = drawTextRect( QRect( left+40, top, right - left - 340, 20 ), cert.toString( cert.showCN() ? "CN" : "GN SN" ) ); drawTextRect( QRect( left, top, 40, nameHeight ), QString::number( i++ ) ); drawTextRect( QRect( right-300, top, 130, nameHeight ), cert.subjectInfo( "serialNumber" ) ); drawTextRect( QRect( right-170, top, 170, nameHeight ), DateTime( sig.dateTime() ).toStringZ( "dd.MM.yyyy hh:mm:ss" ) ); top += 20 + nameHeight; QString valid; switch( sig.validate() ) { case DigiDocSignature::Valid: valid.append( tr("SIGNATURE IS VALID") ); break; case DigiDocSignature::Invalid: valid.append( tr("SIGNATURE IS NOT VALID") ); break; case DigiDocSignature::Unknown: valid.append( tr("UNKNOWN") ); break; } if( sig.isTest() ) valid += " " + tr("(NB! TEST SIGNATURE)"); customText( tr("VALIDITY OF SIGNATURE"), valid ); customText( tr("ROLE / RESOLUTION"), sig.role() ); customText( tr("PLACE OF CONFIRMATION (CITY, STATE, ZIP, COUNTRY)"), sig.location() ); customText( tr("SERIAL NUMBER OF SIGNER CERTIFICATE"), cert.serialNumber() ); newPage( 50 ); drawText( left, top, tr("ISSUER OF CERTIFICATE") ); drawText( left+207, top, tr("HASH VALUE OF ISSUER'S PUBLIC KEY") ); top += 5; int issuerHeight = drawTextRect( QRect( left, top, 200, 20 ), cert.issuerInfo( QSslCertificate::CommonName ) ); drawTextRect( QRect( left+200, top, right - left - 200, issuerHeight ), cert.toHex( cert.authorityKeyIdentifier() ) ); top += 20 + issuerHeight; customText( tr("HASH VALUE OF VALIDITY CONFIRMATION (OCSP RESPONSE)"), cert.toHex( sig.ocspDigestValue() ) ); top += 15; } save(); newPage( 50 ); QTextDocument textDoc; textDoc.setTextWidth( right - margin ); textDoc.setHtml( tr("The print out of files listed in the section <b>\"Signed Files\"</b> " "are inseparable part of this Validity Confirmation Sheet.") ); translate( QPoint( left, top - 30) ); textDoc.drawContents( this , QRectF( 0, 0, right - margin, 40) ); top += 30; restore(); newPage( 90 ); drawText( left+3, top, tr("NOTES") ); top += 10; drawRect( left, top, right - margin, 80 ); end(); }
PinDialog::PinDialog( PinType type, const QSslCertificate &cert, TokenData::TokenFlags flags, QWidget *parent ) : QDialog( parent ) { SslCertificate c = cert; init( type, c.toString( c.isTempel() ? "CN serialNumber" : "GN SN serialNumber" ), flags ); }
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() ); }
PrintSheet::PrintSheet( DigiDoc *doc, QPrinter *printer ) : QPainter( printer ) , p( printer ) { printer->setOrientation( QPrinter::Portrait ); QDateTime utc = QDateTime::currentDateTime().toUTC(); utc.setTimeSpec( Qt::LocalTime ); int diffsec = utc.secsTo( QDateTime::currentDateTime() ); QString timediff = diffsec >= 0 ? "+" : "-"; timediff += QTime().addSecs( diffsec >= 0 ? diffsec : -diffsec ).toString( "hh:mm" ); left = p->pageRect().x(); margin = left; right = p->pageRect().topRight().x() - 2*margin; top = p->pageRect().topLeft().y() + 30; #ifdef Q_OS_MAC scale( 0.8, 0.8 ); right /= 0.8; #endif QFont text = font(); text.setFamily( "Arial, Liberation Sans, Helvetica, sans-serif" ); text.setPixelSize( 12 ); QFont head = text; QFont sHead = text; head.setPixelSize( 28 ); sHead.setPixelSize( 18 ); QPen oPen = pen(); QPen sPen = pen(); QPen hPen = pen(); hPen.setWidth( 2 ); sPen.setWidth( 1 ); sPen.setStyle( Qt::DotLine ); setFont( head ); drawText( left, top, tr("VALIDITY CONFIRMATION SHEET") ); setPen( hPen ); drawLine( left, top+3, right, top+3 ); top += 45; setFont( sHead ); drawText( left, top, tr("SIGNED FILES") ); setPen( sPen ); drawLine( left, top+3, right, top+3 ); top += 30; setFont( text ); setPen( oPen ); drawText( left, top, tr("FILE NAME") ); drawText( left+400, top, tr("FILE SIZE") ); for( int i = 0; i < doc->documentModel()->rowCount(); ++i ) { drawLine( left, top+5, right, top+5 ); drawLine( left, top+5, left, top+25 ); drawLine( left+395, top+5, left+395, top+25 ); drawLine( right, top+5, right, top+25 ); top += 20; drawText( left+5, top, doc->documentModel()->index( i, 0 ).data().toString() ); drawText( left+400, top, doc->documentModel()->index( i, 2 ).data().toString() ); drawLine( left, top+5, right, top+5 ); newPage( 50 ); } top += 35; newPage( 50 ); setFont( sHead ); drawText( left, top, tr("SIGNERS") ); setPen( sPen ); drawLine( left, top+3, right, top+3 ); top += 30; setFont( text ); setPen( oPen ); int i = 1; Q_FOREACH( const DigiDocSignature &sig, doc->signatures() ) { newPage( 50 ); const SslCertificate cert = sig.cert(); bool tempel = cert.isTempel(); drawText( left, top, tr("NO.") ); drawLine( left+35, top+5, left+35, top+25 ); drawText( left+40, top, tempel ? tr( "COMPANY" ) : tr( "NAME" ) ); drawLine( right-305, top+5, right-305, top+25 ); drawText( right-300, top, tempel ? tr("REGISTER CODE") : tr("PERSONAL CODE") ); drawLine( right-165, top+5, right-165, top+25 ); drawText( right-160, top, tr("TIME") ); drawRect( left, top+5, right - margin, 20 ); top += 20; drawText( left+5, top, QString::number( i ) ); drawText( left+40, top, cert.toString( cert.showCN() ? "CN" : "GN SN" ) ); drawText( right-300, top, cert.subjectInfo( "serialNumber" ) ); drawText( right-160, top, sig.dateTime().toString( "dd.MM.yyyy hh:mm:ss" ) + " " + timediff ); top += 25; QString valid = tr("SIGNATURE") + " "; switch( sig.validate() ) { case DigiDocSignature::Valid: valid.append( tr("VALID") ); break; case DigiDocSignature::Invalid: valid.append( tr("NOT VALID") ); break; case DigiDocSignature::Unknown: valid.append( tr("UNKNOWN") ); break; } if( sig.isTest() ) valid += " " + tr("(NB! TEST SIGNATURE)"); customText( tr("VALIDITY OF SIGNATURE"), valid ); top += 45; customText( tr("ROLE / RESOLUTION"), sig.role() ); top += 45; customText( tr("PLACE OF CONFIRMATION (CITY, STATE, ZIP, COUNTRY)"), sig.location() ); top += 45; customText( tr("SERIAL NUMBER OF SIGNER CERTIFICATE"), cert.serialNumber() ); top += 45; customText( tr("ISSUER OF CERTIFICATE"), cert.issuerInfo( QSslCertificate::CommonName ) ); drawText( left+207, top, tr("HASH VALUE OF ISSUER'S PUBLIC KEY") ); drawLine( left+200, top+5, left+200, top+25 ); drawText( left+207, top+20, cert.toHex( cert.authorityKeyIdentifier() ) ); top += 45; customText( tr("HASH VALUE OF VALIDITY CONFIRMATION (OCSP RESPONSE)"), cert.toHex( sig.ocspDigestValue() ) ); top += 60; ++i; } save(); newPage( 50 ); QTextDocument textDoc; textDoc.setTextWidth( right - margin ); textDoc.setHtml( tr("The print out of files listed in the section <b>\"Signed Files\"</b> " "are inseparable part of this Validity Confirmation Sheet.") ); translate( QPoint( left, top - 30) ); textDoc.drawContents( this , QRectF( 0, 0, right - margin, 40) ); top += 30; restore(); newPage( 90 ); drawText( left+3, top, tr("NOTES") ); top += 10; drawRect( left, top, right - margin, 80 ); end(); }
PinDialog::PinDialog( PinFlags flags, const QSslCertificate &cert, TokenData::TokenFlags token, QWidget *parent ) : QDialog( parent ) { SslCertificate c = cert; init( flags, c.toString( c.showCN() ? "CN serialNumber" : "GN SN serialNumber" ), token ); }
CertificateDialog::CertificateDialog(const QSslCertificate &cert, QWidget *parent, bool removePath) : QDialog( parent ) , d( new CertificateDialogPrivate ) { d->setupUi( this ); QPushButton *save = d->buttonBox->button(QDialogButtonBox::Save); if(save && Settings(QSettings::SystemScope).value("disableSave", false).toBool()) { d->buttonBox->removeButton(save); save->deleteLater(); } if(removePath) d->tabWidget->removeTab( 2 ); d->cert = cert; SslCertificate c = cert; QString i; QTextStream s( &i ); s << "<b>" << tr("Certificate Information") << "</b><br />"; s << "<hr>"; s << "<b>" << tr("This certificate is intended for following purpose(s):") << "</b>"; s << "<ul>"; for(const QString &ext: c.enhancedKeyUsage()) s << "<li>" << ext << "</li>"; s << "</ul>"; s << "<br /><br /><br /><br />"; //s << tr("* Refer to the certification authority's statement for details.") << "<br />"; s << "<hr>"; s << "<p style='margin-left: 30px;'>"; s << "<b>" << tr("Issued to:") << "</b> " << c.subjectInfo( QSslCertificate::CommonName ); s << "<br /><br /><br />"; s << "<b>" << tr("Issued by:") << "</b> " << c.issuerInfo( QSslCertificate::CommonName ); s << "<br /><br /><br />"; s << "<b>" << tr("Valid from") << "</b> " << c.effectiveDate().toLocalTime().toString( "dd.MM.yyyy" ) << " "; s << "<b>" << tr("to") << "</b> "<< c.expiryDate().toLocalTime().toString( "dd.MM.yyyy" ); s << "</p>"; d->info->setHtml( i ); d->addItem( tr("Version"), "V" + c.version() ); d->addItem( tr("Serial number"), QString( "%1 (0x%2)" ) .arg( c.serialNumber().constData() ) .arg( c.serialNumber( true ).constData() ) ); d->addItem( tr("Signature algorithm"), c.signatureAlgorithm() ); QStringList text, textExt; for(const QByteArray &obj: c.issuerInfoAttributes()) { const QString &data = c.issuerInfo( obj ); if( data.isEmpty() ) continue; text << data; textExt << QString( "%1 = %2" ).arg( obj.constData() ).arg( data ); } d->addItem( tr("Issuer"), text.join( ", " ), textExt.join( "\n" ) ); d->addItem( tr("Valid from"), DateTime( c.effectiveDate().toLocalTime() ).toStringZ( "dd.MM.yyyy hh:mm:ss" ) ); d->addItem( tr("Valid to"), DateTime( c.expiryDate().toLocalTime() ).toStringZ( "dd.MM.yyyy hh:mm:ss" ) ); text.clear(); textExt.clear(); for(const QByteArray &obj: c.subjectInfoAttributes()) { const QString &data = c.subjectInfo( obj ); if( data.isEmpty() ) continue; text << data; textExt << QString( "%1 = %2" ).arg( obj.constData() ).arg( data ); } d->addItem( tr("Subject"), text.join( ", " ), textExt.join( "\n" ) ); d->addItem( tr("Public key"), c.keyName(), c.publicKeyHex() ); QStringList enhancedKeyUsage = c.enhancedKeyUsage().values(); if( !enhancedKeyUsage.isEmpty() ) d->addItem( tr("Enhanched key usage"), enhancedKeyUsage.join( ", " ), enhancedKeyUsage.join( "\n" ) ); QStringList policies = c.policies(); if( !policies.isEmpty() ) d->addItem( tr("Certificate policies"), policies.join( ", " ) ); d->addItem( tr("Authority key identifier"), c.toHex( c.authorityKeyIdentifier() ) ); d->addItem( tr("Subject key identifier"), c.toHex( c.subjectKeyIdentifier() ) ); QStringList keyUsage = c.keyUsage().values(); if( !keyUsage.isEmpty() ) d->addItem( tr("Key usage"), keyUsage.join( ", " ), keyUsage.join( "\n" ) ); d->parameters->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents); }
SignatureWidget::SignatureWidget( const DigiDocSignature &signature, unsigned int signnum, QWidget *parent ) : QLabel( parent ) , num( signnum ) , s( signature ) { setObjectName( QString("signatureWidget%1").arg(signnum) ); setSizePolicy( QSizePolicy::Ignored, QSizePolicy::Preferred ); setWordWrap( true ); setTextInteractionFlags( Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse ); connect( this, SIGNAL(linkActivated(QString)), SLOT(link(QString)) ); const SslCertificate cert = s.cert(); QString accessibility, content, tooltip; QTextStream sa( &accessibility ); QTextStream sc( &content ); QTextStream st( &tooltip ); if( cert.type() & SslCertificate::TempelType ) sc << "<img src=\":/images/ico_stamp_blue_16.png\">"; else sc << "<img src=\":/images/ico_person_blue_16.png\">"; sc << "<b>" << Qt::escape( cert.toString( cert.showCN() ? "CN" : "GN SN" ) ) << "</b>"; if( !s.location().isEmpty() ) { sa << " " << tr("Location") << " " << s.location(); sc << "<br />" << Qt::escape( s.location() ); st << Qt::escape( s.location() ) << "<br />"; } if( !s.role().isEmpty() ) { sa << " " << tr("Role") << " " << s.role(); sc << "<br />" << Qt::escape( s.role() ); st << Qt::escape( s.role() ) << "<br />"; } DateTime date( s.dateTime().toLocalTime() ); if( !date.isNull() ) { sa << " " << tr("Signed on") << " " << date.formatDate( "dd. MMMM yyyy" ) << " " << tr("time") << " " << date.toString( "hh:mm" ); sc << "<br />" << tr("Signed on") << " " << date.formatDate( "dd. MMMM yyyy" ) << " " << tr("time") << " " << date.toString( "hh:mm" ); st << tr("Signed on") << " " << date.formatDate( "dd. MMMM yyyy" ) << " " << tr("time") << " " << date.toString( "hh:mm" ); } setToolTip( tooltip ); sa << " " << tr("Signature is") << " "; sc << "<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\"><tr>"; sc << "<td>" << tr("Signature is") << " "; switch( s.validate() ) { case DigiDocSignature::Valid: sa << tr("valid"); sc << "<font color=\"green\">" << tr("valid"); break; case DigiDocSignature::Warning: sa << tr("valid") << " (" << tr("Warnings") << ")"; sc << "<font color=\"green\">" << tr("valid") << "</font> <font>(" << tr("Warnings") << ")"; break; case DigiDocSignature::Test: sa << tr("valid") << " (" << tr("Test signature") << ")"; sc << "<font color=\"green\">" << tr("valid") << "</font> <font>(" << tr("Test signature") << ")"; break; case DigiDocSignature::Invalid: sa << tr("not valid"); sc << "<font color=\"red\">" << tr("not valid"); break; case DigiDocSignature::Unknown: sa << tr("unknown"); sc << "<font color=\"red\">" << tr("unknown"); break; } sc << "</font>"; sc << "</td><td align=\"right\">"; sc << "<a href=\"details\" style=\"color: #509B00\" title=\"" << tr("Show details") << "\">" << tr("Show details") << "</a>"; sc << "</td></tr><tr><td></td>"; sc << "<td align=\"right\">"; if( s.parent()->isSupported() ) sc << "<a href=\"remove\" style=\"color: #509B00\" title=\"" << tr("Remove") << "\">" << tr("Remove") << "</a>"; sc << "</td></tr></table>"; setText( content ); setAccessibleName( tr("Signature") + " " + cert.toString( cert.showCN() ? "CN" : "GN SN" ) ); setAccessibleDescription( accessibility ); }