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.h" | 5 #include "chrome/common/extensions/extension.h" |
6 | 6 |
7 #include "app/resource_bundle.h" | 7 #include "app/resource_bundle.h" |
8 #include "base/basictypes.h" | 8 #include "base/basictypes.h" |
9 #include "base/file_path.h" | 9 #include "base/file_path.h" |
10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
(...skipping 17 matching lines...) Expand all Loading... |
28 const int kPEMOutputColumns = 65; | 28 const int kPEMOutputColumns = 65; |
29 | 29 |
30 // KEY MARKERS | 30 // KEY MARKERS |
31 const char kKeyBeginHeaderMarker[] = "-----BEGIN"; | 31 const char kKeyBeginHeaderMarker[] = "-----BEGIN"; |
32 const char kKeyBeginFooterMarker[] = "-----END"; | 32 const char kKeyBeginFooterMarker[] = "-----END"; |
33 const char kKeyInfoEndMarker[] = "KEY-----"; | 33 const char kKeyInfoEndMarker[] = "KEY-----"; |
34 const char kPublic[] = "PUBLIC"; | 34 const char kPublic[] = "PUBLIC"; |
35 const char kPrivate[] = "PRIVATE"; | 35 const char kPrivate[] = "PRIVATE"; |
36 | 36 |
37 const int kRSAKeySize = 1024; | 37 const int kRSAKeySize = 1024; |
| 38 |
| 39 // Converts a normal hexadecimal string into the alphabet used by extensions. |
| 40 // We use the characters 'a'-'p' instead of '0'-'f' to avoid ever having a |
| 41 // completely numeric host, since some software interprets that as an IP |
| 42 // address. |
| 43 static void ConvertHexadecimalToIDAlphabet(std::string* id) { |
| 44 for (size_t i = 0; i < id->size(); ++i) |
| 45 (*id)[i] = HexStringToInt(id->substr(i, 1)) + 'a'; |
| 46 } |
38 }; | 47 }; |
39 | 48 |
40 int Extension::id_counter_ = 0; | 49 int Extension::id_counter_ = 0; |
41 | 50 |
42 const char Extension::kManifestFilename[] = "manifest.json"; | 51 const char Extension::kManifestFilename[] = "manifest.json"; |
43 | 52 |
44 const wchar_t* Extension::kBackgroundKey = L"background_page"; | 53 const wchar_t* Extension::kBackgroundKey = L"background_page"; |
45 const wchar_t* Extension::kContentScriptsKey = L"content_scripts"; | 54 const wchar_t* Extension::kContentScriptsKey = L"content_scripts"; |
46 const wchar_t* Extension::kCssKey = L"css"; | 55 const wchar_t* Extension::kCssKey = L"css"; |
47 const wchar_t* Extension::kDescriptionKey = L"description"; | 56 const wchar_t* Extension::kDescriptionKey = L"description"; |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 const char* Extension::kInvalidThemeTintsError = | 178 const char* Extension::kInvalidThemeTintsError = |
170 "Invalid value for theme images - tints must be decimal numbers."; | 179 "Invalid value for theme images - tints must be decimal numbers."; |
171 const char* Extension::kThemesCannotContainExtensionsError = | 180 const char* Extension::kThemesCannotContainExtensionsError = |
172 "A theme cannot contain extensions code."; | 181 "A theme cannot contain extensions code."; |
173 | 182 |
174 #if defined(OS_WIN) | 183 #if defined(OS_WIN) |
175 const char* Extension::kExtensionRegistryPath = | 184 const char* Extension::kExtensionRegistryPath = |
176 "Software\\Google\\Chrome\\Extensions"; | 185 "Software\\Google\\Chrome\\Extensions"; |
177 #endif | 186 #endif |
178 | 187 |
179 // first 20 bytes of SHA256 hashed public key. | 188 // first 16 bytes of SHA256 hashed public key. |
180 const size_t Extension::kIdSize = 20; | 189 const size_t Extension::kIdSize = 16; |
181 | 190 |
182 Extension::~Extension() { | 191 Extension::~Extension() { |
183 for (PageActionMap::iterator i = page_actions_.begin(); | 192 for (PageActionMap::iterator i = page_actions_.begin(); |
184 i != page_actions_.end(); ++i) | 193 i != page_actions_.end(); ++i) |
185 delete i->second; | 194 delete i->second; |
186 } | 195 } |
187 | 196 |
188 const std::string Extension::VersionString() const { | 197 const std::string Extension::VersionString() const { |
189 return version_->GetString(); | 198 return version_->GetString(); |
190 } | 199 } |
191 | 200 |
192 // static | 201 // static |
193 bool Extension::IdIsValid(const std::string& id) { | 202 bool Extension::IdIsValid(const std::string& id) { |
194 // Verify that the id is legal. The id is a hex string of the SHA-1 hash of | 203 // Verify that the id is legal. |
195 // the public key. | 204 if (id.size() != (kIdSize * 2)) |
196 std::vector<uint8> id_bytes; | |
197 if (!HexStringToBytes(id, &id_bytes) || id_bytes.size() != kIdSize) | |
198 return false; | 205 return false; |
199 | 206 |
200 // We only support lowercase IDs, because IDs can be used as URL components | 207 // We only support lowercase IDs, because IDs can be used as URL components |
201 // (where GURL will lowercase it). | 208 // (where GURL will lowercase it). |
202 std::string temp = id; | 209 std::string temp = StringToLowerASCII(id); |
203 StringToLowerASCII(temp); | 210 for (size_t i = 0; i < temp.size(); i++) |
204 if (temp != id) | 211 if (temp[i] < 'a' || temp[i] > 'p') |
205 return false; | 212 return false; |
206 | 213 |
207 return true; | 214 return true; |
208 } | 215 } |
209 | 216 |
210 // static | 217 // static |
211 GURL Extension::GetResourceURL(const GURL& extension_url, | 218 GURL Extension::GetResourceURL(const GURL& extension_url, |
212 const std::string& relative_path) { | 219 const std::string& relative_path) { |
213 DCHECK(extension_url.SchemeIs(chrome::kExtensionScheme)); | 220 DCHECK(extension_url.SchemeIs(chrome::kExtensionScheme)); |
214 DCHECK(extension_url.path() == "/"); | 221 DCHECK(extension_url.path() == "/"); |
215 | 222 |
(...skipping 30 matching lines...) Expand all Loading... |
246 if (input.length() == 0) | 253 if (input.length() == 0) |
247 return false; | 254 return false; |
248 | 255 |
249 const uint8* ubuf = reinterpret_cast<const unsigned char*>(input.data()); | 256 const uint8* ubuf = reinterpret_cast<const unsigned char*>(input.data()); |
250 SHA256Context ctx; | 257 SHA256Context ctx; |
251 SHA256_Begin(&ctx); | 258 SHA256_Begin(&ctx); |
252 SHA256_Update(&ctx, ubuf, input.length()); | 259 SHA256_Update(&ctx, ubuf, input.length()); |
253 uint8 hash[Extension::kIdSize]; | 260 uint8 hash[Extension::kIdSize]; |
254 SHA256_End(&ctx, hash, NULL, sizeof(hash)); | 261 SHA256_End(&ctx, hash, NULL, sizeof(hash)); |
255 *output = StringToLowerASCII(HexEncode(hash, sizeof(hash))); | 262 *output = StringToLowerASCII(HexEncode(hash, sizeof(hash))); |
| 263 ConvertHexadecimalToIDAlphabet(output); |
256 | 264 |
257 return true; | 265 return true; |
258 } | 266 } |
259 | 267 |
260 // Helper method that loads a UserScript object from a dictionary in the | 268 // Helper method that loads a UserScript object from a dictionary in the |
261 // content_script list of the manifest. | 269 // content_script list of the manifest. |
262 bool Extension::LoadUserScriptHelper(const DictionaryValue* content_script, | 270 bool Extension::LoadUserScriptHelper(const DictionaryValue* content_script, |
263 int definition_index, std::string* error, | 271 int definition_index, std::string* error, |
264 UserScript* result) { | 272 UserScript* result) { |
265 // run_at | 273 // run_at |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
602 } | 610 } |
603 } else if (require_id) { | 611 } else if (require_id) { |
604 *error = kInvalidKeyError; | 612 *error = kInvalidKeyError; |
605 return false; | 613 return false; |
606 } else { | 614 } else { |
607 // Generate a random ID | 615 // Generate a random ID |
608 id_ = StringPrintf("%x", NextGeneratedId()); | 616 id_ = StringPrintf("%x", NextGeneratedId()); |
609 | 617 |
610 // pad the string out to kIdSize*2 chars with zeroes. | 618 // pad the string out to kIdSize*2 chars with zeroes. |
611 id_.insert(0, Extension::kIdSize*2 - id_.length(), '0'); | 619 id_.insert(0, Extension::kIdSize*2 - id_.length(), '0'); |
| 620 |
| 621 // Convert to our mp-decimal. |
| 622 ConvertHexadecimalToIDAlphabet(&id_); |
612 } | 623 } |
613 | 624 |
614 // Initialize the URL. | 625 // Initialize the URL. |
615 extension_url_ = GURL(std::string(chrome::kExtensionScheme) + | 626 extension_url_ = GURL(std::string(chrome::kExtensionScheme) + |
616 chrome::kStandardSchemeSeparator + id_ + "/"); | 627 chrome::kStandardSchemeSeparator + id_ + "/"); |
617 | 628 |
618 // Initialize version. | 629 // Initialize version. |
619 std::string version_str; | 630 std::string version_str; |
620 if (!source.GetString(kVersionKey, &version_str)) { | 631 if (!source.GetString(kVersionKey, &version_str)) { |
621 *error = kInvalidVersionError; | 632 *error = kInvalidVersionError; |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
914 } | 925 } |
915 } | 926 } |
916 | 927 |
917 for (PageActionMap::const_iterator it = page_actions().begin(); | 928 for (PageActionMap::const_iterator it = page_actions().begin(); |
918 it != page_actions().end(); ++it) { | 929 it != page_actions().end(); ++it) { |
919 image_paths.insert(it->second->icon_path()); | 930 image_paths.insert(it->second->icon_path()); |
920 } | 931 } |
921 | 932 |
922 return image_paths; | 933 return image_paths; |
923 } | 934 } |
OLD | NEW |