Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "extensions/browser/content_hash_reader.h" | 5 #include "extensions/browser/content_hash_reader.h" |
| 6 | 6 |
| 7 #include "base/base64.h" | |
| 8 #include "base/file_util.h" | |
| 9 #include "base/json/json_reader.h" | |
| 10 #include "base/strings/string_util.h" | |
| 11 #include "base/values.h" | |
| 12 #include "crypto/sha2.h" | |
| 13 #include "extensions/browser/computed_hashes.h" | |
| 14 #include "extensions/browser/content_hash_tree.h" | |
| 15 #include "extensions/browser/verified_contents.h" | |
| 16 #include "extensions/common/extension.h" | |
| 17 #include "extensions/common/file_util.h" | |
| 18 | |
| 19 using base::DictionaryValue; | |
| 20 using base::ListValue; | |
| 21 using base::Value; | |
| 22 | |
| 7 namespace extensions { | 23 namespace extensions { |
| 8 | 24 |
| 9 ContentHashReader::ContentHashReader(const std::string& extension_id, | 25 ContentHashReader::ContentHashReader(const std::string& extension_id, |
| 10 const base::Version& extension_version, | 26 const base::Version& extension_version, |
| 11 const base::FilePath& extension_root, | 27 const base::FilePath& extension_root, |
| 12 const base::FilePath& relative_path, | 28 const base::FilePath& relative_path, |
| 13 const ContentVerifierKey& key) | 29 const ContentVerifierKey& key) |
| 14 : extension_id_(extension_id), | 30 : extension_id_(extension_id), |
| 15 extension_version_(extension_version.GetString()), | 31 extension_version_(extension_version.GetString()), |
| 16 extension_root_(extension_root), | 32 extension_root_(extension_root), |
| 17 relative_path_(relative_path), | 33 relative_path_(relative_path), |
| 18 key_(key) { | 34 key_(key), |
| 35 status_(NOT_INITIALIZED), | |
| 36 block_size_(0) { | |
| 19 } | 37 } |
| 20 | 38 |
| 21 ContentHashReader::~ContentHashReader() { | 39 ContentHashReader::~ContentHashReader() { |
| 22 } | 40 } |
| 23 | 41 |
| 24 bool ContentHashReader::Init() { | 42 bool ContentHashReader::Init() { |
| 43 DCHECK_EQ(status_, NOT_INITIALIZED); | |
| 44 status_ = FAILURE; | |
| 45 base::FilePath verified_contents_path = | |
| 46 file_util::GetVerifiedContentsPath(extension_root_); | |
| 47 | |
| 48 if (base::PathExists(verified_contents_path)) { | |
| 49 verified_contents_.reset(new VerifiedContents(key_.data, key_.size)); | |
| 50 // TODO(asargent) - we need to switch on signature validation. | |
| 51 // (crbug.com/369895) | |
| 52 if (!verified_contents_->InitFrom(verified_contents_path, | |
| 53 true /* ignore invalid signature */)) { | |
| 54 verified_contents_.reset(); | |
| 55 } else { | |
| 56 if (!verified_contents_->valid_signature()) { | |
| 57 // Reminder to fix the TODO above. | |
| 58 LOG(WARNING) << "Temporarily ignoring invalid signature!"; | |
| 59 } | |
| 60 if (verified_contents_->extension_id() != extension_id_ || | |
| 61 !verified_contents_->version().Equals(extension_version_)) | |
| 62 return false; | |
| 63 } | |
| 64 } | |
| 65 | |
| 66 ComputedHashes::Reader reader; | |
| 67 if (!reader.InitFromFile(file_util::GetComputedHashesPath(extension_root_)) || | |
| 68 !reader.GetHashes(relative_path_, &block_size_, &hashes_) || | |
| 69 block_size_ % crypto::kSHA256Length != 0) | |
| 70 return false; | |
| 71 | |
| 72 std::string root = | |
| 73 ComputeTreeHashRoot(hashes_, block_size_ / crypto::kSHA256Length); | |
| 74 const std::string* expected_root = NULL; | |
| 75 if (verified_contents_.get()) | |
| 76 expected_root = verified_contents_->GetTreeHashRoot(relative_path_); | |
| 77 if (expected_root && *expected_root != root) | |
| 78 return false; | |
| 79 | |
| 80 status_ = SUCCESS; | |
| 25 return true; | 81 return true; |
| 26 } | 82 } |
| 27 | 83 |
| 28 int ContentHashReader::block_count() const { | 84 int ContentHashReader::block_count() const { |
| 29 return 0; | 85 DCHECK(status_ != NOT_INITIALIZED); |
| 86 return hashes_.size(); | |
| 30 } | 87 } |
| 31 | 88 |
| 32 int ContentHashReader::block_size() const { | 89 int ContentHashReader::block_size() const { |
| 33 return 0; | 90 DCHECK(status_ != NOT_INITIALIZED); |
| 91 return block_size_; | |
| 34 } | 92 } |
| 35 | 93 |
| 36 bool ContentHashReader::GetHashForBlock(int block_index, | 94 bool ContentHashReader::GetHashForBlock(int block_index, |
| 37 const std::string** result) const { | 95 const std::string** result) const { |
| 38 return false; | 96 if (status_ != SUCCESS) |
| 97 return false; | |
| 98 | |
|
Ken Rockot(use gerrit already)
2014/05/15 00:51:25
nit: Maybe worth a DCHECK(block_index >= 0)
asargent_no_longer_on_chrome
2014/05/15 04:02:49
Done.
| |
| 99 if (static_cast<unsigned>(block_index) >= hashes_.size()) | |
| 100 return false; | |
| 101 *result = &hashes_[block_index]; | |
| 102 | |
| 103 return true; | |
| 39 } | 104 } |
| 40 | 105 |
| 41 } // namespace extensions | 106 } // namespace extensions |
| OLD | NEW |