Skip to content

Commit 8508ef5

Browse files
authored
Support of eTokens (e-Seals) in DigiDoc4 client (#159)
DDKLIEN-52: eToken (e-Tempel / e-Seal) support implemented in DigiDoc4 Additionally - Card polling is done only in QSigner backend/thread - QSmartCard polling thread removed, card change called from QSigner poll - If Windows CAPI backend is used in QSigner, the returned id for the selected card is certificate CN; QSmartCard matches serial instead of document id Signed-off-by: Toomas Uudisaru <toomas.uudisaru@aktors.ee>
1 parent 1398e2f commit 8508ef5

34 files changed

+720
-401
lines changed

client/Application.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222
#include "Application.h"
2323

2424
#include "MainWindow.h"
25+
#include "QCardInfo.h"
2526
#include "QSigner.h"
26-
#include "QSmartCard.h"
2727
#include "DigiDoc.h"
2828
#include "dialogs/FirstRun.h"
2929
#include "dialogs/WaitDialog.h"
@@ -255,7 +255,7 @@ class ApplicationPrivate
255255
QAction *closeAction = nullptr, *newClientAction = nullptr, *newCryptoAction = nullptr;
256256
MacMenuBar *bar = nullptr;
257257
QSigner *signer = nullptr;
258-
QSmartCard *smartcard = nullptr;
258+
259259
QTranslator appTranslator, commonTranslator, cryptoTranslator, qtTranslator;
260260
QString lang;
261261
QTimer lastWindowTimer;
@@ -325,9 +325,7 @@ Application::Application( int &argc, char **argv )
325325
try
326326
{
327327
digidoc::Conf::init( new DigidocConf );
328-
d->signer = new QSigner( api, this );
329-
d->smartcard = new QSmartCard( this );
330-
d->smartcard->start();
328+
d->signer = new QSigner(api, this);
331329

332330
auto readVersion = [](const QString &path) -> uint {
333331
QFile f(path);
@@ -866,7 +864,7 @@ void Application::showWarning( const QString &msg, const QString &details )
866864

867865
QSigner* Application::signer() const { return d->signer; }
868866

869-
QSmartCard* Application::smartcard() const { return d->smartcard; }
867+
QSmartCard* Application::smartcard() const { return d->signer->smartcard(); }
870868

871869
QWidget* Application::uniqueRoot()
872870
{

client/MainWindow.cpp

Lines changed: 55 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151

5252
#include <QDebug>
5353
#include <QFileDialog>
54+
#include <QLoggingCategory>
5455
#include <QMessageBox>
5556
#include <QMimeData>
5657
#include <QSvgWidget>
@@ -60,6 +61,8 @@
6061
using namespace ria::qdigidoc4;
6162
using namespace ria::qdigidoc4::colors;
6263

64+
Q_LOGGING_CATEGORY(MLog, "qdigidoc4.MainWindow")
65+
6366
MainWindow::MainWindow( QWidget *parent ) :
6467
QWidget( parent ),
6568
ui( new Ui::MainWindow )
@@ -127,9 +130,9 @@ MainWindow::MainWindow( QWidget *parent ) :
127130
setAcceptDrops( true );
128131

129132
// Refresh ID card info in card widget
130-
connect( qApp->smartcard(), &QSmartCard::dataChanged, this, &MainWindow::showCardStatus );
131-
// Refresh card info in card pop-up menu
132-
connect( qApp->smartcard(), &QSmartCard::dataLoaded, this, &MainWindow::updateCardData );
133+
connect(qApp->signer(), &QSigner::signDataChanged, this, &MainWindow::showCardStatus);
134+
// Refresh card info on "My EID" page
135+
connect(qApp->smartcard(), &QSmartCard::dataChanged, this, &MainWindow::updateMyEid);
133136
// Show card pop-up menu
134137
connect( selector, &DropdownButton::dropdown, this, &MainWindow::showCardMenu );
135138

@@ -513,11 +516,9 @@ void MainWindow::navigateToPage( Pages page, const QStringList &files, bool crea
513516
cryptoContainer->clear(filename);
514517
for(auto file: files)
515518
cryptoContainer->documentModel()->addFile(file);
516-
auto cardData = qApp->smartcard()->data();
517-
if(!cardData.isNull())
518-
{
519-
cryptoContainer->addKey(CKey(cardData.authCert()));
520-
}
519+
auto authCert = qApp->signer()->tokenauth().cert();
520+
if(!authCert.isNull())
521+
cryptoContainer->addKey(CKey(authCert));
521522
navigate = true;
522523
}
523524
}
@@ -545,6 +546,7 @@ void MainWindow::onSignAction(int action, const QString &info1, const QString &i
545546
switch(action)
546547
{
547548
case SignatureAdd:
549+
case SignatureToken:
548550
if(digiDoc->isService())
549551
wrapAndSign();
550552
else
@@ -826,7 +828,7 @@ void MainWindow::openContainer()
826828

827829
void MainWindow::operation(int op, bool started)
828830
{
829-
qDebug() << "Op " << op << (started ? " started" : " ended");
831+
qCDebug(MLog) << "Op " << op << (started ? " started" : " ended");
830832
}
831833

832834
void MainWindow::resetCryptoDoc(CryptoDoc *doc)
@@ -949,7 +951,7 @@ void MainWindow::showCardMenu( bool show )
949951
{
950952
if( show )
951953
{
952-
cardPopup.reset( new CardPopup( qApp->smartcard(), this ) );
954+
cardPopup.reset(new CardPopup(qApp->signer()->tokensign(), qApp->signer()->cache(), this));
953955
// To select active card from several cards in readers ..
954956
connect( cardPopup.get(), &CardPopup::activated, qApp->smartcard(), &QSmartCard::selectCard, Qt::QueuedConnection );
955957
connect( cardPopup.get(), &CardPopup::activated, qApp->signer(), &QSigner::selectSignCard, Qt::QueuedConnection );
@@ -967,32 +969,43 @@ void MainWindow::showCardMenu( bool show )
967969
void MainWindow::showCardStatus()
968970
{
969971
Application::restoreOverrideCursor();
970-
QSmartCardData t = qApp->smartcard()->data();
972+
TokenData t = qApp->signer()->tokensign();
971973

972974
closeWarnings(-1);
973975

974-
if( !t.isNull() )
976+
if(!t.card().isEmpty() && !t.cert().isNull())
975977
{
976978
ui->idSelector->show();
977979
ui->infoStack->show();
978980
ui->accordion->show();
979981
ui->noCardInfo->hide();
980982

981-
QSharedPointer<const QCardInfo> cardInfo(new QCardInfo(t));
982-
ui->cardInfo->update(cardInfo);
983-
emit ui->signContainerPage->cardChanged(cardInfo->id);
983+
qCDebug(MLog) << "Select card" << t.card();
984+
auto cardInfo = qApp->signer()->cache()[t.card()];
985+
986+
if(ui->cardInfo->id() != t.card())
987+
{
988+
ui->infoStack->clearData();
989+
ui->accordion->clear();
990+
}
991+
992+
ui->cardInfo->update(cardInfo, t.card());
993+
emit ui->signContainerPage->cardChanged(cardInfo->id, cardInfo->type & SslCertificate::TempelType);
984994
emit ui->cryptoContainerPage->cardChanged(cardInfo->id);
985995

986-
if( t.authCert().type() & SslCertificate::EstEidType )
996+
if(cardInfo->type & SslCertificate::EstEidType)
987997
{
988-
Styles::cachedPicture( t.data(QSmartCardData::Id ).toString(), { ui->cardInfo, ui->infoStack } );
998+
Styles::cachedPicture(cardInfo->id, {ui->cardInfo, ui->infoStack});
989999
}
990-
ui->infoStack->update( t );
991-
ui->accordion->updateInfo( qApp->smartcard() );
992-
ui->myEid->invalidIcon( !t.authCert().isValid() || !t.signCert().isValid() );
993-
updateCardWarnings();
994-
showIdCardAlerts( t );
995-
showPinBlockedWarning( t );
1000+
else if(cardInfo->type & SslCertificate::TempelType)
1001+
{
1002+
ui->infoStack->update(*cardInfo);
1003+
const SslCertificate &authCert = qApp->signer()->tokenauth().cert();
1004+
const SslCertificate &signCert = t.cert();
1005+
ui->accordion->updateInfo(*cardInfo, authCert, signCert);
1006+
ui->myEid->invalidIcon(!authCert.isValid() || !signCert.isValid());
1007+
updateCardWarnings();
1008+
}
9961009
}
9971010
else
9981011
{
@@ -1128,12 +1141,29 @@ bool MainWindow::signMobile(const QString &idCode, const QString &phoneNumber)
11281141

11291142
void MainWindow::updateCardData()
11301143
{
1131-
if( cardPopup )
1132-
cardPopup->update( qApp->smartcard() );
1144+
if(cardPopup)
1145+
cardPopup->update(qApp->signer()->cache());
1146+
}
1147+
1148+
void MainWindow::updateMyEid()
1149+
{
1150+
Application::restoreOverrideCursor();
1151+
QSmartCardData t = qApp->smartcard()->data();
1152+
1153+
if(!t.card().isEmpty() && !t.signCert().isNull())
1154+
{
1155+
ui->infoStack->update(t);
1156+
ui->accordion->updateInfo(qApp->smartcard());
1157+
ui->myEid->invalidIcon(!t.authCert().isValid() || !t.authCert().isValid());
1158+
updateCardWarnings();
1159+
showIdCardAlerts(t);
1160+
showPinBlockedWarning(t);
1161+
}
11331162
}
11341163

11351164
void MainWindow::noReader_NoCard_Loading_Event(NoCardInfo::Status status)
11361165
{
1166+
qCDebug(MLog) << "noReader_NoCard_Loading_Event" << status;
11371167
ui->idSelector->hide();
11381168
if(status == NoCardInfo::Loading)
11391169
Application::setOverrideCursor(Qt::BusyCursor);

client/MainWindow.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ private Q_SLOTS:
7575
void photoClicked( const QPixmap *photo );
7676
void savePhoto( const QPixmap *photo );
7777
void showCardStatus();
78+
void updateMyEid();
7879
void warningClicked(const QString &link);
7980
void removeOldCert();
8081

client/MainWindow_MyEID.cpp

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "MainWindow.h"
2121
#include "ui_MainWindow.h"
2222
#include "Application.h"
23+
#include "QCardInfo.h"
2324
#include "QCardLock.h"
2425
#include "QSigner.h"
2526
#include "XmlReader.h"
@@ -74,10 +75,8 @@ void MainWindow::changePukClicked()
7475

7576
bool MainWindow::checkExpiration()
7677
{
77-
QSmartCardData t = qApp->smartcard()->data();
78-
7978
int expiresIn = 106;
80-
for(const SslCertificate &cert: {t.authCert(), t.signCert()})
79+
for(const SslCertificate &cert: {qApp->signer()->tokenauth().cert(), qApp->signer()->tokensign().cert()})
8180
{
8281
expiresIn = std::min<int>(expiresIn,
8382
QDateTime::currentDateTime().daysTo(cert.expiryDate().toLocalTime()));
@@ -97,33 +96,33 @@ void MainWindow::pinUnblock( QSmartCardData::PinType type, bool isForgotPin )
9796
.arg( QSmartCardData::typeString( type ) );
9897

9998
if( validateCardError( type, 1025,
100-
( (QSmartCard *)qApp->smartcard() )->pinUnblock( type, isForgotPin ) ) )
99+
qApp->smartcard()->pinUnblock( type, isForgotPin ) ) )
101100
{
102101
if( isForgotPin )
103102
text = tr("%1 changed!").arg( QSmartCardData::typeString( type ) );
104103
showNotification( text, true );
105104
ui->accordion->updateInfo( qApp->smartcard() );
106105
updateCardWarnings();
107106

108-
QCardInfo cardInfo(qApp->smartcard()->data());
107+
QString card = qApp->smartcard()->data().card();
109108

110109
if (type == QSmartCardData::Pin1Type)
111110
{
112111
clearWarning(WarningType::UnblockPin1Warning);
113-
emit ui->cryptoContainerPage->cardChanged(cardInfo.id);
112+
emit ui->cryptoContainerPage->cardChanged(card);
114113
}
115114
if (type == QSmartCardData::Pin2Type)
116115
{
117116
clearWarning(WarningType::UnblockPin2Warning);
118-
emit ui->signContainerPage->cardChanged(cardInfo.id);
117+
emit ui->cryptoContainerPage->cardChanged(card);
119118
}
120119
}
121120
}
122121

123122
void MainWindow::pinPukChange( QSmartCardData::PinType type )
124123
{
125124
if( validateCardError( type, 1024,
126-
( (QSmartCard *)qApp->smartcard() )->pinChange( type ) ) )
125+
qApp->smartcard()->pinChange( type ) ) )
127126
{
128127
showNotification( tr("%1 changed!")
129128
.arg( QSmartCardData::typeString( type ) ), true );
@@ -133,7 +132,7 @@ void MainWindow::pinPukChange( QSmartCardData::PinType type )
133132

134133
void MainWindow::certDetailsClicked( const QString &link )
135134
{
136-
CertificateDetails dlg( (link == "PIN1") ? qApp->smartcard()->data().authCert() : qApp->smartcard()->data().signCert(), this );
135+
CertificateDetails dlg((link == "PIN1") ? qApp->signer()->tokenauth().cert() : qApp->signer()->tokensign().cert(), this);
137136
dlg.exec();
138137
}
139138

@@ -399,7 +398,7 @@ void MainWindow::updateCardWarnings()
399398
if(checkExpiration())
400399
showWarning = true;
401400

402-
if(!showWarning)
401+
if(!showWarning && !qApp->smartcard()->data().isNull())
403402
showWarning = qApp->smartcard()->data().retryCount( QSmartCardData::Pin1Type ) == 0 ||
404403
qApp->smartcard()->data().retryCount( QSmartCardData::Pin2Type ) == 0 ||
405404
qApp->smartcard()->data().retryCount( QSmartCardData::PukType ) == 0;

client/QCardInfo.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* QDigiDoc4
3+
*
4+
* This library is free software; you can redistribute it and/or
5+
* modify it under the terms of the GNU Lesser General Public
6+
* License as published by the Free Software Foundation; either
7+
* version 2.1 of the License, or (at your option) any later version.
8+
*
9+
* This library is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+
* Lesser General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Lesser General Public
15+
* License along with this library; if not, write to the Free Software
16+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17+
*
18+
*/
19+
20+
#pragma once
21+
22+
#include <QString>
23+
24+
struct QCardInfo
25+
{
26+
QString id;
27+
QString fullName;
28+
QString cardType;
29+
QString country;
30+
int type;
31+
bool loading;
32+
bool isEResident;
33+
};

0 commit comments

Comments
 (0)