diff options
author | asargent@chromium.org <asargent@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-16 05:22:56 +0000 |
---|---|---|
committer | asargent@chromium.org <asargent@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-16 05:22:56 +0000 |
commit | abd4cb2a97c4a40bde722099b196178f439edf4d (patch) | |
tree | b104fe77cf8a869ab1e0c4af16e3fa7f412f1609 /extensions/browser/content_hash_reader.cc | |
parent | 3ec0c24c6058c6f417d9fe41b3ce1fd5afd52086 (diff) | |
download | chromium_src-abd4cb2a97c4a40bde722099b196178f439edf4d.zip chromium_src-abd4cb2a97c4a40bde722099b196178f439edf4d.tar.gz chromium_src-abd4cb2a97c4a40bde722099b196178f439edf4d.tar.bz2 |
A bunch of remaining parts of extension content verification (Reland)
-The real guts of content_hash_fetcher.cc, which fetches the
verified_contents.json file from the webstore if needed and also runs
tasks to compute and cache the block-level hashes of all files in an
extension.
-The real guts of content_hash_reader.cc, which uses the work done by
the content_hash_fetcher during validation of extension file content as
it's read off of disk at time of use.
-Code to avoid verifying transcoded files (images used in browser
process, and message catalogs).
-Don't allow downgrade of mode via kForceFieldTrials command line switch
-Various bits of plumbing to support all of the above
This is a re-land with fixes; original review was:
https://codereview.chromium.org/289533003
BUG=369895,373854
R=rockot@chromium.org
Review URL: https://codereview.chromium.org/288273004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@270937 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'extensions/browser/content_hash_reader.cc')
-rw-r--r-- | extensions/browser/content_hash_reader.cc | 76 |
1 files changed, 72 insertions, 4 deletions
diff --git a/extensions/browser/content_hash_reader.cc b/extensions/browser/content_hash_reader.cc index 9a327ac..06c8ef0 100644 --- a/extensions/browser/content_hash_reader.cc +++ b/extensions/browser/content_hash_reader.cc @@ -4,6 +4,22 @@ #include "extensions/browser/content_hash_reader.h" +#include "base/base64.h" +#include "base/file_util.h" +#include "base/json/json_reader.h" +#include "base/strings/string_util.h" +#include "base/values.h" +#include "crypto/sha2.h" +#include "extensions/browser/computed_hashes.h" +#include "extensions/browser/content_hash_tree.h" +#include "extensions/browser/verified_contents.h" +#include "extensions/common/extension.h" +#include "extensions/common/file_util.h" + +using base::DictionaryValue; +using base::ListValue; +using base::Value; + namespace extensions { ContentHashReader::ContentHashReader(const std::string& extension_id, @@ -15,27 +31,79 @@ ContentHashReader::ContentHashReader(const std::string& extension_id, extension_version_(extension_version.GetString()), extension_root_(extension_root), relative_path_(relative_path), - key_(key) { + key_(key), + status_(NOT_INITIALIZED), + block_size_(0) { } ContentHashReader::~ContentHashReader() { } bool ContentHashReader::Init() { + DCHECK_EQ(status_, NOT_INITIALIZED); + status_ = FAILURE; + base::FilePath verified_contents_path = + file_util::GetVerifiedContentsPath(extension_root_); + + if (!base::PathExists(verified_contents_path)) + return false; + + verified_contents_.reset(new VerifiedContents(key_.data, key_.size)); + if (!verified_contents_->InitFrom(verified_contents_path, false) || + !verified_contents_->valid_signature() || + !verified_contents_->version().Equals(extension_version_) || + verified_contents_->extension_id() != extension_id_) { + base::DeleteFile(verified_contents_path, false /* recursive */); + return false; + } + + base::FilePath computed_hashes_path = + file_util::GetComputedHashesPath(extension_root_); + if (!base::PathExists(computed_hashes_path)) + return false; + + ComputedHashes::Reader reader; + if (!reader.InitFromFile(computed_hashes_path) || + !reader.GetHashes(relative_path_, &block_size_, &hashes_) || + block_size_ % crypto::kSHA256Length != 0) { + base::DeleteFile(computed_hashes_path, false /* recursive */); + return false; + } + + std::string root = + ComputeTreeHashRoot(hashes_, block_size_ / crypto::kSHA256Length); + const std::string* expected_root = NULL; + expected_root = verified_contents_->GetTreeHashRoot(relative_path_); + if (expected_root && *expected_root != root) { + base::DeleteFile(computed_hashes_path, false /* recursive */); + return false; + } + + status_ = SUCCESS; return true; } int ContentHashReader::block_count() const { - return 0; + DCHECK(status_ != NOT_INITIALIZED); + return hashes_.size(); } int ContentHashReader::block_size() const { - return 0; + DCHECK(status_ != NOT_INITIALIZED); + return block_size_; } bool ContentHashReader::GetHashForBlock(int block_index, const std::string** result) const { - return false; + if (status_ != SUCCESS) + return false; + DCHECK(block_index >= 0); + + if (static_cast<unsigned>(block_index) >= hashes_.size()) + return false; + *result = &hashes_[block_index]; + + return true; } } // namespace extensions |