Skip to content

Commit

Permalink
Extend signature to LTA
Browse files Browse the repository at this point in the history
Signed-off-by: Raul Metsma <[email protected]>
  • Loading branch information
metsma committed Dec 12, 2024
1 parent 283502f commit 2f81364
Show file tree
Hide file tree
Showing 12 changed files with 218 additions and 154 deletions.
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

0 comments on commit 2f81364

Please sign in to comment.