Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend signature to LTA #1326

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 89 additions & 36 deletions client/DigiDoc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,14 +242,12 @@ QDateTime DigiDocSignature::tsTime() const
return toTime(s->TimeStampTime());
}

QSslCertificate DigiDocSignature::tsaCert() const
QList<std::pair<QSslCertificate,QDateTime>> DigiDocSignature::archiveTimeStamps() const
{
return toCertificate(s->ArchiveTimeStampCertificate());
}

QDateTime DigiDocSignature::tsaTime() const
{
return toTime(s->ArchiveTimeStampTime());
QList<std::pair<QSslCertificate,QDateTime>> result;
for(const TSAInfo &i: s->ArchiveTimeStamps())
result.append({toCertificate(i.cert), toTime(i.time)});;
return result;
}

DigiDocSignature::SignatureStatus DigiDocSignature::validate(bool qscd)
Expand Down Expand Up @@ -448,6 +446,56 @@ DocumentModel* DigiDoc::documentModel() const
return m_documentModel.get();
}

bool DigiDoc::extend()
{
try {
auto *signer = qApp->signer();
signer->setUserAgent(QStringLiteral("%1/%2 (%3) Devices: %4").arg(
QCoreApplication::applicationName(),
QCoreApplication::applicationVersion(),
Common::applicationOs(),
Common::drivers().join(',')).toUtf8().constData());
qApp->waitForTSL(fileName());
QWidget *parent = qobject_cast<QWidget *>(QObject::parent());
if(parent == nullptr)
parent = Application::activeWindow();
ServiceConfirmation cb(parent);
QString current = m_fileName;
if(waitFor([&] {
if(auto container = Container::extendContainerValidity(*b, signer))
{
load(std::move(container), cb);
return true;
}
return false;
}))
{
const QString asics = QCoreApplication::translate("MainWindow", "Documents (%1)").arg(QLatin1String("*.asics *.scs"));
QFileInfo f(current);
QString name = f.absolutePath() + '/' + f.completeBaseName() + QStringLiteral(".asics");
return save(FileDialog::getSaveFileName(Application::mainWindow(), QCoreApplication::translate("MainWindow", "Save file"), name, asics));
}
else
save();
}
catch(const Exception &e)
{
Exception::ExceptionCode code = Exception::General;
QStringList causes = parseException(e, code);
switch(code)
{
case Exception::NetworkError:
case Exception::HostNotFound:
WarningDialog::show(tr("Failed to sign container. Please check the access to signing services and network settings."), causes.join('\n')); break;
case Exception::InvalidUrl:
WarningDialog::show(tr("Failed to sign container. Signing service URL is incorrect."), causes.join('\n')); break;
default:
setLastError(tr("Failed to sign container."), e); break;
}
}
return false;
}

QString DigiDoc::fileName() const { return m_fileName; }

bool DigiDoc::isError(bool failure, const QString &msg) const
Expand Down Expand Up @@ -485,6 +533,39 @@ bool DigiDoc::isSupported() const
return b && b->mediaType() == "application/vnd.etsi.asic-e+zip" && !isCades();
}

void DigiDoc::load(std::unique_ptr<Container> &&doc, ServiceConfirmation &cb)
{
clear();
b = std::move(doc);
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))
{
const QString tmppath = FileDialog::tempPath(FileDialog::safeName(from(f->fileName())));
f->saveAs(to(tmppath));
if(QFileInfo::exists(tmppath))
{
m_tempFiles.append(tmppath);
try {
parentContainer = std::exchange(b, Container::openPtr(to(tmppath), &cb));
} catch(const Exception &) {}
}
}
}
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));
}
containerState = signatures().isEmpty() ? ContainerState::UnsignedSavedContainer : ContainerState::SignedContainer;
}

QString DigiDoc::mediaType() const
{ return b ? from( b->mediaType() ) : QString(); }

Expand Down Expand Up @@ -513,40 +594,12 @@ bool DigiDoc::open( const QString &file )
parent = Application::activeWindow();
ServiceConfirmation cb(parent);
qApp->waitForTSL( file );
clear();
try {
WaitDialogHolder waitDialog(parent, tr("Opening"), false);
return waitFor([&] {
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))
{
const QString tmppath = FileDialog::tempPath(FileDialog::safeName(from(f->fileName())));
f->saveAs(to(tmppath));
if(QFileInfo::exists(tmppath))
{
m_tempFiles.append(tmppath);
try {
parentContainer = std::exchange(b, Container::openPtr(to(tmppath), &cb));
} catch(const Exception &) {}
}
}
}
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));
}
load(Container::openPtr(to(file), &cb), cb);
Application::addRecent(file);
m_fileName = file;
containerState = signatures().isEmpty() ? ContainerState::UnsignedSavedContainer : ContainerState::SignedContainer;
return true;
});
} catch(const Exception &e) {
Expand Down
6 changes: 4 additions & 2 deletions client/DigiDoc.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,7 @@ class DigiDocSignature
QDateTime trustedTime() const;
QSslCertificate tsCert() const;
QDateTime tsTime() const;
QSslCertificate tsaCert() const;
QDateTime tsaTime() const;
QList<std::pair<QSslCertificate,QDateTime>> archiveTimeStamps() const;
int warning() const;

private:
Expand Down Expand Up @@ -110,6 +109,7 @@ class SDocumentModel final: public DocumentModel
friend class DigiDoc;
};

struct ServiceConfirmation;

class DigiDoc: public QObject
{
Expand All @@ -122,6 +122,7 @@ class DigiDoc: public QObject
void create( const QString &file );
void clear();
DocumentModel *documentModel() const;
bool extend();
QString fileName() const;
bool isAsicS() const;
bool isCades() const;
Expand Down Expand Up @@ -149,6 +150,7 @@ class DigiDoc: public QObject

private:
bool isError(bool failure, const QString &msg = {}) const;
void load(std::unique_ptr<digidoc::Container> &&doc, ServiceConfirmation &cb);
static void setLastError( const QString &msg, const digidoc::Exception &e );

std::unique_ptr<digidoc::Container> b;
Expand Down
79 changes: 27 additions & 52 deletions client/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ MainWindow::MainWindow( QWidget *parent )
separator->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
separator->setStyleSheet(QStringLiteral("background-color: #D9D9D9;"));
separator->resize(8000, 1);
separator->move(110, 0);
separator->move(mapToGlobal(ui->topBar->pos()));
separator->show();
#endif

Expand All @@ -124,8 +124,6 @@ MainWindow::MainWindow( QWidget *parent )
updateSelectorData(token);
updateMyEID(token);
ui->cryptoContainerPage->cardChanged(token.cert());
if(cryptoDoc)
ui->cryptoContainerPage->update(cryptoDoc, token.cert());
});
QPCSC::instance().start();

Expand All @@ -151,8 +149,6 @@ MainWindow::MainWindow( QWidget *parent )
connect(ui->cryptoContainerPage, &ContainerPage::action, this, &MainWindow::onCryptoAction);
connect(ui->cryptoContainerPage, &ContainerPage::addFiles, this, [this](const QStringList &files) { openFiles(files, true); } );
connect(ui->cryptoContainerPage, &ContainerPage::fileRemoved, this, &MainWindow::removeCryptoFile);
connect(ui->cryptoContainerPage, &ContainerPage::keysSelected, this, &MainWindow::updateKeys);
connect(ui->cryptoContainerPage, &ContainerPage::removed, this, &MainWindow::removeAddress);
connect(ui->cryptoContainerPage, &ContainerPage::warning, this, [this](WarningText warningText) {
ui->warnings->showWarning(warningText);
ui->crypto->warningIcon(true);
Expand Down Expand Up @@ -339,19 +335,15 @@ void MainWindow::navigateToPage( Pages page, const QStringList &files, bool crea
if(!filename.isNull())
{
signatureContainer->create(filename);
bool filesAdded = false;
for(const auto &file: files)
{
if(signatureContainer->documentModel()->addFile(file))
filesAdded = true;
navigate = true;
}
navigate = filesAdded;
}
}
else if(signatureContainer->open(files[0]))
{
navigate = true;
}
else
navigate = signatureContainer->open(files[0]);
if(navigate)
{
resetDigiDoc(signatureContainer.release());
Expand All @@ -361,31 +353,27 @@ void MainWindow::navigateToPage( Pages page, const QStringList &files, bool crea
else if(page == CryptoDetails)
{
navigate = false;
std::unique_ptr<CryptoDoc> cryptoContainer(new CryptoDoc(this));
auto cryptoContainer = std::make_unique<CryptoDoc>(this);

if(create)
{
QString filename = FileDialog::createNewFileName(files[0], false, this);
if(!filename.isNull())
{
cryptoContainer->clear(filename);
bool filesAdded = false;
for(const auto &file: files)
{
if(cryptoContainer->documentModel()->addFile(file))
filesAdded = true;
navigate = true;
}
navigate = filesAdded;
}
}
else if(cryptoContainer->open(files[0]))
{
navigate = true;
}
else
navigate = cryptoContainer->open(files[0]);
if(navigate)
{
resetCryptoDoc(cryptoContainer.release());
ui->cryptoContainerPage->transition(cryptoDoc, qApp->signer()->tokenauth().cert());
resetCryptoDoc(std::move(cryptoContainer));
ui->cryptoContainerPage->transition(cryptoDoc.get(), qApp->signer()->tokenauth().cert());
}
}

Expand Down Expand Up @@ -417,6 +405,16 @@ void MainWindow::onSignAction(int action, const QString &info1, const QString &i
digiDoc->sign(city, state, zip, country, role, &s);
});
break;
case SignatureExtend:
{
if(!digiDoc)
break;
WarningDialog *d = new WarningDialog(tr("All signatures are extended in container."), this);
d->addButton(tr("Extend"), QMessageBox::Yes);
if(d->exec() == QMessageBox::Yes && digiDoc->extend())
ui->signContainerPage->transition(digiDoc);
break;
}
case ClearSignatureWarning:
ui->signature->warningIcon(false);
ui->warnings->closeWarnings(SignDetails);
Expand Down Expand Up @@ -469,7 +467,7 @@ void MainWindow::convertToCDoc()
if(filename.isNull())
return;

std::unique_ptr<CryptoDoc> cryptoContainer(new CryptoDoc(this));
auto cryptoContainer = std::make_unique<CryptoDoc>(this);
cryptoContainer->clear(filename);

// If signed, add whole signed document to cryptocontainer; otherwise content only
Expand All @@ -482,9 +480,9 @@ void MainWindow::convertToCDoc()
if(!cardData.cert().isNull())
cryptoContainer->addKey(CKey(cardData.cert()));

resetCryptoDoc(cryptoContainer.release());
resetCryptoDoc(std::move(cryptoContainer));
resetDigiDoc(nullptr, false);
ui->cryptoContainerPage->transition(cryptoDoc, qApp->signer()->tokenauth().cert());
ui->cryptoContainerPage->transition(cryptoDoc.get(), qApp->signer()->tokenauth().cert());
selectPage(CryptoDetails);

FadeInNotification::success(ui->topBar, tr("Converted to crypto container!"));
Expand Down Expand Up @@ -520,14 +518,14 @@ void MainWindow::onCryptoAction(int action, const QString &/*id*/, const QString
case DecryptToken:
if(decrypt())
{
ui->cryptoContainerPage->transition(cryptoDoc, qApp->signer()->tokenauth().cert());
ui->cryptoContainerPage->transition(cryptoDoc.get(), qApp->signer()->tokenauth().cert());
FadeInNotification::success(ui->topBar, tr("Decryption succeeded!"));
}
break;
case EncryptContainer:
if(encrypt())
{
ui->cryptoContainerPage->transition(cryptoDoc, qApp->signer()->tokenauth().cert());
ui->cryptoContainerPage->transition(cryptoDoc.get(), qApp->signer()->tokenauth().cert());
FadeInNotification::success(ui->topBar, tr("Encryption succeeded!"));
}
break;
Expand Down Expand Up @@ -688,12 +686,10 @@ void MainWindow::openContainer(bool signature)
openFiles(files);
}

void MainWindow::resetCryptoDoc(CryptoDoc *doc)
void MainWindow::resetCryptoDoc(std::unique_ptr<CryptoDoc> &&doc)
{
ui->crypto->warningIcon(false);
ui->cryptoContainerPage->clear();
delete cryptoDoc;
cryptoDoc = doc;
cryptoDoc = std::move(doc);
}

void MainWindow::resetDigiDoc(DigiDoc *doc, bool warnOnChange)
Expand Down Expand Up @@ -886,15 +882,6 @@ void MainWindow::sign(F &&sign)
adjustDrops();
}

void MainWindow::removeAddress(int index)
{
if(cryptoDoc)
{
cryptoDoc->removeKey(index);
ui->cryptoContainerPage->update(cryptoDoc, qApp->signer()->tokenauth().cert());
}
}

void MainWindow::removeCryptoFile(int index)
{
if(!cryptoDoc)
Expand Down Expand Up @@ -1077,18 +1064,6 @@ void MainWindow::updateSelectorData(TokenData data)
showCardMenu(false);
}

void MainWindow::updateKeys(const QList<CKey> &keys)
{
if(!cryptoDoc)
return;

for(auto i = cryptoDoc->keys().size() - 1; i >= 0; i--)
cryptoDoc->removeKey(i);
for(const auto &key: keys)
cryptoDoc->addKey(key);
ui->cryptoContainerPage->update(cryptoDoc, qApp->signer()->tokenauth().cert());
}

void MainWindow::containerSummary()
{
#ifdef Q_OS_WIN
Expand Down
Loading
Loading