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/verified_contents.h" | 5 #include "extensions/browser/verified_contents.h" |
6 | 6 |
7 #include "base/base64.h" | 7 #include "base/base64.h" |
8 #include "base/files/file_util.h" | 8 #include "base/files/file_util.h" |
9 #include "base/json/json_reader.h" | 9 #include "base/json/json_reader.h" |
10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 std::string key, | 53 std::string key, |
54 std::string value) { | 54 std::string value) { |
55 for (ListValue::const_iterator i = list->begin(); i != list->end(); ++i) { | 55 for (ListValue::const_iterator i = list->begin(); i != list->end(); ++i) { |
56 if (!(*i)->IsType(Value::TYPE_DICTIONARY)) | 56 if (!(*i)->IsType(Value::TYPE_DICTIONARY)) |
57 continue; | 57 continue; |
58 DictionaryValue* dictionary = static_cast<DictionaryValue*>(*i); | 58 DictionaryValue* dictionary = static_cast<DictionaryValue*>(*i); |
59 std::string found_value; | 59 std::string found_value; |
60 if (dictionary->GetString(key, &found_value) && found_value == value) | 60 if (dictionary->GetString(key, &found_value) && found_value == value) |
61 return dictionary; | 61 return dictionary; |
62 } | 62 } |
63 return NULL; | 63 return nullptr; |
64 } | 64 } |
65 | 65 |
66 } // namespace | 66 } // namespace |
67 | 67 |
68 namespace extensions { | 68 namespace extensions { |
69 | 69 |
70 // static | 70 // static |
71 bool VerifiedContents::FixupBase64Encoding(std::string* input) { | 71 bool VerifiedContents::FixupBase64Encoding(std::string* input) { |
72 for (std::string::iterator i = input->begin(); i != input->end(); ++i) { | 72 for (std::string::iterator i = input->begin(); i != input->end(); ++i) { |
73 if (*i == '-') | 73 if (*i == '-') |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 return false; | 136 return false; |
137 extension_id_ = item_id; | 137 extension_id_ = item_id; |
138 | 138 |
139 std::string version_string; | 139 std::string version_string; |
140 if (!dictionary->GetString(kItemVersionKey, &version_string)) | 140 if (!dictionary->GetString(kItemVersionKey, &version_string)) |
141 return false; | 141 return false; |
142 version_ = base::Version(version_string); | 142 version_ = base::Version(version_string); |
143 if (!version_.IsValid()) | 143 if (!version_.IsValid()) |
144 return false; | 144 return false; |
145 | 145 |
146 ListValue* hashes_list = NULL; | 146 ListValue* hashes_list = nullptr; |
147 if (!dictionary->GetList(kContentHashesKey, &hashes_list)) | 147 if (!dictionary->GetList(kContentHashesKey, &hashes_list)) |
148 return false; | 148 return false; |
149 | 149 |
150 for (size_t i = 0; i < hashes_list->GetSize(); i++) { | 150 for (size_t i = 0; i < hashes_list->GetSize(); i++) { |
151 DictionaryValue* hashes = NULL; | 151 DictionaryValue* hashes = nullptr; |
152 if (!hashes_list->GetDictionary(i, &hashes)) | 152 if (!hashes_list->GetDictionary(i, &hashes)) |
153 return false; | 153 return false; |
154 std::string format; | 154 std::string format; |
155 if (!hashes->GetString(kFormatKey, &format) || format != kTreeHash) | 155 if (!hashes->GetString(kFormatKey, &format) || format != kTreeHash) |
156 continue; | 156 continue; |
157 | 157 |
158 int block_size = 0; | 158 int block_size = 0; |
159 int hash_block_size = 0; | 159 int hash_block_size = 0; |
160 if (!hashes->GetInteger(kBlockSizeKey, &block_size) || | 160 if (!hashes->GetInteger(kBlockSizeKey, &block_size) || |
161 !hashes->GetInteger(kHashBlockSizeKey, &hash_block_size)) | 161 !hashes->GetInteger(kHashBlockSizeKey, &hash_block_size)) |
162 return false; | 162 return false; |
163 block_size_ = block_size; | 163 block_size_ = block_size; |
164 | 164 |
165 // We don't support using a different block_size and hash_block_size at | 165 // We don't support using a different block_size and hash_block_size at |
166 // the moment. | 166 // the moment. |
167 if (block_size_ != hash_block_size) | 167 if (block_size_ != hash_block_size) |
168 return false; | 168 return false; |
169 | 169 |
170 ListValue* files = NULL; | 170 ListValue* files = nullptr; |
171 if (!hashes->GetList(kFilesKey, &files)) | 171 if (!hashes->GetList(kFilesKey, &files)) |
172 return false; | 172 return false; |
173 | 173 |
174 for (size_t j = 0; j < files->GetSize(); j++) { | 174 for (size_t j = 0; j < files->GetSize(); j++) { |
175 DictionaryValue* data = NULL; | 175 DictionaryValue* data = nullptr; |
176 if (!files->GetDictionary(j, &data)) | 176 if (!files->GetDictionary(j, &data)) |
177 return false; | 177 return false; |
178 std::string file_path_string; | 178 std::string file_path_string; |
179 std::string encoded_root_hash; | 179 std::string encoded_root_hash; |
180 std::string root_hash; | 180 std::string root_hash; |
181 if (!data->GetString(kPathKey, &file_path_string) || | 181 if (!data->GetString(kPathKey, &file_path_string) || |
182 !base::IsStringUTF8(file_path_string) || | 182 !base::IsStringUTF8(file_path_string) || |
183 !data->GetString(kRootHashKey, &encoded_root_hash) || | 183 !data->GetString(kRootHashKey, &encoded_root_hash) || |
184 !FixupBase64Encoding(&encoded_root_hash) || | 184 !FixupBase64Encoding(&encoded_root_hash) || |
185 !base::Base64Decode(encoded_root_hash, &root_hash)) | 185 !base::Base64Decode(encoded_root_hash, &root_hash)) |
186 return false; | 186 return false; |
187 base::FilePath file_path = | 187 base::FilePath file_path = |
188 base::FilePath::FromUTF8Unsafe(file_path_string); | 188 base::FilePath::FromUTF8Unsafe(file_path_string); |
189 root_hashes_[file_path] = std::string(); | 189 root_hashes_[file_path] = std::string(); |
190 root_hashes_[file_path].swap(root_hash); | 190 root_hashes_[file_path].swap(root_hash); |
191 } | 191 } |
192 | 192 |
193 break; | 193 break; |
194 } | 194 } |
195 return true; | 195 return true; |
196 } | 196 } |
197 | 197 |
198 const std::string* VerifiedContents::GetTreeHashRoot( | 198 const std::string* VerifiedContents::GetTreeHashRoot( |
199 const base::FilePath& relative_path) { | 199 const base::FilePath& relative_path) { |
200 std::map<base::FilePath, std::string>::const_iterator i = | 200 std::map<base::FilePath, std::string>::const_iterator i = |
201 root_hashes_.find(relative_path.NormalizePathSeparatorsTo('/')); | 201 root_hashes_.find(relative_path.NormalizePathSeparatorsTo('/')); |
202 if (i == root_hashes_.end()) | 202 if (i == root_hashes_.end()) |
203 return NULL; | 203 return nullptr; |
204 return &i->second; | 204 return &i->second; |
205 } | 205 } |
206 | 206 |
207 // We're loosely following the "JSON Web Signature" draft spec for signing | 207 // We're loosely following the "JSON Web Signature" draft spec for signing |
208 // a JSON payload: | 208 // a JSON payload: |
209 // | 209 // |
210 // http://tools.ietf.org/html/draft-ietf-jose-json-web-signature-26 | 210 // http://tools.ietf.org/html/draft-ietf-jose-json-web-signature-26 |
211 // | 211 // |
212 // The idea is that you have some JSON that you want to sign, so you | 212 // The idea is that you have some JSON that you want to sign, so you |
213 // base64-encode that and put it as the "payload" field in a containing | 213 // base64-encode that and put it as the "payload" field in a containing |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
261 // { | 261 // { |
262 // "description": "treehash per file", | 262 // "description": "treehash per file", |
263 // "signed_content": { | 263 // "signed_content": { |
264 // "signatures": [ ... ], | 264 // "signatures": [ ... ], |
265 // "payload": "..." | 265 // "payload": "..." |
266 // } | 266 // } |
267 // } | 267 // } |
268 // ] | 268 // ] |
269 DictionaryValue* dictionary = | 269 DictionaryValue* dictionary = |
270 FindDictionaryWithValue(top_list, kDescriptionKey, kTreeHashPerFile); | 270 FindDictionaryWithValue(top_list, kDescriptionKey, kTreeHashPerFile); |
271 DictionaryValue* signed_content = NULL; | 271 DictionaryValue* signed_content = nullptr; |
272 if (!dictionary || | 272 if (!dictionary || |
273 !dictionary->GetDictionaryWithoutPathExpansion(kSignedContentKey, | 273 !dictionary->GetDictionaryWithoutPathExpansion(kSignedContentKey, |
274 &signed_content)) { | 274 &signed_content)) { |
275 return false; | 275 return false; |
276 } | 276 } |
277 | 277 |
278 ListValue* signatures = NULL; | 278 ListValue* signatures = nullptr; |
279 if (!signed_content->GetList(kSignaturesKey, &signatures)) | 279 if (!signed_content->GetList(kSignaturesKey, &signatures)) |
280 return false; | 280 return false; |
281 | 281 |
282 DictionaryValue* signature_dict = | 282 DictionaryValue* signature_dict = |
283 FindDictionaryWithValue(signatures, kHeaderKidKey, kWebstoreKId); | 283 FindDictionaryWithValue(signatures, kHeaderKidKey, kWebstoreKId); |
284 if (!signature_dict) | 284 if (!signature_dict) |
285 return false; | 285 return false; |
286 | 286 |
287 std::string protected_value; | 287 std::string protected_value; |
288 std::string encoded_signature; | 288 std::string encoded_signature; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 reinterpret_cast<const uint8*>(payload.data()), payload.size()); | 336 reinterpret_cast<const uint8*>(payload.data()), payload.size()); |
337 | 337 |
338 if (!signature_verifier.VerifyFinal()) { | 338 if (!signature_verifier.VerifyFinal()) { |
339 VLOG(1) << "Could not verify signature - VerifyFinal failure"; | 339 VLOG(1) << "Could not verify signature - VerifyFinal failure"; |
340 return false; | 340 return false; |
341 } | 341 } |
342 return true; | 342 return true; |
343 } | 343 } |
344 | 344 |
345 } // namespace extensions | 345 } // namespace extensions |
OLD | NEW |