OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "chrome/common/extensions/extension_unpacker.h" | 5 #include "chrome/common/extensions/extension_unpacker.h" |
6 | 6 |
7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
8 #include "base/scoped_handle.h" | 8 #include "base/scoped_handle.h" |
9 #include "base/scoped_temp_dir.h" | 9 #include "base/scoped_temp_dir.h" |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 if (!val.get()) { | 141 if (!val.get()) { |
142 SetError(error); | 142 SetError(error); |
143 return NULL; | 143 return NULL; |
144 } | 144 } |
145 if (!val->IsType(Value::TYPE_DICTIONARY)) { | 145 if (!val->IsType(Value::TYPE_DICTIONARY)) { |
146 SetError("manifest isn't a JSON dictionary"); | 146 SetError("manifest isn't a JSON dictionary"); |
147 return NULL; | 147 return NULL; |
148 } | 148 } |
149 DictionaryValue* manifest = static_cast<DictionaryValue*>(val.get()); | 149 DictionaryValue* manifest = static_cast<DictionaryValue*>(val.get()); |
150 | 150 |
151 std::string zip_hash; | |
152 if (!manifest->GetString(Extension::kZipHashKey, &zip_hash)) { | |
153 SetError("missing zip_hash key"); | |
154 return NULL; | |
155 } | |
156 if (zip_hash.size() != kZipHashHexBytes) { | |
157 SetError("invalid zip_hash key"); | |
158 return NULL; | |
159 } | |
160 | |
161 // Read the rest of the zip file and compute a hash to compare against | |
162 // what the manifest claims. Compute the hash incrementally since the | |
163 // zip file could be large. | |
164 const unsigned char* ubuf = reinterpret_cast<const unsigned char*>(buf); | |
165 SHA256Context ctx; | |
166 SHA256_Begin(&ctx); | |
167 while ((len = fread(buf, 1, sizeof(buf), file.get())) > 0) | |
168 SHA256_Update(&ctx, ubuf, len); | |
169 uint8 hash[32]; | |
170 SHA256_End(&ctx, hash, NULL, sizeof(hash)); | |
171 | |
172 std::vector<uint8> zip_hash_bytes; | |
173 if (!HexStringToBytes(zip_hash, &zip_hash_bytes)) { | |
174 SetError("invalid zip_hash key"); | |
175 return NULL; | |
176 } | |
177 if (zip_hash_bytes.size() != kZipHashBytes) { | |
178 SetError("invalid zip_hash key"); | |
179 return NULL; | |
180 } | |
181 for (size_t i = 0; i < kZipHashBytes; ++i) { | |
182 if (zip_hash_bytes[i] != hash[i]) { | |
183 SetError("zip_hash key didn't match zip hash"); | |
184 return NULL; | |
185 } | |
186 } | |
187 | |
188 // TODO(erikkay): The manifest will also contain a signature of the hash | 151 // TODO(erikkay): The manifest will also contain a signature of the hash |
189 // (or perhaps the whole manifest) for authentication purposes. | 152 // (or perhaps the whole manifest) for authentication purposes. |
190 | 153 |
191 // The caller owns val (now cast to manifest). | 154 // The caller owns val (now cast to manifest). |
192 val.release(); | 155 val.release(); |
193 return manifest; | 156 return manifest; |
194 } | 157 } |
195 | 158 |
196 DictionaryValue* ExtensionUnpacker::ReadManifest() { | 159 DictionaryValue* ExtensionUnpacker::ReadManifest() { |
197 FilePath manifest_path = | 160 FilePath manifest_path = |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 return false; | 279 return false; |
317 } | 280 } |
318 | 281 |
319 decoded_images_.push_back(MakeTuple(image_bitmap, path)); | 282 decoded_images_.push_back(MakeTuple(image_bitmap, path)); |
320 return true; | 283 return true; |
321 } | 284 } |
322 | 285 |
323 void ExtensionUnpacker::SetError(const std::string &error) { | 286 void ExtensionUnpacker::SetError(const std::string &error) { |
324 error_message_ = error; | 287 error_message_ = error; |
325 } | 288 } |
OLD | NEW |