diff options
-rw-r--r-- | lib/connection.h | 2 | ||||
-rw-r--r-- | lib/events/eventcontent.cpp | 9 | ||||
-rw-r--r-- | lib/events/eventcontent.h | 6 | ||||
-rw-r--r-- | lib/events/filesourceinfo.cpp | 49 | ||||
-rw-r--r-- | lib/jobs/downloadfilejob.cpp | 10 | ||||
-rw-r--r-- | lib/room.cpp | 2 |
6 files changed, 37 insertions, 41 deletions
diff --git a/lib/connection.h b/lib/connection.h index 72383abb..43e285c1 100644 --- a/lib/connection.h +++ b/lib/connection.h @@ -605,7 +605,7 @@ public Q_SLOTS: #ifdef Quotient_E2EE_ENABLED DownloadFileJob* downloadFile(const QUrl& url, - const EncryptedFileMetadata& file, + const EncryptedFileMetadata& fileMetadata, const QString& localFilename = {}); #endif /** diff --git a/lib/events/eventcontent.cpp b/lib/events/eventcontent.cpp index 36b647cb..8db3b7e3 100644 --- a/lib/events/eventcontent.cpp +++ b/lib/events/eventcontent.cpp @@ -103,14 +103,13 @@ QJsonObject Quotient::EventContent::toInfoJson(const ImageInfo& info) return infoJson; } -Thumbnail::Thumbnail( - const QJsonObject& infoJson, - const Omittable<EncryptedFileMetadata>& encryptedFileMetadata) +Thumbnail::Thumbnail(const QJsonObject& infoJson, + const Omittable<EncryptedFileMetadata>& efm) : ImageInfo(QUrl(infoJson["thumbnail_url"_ls].toString()), infoJson["thumbnail_info"_ls].toObject()) { - if (encryptedFileMetadata) - source = *encryptedFileMetadata; + if (efm) + source = *efm; } void Thumbnail::dumpTo(QJsonObject& infoJson) const diff --git a/lib/events/eventcontent.h b/lib/events/eventcontent.h index 23281876..ea240122 100644 --- a/lib/events/eventcontent.h +++ b/lib/events/eventcontent.h @@ -146,7 +146,7 @@ namespace EventContent { public: using ImageInfo::ImageInfo; Thumbnail(const QJsonObject& infoJson, - const Omittable<EncryptedFileMetadata>& encryptedFile = none); + const Omittable<EncryptedFileMetadata>& efm = none); //! \brief Add thumbnail information to the passed `info` JSON object void dumpTo(QJsonObject& infoJson) const; @@ -181,8 +181,8 @@ namespace EventContent { json["filename"].toString()) , thumbnail(FileInfo::originalInfoJson) { - const auto efmJson = json.value("file"_ls).toObject(); - if (!efmJson.isEmpty()) + if (const auto efmJson = json.value("file"_ls).toObject(); + !efmJson.isEmpty()) InfoT::source = fromJson<EncryptedFileMetadata>(efmJson); // Two small hacks on originalJson to expose mediaIds to QML originalJson.insert("mediaId", InfoT::mediaId()); diff --git a/lib/events/filesourceinfo.cpp b/lib/events/filesourceinfo.cpp index 43e8e44c..11f93d80 100644 --- a/lib/events/filesourceinfo.cpp +++ b/lib/events/filesourceinfo.cpp @@ -20,36 +20,33 @@ QByteArray Quotient::decryptFile(const QByteArray& ciphertext, const EncryptedFileMetadata& metadata) { #ifdef Quotient_E2EE_ENABLED - auto _key = metadata.key.k; - const auto keyBytes = QByteArray::fromBase64( - _key.replace(u'_', u'/').replace(u'-', u'+').toLatin1()); - const auto sha256 = - QByteArray::fromBase64(metadata.hashes["sha256"_ls].toLatin1()); - if (sha256 + if (QByteArray::fromBase64(metadata.hashes["sha256"_ls].toLatin1()) != QCryptographicHash::hash(ciphertext, QCryptographicHash::Sha256)) { qCWarning(E2EE) << "Hash verification failed for file"; return {}; } - { - int length; - auto* ctx = EVP_CIPHER_CTX_new(); - QByteArray plaintext(ciphertext.size() + EVP_MAX_BLOCK_LENGTH - 1, '\0'); - EVP_DecryptInit_ex( - ctx, EVP_aes_256_ctr(), nullptr, - reinterpret_cast<const unsigned char*>(keyBytes.data()), - reinterpret_cast<const unsigned char*>( - QByteArray::fromBase64(metadata.iv.toLatin1()).data())); - EVP_DecryptUpdate( - ctx, reinterpret_cast<unsigned char*>(plaintext.data()), &length, - reinterpret_cast<const unsigned char*>(ciphertext.data()), - ciphertext.size()); - EVP_DecryptFinal_ex(ctx, - reinterpret_cast<unsigned char*>(plaintext.data()) - + length, - &length); - EVP_CIPHER_CTX_free(ctx); - return plaintext.left(ciphertext.size()); - } + + auto _key = metadata.key.k; + const auto keyBytes = QByteArray::fromBase64( + _key.replace(u'_', u'/').replace(u'-', u'+').toLatin1()); + int length; + auto* ctx = EVP_CIPHER_CTX_new(); + QByteArray plaintext(ciphertext.size() + EVP_MAX_BLOCK_LENGTH - 1, '\0'); + EVP_DecryptInit_ex( + ctx, EVP_aes_256_ctr(), nullptr, + reinterpret_cast<const unsigned char*>(keyBytes.data()), + reinterpret_cast<const unsigned char*>( + QByteArray::fromBase64(metadata.iv.toLatin1()).data())); + EVP_DecryptUpdate(ctx, reinterpret_cast<unsigned char*>(plaintext.data()), + &length, + reinterpret_cast<const unsigned char*>(ciphertext.data()), + ciphertext.size()); + EVP_DecryptFinal_ex(ctx, + reinterpret_cast<unsigned char*>(plaintext.data()) + + length, + &length); + EVP_CIPHER_CTX_free(ctx); + return plaintext.left(ciphertext.size()); #else qWarning(MAIN) << "This build of libQuotient doesn't support E2EE, " "cannot decrypt the file"; diff --git a/lib/jobs/downloadfilejob.cpp b/lib/jobs/downloadfilejob.cpp index 99c2bf9b..759d52c9 100644 --- a/lib/jobs/downloadfilejob.cpp +++ b/lib/jobs/downloadfilejob.cpp @@ -139,11 +139,11 @@ BaseJob::Status DownloadFileJob::prepareResult() #endif d->targetFile->close(); if (!d->targetFile->remove()) { - qCWarning(JOBS) << "Failed to remove the target file placeholder"; + qWarning(JOBS) << "Failed to remove the target file placeholder"; return { FileError, "Couldn't finalise the download" }; } if (!d->tempFile->rename(d->targetFile->fileName())) { - qCWarning(JOBS) << "Failed to rename" << d->tempFile->fileName() + qWarning(JOBS) << "Failed to rename" << d->tempFile->fileName() << "to" << d->targetFile->fileName(); return { FileError, "Couldn't finalise the download" }; } @@ -157,12 +157,12 @@ BaseJob::Status DownloadFileJob::prepareResult() decryptFile(*d->tempFile, *d->encryptedFileMetadata, tempTempFile); d->tempFile->close(); if (!d->tempFile->remove()) { - qCWarning(JOBS) + qWarning(JOBS) << "Failed to remove the decrypted file placeholder"; return { FileError, "Couldn't finalise the download" }; } if (!tempTempFile.rename(d->tempFile->fileName())) { - qCWarning(JOBS) << "Failed to rename" << tempTempFile.fileName() + qWarning(JOBS) << "Failed to rename" << tempTempFile.fileName() << "to" << d->tempFile->fileName(); return { FileError, "Couldn't finalise the download" }; } @@ -173,6 +173,6 @@ BaseJob::Status DownloadFileJob::prepareResult() } #endif } - qCDebug(JOBS) << "Saved a file as" << targetFileName(); + qDebug(JOBS) << "Saved a file as" << targetFileName(); return Success; } diff --git a/lib/room.cpp b/lib/room.cpp index 4cb01a39..26fe80e3 100644 --- a/lib/room.cpp +++ b/lib/room.cpp @@ -2274,7 +2274,7 @@ QString Room::Private::doPostFile(RoomEventPtr&& msgEvent, const QUrl& localUrl) const auto& transferJob = fileTransfers.value(txnId).job; connect(q, &Room::fileTransferCompleted, transferJob, [this, txnId](const QString& tId, const QUrl&, - const FileSourceInfo fileMetadata) { + const FileSourceInfo& fileMetadata) { if (tId != txnId) return; |