diff options
author | asargent@chromium.org <asargent@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-15 17:00:52 +0000 |
---|---|---|
committer | asargent@chromium.org <asargent@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-15 17:00:52 +0000 |
commit | 620f3e50bdbb11cf69dd239b5a976fcdf0d2dade (patch) | |
tree | bba45635583c93f799d82b4750a6210fcd5a72fe /extensions/browser/content_hash_reader.cc | |
parent | 8e3a653ada2c5c2fc78d7d9b9ef48f07a66beb71 (diff) | |
download | chromium_src-620f3e50bdbb11cf69dd239b5a976fcdf0d2dade.zip chromium_src-620f3e50bdbb11cf69dd239b5a976fcdf0d2dade.tar.gz chromium_src-620f3e50bdbb11cf69dd239b5a976fcdf0d2dade.tar.bz2 |
A bunch of remaining parts of extension content verification
-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
BUG=369895
R=rockot@chromium.org
Review URL: https://codereview.chromium.org/289533003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@270694 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'extensions/browser/content_hash_reader.cc')
-rw-r--r-- | extensions/browser/content_hash_reader.cc | 74 |
1 files changed, 70 insertions, 4 deletions
diff --git a/extensions/browser/content_hash_reader.cc b/extensions/browser/content_hash_reader.cc index 9a327ac..cc923ad 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,77 @@ 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)) { + verified_contents_.reset(new VerifiedContents(key_.data, key_.size)); + // TODO(asargent) - we need to switch on signature validation. + // (crbug.com/369895) + if (!verified_contents_->InitFrom(verified_contents_path, + true /* ignore invalid signature */)) { + verified_contents_.reset(); + } else { + if (!verified_contents_->valid_signature()) { + // Reminder to fix the TODO above. + LOG(WARNING) << "Temporarily ignoring invalid signature!"; + } + if (verified_contents_->extension_id() != extension_id_ || + !verified_contents_->version().Equals(extension_version_)) + return false; + } + } + + ComputedHashes::Reader reader; + if (!reader.InitFromFile(file_util::GetComputedHashesPath(extension_root_)) || + !reader.GetHashes(relative_path_, &block_size_, &hashes_) || + block_size_ % crypto::kSHA256Length != 0) + return false; + + std::string root = + ComputeTreeHashRoot(hashes_, block_size_ / crypto::kSHA256Length); + const std::string* expected_root = NULL; + if (verified_contents_.get()) + expected_root = verified_contents_->GetTreeHashRoot(relative_path_); + if (expected_root && *expected_root != root) + 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 |