diff --git a/CMakeLists.txt b/CMakeLists.txt index 0b7535001..e29adabd3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,7 @@ include( GNUInstallDirs ) include( VersionInfo ) find_package( PKCS11 ) -find_package(LibDigiDocpp 3.15.0 REQUIRED) +find_package(LibDigiDocpp 3.17.0 REQUIRED) find_package( LDAP REQUIRED ) find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED) find_package(Qt${QT_VERSION_MAJOR} 5.12.0 REQUIRED COMPONENTS Core Widgets Network PrintSupport Svg LinguistTools) diff --git a/README.md b/README.md index cd9014b0b..91a170856 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ * Install # Ubuntu - sudo apt install cmake qt6-tools-dev libqt6core5compat6-dev libqt6svg6-dev libpcsclite-dev libssl-dev libdigidocpp-dev libldap2-dev gettext pkg-config + sudo apt install cmake qt6-tools-dev libqt6core5compat6-dev libqt6svg6-dev libpcsclite-dev libssl-dev libdigidocpp-dev libldap2-dev gettext pkg-config libflatbuffers-dev zlib1g-dev # Fedora sudo dnf install qt6-qtsvg-devel qt6-qttools-devel qt6-qt5compat-devel pcsc-lite-devel openssl-devel libdigidocpp openldap-devel gettext pkg-config flatbuffers-devel flatbuffers-compiler diff --git a/client/DigiDoc.cpp b/client/DigiDoc.cpp index 4cb4f683f..13966565d 100644 --- a/client/DigiDoc.cpp +++ b/client/DigiDoc.cpp @@ -46,6 +46,27 @@ using namespace ria::qdigidoc4; static std::string to(const QString &str) { return str.toStdString(); } static QString from(const std::string &str) { return FileDialog::normalized(QString::fromStdString(str)); } +struct ServiceConfirmation final: public ContainerOpenCB +{ + QWidget *parent = nullptr; + ServiceConfirmation(QWidget *_parent): parent(_parent) {} + bool validateOnline() const final { + if(!CheckConnection().check()) + return false; + return dispatchToMain([this] { + auto *dlg = new WarningDialog(DigiDoc::tr("This type of signed document will be transmitted to the " + "Digital Signature Validation Service SiVa to verify the validity of the digital signature. " + "Read more information about transmitted data to Digital Signature Validation service from " + "here.
" + "Do you want to continue?"), parent); + dlg->setCancelText(WarningDialog::Cancel); + dlg->addButton(WarningDialog::YES, ContainerSave); + return dlg->exec() == ContainerSave; + }); + } + Q_DISABLE_COPY(ServiceConfirmation) +}; + DigiDocSignature::DigiDocSignature(const digidoc::Signature *signature, const DigiDoc *parent, bool isTimeStamped) @@ -65,6 +86,11 @@ QDateTime DigiDocSignature::claimedTime() const return toTime(s->claimedSigningTime()); } +const DigiDoc* DigiDocSignature::container() const +{ + return m_parent; +} + bool DigiDocSignature::isInvalid() const { return m_status >= Invalid; @@ -104,10 +130,9 @@ QDateTime DigiDocSignature::ocspTime() const return toTime(s->OCSPProducedAt()); } -const DigiDoc* DigiDocSignature::parent() const { return m_parent; } - -void DigiDocSignature::parseException(DigiDocSignature::SignatureStatus &result, const digidoc::Exception &e) +DigiDocSignature::SignatureStatus DigiDocSignature::status(const digidoc::Exception &e) { + DigiDocSignature::SignatureStatus result = Valid; for(const Exception &child: e.causes()) { switch( child.code() ) @@ -135,8 +160,9 @@ void DigiDocSignature::parseException(DigiDocSignature::SignatureStatus &result, default: result = std::max( result, Invalid ); } - parseException( result, child ); + result = std::max(result, status(child)); } + return result; } QString DigiDocSignature::policy() const @@ -164,15 +190,6 @@ QStringList DigiDocSignature::roles() const return list; } -void DigiDocSignature::setLastError(const Exception &e) -{ - Exception::ExceptionCode code = Exception::General; - QStringList causes = DigiDoc::parseException(e, code); - m_lastError = code == Exception::OCSPBeforeTimeStamp ? - DigiDoc::tr("The timestamp added to the signature must be taken before validity confirmation.") : - causes.join('\n'); -} - QString DigiDocSignature::signatureMethod() const { return from( s->signatureMethod() ); } @@ -230,33 +247,25 @@ QDateTime DigiDocSignature::tsaTime() const return toTime(s->ArchiveTimeStampTime()); } -DigiDocSignature::SignatureStatus DigiDocSignature::validate() +DigiDocSignature::SignatureStatus DigiDocSignature::validate(bool qscd) { if(!s) return Invalid; - DigiDocSignature::SignatureStatus result = Valid; try { - s->validate(); - return Valid; + s->validate(qscd ? digidoc::Signature::POLv2 : digidoc::Signature::POLv1); + return qscd ? Valid : NonQSCD; } catch(const Exception &e) { - parseException(result, e); - setLastError(e); - } - if(result != Unknown) - return result; - try - { - s->validate(digidoc::Signature::POLv1); - return NonQSCD; - } - catch(const Exception &e) - { - parseException(result, e); + Exception::ExceptionCode code = Exception::General; + QStringList causes = DigiDoc::parseException(e, code); + m_lastError = code == Exception::OCSPBeforeTimeStamp ? + DigiDoc::tr("The timestamp added to the signature must be taken before validity confirmation.") : + causes.join('\n'); + auto result = status(e); + return qscd && result == Unknown ? validate(false) : result; } - return result; } int DigiDocSignature::warning() const @@ -497,32 +506,19 @@ bool DigiDoc::open( const QString &file ) QWidget *parent = qobject_cast(QObject::parent()); if(parent == nullptr) parent = Application::activeWindow(); + ServiceConfirmation cb(parent); qApp->waitForTSL( file ); clear(); - auto serviceConfirmation = [parent] { - auto *dlg = new WarningDialog(tr("Signed document in PDF and DDOC format will be transmitted to the Digital Signature Validation Service SiVa to verify the validity of the digital signature. " - "Read more information about transmitted data to Digital Signature Validation service from here.
" - "Do you want to continue?"), parent); - dlg->setCancelText(WarningDialog::Cancel); - dlg->addButton(WarningDialog::YES, ContainerSave); - return dlg->exec() == ContainerSave; - }; - if((file.endsWith(QLatin1String(".pdf"), Qt::CaseInsensitive) || - file.endsWith(QLatin1String(".ddoc"), Qt::CaseInsensitive)) && !serviceConfirmation()) - return false; - try { WaitDialogHolder waitDialog(parent, tr("Opening"), false); return waitFor([&] { - b = Container::openPtr(to(file)); + b = Container::openPtr(to(file), &cb); if(b && b->mediaType() == "application/vnd.etsi.asic-s+zip" && b->dataFiles().size() == 1 && b->signatures().size() == 1) { const DataFile *f = b->dataFiles().at(0); - if(from(f->fileName()).endsWith(QStringLiteral(".ddoc"), Qt::CaseInsensitive) && - CheckConnection().check() && - dispatchToMain(serviceConfirmation)) + if(from(f->fileName()).endsWith(QStringLiteral(".ddoc"), Qt::CaseInsensitive)) { const QString tmppath = FileDialog::tempPath(FileDialog::safeName(from(f->fileName()))); f->saveAs(to(tmppath)); @@ -530,7 +526,7 @@ bool DigiDoc::open( const QString &file ) { m_tempFiles.append(tmppath); try { - parentContainer = std::exchange(b, Container::openPtr(to(tmppath))); + parentContainer = std::exchange(b, Container::openPtr(to(tmppath), &cb)); } catch(const Exception &) {} } } @@ -559,7 +555,8 @@ bool DigiDoc::open( const QString &file ) setLastError(tr("Connecting to SiVa server failed! Please check your internet connection and network settings."), e); break; default: - setLastError(tr("An error occurred while opening the document."), e); + if(e.msg().find("Online validation disabled") == std::string::npos) + setLastError(tr("An error occurred while opening the document."), e); break; } } diff --git a/client/DigiDoc.h b/client/DigiDoc.h index fa4ba4ab3..7082de1bc 100644 --- a/client/DigiDoc.h +++ b/client/DigiDoc.h @@ -49,6 +49,7 @@ class DigiDocSignature QSslCertificate cert() const; QDateTime claimedTime() const; + const DigiDoc *container() const; bool isInvalid() const; QString lastError() const; QString location() const; @@ -56,7 +57,6 @@ class DigiDocSignature QByteArray messageImprint() const; QSslCertificate ocspCert() const; QDateTime ocspTime() const; - const DigiDoc *parent() const; QString policy() const; QString profile() const; QString role() const; @@ -73,9 +73,8 @@ class DigiDocSignature int warning() const; private: - void setLastError(const digidoc::Exception &e); - void parseException(SignatureStatus &result, const digidoc::Exception &e); - SignatureStatus validate(); + SignatureStatus status(const digidoc::Exception &e); + SignatureStatus validate(bool qscd = true); static QSslCertificate toCertificate(const std::vector &der) ; static QDateTime toTime(const std::string &time) ; diff --git a/client/dialogs/SignatureDialog.cpp b/client/dialogs/SignatureDialog.cpp index e0bb8efc5..4a2b7c0e1 100644 --- a/client/dialogs/SignatureDialog.cpp +++ b/client/dialogs/SignatureDialog.cpp @@ -173,7 +173,7 @@ SignatureDialog::SignatureDialog(const DigiDocSignature &signature, QWidget *par addCert(t, tr("Signer's Certificate"), tr("Signer's Certificate issuer"), c); addItem(t, tr("Signature method"), QUrl(s.signatureMethod())); - addItem(t, tr("Container format"), s.parent()->mediaType()); + addItem(t, tr("Container format"), s.container()->mediaType()); addItem(t, tr("Signature format"), s.profile()); if( !s.policy().isEmpty() ) { @@ -184,7 +184,7 @@ SignatureDialog::SignatureDialog(const DigiDocSignature &signature, QWidget *par else addItem( t, tr("Signature policy"), s.policy() ); } - addItem(t, tr("Signed file count"), QString::number(s.parent()->documentModel()->rowCount())); + addItem(t, tr("Signed file count"), QString::number(s.container()->documentModel()->rowCount())); addItem(t, QStringLiteral("SPUri"), QUrl(s.spuri())); addTime(t, tr("Archive Timestamp"), s.tsaTime()); addCert(t, tr("Archive TS Certificate"), tr("Archive TS Certificate issuer"), s.tsaCert()); diff --git a/client/translations/en.ts b/client/translations/en.ts index 0e1b430dd..1c6a14509 100644 --- a/client/translations/en.ts +++ b/client/translations/en.ts @@ -859,8 +859,8 @@ Failed to sign container. - Signed document in PDF and DDOC format will be transmitted to the Digital Signature Validation Service SiVa to verify the validity of the digital signature. Read more information about transmitted data to Digital Signature Validation service from <a href="https://www.id.ee/en/article/data-protection-conditions-for-the-id-software-of-the-national-information-system-authority/">here</a>.<br />Do you want to continue? - Signed document in PDF and DDOC format will be transmitted to the Digital Signature Validation Service SiVa to verify the validity of the digital signature. Read more information about transmitted data to Digital Signature Validation service from <a href="https://www.id.ee/en/article/data-protection-conditions-for-the-id-software-of-the-national-information-system-authority/">here</a>.<br />Do you want to continue? + This type of signed document will be transmitted to the Digital Signature Validation Service SiVa to verify the validity of the digital signature. Read more information about transmitted data to Digital Signature Validation service from <a href="https://www.id.ee/en/article/data-protection-conditions-for-the-id-software-of-the-national-information-system-authority/">here</a>.<br />Do you want to continue? + This type of signed document will be transmitted to the Digital Signature Validation Service SiVa to verify the validity of the digital signature. Read more information about transmitted data to Digital Signature Validation service from <a href="https://www.id.ee/en/article/data-protection-conditions-for-the-id-software-of-the-national-information-system-authority/">here</a>.<br />Do you want to continue? Connecting to SiVa server failed! Please check your internet connection and network settings. diff --git a/client/translations/et.ts b/client/translations/et.ts index a45cfbf1b..190fcd725 100644 --- a/client/translations/et.ts +++ b/client/translations/et.ts @@ -859,8 +859,8 @@ Ümbriku allkirjastamine ebaõnnestus. - Signed document in PDF and DDOC format will be transmitted to the Digital Signature Validation Service SiVa to verify the validity of the digital signature. Read more information about transmitted data to Digital Signature Validation service from <a href="https://www.id.ee/en/article/data-protection-conditions-for-the-id-software-of-the-national-information-system-authority/">here</a>.<br />Do you want to continue? - PDF ja DDOC formaadis digitaalallkirjade kehtivuse kontrollimiseks edastatakse fail valideerimisteenusele SiVa. Digitaalallkirjade kehtivuse kontrollimisel edastatud andmete kohta loe lähemalt <a href="https://www.id.ee/artikkel/riigi-infosusteemi-ameti-id-tarkvara-andmekaitsetingimused/">siit</a>.<br />Kas soovid jätkata? + This type of signed document will be transmitted to the Digital Signature Validation Service SiVa to verify the validity of the digital signature. Read more information about transmitted data to Digital Signature Validation service from <a href="https://www.id.ee/en/article/data-protection-conditions-for-the-id-software-of-the-national-information-system-authority/">here</a>.<br />Do you want to continue? + Seda tüüpi allkirjastatud dokument edastatakse digitaalallkirjade kehtivuse kontrollimiseks valideerimisteenusele SiVa. Digitaalallkirjade kehtivuse kontrollimisel edastatud andmete kohta loe lähemalt <a href="https://www.id.ee/artikkel/riigi-infosusteemi-ameti-id-tarkvara-andmekaitsetingimused/">siit</a>.<br />Kas soovid jätkata? Connecting to SiVa server failed! Please check your internet connection and network settings. diff --git a/client/translations/ru.ts b/client/translations/ru.ts index 621801b4d..a1e9490ad 100644 --- a/client/translations/ru.ts +++ b/client/translations/ru.ts @@ -859,8 +859,8 @@ Не удалось подписать контейнер. - Signed document in PDF and DDOC format will be transmitted to the Digital Signature Validation Service SiVa to verify the validity of the digital signature. Read more information about transmitted data to Digital Signature Validation service from <a href="https://www.id.ee/en/article/data-protection-conditions-for-the-id-software-of-the-national-information-system-authority/">here</a>.<br />Do you want to continue? - Для проверки действительности электронно-цифровых подписей в форматах PDF и DDOC файл пересылается в службу проверки цифровых подписей SiVa. Подробнее о данных, переданных для проверки действительности электронно-цифровых подписей, можно прочитать <a href="https://www.id.ee/ru/artikkel/usloviya-zashhity-dannyh-programmnogo-obespecheniya-id-karty-departamenta-gosudarstvennoj-infosistemy/">здесь</a>.<br />Желаете продолжить? + This type of signed document will be transmitted to the Digital Signature Validation Service SiVa to verify the validity of the digital signature. Read more information about transmitted data to Digital Signature Validation service from <a href="https://www.id.ee/en/article/data-protection-conditions-for-the-id-software-of-the-national-information-system-authority/">here</a>.<br />Do you want to continue? + Данный тип подписанного документа передается в службу валидации SiVa для проверки действительности цифровых подписей. Подробнее о данных, переданных для проверки действительности электронно-цифровых подписей, можно прочитать <a href="https://www.id.ee/ru/artikkel/usloviya-zashhity-dannyh-programmnogo-obespecheniya-id-karty-departamenta-gosudarstvennoj-infosistemy/">здесь</a>.<br />Желаете продолжить? Connecting to SiVa server failed! Please check your internet connection and network settings. diff --git a/client/widgets/SignatureItem.cpp b/client/widgets/SignatureItem.cpp index 1efe064ec..cad1a904e 100644 --- a/client/widgets/SignatureItem.cpp +++ b/client/widgets/SignatureItem.cpp @@ -63,7 +63,7 @@ SignatureItem::SignatureItem(DigiDocSignature s, ContainerState /*state*/, QWidg ui->remove->setIcons(QStringLiteral("/images/icon_remove.svg"), QStringLiteral("/images/icon_remove_hover.svg"), QStringLiteral("/images/icon_remove_pressed.svg"), 17, 17); ui->remove->init(LabelButton::White, {}, 0); - ui->remove->setVisible(ui->signature.parent()->isSupported()); + ui->remove->setVisible(ui->signature.container()->isSupported()); connect(ui->remove, &LabelButton::clicked, this, &SignatureItem::removeSignature); init(); }