diff --git a/client/DigiDoc.cpp b/client/DigiDoc.cpp index 1aa9d3ff0..7756b98e3 100644 --- a/client/DigiDoc.cpp +++ b/client/DigiDoc.cpp @@ -423,8 +423,6 @@ void DigiDoc::clear() { b.reset(); parentContainer.reset(); - m_signatures.clear(); - m_timestamps.clear(); m_fileName.clear(); for(const QString &file: m_tempFiles) { @@ -462,17 +460,12 @@ bool DigiDoc::isError(bool failure, const QString &msg) const bool DigiDoc::isAsicS() const { - return b && b->mediaType() == "application/vnd.etsi.asic-s+zip" && - std::any_of(m_signatures.cbegin(), m_signatures.cend(), [](const DigiDocSignature &s) { - return s.profile().contains(QLatin1String("BES"), Qt::CaseInsensitive); - }); + return b && b->mediaType() == "application/vnd.etsi.asic-s+zip"; } -bool DigiDoc::isCades() const +bool DigiDoc::isAsicE() const { - return std::any_of(m_signatures.cbegin(), m_signatures.cend(), [](const DigiDocSignature &s) { - return s.profile().contains(QLatin1String("CADES"), Qt::CaseInsensitive); - }); + return b && b->mediaType() == "application/vnd.etsi.asic-e+zip"; } bool DigiDoc::isPDF() const @@ -481,11 +474,6 @@ bool DigiDoc::isPDF() const } bool DigiDoc::isModified() const { return modified; } -bool DigiDoc::isSupported() const -{ - return b && b->mediaType() == "application/vnd.etsi.asic-e+zip" && !isCades(); -} - QString DigiDoc::mediaType() const { return b ? from( b->mediaType() ) : QString(); } @@ -537,17 +525,9 @@ bool DigiDoc::open( const QString &file ) } } } - bool isTimeStamped = parentContainer && parentContainer->signatures().at(0)->trustedSigningTime().compare("2018-07-01T00:00:00Z") < 0; - for(const Signature *signature: b->signatures()) - m_signatures.append(DigiDocSignature(signature, this, isTimeStamped)); - if(parentContainer) - { - for(const Signature *signature: parentContainer->signatures()) - m_timestamps.append(DigiDocSignature(signature, this)); - } Application::addRecent(file); m_fileName = file; - containerState = signatures().isEmpty() ? ContainerState::UnsignedSavedContainer : ContainerState::SignedContainer; + containerState = b->signatures().empty() ? ContainerState::UnsignedSavedContainer : ContainerState::SignedContainer; return true; }); } catch(const Exception &e) { @@ -604,7 +584,6 @@ void DigiDoc::removeSignature( unsigned int num ) try { modified = waitFor([&] { b->removeSignature(num); - m_signatures.removeAt(num); return true; }); } @@ -619,7 +598,7 @@ bool DigiDoc::save( const QString &filename ) return false; Application::addRecent(m_fileName); modified = false; - containerState = signatures().isEmpty() ? ContainerState::UnsignedSavedContainer : ContainerState::SignedContainer; + containerState = b->signatures().empty() ? ContainerState::UnsignedSavedContainer : ContainerState::SignedContainer; return true; } @@ -697,11 +676,7 @@ bool DigiDoc::sign(const QString &city, const QString &state, const QString &zip Common::applicationOs(), Common::drivers().join(',')).toUtf8().constData()); qApp->waitForTSL( fileName() ); - digidoc::Signature *s = b->sign(signer); - return modified = waitFor([&] { - m_signatures.append(DigiDocSignature(s, this, false)); - return true; - }); + return modified = b->sign(signer) != nullptr; } catch( const Exception &e ) { @@ -724,17 +699,22 @@ bool DigiDoc::sign(const QString &city, const QString &state, const QString &zip return false; } -QList DigiDoc::signatures() const +void DigiDoc::enumSignatures(std::function &&cb) const { - return m_signatures; + bool isTimeStamped = parentContainer && parentContainer->signatures().at(0)->trustedSigningTime().compare("2018-07-01T00:00:00Z") < 0; + for(const Signature *signature: b->signatures()) + cb(DigiDocSignature(signature, this, isTimeStamped)); } -ContainerState DigiDoc::state() +void DigiDoc::enumTimestamps(std::function &&cb) const { - return containerState; + if(!parentContainer) + return; + for(const Signature *signature: parentContainer->signatures()) + cb(DigiDocSignature(signature, this)); } -QList DigiDoc::timestamps() const +ContainerState DigiDoc::state() { - return m_timestamps; + return containerState; } diff --git a/client/DigiDoc.h b/client/DigiDoc.h index 92941c825..ff0c0cee6 100644 --- a/client/DigiDoc.h +++ b/client/DigiDoc.h @@ -33,7 +33,7 @@ class QSslCertificate; class DigiDocSignature { public: - enum SignatureStatus + enum SignatureStatus : quint8 { Valid, Warning, @@ -41,7 +41,7 @@ class DigiDocSignature Invalid, Unknown }; - enum SignatureWarning + enum SignatureWarning : quint8 { DigestWeak = 1 << 2 }; @@ -124,10 +124,9 @@ class DigiDoc: public QObject DocumentModel *documentModel() const; QString fileName() const; bool isAsicS() const; - bool isCades() const; + bool isAsicE() const; bool isPDF() const; bool isModified() const; - bool isSupported() const; QString mediaType() const; bool move(const QString &to); bool open( const QString &file ); @@ -140,9 +139,9 @@ class DigiDoc: public QObject const QString &country, const QString &role, digidoc::Signer *signer); - QList signatures() const; + void enumSignatures(std::function &&cb) const; + void enumTimestamps(std::function &&cb) const; ria::qdigidoc4::ContainerState state(); - QList timestamps() const; static QStringList parseException(const digidoc::Exception &e, digidoc::Exception::ExceptionCode &code); @@ -156,7 +155,6 @@ class DigiDoc: public QObject std::unique_ptr m_documentModel; ria::qdigidoc4::ContainerState containerState = ria::qdigidoc4::UnsignedContainer; - QList m_signatures, m_timestamps; bool modified = false; QString m_fileName; QStringList m_tempFiles; diff --git a/client/PrintSheet.cpp b/client/PrintSheet.cpp index 74f2e7d19..8ca76a362 100644 --- a/client/PrintSheet.cpp +++ b/client/PrintSheet.cpp @@ -129,8 +129,7 @@ PrintSheet::PrintSheet( DigiDoc *doc, QPrinter *printer ) setPen( oPen ); int i = 1; - for(const DigiDocSignature &sig: doc->signatures()) - { + doc->enumSignatures([this,&i](DigiDocSignature sig) { const SslCertificate cert = sig.cert(); bool tempel = cert.type() & SslCertificate::TempelType; @@ -177,7 +176,7 @@ PrintSheet::PrintSheet( DigiDoc *doc, QPrinter *printer ) customText(tr("HASH VALUE OF SIGNATURE"), SslCertificate::toHex(sig.messageImprint())); top += 15; - } + }); save(); newPage( 50 ); QStaticText textDoc; diff --git a/client/widgets/ContainerPage.cpp b/client/widgets/ContainerPage.cpp index c7f221f82..0d10af79f 100644 --- a/client/widgets/ContainerPage.cpp +++ b/client/widgets/ContainerPage.cpp @@ -305,34 +305,43 @@ void ContainerPage::transition(DigiDoc* container) showSigningButton(); }); - if(!container->timestamps().isEmpty()) - { + bool hasTimestamps = true; + container->enumTimestamps([&, this](DigiDocSignature &&c) { ui->rightPane->addHeader(QT_TRANSLATE_NOOP("ItemList", "Container timestamps")); - - for(const DigiDocSignature &c: container->timestamps()) + if(!hasTimestamps) { - auto *item = new SignatureItem(c, container->state(), ui->rightPane); - if(c.isInvalid()) - ++errors[item->getError()]; - ui->rightPane->addHeaderWidget(item); + ui->rightPane->addHeader(QT_TRANSLATE_NOOP("ItemList", "Container timestamps")); + hasTimestamps = true; } - } + bool isInvalid = c.isInvalid(); + auto *item = new SignatureItem(std::move(c), container->state(), ui->rightPane); + if(isInvalid) + ++errors[item->getError()]; + ui->rightPane->addHeaderWidget(item); + }); - for(const DigiDocSignature &c: container->signatures()) - { - auto *item = new SignatureItem(c, container->state(), ui->rightPane); - if(c.isInvalid()) + bool isXAdES = false; + bool isCAdES = false; + container->enumSignatures([&, this](DigiDocSignature &&c) { + QString profile = c.profile(); + if(profile.contains(QLatin1String("BES"), Qt::CaseInsensitive)) + isXAdES = true; + if(profile.contains(QLatin1String("CADES"), Qt::CaseInsensitive)) + isCAdES = true; + bool isInvalid = c.isInvalid(); + auto *item = new SignatureItem(std::move(c), container->state(), ui->rightPane); + if(isInvalid) ++errors[item->getError()]; ui->rightPane->addWidget(item); - } + }); for(const auto &[key, value]: errors) emit warning({key, value}); if(container->fileName().endsWith(QStringLiteral("ddoc"), Qt::CaseInsensitive)) emit warning({UnsupportedDDocWarning}); - if(container->isAsicS()) + if(container->isAsicS() && isXAdES) emit warning({UnsupportedAsicSWarning}); - if(container->isCades()) + if(isCAdES) emit warning({UnsupportedAsicCadesWarning}); hasEmptyFile = false; @@ -345,7 +354,7 @@ void ContainerPage::transition(DigiDoc* container) } } - isSupported = container->isSupported() || container->isPDF(); + isSupported = container->isAsicE() && !isCAdES || container->isPDF(); showSigningButton(); ui->leftPane->setModel(container->documentModel()); diff --git a/client/widgets/SignatureItem.cpp b/client/widgets/SignatureItem.cpp index 0d3e9f374..0c1513ca1 100644 --- a/client/widgets/SignatureItem.cpp +++ b/client/widgets/SignatureItem.cpp @@ -57,7 +57,7 @@ SignatureItem::SignatureItem(DigiDocSignature s, ContainerState /*state*/, QWidg ui->name->installEventFilter(this); ui->idSignTime->installEventFilter(this); ui->role->installEventFilter(this); - ui->remove->setVisible(ui->signature.container()->isSupported()); + ui->remove->setVisible(ui->signature.container()->isAsicE() && s.profile().contains("BES", Qt::CaseInsensitive)); connect(ui->remove, &QToolButton::clicked, this, [this]{ const SslCertificate c = ui->signature.cert(); auto *dlg = new WarningDialog(tr("Remove signature %1?")