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
5 changes: 5 additions & 0 deletions client/Application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,10 @@ class Application::Private
#ifdef Q_OS_WIN
QStringList tempFiles;
#endif // Q_OS_WIN

~Private() {
delete signer;
}
};

Application::Application( int &argc, char **argv )
Expand Down Expand Up @@ -428,6 +432,7 @@ Application::Application( int &argc, char **argv )
// Clear obsolete registriy settings
#ifndef Q_OS_DARWIN
Settings::DEFAULT_DIR.clear();
Settings::CDOC2_NOTIFICATION.clear();
#endif

// Actions
Expand Down
91 changes: 53 additions & 38 deletions client/CDocSupport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,11 @@ CDocSupport::getCDocFileList(const QString &filename)
}

static libcdoc::result_t
getDecryptStatus(const std::vector<uint8_t>& result, QCryptoBackend::PinStatus pin_status)
getDecryptStatus(QCryptoBackend::Status pin_status)
{
switch (pin_status) {
case QCryptoBackend::PinOK:
return (result.empty()) ? DDCryptoBackend::BACKEND_ERROR : libcdoc::OK;
return libcdoc::OK;
case QCryptoBackend::PinCanceled:
return DDCryptoBackend::PIN_CANCELED;
case QCryptoBackend::PinIncorrect:
Expand All @@ -110,43 +110,55 @@ getDecryptStatus(const std::vector<uint8_t>& result, QCryptoBackend::PinStatus p
}

libcdoc::result_t
DDCryptoBackend::decryptRSA(std::vector<uint8_t>& result, const std::vector<uint8_t> &data, bool oaep, unsigned int idx)
DDCryptoBackend::decryptRSA(std::vector<uint8_t>& dst, const std::vector<uint8_t> &data, bool oaep, unsigned int idx)
{
QCryptoBackend::PinStatus pin_status;
QByteArray qkek = qApp->signer()->decrypt([qdata = toByteArray(data), &oaep](QCryptoBackend *backend) {
return backend->decrypt(qdata, oaep);
}, pin_status);
result.assign(qkek.cbegin(), qkek.cend());
return getDecryptStatus(result, pin_status);
if (!backend) {
auto val = QCryptoBackend::getBackend(qApp->signer()->tokenauth());
if (!val.value())
return getDecryptStatus(val.error());
backend.reset(val.value());
}
QByteArray decryptedKey = backend->decrypt(toByteArray(data), oaep);
dst.assign(decryptedKey.cbegin(), decryptedKey.cend());
backend.reset();
return (dst.empty() ? BACKEND_ERROR : libcdoc::OK);
}

libcdoc::result_t
DDCryptoBackend::deriveConcatKDF(std::vector<uint8_t>& dst, const std::vector<uint8_t> &publicKey, const std::string &digest,
const std::vector<uint8_t> &algorithmID, const std::vector<uint8_t> &partyUInfo, const std::vector<uint8_t> &partyVInfo, unsigned int idx)
{
QCryptoBackend::PinStatus pin_status;
QByteArray decryptedKey = qApp->signer()->decrypt([&publicKey, &digest, &algorithmID, &partyUInfo, &partyVInfo](QCryptoBackend *backend) {
static const QHash<std::string_view, QCryptographicHash::Algorithm> SHA_MTH{
{"http://www.w3.org/2001/04/xmlenc#sha256", QCryptographicHash::Sha256},
{"http://www.w3.org/2001/04/xmlenc#sha384", QCryptographicHash::Sha384},
{"http://www.w3.org/2001/04/xmlenc#sha512", QCryptographicHash::Sha512}
};
return backend->deriveConcatKDF(toByteArray(publicKey), SHA_MTH.value(digest),
toByteArray(algorithmID), toByteArray(partyUInfo), toByteArray(partyVInfo));
}, pin_status);
static const QHash<std::string_view, QCryptographicHash::Algorithm> SHA_MTH{
{"http://www.w3.org/2001/04/xmlenc#sha256", QCryptographicHash::Sha256},
{"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->signer()->tokenauth());
if (!val.value())
return getDecryptStatus(val.error());
backend.reset(val.value());
}
QByteArray decryptedKey = backend->deriveConcatKDF(toByteArray(publicKey), SHA_MTH.value(digest),
toByteArray(algorithmID), toByteArray(partyUInfo), toByteArray(partyVInfo));
dst.assign(decryptedKey.cbegin(), decryptedKey.cend());
return getDecryptStatus(dst, pin_status);
backend.reset();
return (dst.empty() ? BACKEND_ERROR : libcdoc::OK);
}

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)
{
QCryptoBackend::PinStatus pin_status;
QByteArray qkekpm = qApp->signer()->decrypt([qkey_material = toByteArray(key_material), qsalt = toByteArray(salt)](QCryptoBackend *backend) {
return backend->deriveHMACExtract(qkey_material, qsalt, ECC_KEY_LEN);
}, pin_status);
dst = std::vector<uint8_t>(qkekpm.cbegin(), qkekpm.cend());
return getDecryptStatus(dst, pin_status);
if (!backend) {
auto val = QCryptoBackend::getBackend(qApp->signer()->tokenauth());
if (!val.value())
return getDecryptStatus(val.error());
backend.reset(val.value());
}
QByteArray decryptedKey = backend->deriveHMACExtract(toByteArray(key_material), toByteArray(salt), ECC_KEY_LEN);
dst.assign(decryptedKey.cbegin(), decryptedKey.cend());
backend.reset();
return (dst.empty() ? BACKEND_ERROR : libcdoc::OK);
}

libcdoc::result_t
Expand Down Expand Up @@ -281,32 +293,32 @@ libcdoc::result_t DDNetworkBackend::sendKey(
};

libcdoc::result_t
DDNetworkBackend::fetchKey(std::vector<uint8_t> &result,
const std::string &url,
const std::string &transaction_id) {
DDNetworkBackend::fetchKey(std::vector<uint8_t> &result, const std::string &url, const std::string &transaction_id)
{
QNetworkRequest req(QStringLiteral("%1/key-capsules/%2").arg(QString::fromStdString(url), QLatin1String(transaction_id.c_str())));
req.setHeader(QNetworkRequest::ContentTypeHeader, QStringLiteral("application/json"));
if(!checkConnection()) {
last_error = "No connection";
return BACKEND_ERROR;
}
QCryptoBackend::PinStatus pin_status;
auto authKey = dispatchToMain([&] {
return qApp->signer()->key(pin_status);
});

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

auto authKey = backend->getKey();
if (!authKey.handle()) {
last_error = qApp->signer()->getLastErrorStr().toStdString();
return getDecryptStatus(result, pin_status);
last_error = "Cannot create authentication key";
return BACKEND_ERROR;
}
QScopedPointer<QNetworkAccessManager,QScopedPointerDeleteLater> nam(
CheckConnection::setupNAM(req, qApp->signer()->tokenauth().cert(), authKey, Settings::CDOC2_GET_CERT));
QEventLoop e;
QNetworkReply *reply = nam->get(req);
connect(reply, &QNetworkReply::finished, &e, &QEventLoop::quit);
e.exec();
if(authKey.handle()) {
qApp->signer()->logout();
}

if(reply->error() != QNetworkReply::NoError && reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() != 201) {
last_error = reply->errorString().toStdString();
Expand All @@ -315,6 +327,9 @@ DDNetworkBackend::fetchKey(std::vector<uint8_t> &result,
QJsonObject json = QJsonDocument::fromJson(reply->readAll()).object();
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
10 changes: 9 additions & 1 deletion client/CDocSupport.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

#pragma once

#include "QCryptoBackend.h"

#include <QtCore/QObject>
#include <QtCore/QIODevice>
#include <QtCore/QFile>
Expand Down Expand Up @@ -76,9 +78,14 @@ struct DDCryptoBackend final : public libcdoc::CryptoBackend {
unsigned int idx) final;
std::string getLastErrorStr(libcdoc::result_t code) const final;

std::unique_ptr<QCryptoBackend> backend;
std::vector<uint8_t> secret;

explicit DDCryptoBackend() = default;

void setBackend(std::unique_ptr<QCryptoBackend> &&backend) {
this->backend = std::move(backend);
}
};

//
Expand Down Expand Up @@ -110,8 +117,9 @@ struct DDNetworkBackend final : public libcdoc::NetworkBackend, private QObject
return libcdoc::NOT_IMPLEMENTED;
}

explicit DDNetworkBackend() = default;
explicit DDNetworkBackend(DDCryptoBackend &_crypto) : crypto(_crypto) {}

DDCryptoBackend &crypto;
std::string last_error;
};

Expand Down
29 changes: 4 additions & 25 deletions client/CryptoDoc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ struct CryptoDoc::Private
std::vector<IOEntry> files;
std::vector<CKey> keys;

explicit Private() : network(crypto) {}
bool isEncryptedWarning(const QString &title) const;

bool isEncrypted() const {
Expand Down Expand Up @@ -340,28 +341,6 @@ bool CryptoDoc::decrypt(const libcdoc::Lock *lock, const QByteArray& secret)
return false;
}

if (d->reader->version == 2 &&
(lock->type == libcdoc::Lock::Type::SERVER) &&
!Settings::CDOC2_NOTIFICATION.isSet()) {
auto *dlg = WarningDialog::create()
->withTitle(tr("You must enter your PIN code twice in order to decrypt the CDOC2 container"))
->withText(tr(
"The first PIN entry is required for authentication to the key server referenced in the CDOC2 container. "
"Second PIN entry is required to decrypt the CDOC2 container."))
->setCancelText(WarningDialog::Cancel)
->addButton(WarningDialog::OK, QMessageBox::Ok)
->addButton(tr("Don't show again"), QMessageBox::Ignore);
switch (dlg->exec())
{
case QMessageBox::Ok: break;
case QMessageBox::Ignore:
Settings::CDOC2_NOTIFICATION = true;
break;
default:
return false;
}
}

d->crypto.secret.assign(secret.cbegin(), secret.cend());

TempListConsumer cons;
Expand Down Expand Up @@ -394,13 +373,13 @@ bool CryptoDoc::decrypt(const libcdoc::Lock *lock, const QByteArray& secret)
str = tr("Cannot read file.");
break;
case DDCryptoBackend::PIN_CANCELED:
str = tr("PIN entry canceled");
str = QCryptoBackend::errorString(QCryptoBackend::Status::PinCanceled);
break;
case DDCryptoBackend::PIN_INCORRECT:
str = tr("PIN incorrect");
str = QCryptoBackend::errorString(QCryptoBackend::Status::PinIncorrect);
break;
case DDCryptoBackend::PIN_LOCKED:
str = tr("PIN locked");
QCryptoBackend::errorString(QCryptoBackend::Status::PinLocked);
break;
default:
str = tr("Please check your internet connection and network settings.");
Expand Down
Loading
Loading