• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3 // found in the LICENSE file.
4 
5 #include "extensions/browser/content_hash_reader.h"
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 
23 namespace extensions {
24 
ContentHashReader(const std::string & extension_id,const base::Version & extension_version,const base::FilePath & extension_root,const base::FilePath & relative_path,const ContentVerifierKey & key)25 ContentHashReader::ContentHashReader(const std::string& extension_id,
26                                      const base::Version& extension_version,
27                                      const base::FilePath& extension_root,
28                                      const base::FilePath& relative_path,
29                                      const ContentVerifierKey& key)
30     : extension_id_(extension_id),
31       extension_version_(extension_version.GetString()),
32       extension_root_(extension_root),
33       relative_path_(relative_path),
34       key_(key),
35       status_(NOT_INITIALIZED),
36       have_verified_contents_(false),
37       have_computed_hashes_(false),
38       block_size_(0) {
39 }
40 
~ContentHashReader()41 ContentHashReader::~ContentHashReader() {
42 }
43 
Init()44 bool ContentHashReader::Init() {
45   DCHECK_EQ(status_, NOT_INITIALIZED);
46   status_ = FAILURE;
47   base::FilePath verified_contents_path =
48       file_util::GetVerifiedContentsPath(extension_root_);
49 
50   if (!base::PathExists(verified_contents_path))
51     return false;
52 
53   verified_contents_.reset(new VerifiedContents(key_.data, key_.size));
54   if (!verified_contents_->InitFrom(verified_contents_path, false) ||
55       !verified_contents_->valid_signature() ||
56       !verified_contents_->version().Equals(extension_version_) ||
57       verified_contents_->extension_id() != extension_id_)
58     return false;
59 
60   have_verified_contents_ = true;
61 
62   base::FilePath computed_hashes_path =
63       file_util::GetComputedHashesPath(extension_root_);
64   if (!base::PathExists(computed_hashes_path))
65     return false;
66 
67   ComputedHashes::Reader reader;
68   if (!reader.InitFromFile(computed_hashes_path))
69     return false;
70 
71   have_computed_hashes_ = true;
72 
73   if (!reader.GetHashes(relative_path_, &block_size_, &hashes_) ||
74       block_size_ % crypto::kSHA256Length != 0)
75     return false;
76 
77   const std::string* expected_root =
78       verified_contents_->GetTreeHashRoot(relative_path_);
79   if (!expected_root)
80     return false;
81 
82   std::string root =
83       ComputeTreeHashRoot(hashes_, block_size_ / crypto::kSHA256Length);
84   if (*expected_root != root)
85     return false;
86 
87   status_ = SUCCESS;
88   return true;
89 }
90 
block_count() const91 int ContentHashReader::block_count() const {
92   DCHECK(status_ != NOT_INITIALIZED);
93   return hashes_.size();
94 }
95 
block_size() const96 int ContentHashReader::block_size() const {
97   DCHECK(status_ != NOT_INITIALIZED);
98   return block_size_;
99 }
100 
GetHashForBlock(int block_index,const std::string ** result) const101 bool ContentHashReader::GetHashForBlock(int block_index,
102                                         const std::string** result) const {
103   if (status_ != SUCCESS)
104     return false;
105   DCHECK(block_index >= 0);
106 
107   if (static_cast<unsigned>(block_index) >= hashes_.size())
108     return false;
109   *result = &hashes_[block_index];
110 
111   return true;
112 }
113 
114 }  // namespace extensions
115