refactor: take a uint8_t span in ValidateIntegrityOrDie() (#43614)

refactor: take a uint8_t span in ValidateIntegrityOrDie()

Doing some groundwork for fixing unsafe base::File() APIs:

- Change ValidateIntegrityOrDie() to take a span<const uint8_t> arg.
  We'll need this to migrate asar's base::File API calls away from the
  ones tagged `UNSAFE_BUFFER_USAGE` because the safe counterparts use
  span<uint8_t> too.

- Simplify ValidateIntegrityOrDie()'s implementation by using
  crypto::SHA256Hash() instead of reinventing the wheel.

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
This commit is contained in:
trop[bot] 2024-09-06 22:16:51 -05:00 committed by GitHub
parent 5f97f97f7c
commit 00c0948e7b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 11 additions and 20 deletions

View file

@ -251,9 +251,8 @@ bool Archive::Init() {
// Currently we only support the sha256 algorithm, we can add support for // Currently we only support the sha256 algorithm, we can add support for
// more below ensure we read them in preference order from most secure to // more below ensure we read them in preference order from most secure to
// least // least
if (integrity.value().algorithm != HashAlgorithm::kNone) { if (integrity->algorithm != HashAlgorithm::kNone) {
ValidateIntegrityOrDie(header.c_str(), header.length(), ValidateIntegrityOrDie(base::as_byte_span(header), *integrity);
integrity.value());
} else { } else {
LOG(FATAL) << "No eligible hash for validatable asar archive: " LOG(FATAL) << "No eligible hash for validatable asar archive: "
<< RelativePath().value(); << RelativePath().value();

View file

@ -133,25 +133,17 @@ bool ReadFileToString(const base::FilePath& path, std::string* contents) {
return false; return false;
} }
if (info.integrity.has_value()) { if (info.integrity)
ValidateIntegrityOrDie(contents->data(), contents->size(), ValidateIntegrityOrDie(base::as_byte_span(*contents), *info.integrity);
info.integrity.value());
}
return true; return true;
} }
void ValidateIntegrityOrDie(const char* data, void ValidateIntegrityOrDie(base::span<const uint8_t> input,
size_t size,
const IntegrityPayload& integrity) { const IntegrityPayload& integrity) {
if (integrity.algorithm == HashAlgorithm::kSHA256) { if (integrity.algorithm == HashAlgorithm::kSHA256) {
uint8_t hash[crypto::kSHA256Length];
auto hasher = crypto::SecureHash::Create(crypto::SecureHash::SHA256);
hasher->Update(data, size);
hasher->Finish(hash, sizeof(hash));
const std::string hex_hash = const std::string hex_hash =
base::ToLowerASCII(base::HexEncode(hash, sizeof(hash))); base::ToLowerASCII(base::HexEncode(crypto::SHA256Hash(input)));
if (integrity.hash != hex_hash) { if (integrity.hash != hex_hash) {
LOG(FATAL) << "Integrity check failed for asar archive (" LOG(FATAL) << "Integrity check failed for asar archive ("
<< integrity.hash << " vs " << hex_hash << ")"; << integrity.hash << " vs " << hex_hash << ")";

View file

@ -8,6 +8,8 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include "base/containers/span.h"
namespace base { namespace base {
class FilePath; class FilePath;
} }
@ -29,8 +31,7 @@ bool GetAsarArchivePath(const base::FilePath& full_path,
// Same with base::ReadFileToString but supports asar Archive. // Same with base::ReadFileToString but supports asar Archive.
bool ReadFileToString(const base::FilePath& path, std::string* contents); bool ReadFileToString(const base::FilePath& path, std::string* contents);
void ValidateIntegrityOrDie(const char* data, void ValidateIntegrityOrDie(base::span<const uint8_t> input,
size_t size,
const IntegrityPayload& integrity); const IntegrityPayload& integrity);
} // namespace asar } // namespace asar

View file

@ -68,9 +68,8 @@ bool ScopedTemporaryFile::InitFromFile(
if (len != static_cast<int>(size)) if (len != static_cast<int>(size))
return false; return false;
if (integrity.has_value()) { if (integrity)
ValidateIntegrityOrDie(buf.data(), buf.size(), integrity.value()); ValidateIntegrityOrDie(base::as_byte_span(buf), *integrity);
}
base::File dest(path_, base::File::FLAG_OPEN | base::File::FLAG_WRITE); base::File dest(path_, base::File::FLAG_OPEN | base::File::FLAG_WRITE);
if (!dest.IsValid()) if (!dest.IsValid())