summaryrefslogtreecommitdiffstats
path: root/components/update_client
diff options
context:
space:
mode:
authorasargent <asargent@chromium.org>2015-07-27 14:22:32 -0700
committerCommit bot <commit-bot@chromium.org>2015-07-27 21:23:30 +0000
commit710893f766e00c8501d67e78a61cf6d882641f41 (patch)
tree05776b600180da3ac8a5ff911fe329e917806dcc /components/update_client
parent3d7774c521d716ee91d2f41a1d2df53c1dbbe566 (diff)
downloadchromium_src-710893f766e00c8501d67e78a61cf6d882641f41.zip
chromium_src-710893f766e00c8501d67e78a61cf6d882641f41.tar.gz
chromium_src-710893f766e00c8501d67e78a61cf6d882641f41.tar.bz2
Move ValidateSignature logic for crx files to the CrxFile class
We were using the same logic with two different implementations in both extensions/ and components/update_client, so this lets us share the same code. BUG=490418 Review URL: https://codereview.chromium.org/1235593007 Cr-Commit-Position: refs/heads/master@{#340566}
Diffstat (limited to 'components/update_client')
-rw-r--r--components/update_client/component_unpacker.cc91
1 files changed, 13 insertions, 78 deletions
diff --git a/components/update_client/component_unpacker.cc b/components/update_client/component_unpacker.cc
index d43313d..9dfd555 100644
--- a/components/update_client/component_unpacker.cc
+++ b/components/update_client/component_unpacker.cc
@@ -8,6 +8,7 @@
#include <string>
#include <vector>
+#include "base/base64.h"
#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
@@ -25,79 +26,14 @@
#include "components/update_client/component_patcher_operation.h"
#include "components/update_client/update_client.h"
#include "crypto/secure_hash.h"
-#include "crypto/signature_verifier.h"
+#include "crypto/sha2.h"
#include "third_party/zlib/google/zip.h"
using crypto::SecureHash;
+using crx_file::CrxFile;
namespace update_client {
-namespace {
-
-// This class makes sure that the CRX digital signature is valid
-// and well formed.
-class CRXValidator {
- public:
- explicit CRXValidator(FILE* crx_file) : valid_(false), is_delta_(false) {
- crx_file::CrxFile::Header header;
- size_t len = fread(&header, 1, sizeof(header), crx_file);
- if (len < sizeof(header))
- return;
-
- crx_file::CrxFile::Error error;
- scoped_ptr<crx_file::CrxFile> crx(crx_file::CrxFile::Parse(header, &error));
- if (!crx.get())
- return;
- is_delta_ = crx_file::CrxFile::HeaderIsDelta(header);
-
- std::vector<uint8_t> key(header.key_size);
- len = fread(&key[0], sizeof(uint8_t), header.key_size, crx_file);
- if (len < header.key_size)
- return;
-
- std::vector<uint8_t> signature(header.signature_size);
- len =
- fread(&signature[0], sizeof(uint8_t), header.signature_size, crx_file);
- if (len < header.signature_size)
- return;
-
- crypto::SignatureVerifier verifier;
- if (!verifier.VerifyInit(
- crx_file::kSignatureAlgorithm,
- base::checked_cast<int>(sizeof(crx_file::kSignatureAlgorithm)),
- &signature[0], base::checked_cast<int>(signature.size()), &key[0],
- base::checked_cast<int>(key.size()))) {
- // Signature verification initialization failed. This is most likely
- // caused by a public key in the wrong format (should encode algorithm).
- return;
- }
-
- const size_t kBufSize = 8 * 1024;
- scoped_ptr<uint8_t[]> buf(new uint8_t[kBufSize]);
- while ((len = fread(buf.get(), 1, kBufSize, crx_file)) > 0)
- verifier.VerifyUpdate(buf.get(), base::checked_cast<int>(len));
-
- if (!verifier.VerifyFinal())
- return;
-
- public_key_.swap(key);
- valid_ = true;
- }
-
- bool valid() const { return valid_; }
-
- bool is_delta() const { return is_delta_; }
-
- const std::vector<uint8_t>& public_key() const { return public_key_; }
-
- private:
- bool valid_;
- bool is_delta_;
- std::vector<uint8_t> public_key_;
-};
-
-} // namespace
-
ComponentUnpacker::ComponentUnpacker(
const std::vector<uint8_t>& pk_hash,
const base::FilePath& path,
@@ -154,25 +90,24 @@ bool ComponentUnpacker::Verify() {
}
// First, validate the CRX header and signature. As of today
// this is SHA1 with RSA 1024.
- base::ScopedFILE file(base::OpenFile(path_, "rb"));
- if (!file.get()) {
- error_ = kInvalidFile;
- return false;
- }
- CRXValidator validator(file.get());
- file.reset();
- if (!validator.valid()) {
+ std::string public_key_bytes;
+ std::string public_key_base64;
+ CrxFile::Header header;
+ CrxFile::ValidateError error = CrxFile::ValidateSignature(
+ path_, std::string(), &public_key_base64, nullptr, &header);
+ if (error != CrxFile::ValidateError::NONE ||
+ !base::Base64Decode(public_key_base64, &public_key_bytes)) {
error_ = kInvalidFile;
return false;
}
- is_delta_ = validator.is_delta();
+ is_delta_ = CrxFile::HeaderIsDelta(header);
// File is valid and the digital signature matches. Now make sure
// the public key hash matches the expected hash. If they do we fully
// trust this CRX.
- uint8_t hash[32] = {};
+ uint8_t hash[crypto::kSHA256Length] = {};
scoped_ptr<SecureHash> sha256(SecureHash::Create(SecureHash::SHA256));
- sha256->Update(&(validator.public_key()[0]), validator.public_key().size());
+ sha256->Update(public_key_bytes.data(), public_key_bytes.size());
sha256->Finish(hash, arraysize(hash));
if (!std::equal(pk_hash_.begin(), pk_hash_.end(), hash)) {