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/file_path.h" | 9 #include "base/file_path.h" |
9 #include "base/file_util.h" | 10 #include "base/file_util.h" |
10 #include "base/logging.h" | 11 #include "base/logging.h" |
11 #include "base/string_util.h" | 12 #include "base/string_util.h" |
| 13 #include "base/third_party/nss/blapi.h" |
| 14 #include "base/third_party/nss/sha256.h" |
| 15 #include "net/base/base64.h" |
12 #include "net/base/net_util.h" | 16 #include "net/base/net_util.h" |
13 #include "chrome/common/extensions/extension_error_reporter.h" | 17 #include "chrome/common/extensions/extension_error_reporter.h" |
14 #include "chrome/common/extensions/extension_error_utils.h" | 18 #include "chrome/common/extensions/extension_error_utils.h" |
15 #include "chrome/common/extensions/user_script.h" | 19 #include "chrome/common/extensions/user_script.h" |
16 #include "chrome/common/url_constants.h" | 20 #include "chrome/common/url_constants.h" |
17 #include "net/base/base64.h" | 21 #include "net/base/base64.h" |
18 | 22 |
19 #if defined(OS_WIN) | 23 #if defined(OS_WIN) |
20 #include "base/registry.h" | 24 #include "base/registry.h" |
21 #endif | 25 #endif |
22 | 26 |
23 namespace { | 27 namespace { |
24 const int kPEMOutputColumns = 65; | 28 const int kPEMOutputColumns = 65; |
25 | 29 |
26 // KEY MARKERS | 30 // KEY MARKERS |
27 const char kKeyBeginHeaderMarker[] = "-----BEGIN"; | 31 const char kKeyBeginHeaderMarker[] = "-----BEGIN"; |
28 const char kKeyBeginFooterMarker[] = "-----END"; | 32 const char kKeyBeginFooterMarker[] = "-----END"; |
29 const char kKeyInfoEndMarker[] = "KEY-----"; | 33 const char kKeyInfoEndMarker[] = "KEY-----"; |
30 const char kPublic[] = "PUBLIC"; | 34 const char kPublic[] = "PUBLIC"; |
31 const char kPrivate[] = "PRIVATE"; | 35 const char kPrivate[] = "PRIVATE"; |
32 | 36 |
33 const int kRSAKeySize = 1024; | 37 const int kRSAKeySize = 1024; |
34 }; | 38 }; |
35 | 39 |
| 40 int Extension::id_counter_ = 0; |
| 41 |
36 const char Extension::kManifestFilename[] = "manifest.json"; | 42 const char Extension::kManifestFilename[] = "manifest.json"; |
37 | 43 |
38 const wchar_t* Extension::kBackgroundKey = L"background_page"; | 44 const wchar_t* Extension::kBackgroundKey = L"background_page"; |
39 const wchar_t* Extension::kContentScriptsKey = L"content_scripts"; | 45 const wchar_t* Extension::kContentScriptsKey = L"content_scripts"; |
40 const wchar_t* Extension::kCssKey = L"css"; | 46 const wchar_t* Extension::kCssKey = L"css"; |
41 const wchar_t* Extension::kDescriptionKey = L"description"; | 47 const wchar_t* Extension::kDescriptionKey = L"description"; |
42 const wchar_t* Extension::kIconPathKey = L"icon"; | 48 const wchar_t* Extension::kIconPathKey = L"icon"; |
43 const wchar_t* Extension::kIdKey = L"id"; | |
44 const wchar_t* Extension::kJsKey = L"js"; | 49 const wchar_t* Extension::kJsKey = L"js"; |
45 const wchar_t* Extension::kMatchesKey = L"matches"; | 50 const wchar_t* Extension::kMatchesKey = L"matches"; |
46 const wchar_t* Extension::kNameKey = L"name"; | 51 const wchar_t* Extension::kNameKey = L"name"; |
| 52 const wchar_t* Extension::kPageActionIdKey = L"id"; |
47 const wchar_t* Extension::kPageActionsKey = L"page_actions"; | 53 const wchar_t* Extension::kPageActionsKey = L"page_actions"; |
48 const wchar_t* Extension::kPermissionsKey = L"permissions"; | 54 const wchar_t* Extension::kPermissionsKey = L"permissions"; |
49 const wchar_t* Extension::kPluginsKey = L"plugins"; | 55 const wchar_t* Extension::kPluginsKey = L"plugins"; |
50 const wchar_t* Extension::kPluginsPathKey = L"path"; | 56 const wchar_t* Extension::kPluginsPathKey = L"path"; |
51 const wchar_t* Extension::kPluginsPublicKey = L"public"; | 57 const wchar_t* Extension::kPluginsPublicKey = L"public"; |
52 const wchar_t* Extension::kPublicKeyKey = L"key"; | 58 const wchar_t* Extension::kPublicKeyKey = L"key"; |
53 const wchar_t* Extension::kRunAtKey = L"run_at"; | 59 const wchar_t* Extension::kRunAtKey = L"run_at"; |
54 const wchar_t* Extension::kSignatureKey = L"signature"; | 60 const wchar_t* Extension::kSignatureKey = L"signature"; |
55 const wchar_t* Extension::kThemeKey = L"theme"; | 61 const wchar_t* Extension::kThemeKey = L"theme"; |
56 const wchar_t* Extension::kThemeImagesKey = L"images"; | 62 const wchar_t* Extension::kThemeImagesKey = L"images"; |
57 const wchar_t* Extension::kThemeColorsKey = L"colors"; | 63 const wchar_t* Extension::kThemeColorsKey = L"colors"; |
58 const wchar_t* Extension::kThemeTintsKey = L"tints"; | 64 const wchar_t* Extension::kThemeTintsKey = L"tints"; |
59 const wchar_t* Extension::kThemeDisplayPropertiesKey = L"properties"; | 65 const wchar_t* Extension::kThemeDisplayPropertiesKey = L"properties"; |
60 const wchar_t* Extension::kToolstripsKey = L"toolstrips"; | 66 const wchar_t* Extension::kToolstripsKey = L"toolstrips"; |
61 const wchar_t* Extension::kTooltipKey = L"tooltip"; | 67 const wchar_t* Extension::kTooltipKey = L"tooltip"; |
62 const wchar_t* Extension::kTypeKey = L"type"; | 68 const wchar_t* Extension::kTypeKey = L"type"; |
63 const wchar_t* Extension::kVersionKey = L"version"; | 69 const wchar_t* Extension::kVersionKey = L"version"; |
64 | 70 |
65 const char* Extension::kRunAtDocumentStartValue = "document_start"; | 71 const char* Extension::kRunAtDocumentStartValue = "document_start"; |
66 const char* Extension::kRunAtDocumentEndValue = "document_end"; | 72 const char* Extension::kRunAtDocumentEndValue = "document_end"; |
67 const char* Extension::kPageActionTypeTab = "tab"; | 73 const char* Extension::kPageActionTypeTab = "tab"; |
68 const char* Extension::kPageActionTypePermanent = "permanent"; | 74 const char* Extension::kPageActionTypePermanent = "permanent"; |
69 | 75 |
70 // A list of all the keys allowed by themes. | 76 // A list of all the keys allowed by themes. |
71 static const wchar_t* kValidThemeKeys[] = { | 77 static const wchar_t* kValidThemeKeys[] = { |
72 Extension::kDescriptionKey, | 78 Extension::kDescriptionKey, |
73 Extension::kIconPathKey, | 79 Extension::kIconPathKey, |
74 Extension::kIdKey, | |
75 Extension::kNameKey, | 80 Extension::kNameKey, |
76 Extension::kPublicKeyKey, | 81 Extension::kPublicKeyKey, |
77 Extension::kSignatureKey, | 82 Extension::kSignatureKey, |
78 Extension::kThemeKey, | 83 Extension::kThemeKey, |
79 Extension::kVersionKey | 84 Extension::kVersionKey |
80 }; | 85 }; |
81 | 86 |
82 // Extension-related error messages. Some of these are simple patterns, where a | 87 // Extension-related error messages. Some of these are simple patterns, where a |
83 // '*' is replaced at runtime with a specific value. This is used instead of | 88 // '*' is replaced at runtime with a specific value. This is used instead of |
84 // printf because we want to unit test them and scanf is hard to make | 89 // printf because we want to unit test them and scanf is hard to make |
85 // cross-platform. | 90 // cross-platform. |
86 const char* Extension::kInvalidContentScriptError = | 91 const char* Extension::kInvalidContentScriptError = |
87 "Invalid value for 'content_scripts[*]'."; | 92 "Invalid value for 'content_scripts[*]'."; |
88 const char* Extension::kInvalidContentScriptsListError = | 93 const char* Extension::kInvalidContentScriptsListError = |
89 "Invalid value for 'content_scripts'."; | 94 "Invalid value for 'content_scripts'."; |
90 const char* Extension::kInvalidCssError = | 95 const char* Extension::kInvalidCssError = |
91 "Invalid value for 'content_scripts[*].css[*]'."; | 96 "Invalid value for 'content_scripts[*].css[*]'."; |
92 const char* Extension::kInvalidCssListError = | 97 const char* Extension::kInvalidCssListError = |
93 "Required value 'content_scripts[*].css is invalid."; | 98 "Required value 'content_scripts[*].css is invalid."; |
94 const char* Extension::kInvalidDescriptionError = | 99 const char* Extension::kInvalidDescriptionError = |
95 "Invalid value for 'description'."; | 100 "Invalid value for 'description'."; |
96 const char* Extension::kInvalidIdError = | |
97 "Required value 'id' is missing or invalid."; | |
98 const char* Extension::kInvalidJsError = | 101 const char* Extension::kInvalidJsError = |
99 "Invalid value for 'content_scripts[*].js[*]'."; | 102 "Invalid value for 'content_scripts[*].js[*]'."; |
100 const char* Extension::kInvalidJsListError = | 103 const char* Extension::kInvalidJsListError = |
101 "Required value 'content_scripts[*].js is invalid."; | 104 "Required value 'content_scripts[*].js is invalid."; |
| 105 const char* Extension::kInvalidKeyError = |
| 106 "Value 'key' is missing or invalid."; |
102 const char* Extension::kInvalidManifestError = | 107 const char* Extension::kInvalidManifestError = |
103 "Manifest is missing or invalid."; | 108 "Manifest is missing or invalid."; |
104 const char* Extension::kInvalidMatchCountError = | 109 const char* Extension::kInvalidMatchCountError = |
105 "Invalid value for 'content_scripts[*].matches. There must be at least one " | 110 "Invalid value for 'content_scripts[*].matches. There must be at least one " |
106 "match specified."; | 111 "match specified."; |
107 const char* Extension::kInvalidMatchError = | 112 const char* Extension::kInvalidMatchError = |
108 "Invalid value for 'content_scripts[*].matches[*]'."; | 113 "Invalid value for 'content_scripts[*].matches[*]'."; |
109 const char* Extension::kInvalidMatchesError = | 114 const char* Extension::kInvalidMatchesError = |
110 "Required value 'content_scripts[*].matches' is missing or invalid."; | 115 "Required value 'content_scripts[*].matches' is missing or invalid."; |
111 const char* Extension::kInvalidNameError = | 116 const char* Extension::kInvalidNameError = |
112 "Required value 'name' is missing or invalid."; | 117 "Required value 'name' is missing or invalid."; |
113 const char* Extension::kInvalidPageActionError = | 118 const char* Extension::kInvalidPageActionError = |
114 "Invalid value for 'page_actions[*]'."; | 119 "Invalid value for 'page_actions[*]'."; |
115 const char* Extension::kInvalidPageActionsListError = | 120 const char* Extension::kInvalidPageActionsListError = |
116 "Invalid value for 'page_actions'."; | 121 "Invalid value for 'page_actions'."; |
117 const char* Extension::kInvalidPageActionIconPathError = | 122 const char* Extension::kInvalidPageActionIconPathError = |
118 "Invalid value for 'page_actions[*].icon'."; | 123 "Invalid value for 'page_actions[*].icon'."; |
| 124 const char* Extension::kInvalidPageActionIdError = |
| 125 "Required value 'id' is missing or invalid."; |
119 const char* Extension::kInvalidPageActionTooltipError = | 126 const char* Extension::kInvalidPageActionTooltipError = |
120 "Invalid value for 'page_actions[*].tooltip'."; | 127 "Invalid value for 'page_actions[*].tooltip'."; |
121 const char* Extension::kInvalidPageActionTypeValueError = | 128 const char* Extension::kInvalidPageActionTypeValueError = |
122 "Invalid value for 'page_actions[*].type', expected 'tab' or 'permanent'."; | 129 "Invalid value for 'page_actions[*].type', expected 'tab' or 'permanent'."; |
123 const char* Extension::kInvalidPermissionsError = | 130 const char* Extension::kInvalidPermissionsError = |
124 "Required value 'permissions' is missing or invalid."; | 131 "Required value 'permissions' is missing or invalid."; |
125 const char* Extension::kInvalidPermissionCountWarning = | 132 const char* Extension::kInvalidPermissionCountWarning = |
126 "Warning, 'permissions' key found, but array is empty."; | 133 "Warning, 'permissions' key found, but array is empty."; |
127 const char* Extension::kInvalidPermissionError = | 134 const char* Extension::kInvalidPermissionError = |
128 "Invalid value for 'permissions[*]'."; | 135 "Invalid value for 'permissions[*]'."; |
129 const char* Extension::kInvalidPermissionSchemeError = | 136 const char* Extension::kInvalidPermissionSchemeError = |
130 "Invalid scheme for 'permissions[*]'. Only 'http' and 'https' are " | 137 "Invalid scheme for 'permissions[*]'. Only 'http' and 'https' are " |
131 "allowed."; | 138 "allowed."; |
132 const char* Extension::kInvalidPluginsError = | 139 const char* Extension::kInvalidPluginsError = |
133 "Invalid value for 'plugins'."; | 140 "Invalid value for 'plugins'."; |
134 const char* Extension::kInvalidPluginsPathError = | 141 const char* Extension::kInvalidPluginsPathError = |
135 "Invalid value for 'plugins[*].path'."; | 142 "Invalid value for 'plugins[*].path'."; |
136 const char* Extension::kInvalidPluginsPublicError = | 143 const char* Extension::kInvalidPluginsPublicError = |
137 "Invalid value for 'plugins[*].public'."; | 144 "Invalid value for 'plugins[*].public'."; |
138 const char* Extension::kInvalidBackgroundError = | 145 const char* Extension::kInvalidBackgroundError = |
139 "Invalid value for 'background'."; | 146 "Invalid value for 'background'."; |
140 const char* Extension::kInvalidRunAtError = | 147 const char* Extension::kInvalidRunAtError = |
141 "Invalid value for 'content_scripts[*].run_at'."; | 148 "Invalid value for 'content_scripts[*].run_at'."; |
| 149 const char* Extension::kInvalidSignatureError = |
| 150 "Value 'signature' is missing or invalid."; |
142 const char* Extension::kInvalidToolstripError = | 151 const char* Extension::kInvalidToolstripError = |
143 "Invalid value for 'toolstrips[*]'"; | 152 "Invalid value for 'toolstrips[*]'"; |
144 const char* Extension::kInvalidToolstripsError = | 153 const char* Extension::kInvalidToolstripsError = |
145 "Invalid value for 'toolstrips'."; | 154 "Invalid value for 'toolstrips'."; |
146 const char* Extension::kInvalidVersionError = | 155 const char* Extension::kInvalidVersionError = |
147 "Required value 'version' is missing or invalid."; | 156 "Required value 'version' is missing or invalid."; |
148 const char* Extension::kInvalidZipHashError = | 157 const char* Extension::kInvalidZipHashError = |
149 "Required key 'zip_hash' is missing or invalid."; | 158 "Required key 'zip_hash' is missing or invalid."; |
150 const char* Extension::kMissingFileError = | 159 const char* Extension::kMissingFileError = |
151 "At least one js or css file is required for 'content_scripts[*]'."; | 160 "At least one js or css file is required for 'content_scripts[*]'."; |
152 const char* Extension::kInvalidThemeError = | 161 const char* Extension::kInvalidThemeError = |
153 "Invalid value for 'theme'."; | 162 "Invalid value for 'theme'."; |
154 const char* Extension::kInvalidThemeImagesError = | 163 const char* Extension::kInvalidThemeImagesError = |
155 "Invalid value for theme images - images must be strings."; | 164 "Invalid value for theme images - images must be strings."; |
156 const char* Extension::kInvalidThemeImagesMissingError = | 165 const char* Extension::kInvalidThemeImagesMissingError = |
157 "Am image specified in the theme is missing."; | 166 "Am image specified in the theme is missing."; |
158 const char* Extension::kInvalidThemeColorsError = | 167 const char* Extension::kInvalidThemeColorsError = |
159 "Invalid value for theme colors - colors must be integers"; | 168 "Invalid value for theme colors - colors must be integers"; |
160 const char* Extension::kInvalidThemeTintsError = | 169 const char* Extension::kInvalidThemeTintsError = |
161 "Invalid value for theme images - tints must be decimal numbers."; | 170 "Invalid value for theme images - tints must be decimal numbers."; |
162 const char* Extension::kThemesCannotContainExtensionsError = | 171 const char* Extension::kThemesCannotContainExtensionsError = |
163 "A theme cannot contain extensions code."; | 172 "A theme cannot contain extensions code."; |
164 | 173 |
165 #if defined(OS_WIN) | 174 #if defined(OS_WIN) |
166 const char* Extension::kExtensionRegistryPath = | 175 const char* Extension::kExtensionRegistryPath = |
167 "Software\\Google\\Chrome\\Extensions"; | 176 "Software\\Google\\Chrome\\Extensions"; |
168 #endif | 177 #endif |
169 | 178 |
170 const size_t Extension::kIdSize = 20; // SHA1 (160 bits) == 20 bytes | 179 // first 20 bytes of SHA256 hashed public key. |
| 180 const size_t Extension::kIdSize = 20; |
171 | 181 |
172 Extension::~Extension() { | 182 Extension::~Extension() { |
173 for (PageActionMap::iterator i = page_actions_.begin(); | 183 for (PageActionMap::iterator i = page_actions_.begin(); |
174 i != page_actions_.end(); ++i) | 184 i != page_actions_.end(); ++i) |
175 delete i->second; | 185 delete i->second; |
176 } | 186 } |
177 | 187 |
178 const std::string Extension::VersionString() const { | 188 const std::string Extension::VersionString() const { |
179 return version_->GetString(); | 189 return version_->GetString(); |
180 } | 190 } |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 HKEY reg_root = HKEY_LOCAL_MACHINE; | 233 HKEY reg_root = HKEY_LOCAL_MACHINE; |
224 RegKey key; | 234 RegKey key; |
225 registry_path.append("\\"); | 235 registry_path.append("\\"); |
226 registry_path.append(id_); | 236 registry_path.append(id_); |
227 if (key.Open(reg_root, ASCIIToWide(registry_path).c_str())) | 237 if (key.Open(reg_root, ASCIIToWide(registry_path).c_str())) |
228 return Extension::EXTERNAL_REGISTRY; | 238 return Extension::EXTERNAL_REGISTRY; |
229 #endif | 239 #endif |
230 return Extension::EXTERNAL_PREF; | 240 return Extension::EXTERNAL_PREF; |
231 } | 241 } |
232 | 242 |
| 243 bool Extension::GenerateIdFromPublicKey(const std::string& input, |
| 244 std::string* output) { |
| 245 CHECK(output); |
| 246 if (input.length() == 0) |
| 247 return false; |
| 248 |
| 249 const uint8* ubuf = reinterpret_cast<const unsigned char*>(input.data()); |
| 250 SHA256Context ctx; |
| 251 SHA256_Begin(&ctx); |
| 252 SHA256_Update(&ctx, ubuf, input.length()); |
| 253 uint8 hash[Extension::kIdSize]; |
| 254 SHA256_End(&ctx, hash, NULL, sizeof(hash)); |
| 255 *output = StringToLowerASCII(HexEncode(hash, sizeof(hash))); |
| 256 |
| 257 return true; |
| 258 } |
| 259 |
233 // Helper method that loads a UserScript object from a dictionary in the | 260 // Helper method that loads a UserScript object from a dictionary in the |
234 // content_script list of the manifest. | 261 // content_script list of the manifest. |
235 bool Extension::LoadUserScriptHelper(const DictionaryValue* content_script, | 262 bool Extension::LoadUserScriptHelper(const DictionaryValue* content_script, |
236 int definition_index, std::string* error, | 263 int definition_index, std::string* error, |
237 UserScript* result) { | 264 UserScript* result) { |
238 // run_at | 265 // run_at |
239 if (content_script->HasKey(kRunAtKey)) { | 266 if (content_script->HasKey(kRunAtKey)) { |
240 std::string run_location; | 267 std::string run_location; |
241 if (!content_script->GetString(kRunAtKey, &run_location)) { | 268 if (!content_script->GetString(kRunAtKey, &run_location)) { |
242 *error = ExtensionErrorUtils::FormatErrorMessage(kInvalidRunAtError, | 269 *error = ExtensionErrorUtils::FormatErrorMessage(kInvalidRunAtError, |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
360 if (!page_action->GetString(kIconPathKey, &icon)) { | 387 if (!page_action->GetString(kIconPathKey, &icon)) { |
361 *error = ExtensionErrorUtils::FormatErrorMessage( | 388 *error = ExtensionErrorUtils::FormatErrorMessage( |
362 kInvalidPageActionIconPathError, IntToString(definition_index)); | 389 kInvalidPageActionIconPathError, IntToString(definition_index)); |
363 return NULL; | 390 return NULL; |
364 } | 391 } |
365 FilePath icon_path = path_.AppendASCII(icon); | 392 FilePath icon_path = path_.AppendASCII(icon); |
366 result->set_icon_path(icon_path); | 393 result->set_icon_path(icon_path); |
367 | 394 |
368 // Read the page action |id|. | 395 // Read the page action |id|. |
369 std::string id; | 396 std::string id; |
370 if (!page_action->GetString(kIdKey, &id)) { | 397 if (!page_action->GetString(kPageActionIdKey, &id)) { |
371 *error = ExtensionErrorUtils::FormatErrorMessage(kInvalidIdError, | 398 *error = ExtensionErrorUtils::FormatErrorMessage(kInvalidPageActionIdError, |
372 IntToString(definition_index)); | 399 IntToString(definition_index)); |
373 return NULL; | 400 return NULL; |
374 } | 401 } |
375 result->set_id(id); | 402 result->set_id(id); |
376 | 403 |
377 // Read the page action |name|. | 404 // Read the page action |name|. |
378 std::string name; | 405 std::string name; |
379 if (!page_action->GetString(kNameKey, &name)) { | 406 if (!page_action->GetString(kNameKey, &name)) { |
380 *error = ExtensionErrorUtils::FormatErrorMessage(kInvalidNameError, | 407 *error = ExtensionErrorUtils::FormatErrorMessage(kInvalidNameError, |
381 IntToString(definition_index)); | 408 IntToString(definition_index)); |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
485 if (path_str.size() >= 2 && path_str[0] >= L'a' && path_str[0] <= L'z' && | 512 if (path_str.size() >= 2 && path_str[0] >= L'a' && path_str[0] <= L'z' && |
486 path_str[1] == ':') | 513 path_str[1] == ':') |
487 path_str[0] += ('A' - 'a'); | 514 path_str[0] += ('A' - 'a'); |
488 | 515 |
489 path_ = FilePath(path_str); | 516 path_ = FilePath(path_str); |
490 #else | 517 #else |
491 path_ = path; | 518 path_ = path; |
492 #endif | 519 #endif |
493 } | 520 } |
494 | 521 |
495 | |
496 // TODO(rafaelw): Move ParsePEMKeyBytes, ProducePEM & FormatPEMForOutput to a | 522 // TODO(rafaelw): Move ParsePEMKeyBytes, ProducePEM & FormatPEMForOutput to a |
497 // util class in base: | 523 // util class in base: |
498 // http://code.google.com/p/chromium/issues/detail?id=13572 | 524 // http://code.google.com/p/chromium/issues/detail?id=13572 |
499 bool Extension::ParsePEMKeyBytes(const std::string& input, | 525 bool Extension::ParsePEMKeyBytes(const std::string& input, |
500 std::string* output) { | 526 std::string* output) { |
501 CHECK(output); | 527 DCHECK(output); |
| 528 if (!output) |
| 529 return false; |
502 if (input.length() == 0) | 530 if (input.length() == 0) |
503 return false; | 531 return false; |
504 | 532 |
505 std::string working = input; | 533 std::string working = input; |
506 if (StartsWithASCII(working, kKeyBeginHeaderMarker, true)) { | 534 if (StartsWithASCII(working, kKeyBeginHeaderMarker, true)) { |
507 working = CollapseWhitespaceASCII(working, true); | 535 working = CollapseWhitespaceASCII(working, true); |
508 size_t header_pos = working.find(kKeyInfoEndMarker, | 536 size_t header_pos = working.find(kKeyInfoEndMarker, |
509 sizeof(kKeyBeginHeaderMarker) - 1); | 537 sizeof(kKeyBeginHeaderMarker) - 1); |
510 if (header_pos == std::string::npos) | 538 if (header_pos == std::string::npos) |
511 return false; | 539 return false; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
557 output->append(is_public ? kPublic : kPrivate); | 585 output->append(is_public ? kPublic : kPrivate); |
558 output->append(" "); | 586 output->append(" "); |
559 output->append(kKeyInfoEndMarker); | 587 output->append(kKeyInfoEndMarker); |
560 output->append("\n"); | 588 output->append("\n"); |
561 | 589 |
562 return true; | 590 return true; |
563 } | 591 } |
564 | 592 |
565 bool Extension::InitFromValue(const DictionaryValue& source, bool require_id, | 593 bool Extension::InitFromValue(const DictionaryValue& source, bool require_id, |
566 std::string* error) { | 594 std::string* error) { |
567 // Initialize id. | 595 if (source.HasKey(kPublicKeyKey)) { |
568 if (source.HasKey(kIdKey)) { | 596 std::string public_key_bytes; |
569 if (!source.GetString(kIdKey, &id_)) { | 597 if (!source.GetString(kPublicKeyKey, &public_key_) || |
570 *error = kInvalidIdError; | 598 !ParsePEMKeyBytes(public_key_, &public_key_bytes) || |
571 return false; | 599 !GenerateIdFromPublicKey(public_key_bytes, &id_)) { |
572 } | 600 *error = kInvalidKeyError; |
573 | 601 return false; |
574 // Normalize the string to lowercase, so it can be used as an URL component | |
575 // (where GURL will lowercase it). | |
576 StringToLowerASCII(&id_); | |
577 | |
578 // Verify that the id is legal. | |
579 if (!IdIsValid(id_)) { | |
580 *error = kInvalidIdError; | |
581 return false; | |
582 } | 602 } |
583 } else if (require_id) { | 603 } else if (require_id) { |
584 *error = kInvalidIdError; | 604 *error = kInvalidKeyError; |
585 return false; | 605 return false; |
586 } else { | 606 } else { |
587 // Generate a random ID | 607 // Generate a random ID |
588 static int counter = 0; | 608 id_ = StringPrintf("%x", NextGeneratedId()); |
589 id_ = StringPrintf("%x", counter); | |
590 ++counter; | |
591 | 609 |
592 // pad the string out to 40 chars with zeroes. | 610 // pad the string out to kIdSize*2 chars with zeroes. |
593 id_.insert(0, 40 - id_.length(), '0'); | 611 id_.insert(0, Extension::kIdSize*2 - id_.length(), '0'); |
594 } | 612 } |
595 | 613 |
596 // Initialize the URL. | 614 // Initialize the URL. |
597 extension_url_ = GURL(std::string(chrome::kExtensionScheme) + | 615 extension_url_ = GURL(std::string(chrome::kExtensionScheme) + |
598 chrome::kStandardSchemeSeparator + id_ + "/"); | 616 chrome::kStandardSchemeSeparator + id_ + "/"); |
599 | 617 |
600 // Initialize version. | 618 // Initialize version. |
601 std::string version_str; | 619 std::string version_str; |
602 if (!source.GetString(kVersionKey, &version_str)) { | 620 if (!source.GetString(kVersionKey, &version_str)) { |
603 *error = kInvalidVersionError; | 621 *error = kInvalidVersionError; |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
896 } | 914 } |
897 } | 915 } |
898 | 916 |
899 for (PageActionMap::const_iterator it = page_actions().begin(); | 917 for (PageActionMap::const_iterator it = page_actions().begin(); |
900 it != page_actions().end(); ++it) { | 918 it != page_actions().end(); ++it) { |
901 image_paths.insert(it->second->icon_path()); | 919 image_paths.insert(it->second->icon_path()); |
902 } | 920 } |
903 | 921 |
904 return image_paths; | 922 return image_paths; |
905 } | 923 } |
OLD | NEW |