aboutsummaryrefslogtreecommitdiff
path: root/src/qt
diff options
context:
space:
mode:
Diffstat (limited to 'src/qt')
-rw-r--r--src/qt/downloader.cpp19
-rw-r--r--src/qt/downloader.h2
-rw-r--r--src/qt/network.cpp11
-rw-r--r--src/qt/network.h1
-rw-r--r--src/qt/updater.cpp55
-rw-r--r--src/qt/updater.h11
6 files changed, 86 insertions, 13 deletions
diff --git a/src/qt/downloader.cpp b/src/qt/downloader.cpp
index afd2049e..d925c77c 100644
--- a/src/qt/downloader.cpp
+++ b/src/qt/downloader.cpp
@@ -31,6 +31,8 @@
#include <QReadLocker>
#include <QWriteLocker>
+#include "updater.h"
+
namespace
{
@@ -112,10 +114,10 @@ void Downloader::cancel()
m_contents.clear();
}
-bool Downloader::get(const QString &url, const QJSValue &callback)
+bool Downloader::get(const QString &url, const QString &hash, const QJSValue &callback)
{
auto future = m_scheduler.run(
- [this, url]() {
+ [this, url, hash]() {
DownloaderStateGuard stateGuard(m_active, m_mutex, [this]() {
emit activeChanged();
});
@@ -153,6 +155,19 @@ bool Downloader::get(const QString &url, const QJSValue &callback)
return QJSValueList({"empty response"});
}
+ try
+ {
+ const QByteArray calculatedHash = Updater().getHash(&response[0], response.size());
+ if (QByteArray::fromHex(hash.toUtf8()) != calculatedHash)
+ {
+ return QJSValueList({"hash sum mismatch"});
+ }
+ }
+ catch (const std::exception &e)
+ {
+ return QJSValueList({e.what()});
+ }
+
{
QWriteLocker locker(&m_mutex);
diff --git a/src/qt/downloader.h b/src/qt/downloader.h
index 44840535..418627a5 100644
--- a/src/qt/downloader.h
+++ b/src/qt/downloader.h
@@ -44,7 +44,7 @@ public:
~Downloader();
Q_INVOKABLE void cancel();
- Q_INVOKABLE bool get(const QString &url, const QJSValue &callback);
+ Q_INVOKABLE bool get(const QString &url, const QString &hash, const QJSValue &callback);
Q_INVOKABLE bool saveToFile(const QString &path) const;
signals:
diff --git a/src/qt/network.cpp b/src/qt/network.cpp
index 01d0f296..1a674508 100644
--- a/src/qt/network.cpp
+++ b/src/qt/network.cpp
@@ -117,6 +117,17 @@ void Network::getJSON(const QString &url, const QJSValue &callback) const
get(url, callback, "application/json; charset=utf-8");
}
+std::string Network::get(const QString &url, const QString &contentType /* = {} */) const
+{
+ std::string response;
+ QString error = get(std::shared_ptr<http_simple_client>(new http_simple_client()), url, response, contentType);
+ if (!error.isEmpty())
+ {
+ throw std::runtime_error(QString("failed to fetch %1: %2").arg(url).arg(error).toStdString());
+ }
+ return response;
+}
+
QString Network::get(
std::shared_ptr<http_simple_client> httpClient,
const QString &url,
diff --git a/src/qt/network.h b/src/qt/network.h
index acdd6280..e741247d 100644
--- a/src/qt/network.h
+++ b/src/qt/network.h
@@ -77,6 +77,7 @@ public:
Q_INVOKABLE void get(const QString &url, const QJSValue &callback, const QString &contentType = {}) const;
Q_INVOKABLE void getJSON(const QString &url, const QJSValue &callback) const;
+ std::string get(const QString &url, const QString &contentType = {}) const;
QString get(
std::shared_ptr<epee::net_utils::http::http_simple_client> httpClient,
const QString &url,
diff --git a/src/qt/updater.cpp b/src/qt/updater.cpp
index 5968c2b5..17d6eddb 100644
--- a/src/qt/updater.cpp
+++ b/src/qt/updater.cpp
@@ -30,6 +30,7 @@
#include <openpgp/hash.h>
+#include "network.h"
#include "utils.h"
Updater::Updater()
@@ -39,17 +40,41 @@ Updater::Updater()
m_maintainers.emplace_back(fileGetContents(":/monero/utils/gpg_keys/luigi1111.asc").toStdString());
}
-QPair<QString, QString> Updater::verifySignaturesAndHashSum(
+QByteArray Updater::fetchSignedHash(
+ const QString &binaryFilename,
+ const QByteArray &hashFromDns,
+ QPair<QString, QString> &signers) const
+{
+ static constexpr const char hashesTxtUrl[] = "https://web.getmonero.org/downloads/hashes.txt";
+ static constexpr const char hashesTxtSigUrl[] = "https://web.getmonero.org/downloads/hashes.txt.sig";
+
+ const Network network;
+ std::string hashesTxt = network.get(hashesTxtUrl);
+ std::string hashesTxtSig = network.get(hashesTxtSigUrl);
+
+ const QByteArray signedHash = verifyParseSignedHahes(
+ QByteArray(&hashesTxt[0], hashesTxt.size()),
+ QByteArray(&hashesTxtSig[0], hashesTxtSig.size()),
+ binaryFilename,
+ signers);
+
+ if (signedHash != hashFromDns)
+ {
+ throw std::runtime_error("DNS hash mismatch");
+ }
+
+ return signedHash;
+}
+
+QByteArray Updater::verifyParseSignedHahes(
const QByteArray &armoredSignedHashes,
const QByteArray &secondDetachedSignature,
const QString &binaryFilename,
- const void *binaryData,
- size_t binarySize) const
+ QPair<QString, QString> &signers) const
{
- QString firstSigner;
- const QString signedMessage = verifySignature(armoredSignedHashes, firstSigner);
+ const QString signedMessage = verifySignature(armoredSignedHashes, signers.first);
- QString secondSigner = verifySignature(
+ signers.second = verifySignature(
epee::span<const uint8_t>(
reinterpret_cast<const uint8_t *>(armoredSignedHashes.data()),
armoredSignedHashes.size()),
@@ -57,19 +82,31 @@ QPair<QString, QString> Updater::verifySignaturesAndHashSum(
reinterpret_cast<const uint8_t *>(secondDetachedSignature.data()),
secondDetachedSignature.size())));
- if (firstSigner == secondSigner)
+ if (signers.first == signers.second)
{
throw std::runtime_error("both signatures were generated by the same person");
}
- const QByteArray signedHash = parseShasumOutput(signedMessage, binaryFilename);
+ return parseShasumOutput(signedMessage, binaryFilename);
+}
+
+QPair<QString, QString> Updater::verifySignaturesAndHashSum(
+ const QByteArray &armoredSignedHashes,
+ const QByteArray &secondDetachedSignature,
+ const QString &binaryFilename,
+ const void *binaryData,
+ size_t binarySize) const
+{
+ QPair<QString, QString> signers;
+ const QByteArray signedHash =
+ verifyParseSignedHahes(armoredSignedHashes, secondDetachedSignature, binaryFilename, signers);
const QByteArray calculatedHash = getHash(binaryData, binarySize);
if (signedHash != calculatedHash)
{
throw std::runtime_error("hash sum mismatch");
}
- return {firstSigner, secondSigner};
+ return signers;
}
QByteArray Updater::getHash(const void *data, size_t size) const
diff --git a/src/qt/updater.h b/src/qt/updater.h
index bc06d0c0..48a59a71 100644
--- a/src/qt/updater.h
+++ b/src/qt/updater.h
@@ -37,6 +37,11 @@ class Updater
public:
Updater();
+ QByteArray fetchSignedHash(
+ const QString &binaryFilename,
+ const QByteArray &hashFromDns,
+ QPair<QString, QString> &signers) const;
+ QByteArray getHash(const void *data, size_t size) const;
QPair<QString, QString> verifySignaturesAndHashSum(
const QByteArray &armoredSignedHashes,
const QByteArray &secondDetachedSignature,
@@ -45,7 +50,11 @@ public:
size_t binarySize) const;
private:
- QByteArray getHash(const void *data, size_t size) const;
+ QByteArray verifyParseSignedHahes(
+ const QByteArray &armoredSignedHashes,
+ const QByteArray &secondDetachedSignature,
+ const QString &binaryFilename,
+ QPair<QString, QString> &signers) const;
QString verifySignature(const QByteArray &armoredSignedMessage, QString &signer) const;
QString verifySignature(const epee::span<const uint8_t> data, const openpgp::signature_rsa &signature) const;
QByteArray parseShasumOutput(const QString &message, const QString &filename) const;