forked from Public/monero-gui
updater: fetch signed hashes from getmonero.org, verify downloads
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user