Skip to content
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
3 changes: 2 additions & 1 deletion client/Application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -570,8 +570,9 @@ Application::~Application()
connect(this, &Application::TSLLoadingFinished, &e, &QEventLoop::quit);
if( !d->ready )
e.exec();
digidoc::terminate();
delete d;
d = nullptr;
digidoc::terminate();

QDesktopServices::unsetUrlHandler(QStringLiteral("browse"));
QDesktopServices::unsetUrlHandler(QStringLiteral("mailto"));
Expand Down
42 changes: 13 additions & 29 deletions client/CDocSupport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,8 @@ getDecryptResultStatus(const std::vector<uint8_t> &result, std::unique_ptr<QCryp
libcdoc::result_t
DDCryptoBackend::decryptRSA(std::vector<uint8_t>& dst, const std::vector<uint8_t> &data, bool oaep, unsigned int idx)
{
if (!backend) {
auto val = QCryptoBackend::getBackend(qApp->cryptoManager()->tokenauth());
if (!val)
return getDecryptStatus(val.error());
backend.reset(val.value());
}
if (!backend)
return BACKEND_ERROR;
QByteArray decryptedKey = backend->decrypt(toByteArray(data), oaep);
dst.assign(decryptedKey.cbegin(), decryptedKey.cend());
return getDecryptResultStatus(dst, std::move(backend));
Expand All @@ -147,12 +143,8 @@ DDCryptoBackend::deriveConcatKDF(std::vector<uint8_t>& dst, const std::vector<ui
{"http://www.w3.org/2001/04/xmlenc#sha384", QCryptographicHash::Sha384},
{"http://www.w3.org/2001/04/xmlenc#sha512", QCryptographicHash::Sha512}
};
if (!backend) {
auto val = QCryptoBackend::getBackend(qApp->cryptoManager()->tokenauth());
if (!val)
return getDecryptStatus(val.error());
backend.reset(val.value());
}
if (!backend)
return BACKEND_ERROR;
QByteArray decryptedKey = backend->deriveConcatKDF(toByteArray(publicKey), SHA_MTH.value(digest),
toByteArray(algorithmID), toByteArray(partyUInfo), toByteArray(partyVInfo));
dst.assign(decryptedKey.cbegin(), decryptedKey.cend());
Expand All @@ -162,12 +154,8 @@ DDCryptoBackend::deriveConcatKDF(std::vector<uint8_t>& dst, const std::vector<ui
libcdoc::result_t
DDCryptoBackend::deriveHMACExtract(std::vector<uint8_t>& dst, const std::vector<uint8_t> &key_material, const std::vector<uint8_t> &salt, unsigned int idx)
{
if (!backend) {
auto val = QCryptoBackend::getBackend(qApp->cryptoManager()->tokenauth());
if (!val)
return getDecryptStatus(val.error());
backend.reset(val.value());
}
if (!backend)
return BACKEND_ERROR;
QByteArray decryptedKey = backend->deriveHMACExtract(toByteArray(key_material), toByteArray(salt), ECC_KEY_LEN);
dst.assign(decryptedKey.cbegin(), decryptedKey.cend());
return getDecryptResultStatus(dst, std::move(backend));
Expand Down Expand Up @@ -279,7 +267,7 @@ libcdoc::result_t DDNetworkBackend::sendKey(
if (expiry_ts) {
uint64_t expiry = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now() + std::chrono::months(6));
expiry_ts = std::min(expiry_ts, expiry);
req.setRawHeader("x-expiry-time", QDateTime::fromSecsSinceEpoch(expiry_ts).toString(Qt::ISODate).toLatin1());
req.setRawHeader("x-expiry-time", QDateTime::fromSecsSinceEpoch(expiry_ts, Qt::UTC).toString(Qt::ISODate).toLatin1());
}
if (!checkConnection()) {
last_error = "No connection";
Expand Down Expand Up @@ -330,19 +318,17 @@ DDNetworkBackend::fetchKey(std::vector<uint8_t> &result, const std::string &url,
return BACKEND_ERROR;
}

TokenData auth = qApp->cryptoManager()->tokenauth();
auto val = QCryptoBackend::getBackend(auth);
if (!val)
return getDecryptStatus(val.error());
std::unique_ptr<QCryptoBackend> backend(val.value());

auto authKey = backend->getKey();
if (!crypto.backend) {
last_error = "No authentication backend";
return BACKEND_ERROR;
}
auto authKey = crypto.backend->getKey();
if (!authKey.handle()) {
last_error = "Cannot create authentication key";
return BACKEND_ERROR;
}
QScopedPointer<QNetworkAccessManager,QScopedPointerDeleteLater> nam(
CheckConnection::setupNAM(req, auth.cert(), authKey, Settings::CDOC2_GET_CERT));
CheckConnection::setupNAM(req, crypto.backend->cert(), authKey, Settings::CDOC2_GET_CERT));
QEventLoop e;
QNetworkReply *reply = nam->get(req);
connect(reply, &QNetworkReply::finished, &e, &QEventLoop::quit);
Expand All @@ -356,8 +342,6 @@ DDNetworkBackend::fetchKey(std::vector<uint8_t> &result, const std::string &url,
QByteArray key_material = QByteArray::fromBase64(json.value(QLatin1String("ephemeral_key_material")).toString().toLatin1());
result.assign(key_material.cbegin(), key_material.cend());

crypto.setBackend(std::move(backend));

return libcdoc::OK;
}

Expand Down
49 changes: 13 additions & 36 deletions client/CryptoDoc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,16 +246,6 @@ bool CryptoDoc::addEncryptionKey(const CKey& key) {
return true;
}

bool CryptoDoc::canDecrypt(const QSslCertificate &cert) {
if (!d->reader)
return false;
if (cert.isNull())
return false;
QByteArray der = cert.toDer();
return d->reader->getLockForCert(
std::vector<uint8_t>(der.cbegin(), der.cend())) >= 0;
}

void CryptoDoc::clear(const QString &file, int version)
{
d->documents->clearTempFolder();
Expand All @@ -270,7 +260,7 @@ ContainerState CryptoDoc::state() const
return d->isEncrypted() ? EncryptedContainer : UnencryptedContainer;
}

bool CryptoDoc::decrypt(const libcdoc::Lock *lock, const QByteArray& secret)
bool CryptoDoc::decrypt(const libcdoc::Lock &lock, const QByteArray& secret, std::unique_ptr<QCryptoBackend> &&backend)
{
if(!d->reader)
{
Expand All @@ -281,38 +271,22 @@ bool CryptoDoc::decrypt(const libcdoc::Lock *lock, const QByteArray& secret)
return false;
}

int lock_idx = -1;
// libcdoc addresses the lock by its position; labels can repeat, the lock itself is unique
const std::vector<libcdoc::Lock> &locks = d->reader->getLocks();
if (lock == nullptr) {
QByteArray der = qApp->cryptoManager()->tokenauth().cert().toDer();
lock_idx = d->reader->getLockForCert(
std::vector<uint8_t>(der.cbegin(), der.cend()));
if (lock_idx < 0) {
WarningDialog::create()
->withTitle(tr("Failed to decrypt document"))
->withText(tr("You do not have the key to decrypt this document"))
->open();
return false;
}
lock = &locks.at(lock_idx);
} else {
for (lock_idx = 0; lock_idx < locks.size(); lock_idx++) {
if (lock->label == locks[lock_idx].label) {
lock = &locks.at(lock_idx);
break;
}
}
if (lock_idx >= locks.size())
lock_idx = -1;
}
if (!lock || (lock->isSymmetric() && secret.isEmpty())) {
auto it = std::ranges::find(locks, lock);
if (it == locks.cend() || (lock.isSymmetric() && secret.isEmpty())) {
WarningDialog::create()
->withTitle(tr("Failed to decrypt document"))
->withText(tr("You do not have the key to decrypt this document"))
->open();
return false;
}

auto lock_idx = unsigned(std::distance(locks.cbegin(), it));
d->crypto.setBackend(std::move(backend));
auto resetBackend = qScopeGuard([this] {
d->crypto.setBackend({});
});
d->crypto.secret.assign(secret.cbegin(), secret.cend());

TempListConsumer cons;
Expand All @@ -333,8 +307,11 @@ bool CryptoDoc::decrypt(const libcdoc::Lock *lock, const QByteArray& secret)
QString str;
const std::string &msg = d->reader->getLastErrorStr();
switch (result) {
case libcdoc::NOT_SUPPORTED:
str = QCoreApplication::translate("AddressItem", "Unsupported cryptographic algorithm or recipient type");
break;
case libcdoc::WRONG_KEY:
str = (lock->type == libcdoc::Lock::PASSWORD) ? tr("Wrong password.") : tr("Wrong key.");
str = (lock.type == libcdoc::Lock::PASSWORD) ? tr("Wrong password.") : tr("Wrong key.");
break;
case libcdoc::HASH_MISMATCH:
case libcdoc::DATA_FORMAT_ERROR:
Expand Down
11 changes: 4 additions & 7 deletions client/CryptoDoc.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,14 @@
#include "common_enums.h"
#include "DocumentModel.h"

#include <QtCore/QIODevice>
#include <QtCore/QLoggingCategory>
#include <QtNetwork/QSslCertificate>

#include <cdoc/CDoc.h>
#include <cdoc/Certificate.h>
#include <memory>

#include <cdoc/Lock.h>
#include <cdoc/Recipient.h>

class QSslKey;
class QCryptoBackend;

Q_DECLARE_LOGGING_CATEGORY(CRYPTO)

Expand Down Expand Up @@ -61,9 +59,8 @@ class CryptoDoc final: public QObject

bool supportsSymmetricKeys() const;
bool addEncryptionKey(const CKey& key);
bool canDecrypt(const QSslCertificate &cert);
void clear(const QString &file = {}, int version = -1);
bool decrypt(const libcdoc::Lock *lock, const QByteArray& secret);
bool decrypt(const libcdoc::Lock &lock, const QByteArray& secret, std::unique_ptr<QCryptoBackend> &&backend);
bool encrypt(const QString &filename = {}, const QString& label = {}, const QByteArray& secret = {});
DocumentModel* documentModel() const;
QString fileName() const;
Expand Down
7 changes: 2 additions & 5 deletions client/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ MainWindow::MainWindow( QWidget *parent )

// Refresh ID card info in card widget
connect(qApp->cryptoManager(), &QCryptoManager::cacheChanged, this, &MainWindow::updateSelector);
connect(qApp->cryptoManager(), &QCryptoManager::authDataChanged, ui->cryptoContainerPage, &ContainerPage::tokenChanged);

// Refresh card info on "My EID" page
connect(qApp->cryptoManager()->smartcard(), &QSmartCard::tokenChanged, this, &MainWindow::updateMyEID);
Expand Down Expand Up @@ -120,7 +119,6 @@ MainWindow::MainWindow( QWidget *parent )
connect(ui->infoStack, &MyEidInfo::changePinClicked, this, &MainWindow::changePinClicked);
connect(ui->cardInfo, &CardWidget::selected, ui->selector, &QToolButton::toggle);

ui->cryptoContainerPage->tokenChanged(qApp->cryptoManager()->tokenauth());
updateMyEID(qApp->cryptoManager()->smartcard()->tokenData());
updateMyEid(qApp->cryptoManager()->smartcard()->data());
}
Expand Down Expand Up @@ -273,7 +271,7 @@ void MainWindow::navigateToPage( Pages page, const QStringList &files, bool crea
if(navigate)
{
cryptoDoc = std::move(cryptoContainer);
ui->cryptoContainerPage->transition(cryptoDoc.get(), qApp->cryptoManager()->tokenauth().cert());
ui->cryptoContainerPage->transition(cryptoDoc.get());
}
}

Expand Down Expand Up @@ -334,7 +332,7 @@ void MainWindow::convertToCDoc()

cryptoDoc = std::move(cryptoContainer);
digiDoc.reset();
ui->cryptoContainerPage->transition(cryptoDoc.get(), qApp->cryptoManager()->tokenauth().cert());
ui->cryptoContainerPage->transition(cryptoDoc.get());
selectPage(CryptoDetails);

FadeInNotification::success(ui->topBar, tr("Converted to crypto container!"));
Expand Down Expand Up @@ -645,7 +643,6 @@ void MainWindow::updateMyEid(const QSmartCardData &data)
pin1Blocked || pin1Locked ||
pin2Blocked || pin2Locked ||
pukBlocked);
ui->cryptoContainerPage->cardChanged(data.authCert(), pin1Blocked || pin1Locked);

using enum WarningText::WarningType;
if(pin1Locked)
Expand Down
10 changes: 1 addition & 9 deletions client/QCryptoBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,8 @@ TokenData QCryptoManager::tokensign() const { QReadLocker locker(&d->lock); retu

void QCryptoManager::selectCard(const TokenData &token)
{
bool isSign = SslCertificate(token.cert()).keyUsage().contains(SslCertificate::NonRepudiation);
TokenData other;
{
bool isSign = SslCertificate(token.cert()).keyUsage().contains(SslCertificate::NonRepudiation);
QWriteLocker locker(&d->lock);
if(isSign)
d->sign = token;
Expand All @@ -240,14 +239,9 @@ void QCryptoManager::selectCard(const TokenData &token)
d->auth = t;
else
d->sign = t;
other = t;
break;
}
}
if(!isSign)
Q_EMIT authDataChanged(token);
else if(!other.isNull())
Q_EMIT authDataChanged(other);
d->smartcard.reloadCard(token, false);
}

Expand Down Expand Up @@ -308,8 +302,6 @@ void QCryptoManager::refresh()

if(cacheChangedFlag)
Q_EMIT cacheChanged();
if(aold != anew)
Q_EMIT authDataChanged(anew);
if(sold != snew)
d->smartcard.reloadCard(snew, false);
else if(aold != anew)
Expand Down
1 change: 0 additions & 1 deletion client/QCryptoBackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ class QCryptoManager final : public QThread

Q_SIGNALS:
void cacheChanged();
void authDataChanged(const TokenData &token);

private:
friend class QCryptoBackend;
Expand Down
3 changes: 0 additions & 3 deletions client/common_enums.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,8 @@ enum Actions : unsigned char {
ContainerCancel,
ContainerClearWarning,
ContainerConvert,
ContainerEncrypt,

EncryptContainer,
EncryptContainerSuccess,
DecryptContainer,
DecryptContainerSuccess,

SignatureAdd,
Expand Down
32 changes: 4 additions & 28 deletions client/translations/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,6 @@
</context>
<context>
<name>AddressItem</name>
<message>
<source> (Yourself)</source>
<translation> (Yourself)</translation>
</message>
<message>
<source>digi-ID</source>
<translation>digi-ID</translation>
Expand Down Expand Up @@ -513,6 +509,10 @@
<source>It is removed along with the container.</source>
<translation>It is removed along with the container.</translation>
</message>
<message>
<source>Failed to decrypt document</source>
<translation type="unfinished">Failed to decrypt document</translation>
</message>
<message>
<source>In order to view Validity Confirmation Sheet there has to be at least one printer installed!</source>
<translation>In order to view Validity Confirmation Sheet there has to be at least one printer installed!</translation>
Expand Down Expand Up @@ -1019,10 +1019,6 @@
<source>DigiDoc is created for managing Estonian eIDs and is the official digital signing and encryption application.</source>
<translation>DigiDoc is created for managing Estonian eIDs and is the official digital signing and encryption application.</translation>
</message>
<message>
<source>Skip introductions</source>
<translation>Skip introductions →</translation>
</message>
<message>
<source>The DigiDoc application allows you to:</source>
<translation>The DigiDoc application allows you to:</translation>
Expand Down Expand Up @@ -1123,10 +1119,6 @@
<source>Continue</source>
<translation>Continue</translation>
</message>
<message>
<source>View introduction</source>
<translation>View introduction</translation>
</message>
<message>
<source>View next intro</source>
<translation>View next intro</translation>
Expand All @@ -1135,18 +1127,6 @@
<source>Enter the application</source>
<translation>Enter the application</translation>
</message>
<message>
<source>Go to signing intro</source>
<translation>Go to signing intro</translation>
</message>
<message>
<source>Go to EID intro</source>
<translation>Go to EID intro</translation>
</message>
<message>
<source>Go to encryption intro</source>
<translation>Go to encryption intro</translation>
</message>
<message>
<source>&quot;My eID&quot; also provides a good overview of the status and contact information of the ID card inserted in the card reader.</source>
<translation>&quot;My eID&quot; also provides a good overview of the status and contact information of the ID card inserted in the card reader.</translation>
Expand Down Expand Up @@ -1348,10 +1328,6 @@ LDAP server is unavailable.</translation>
<source>Encrypt</source>
<translation>Encrypt</translation>
</message>
<message>
<source>Decrypt</source>
<translation>Decrypt</translation>
</message>
<message>
<source>Sign</source>
<translation>Sign</translation>
Expand Down
Loading
Loading