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 "chrome/browser/chromeos/platform_keys/platform_keys_service.h" | 5 #include "chrome/browser/chromeos/platform_keys/platform_keys_service.h" |
6 | 6 |
7 #include "base/base64.h" | 7 #include "base/base64.h" |
8 #include "base/callback.h" | 8 #include "base/callback.h" |
| 9 #include "base/callback_helpers.h" |
9 #include "base/values.h" | 10 #include "base/values.h" |
10 #include "chrome/browser/chromeos/platform_keys/platform_keys.h" | 11 #include "chrome/browser/chromeos/platform_keys/platform_keys.h" |
11 #include "content/public/browser/browser_thread.h" | 12 #include "content/public/browser/browser_thread.h" |
12 #include "extensions/browser/state_store.h" | 13 #include "extensions/browser/state_store.h" |
13 #include "net/cert/x509_certificate.h" | 14 #include "net/cert/x509_certificate.h" |
14 | 15 |
15 using content::BrowserThread; | 16 using content::BrowserThread; |
16 | 17 |
17 namespace chromeos { | 18 namespace chromeos { |
18 | 19 |
19 namespace { | 20 namespace { |
20 | 21 |
21 const char kErrorKeyNotAllowedForSigning[] = | 22 const char kErrorKeyNotAllowedForSigning[] = |
22 "This key is not allowed for signing. Either it was used for signing " | 23 "This key is not allowed for signing. Either it was used for signing " |
23 "before or it was not correctly generated."; | 24 "before or it was not correctly generated."; |
24 const char kStateStorePlatformKeys[] = "PlatformKeys"; | 25 const char kStateStorePlatformKeys[] = "PlatformKeys"; |
25 | 26 |
26 scoped_ptr<base::StringValue> GetPublicKeyValue( | 27 scoped_ptr<base::StringValue> GetPublicKeyValue( |
27 const std::string& public_key_spki_der) { | 28 const std::string& public_key_spki_der) { |
28 std::string public_key_spki_der_b64; | 29 std::string public_key_spki_der_b64; |
29 base::Base64Encode(public_key_spki_der, &public_key_spki_der_b64); | 30 base::Base64Encode(public_key_spki_der, &public_key_spki_der_b64); |
30 return make_scoped_ptr(new base::StringValue(public_key_spki_der_b64)); | 31 return make_scoped_ptr(new base::StringValue(public_key_spki_der_b64)); |
31 } | 32 } |
32 | 33 |
33 void RunGenerateKeyCallback( | |
34 const PlatformKeysService::GenerateKeyCallback& callback, | |
35 const std::string& public_key_spki_der) { | |
36 callback.Run(public_key_spki_der, std::string() /* no error */); | |
37 } | |
38 | |
39 // Callback used by |PlatformKeysService::Sign|. | |
40 // Is called with the old validity of |public_key_spki_der| (or false if an | |
41 // error occurred during reading the StateStore). If allowed, starts the actual | |
42 // signing operation which will call back |callback|. If not allowed, calls | |
43 // |callback| with an error. | |
44 void CheckValidityAndSign(const std::string& token_id, | |
45 const std::string& data, | |
46 const std::string& public_key, | |
47 bool sign_direct_pkcs_padded, | |
48 platform_keys::HashAlgorithm hash_algorithm, | |
49 const PlatformKeysService::SignCallback& callback, | |
50 content::BrowserContext* browser_context, | |
51 bool key_is_valid) { | |
52 if (!key_is_valid) { | |
53 callback.Run(std::string() /* no signature */, | |
54 kErrorKeyNotAllowedForSigning); | |
55 return; | |
56 } | |
57 if (sign_direct_pkcs_padded) { | |
58 platform_keys::subtle::SignRSAPKCS1Raw(token_id, data, public_key, callback, | |
59 browser_context); | |
60 } else { | |
61 platform_keys::subtle::SignRSAPKCS1Digest( | |
62 token_id, data, public_key, hash_algorithm, callback, browser_context); | |
63 } | |
64 } | |
65 | |
66 } // namespace | 34 } // namespace |
67 | 35 |
| 36 class PlatformKeysService::Task { |
| 37 public: |
| 38 Task() {} |
| 39 virtual ~Task() {} |
| 40 virtual void Start() = 0; |
| 41 virtual bool IsDone() = 0; |
| 42 |
| 43 private: |
| 44 DISALLOW_ASSIGN(Task); |
| 45 }; |
| 46 |
| 47 class PlatformKeysService::PermissionUpdateTask : public Task { |
| 48 public: |
| 49 enum class Step { |
| 50 READ_PLATFORM_KEYS, |
| 51 WRITE_UPDATE_AND_CALLBACK, |
| 52 DONE, |
| 53 }; |
| 54 |
| 55 // Creates a task that reads the current permission for an extension to access |
| 56 // a certain key. Afterwards it updates and persists the permission to the new |
| 57 // value |new_permission_value|. |callback| will be run after the permission |
| 58 // was persisted. The old permission value is then accessible through |
| 59 // old_permission_value(). |
| 60 PermissionUpdateTask(const bool new_permission_value, |
| 61 const std::string& public_key_spki_der, |
| 62 const std::string& extension_id, |
| 63 base::Callback<void(Task*)> callback, |
| 64 PlatformKeysService* service) |
| 65 : new_permission_value_(new_permission_value), |
| 66 public_key_spki_der_(public_key_spki_der), |
| 67 extension_id_(extension_id), |
| 68 callback_(callback), |
| 69 service_(service), |
| 70 weak_factory_(this) {} |
| 71 |
| 72 ~PermissionUpdateTask() override {} |
| 73 |
| 74 void Start() override { |
| 75 CHECK(next_step_ == Step::READ_PLATFORM_KEYS); |
| 76 DoStep(); |
| 77 } |
| 78 |
| 79 bool IsDone() override { return next_step_ == Step::DONE; } |
| 80 |
| 81 // The original permission value before setting the new value |
| 82 // |new_permission_value|. |
| 83 bool old_permission_value() { return old_permission_value_; } |
| 84 |
| 85 private: |
| 86 void DoStep() { |
| 87 switch (next_step_) { |
| 88 case Step::READ_PLATFORM_KEYS: |
| 89 next_step_ = Step::WRITE_UPDATE_AND_CALLBACK; |
| 90 ReadPlatformKeys(); |
| 91 return; |
| 92 case Step::WRITE_UPDATE_AND_CALLBACK: |
| 93 next_step_ = Step::DONE; |
| 94 WriteUpdate(); |
| 95 if (!callback_.is_null()) { |
| 96 // Make a local copy of the callback to run as it might be deleted |
| 97 // during the Run(). |
| 98 base::ResetAndReturn(&callback_).Run(this); |
| 99 // |this| might be invalid now. |
| 100 } |
| 101 return; |
| 102 case Step::DONE: |
| 103 NOTREACHED(); |
| 104 return; |
| 105 } |
| 106 } |
| 107 |
| 108 // Reads the PlatformKeys value from the extension's state store and calls |
| 109 // back to GotPlatformKeys(). |
| 110 void ReadPlatformKeys() { |
| 111 service_->GetPlatformKeysOfExtension( |
| 112 extension_id_, base::Bind(&PermissionUpdateTask::GotPlatformKeys, |
| 113 weak_factory_.GetWeakPtr())); |
| 114 } |
| 115 |
| 116 void GotPlatformKeys(scoped_ptr<base::ListValue> platform_keys) { |
| 117 platform_keys_ = platform_keys.Pass(); |
| 118 DoStep(); |
| 119 } |
| 120 |
| 121 // Returns whether the extension has permission to use the key for signing |
| 122 // according to the PlatformKeys value read from the extensions state store. |
| 123 // Invalidates the key if it was found to be valid. |
| 124 void WriteUpdate() { |
| 125 scoped_ptr<base::StringValue> key_value( |
| 126 GetPublicKeyValue(public_key_spki_der_)); |
| 127 |
| 128 base::ListValue::const_iterator it = platform_keys_->Find(*key_value); |
| 129 old_permission_value_ = it != platform_keys_->end(); |
| 130 if (old_permission_value_ == new_permission_value_) |
| 131 return; |
| 132 |
| 133 if (new_permission_value_) |
| 134 platform_keys_->Append(key_value.release()); |
| 135 else |
| 136 platform_keys_->Remove(*key_value, nullptr); |
| 137 |
| 138 service_->SetPlatformKeysOfExtension(extension_id_, platform_keys_.Pass()); |
| 139 } |
| 140 |
| 141 Step next_step_ = Step::READ_PLATFORM_KEYS; |
| 142 scoped_ptr<base::ListValue> platform_keys_; |
| 143 bool old_permission_value_ = false; |
| 144 |
| 145 const bool new_permission_value_; |
| 146 const std::string public_key_spki_der_; |
| 147 const std::string extension_id_; |
| 148 base::Callback<void(Task*)> callback_; |
| 149 PlatformKeysService* const service_; |
| 150 base::WeakPtrFactory<PermissionUpdateTask> weak_factory_; |
| 151 |
| 152 DISALLOW_COPY_AND_ASSIGN(PermissionUpdateTask); |
| 153 }; |
| 154 |
| 155 class PlatformKeysService::SignTask : public Task { |
| 156 public: |
| 157 enum class Step { |
| 158 UPDATE_PERMISSION, |
| 159 SIGN_OR_ABORT, |
| 160 DONE, |
| 161 }; |
| 162 |
| 163 // This Task will check the permissions of the extension with |extension_id| |
| 164 // for the key identified by |public_key_spki_der|, then updates the |
| 165 // permission to prevent any future signing operation of that extension using |
| 166 // that same key. If the permission check was positive, it will actually sign |
| 167 // |data| with the key and pass the signature to |callback|. |
| 168 // If an error occurs, an error message is passed to |callback| instead. |
| 169 SignTask(const std::string& token_id, |
| 170 const std::string& data, |
| 171 const std::string& public_key, |
| 172 bool sign_direct_pkcs_padded, |
| 173 platform_keys::HashAlgorithm hash_algorithm, |
| 174 const std::string& extension_id, |
| 175 const SignCallback& callback, |
| 176 PlatformKeysService* service) |
| 177 : token_id_(token_id), |
| 178 data_(data), |
| 179 public_key_(public_key), |
| 180 sign_direct_pkcs_padded_(sign_direct_pkcs_padded), |
| 181 hash_algorithm_(hash_algorithm), |
| 182 extension_id_(extension_id), |
| 183 callback_(callback), |
| 184 service_(service), |
| 185 weak_factory_(this) {} |
| 186 ~SignTask() override {} |
| 187 |
| 188 void Start() override { |
| 189 CHECK(next_step_ == Step::UPDATE_PERMISSION); |
| 190 DoStep(); |
| 191 } |
| 192 bool IsDone() override { return next_step_ == Step::DONE; } |
| 193 |
| 194 private: |
| 195 void DoStep() { |
| 196 switch (next_step_) { |
| 197 case Step::UPDATE_PERMISSION: |
| 198 next_step_ = Step::SIGN_OR_ABORT; |
| 199 UpdatePermission(); |
| 200 return; |
| 201 case Step::SIGN_OR_ABORT: |
| 202 next_step_ = Step::DONE; |
| 203 if (!service_->permission_check_enabled_ || |
| 204 permission_update_->old_permission_value()) { |
| 205 Sign(); |
| 206 } else { |
| 207 callback_.Run(std::string() /* no signature */, |
| 208 kErrorKeyNotAllowedForSigning); |
| 209 DoStep(); |
| 210 } |
| 211 return; |
| 212 case Step::DONE: |
| 213 service_->TaskFinished(this); |
| 214 // |this| might be invalid now. |
| 215 return; |
| 216 } |
| 217 } |
| 218 |
| 219 // Reads the current permission of the extension with |extension_id_| for key |
| 220 // |params_->public_key| and updates the permission to disable further |
| 221 // signing operations with that key. |
| 222 void UpdatePermission() { |
| 223 permission_update_.reset(new PermissionUpdateTask( |
| 224 false /* new permission value */, public_key_, extension_id_, |
| 225 base::Bind(&SignTask::DidUpdatePermission, weak_factory_.GetWeakPtr()), |
| 226 service_)); |
| 227 permission_update_->Start(); |
| 228 } |
| 229 |
| 230 void DidUpdatePermission(Task* /* task */) { DoStep(); } |
| 231 |
| 232 // Starts the actual signing operation and afterwards passes the signature (or |
| 233 // error) to |callback_|. |
| 234 void Sign() { |
| 235 if (sign_direct_pkcs_padded_) { |
| 236 platform_keys::subtle::SignRSAPKCS1Raw( |
| 237 token_id_, data_, public_key_, |
| 238 base::Bind(&SignTask::DidSign, weak_factory_.GetWeakPtr()), |
| 239 service_->browser_context_); |
| 240 } else { |
| 241 platform_keys::subtle::SignRSAPKCS1Digest( |
| 242 token_id_, data_, public_key_, hash_algorithm_, |
| 243 base::Bind(&SignTask::DidSign, weak_factory_.GetWeakPtr()), |
| 244 service_->browser_context_); |
| 245 } |
| 246 } |
| 247 |
| 248 void DidSign(const std::string& signature, const std::string& error_message) { |
| 249 callback_.Run(signature, error_message); |
| 250 DoStep(); |
| 251 } |
| 252 |
| 253 Step next_step_ = Step::UPDATE_PERMISSION; |
| 254 scoped_ptr<base::ListValue> platform_keys_; |
| 255 scoped_ptr<PermissionUpdateTask> permission_update_; |
| 256 |
| 257 const std::string token_id_; |
| 258 const std::string data_; |
| 259 const std::string public_key_; |
| 260 |
| 261 // If true, |data_| will not be hashed before signing. Only PKCS#1 v1.5 |
| 262 // padding will be applied before signing. |
| 263 // If false, |hash_algorithm_| is set to a value != NONE. |
| 264 const bool sign_direct_pkcs_padded_; |
| 265 const platform_keys::HashAlgorithm hash_algorithm_; |
| 266 const std::string extension_id_; |
| 267 const SignCallback callback_; |
| 268 PlatformKeysService* const service_; |
| 269 base::WeakPtrFactory<SignTask> weak_factory_; |
| 270 |
| 271 DISALLOW_COPY_AND_ASSIGN(SignTask); |
| 272 }; |
| 273 |
68 PlatformKeysService::PlatformKeysService( | 274 PlatformKeysService::PlatformKeysService( |
69 content::BrowserContext* browser_context, | 275 content::BrowserContext* browser_context, |
70 extensions::StateStore* state_store) | 276 extensions::StateStore* state_store) |
71 : browser_context_(browser_context), | 277 : browser_context_(browser_context), |
72 state_store_(state_store), | 278 state_store_(state_store), |
73 weak_factory_(this) { | 279 weak_factory_(this) { |
74 DCHECK(state_store); | 280 DCHECK(state_store); |
75 } | 281 } |
76 | 282 |
77 PlatformKeysService::~PlatformKeysService() { | 283 PlatformKeysService::~PlatformKeysService() { |
78 } | 284 } |
79 | 285 |
80 void PlatformKeysService::DisablePermissionCheckForTesting() { | 286 void PlatformKeysService::DisablePermissionCheckForTesting() { |
81 permission_check_enabled_ = false; | 287 permission_check_enabled_ = false; |
82 } | 288 } |
83 | 289 |
84 void PlatformKeysService::GenerateRSAKey(const std::string& token_id, | 290 void PlatformKeysService::GenerateRSAKey(const std::string& token_id, |
85 unsigned int modulus_length, | 291 unsigned int modulus_length, |
86 const std::string& extension_id, | 292 const std::string& extension_id, |
87 const GenerateKeyCallback& callback) { | 293 const GenerateKeyCallback& callback) { |
88 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 294 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
89 | 295 |
90 platform_keys::subtle::GenerateRSAKey( | 296 platform_keys::subtle::GenerateRSAKey( |
91 token_id, | 297 token_id, modulus_length, |
92 modulus_length, | 298 base::Bind(&PlatformKeysService::GeneratedKey, weak_factory_.GetWeakPtr(), |
93 base::Bind(&PlatformKeysService::GenerateRSAKeyCallback, | 299 extension_id, callback), |
94 weak_factory_.GetWeakPtr(), | |
95 extension_id, | |
96 callback), | |
97 browser_context_); | 300 browser_context_); |
98 } | 301 } |
99 | 302 |
100 void PlatformKeysService::SignRSAPKCS1Digest( | 303 void PlatformKeysService::SignRSAPKCS1Digest( |
101 const std::string& token_id, | 304 const std::string& token_id, |
102 const std::string& data, | 305 const std::string& data, |
103 const std::string& public_key, | 306 const std::string& public_key, |
104 platform_keys::HashAlgorithm hash_algorithm, | 307 platform_keys::HashAlgorithm hash_algorithm, |
105 const std::string& extension_id, | 308 const std::string& extension_id, |
106 const SignCallback& callback) { | 309 const SignCallback& callback) { |
107 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 310 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
108 ReadValidityAndInvalidateKey( | 311 StartOrQueueTask(make_scoped_ptr(new SignTask( |
109 extension_id, public_key, | 312 token_id, data, public_key, false /* digest before signing */, |
110 base::Bind(&CheckValidityAndSign, token_id, data, public_key, | 313 hash_algorithm, extension_id, callback, this))); |
111 false /* digest before signing */, hash_algorithm, callback, | |
112 browser_context_)); | |
113 } | 314 } |
114 | 315 |
115 void PlatformKeysService::SignRSAPKCS1Raw(const std::string& token_id, | 316 void PlatformKeysService::SignRSAPKCS1Raw(const std::string& token_id, |
116 const std::string& data, | 317 const std::string& data, |
117 const std::string& public_key, | 318 const std::string& public_key, |
118 const std::string& extension_id, | 319 const std::string& extension_id, |
119 const SignCallback& callback) { | 320 const SignCallback& callback) { |
120 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 321 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
121 ReadValidityAndInvalidateKey( | 322 StartOrQueueTask(make_scoped_ptr(new SignTask( |
122 extension_id, public_key, | 323 token_id, data, public_key, true /* sign directly without hashing */, |
123 base::Bind(&CheckValidityAndSign, token_id, data, public_key, | 324 platform_keys::HASH_ALGORITHM_NONE, extension_id, callback, this))); |
124 true /* sign directly without hashing */, | |
125 platform_keys::HASH_ALGORITHM_NONE, callback, | |
126 browser_context_)); | |
127 } | 325 } |
128 | 326 |
129 void PlatformKeysService::SelectClientCertificates( | 327 void PlatformKeysService::SelectClientCertificates( |
130 const platform_keys::ClientCertificateRequest& request, | 328 const platform_keys::ClientCertificateRequest& request, |
131 const std::string& extension_id, | 329 const std::string& extension_id, |
132 const SelectCertificatesCallback& callback) { | 330 const SelectCertificatesCallback& callback) { |
133 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 331 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
134 | 332 |
135 platform_keys::subtle::SelectClientCertificates( | 333 platform_keys::subtle::SelectClientCertificates( |
136 request, | 334 request, |
137 base::Bind(&PlatformKeysService::SelectClientCertificatesCallback, | 335 base::Bind(&PlatformKeysService::SelectClientCertificatesCallback, |
138 weak_factory_.GetWeakPtr(), extension_id, callback), | 336 weak_factory_.GetWeakPtr(), extension_id, callback), |
139 browser_context_); | 337 browser_context_); |
140 } | 338 } |
141 | 339 |
142 void PlatformKeysService::RegisterPublicKey( | 340 void PlatformKeysService::StartOrQueueTask(scoped_ptr<Task> task) { |
143 const std::string& extension_id, | 341 tasks_.push(make_linked_ptr(task.release())); |
144 const std::string& public_key_spki_der, | 342 if (tasks_.size() == 1) |
145 const base::Closure& callback) { | 343 tasks_.front()->Start(); |
146 GetPlatformKeysOfExtension( | |
147 extension_id, | |
148 base::Bind(&PlatformKeysService::RegisterPublicKeyGotPlatformKeys, | |
149 weak_factory_.GetWeakPtr(), | |
150 extension_id, | |
151 public_key_spki_der, | |
152 callback)); | |
153 } | 344 } |
154 | 345 |
155 void PlatformKeysService::ReadValidityAndInvalidateKey( | 346 void PlatformKeysService::TaskFinished(Task* task) { |
156 const std::string& extension_id, | 347 DCHECK(!tasks_.empty()); |
157 const std::string& public_key_spki_der, | 348 DCHECK(task == tasks_.front().get()); |
158 const base::Callback<void(bool)>& callback) { | 349 // Remove all finished tasks from the queue (should be at most one). |
159 GetPlatformKeysOfExtension(extension_id, | 350 while (!tasks_.empty() && tasks_.front()->IsDone()) |
160 base::Bind(&PlatformKeysService::InvalidateKey, | 351 tasks_.pop(); |
161 weak_factory_.GetWeakPtr(), | 352 |
162 extension_id, | 353 // Now either the queue is empty or the next task is not finished yet and it |
163 public_key_spki_der, | 354 // can be started. |
164 callback)); | 355 if (!tasks_.empty()) |
| 356 tasks_.front()->Start(); |
165 } | 357 } |
166 | 358 |
167 void PlatformKeysService::GetPlatformKeysOfExtension( | 359 void PlatformKeysService::GetPlatformKeysOfExtension( |
168 const std::string& extension_id, | 360 const std::string& extension_id, |
169 const GetPlatformKeysCallback& callback) { | 361 const GetPlatformKeysCallback& callback) { |
170 state_store_->GetExtensionValue( | 362 state_store_->GetExtensionValue( |
171 extension_id, kStateStorePlatformKeys, | 363 extension_id, kStateStorePlatformKeys, |
172 base::Bind(&PlatformKeysService::GotPlatformKeysOfExtension, | 364 base::Bind(&PlatformKeysService::GotPlatformKeysOfExtension, |
173 weak_factory_.GetWeakPtr(), extension_id, callback)); | 365 weak_factory_.GetWeakPtr(), extension_id, callback)); |
174 } | 366 } |
175 | 367 |
176 void PlatformKeysService::SetPlatformKeysOfExtension( | 368 void PlatformKeysService::SetPlatformKeysOfExtension( |
177 const std::string& extension_id, | 369 const std::string& extension_id, |
178 scoped_ptr<base::ListValue> platform_keys) { | 370 scoped_ptr<base::ListValue> platform_keys) { |
179 state_store_->SetExtensionValue(extension_id, kStateStorePlatformKeys, | 371 state_store_->SetExtensionValue(extension_id, kStateStorePlatformKeys, |
180 platform_keys.Pass()); | 372 platform_keys.Pass()); |
181 } | 373 } |
182 | 374 |
183 void PlatformKeysService::GenerateRSAKeyCallback( | 375 void PlatformKeysService::GeneratedKey(const std::string& extension_id, |
184 const std::string& extension_id, | 376 const GenerateKeyCallback& callback, |
185 const GenerateKeyCallback& callback, | 377 const std::string& public_key_spki_der, |
186 const std::string& public_key_spki_der, | 378 const std::string& error_message) { |
187 const std::string& error_message) { | |
188 if (!error_message.empty()) { | 379 if (!error_message.empty()) { |
189 callback.Run(std::string() /* no public key */, error_message); | 380 callback.Run(std::string() /* no public key */, error_message); |
190 return; | 381 return; |
191 } | 382 } |
192 base::Closure wrapped_callback( | 383 |
193 base::Bind(&RunGenerateKeyCallback, callback, public_key_spki_der)); | 384 StartOrQueueTask(make_scoped_ptr(new PermissionUpdateTask( |
194 RegisterPublicKey(extension_id, public_key_spki_der, wrapped_callback); | 385 true /* new permission value */, public_key_spki_der, extension_id, |
| 386 base::Bind(&PlatformKeysService::RegisteredGeneratedKey, |
| 387 base::Unretained(this), callback, public_key_spki_der), |
| 388 this))); |
| 389 } |
| 390 |
| 391 void PlatformKeysService::RegisteredGeneratedKey( |
| 392 const GenerateKeyCallback& callback, |
| 393 const std::string& public_key_spki_der, |
| 394 Task* task) { |
| 395 callback.Run(public_key_spki_der, std::string() /* no error */); |
| 396 TaskFinished(task); |
195 } | 397 } |
196 | 398 |
197 void PlatformKeysService::SelectClientCertificatesCallback( | 399 void PlatformKeysService::SelectClientCertificatesCallback( |
198 const std::string& extension_id, | 400 const std::string& extension_id, |
199 const SelectCertificatesCallback& callback, | 401 const SelectCertificatesCallback& callback, |
200 scoped_ptr<net::CertificateList> matches, | 402 scoped_ptr<net::CertificateList> matches, |
201 const std::string& error_message) { | 403 const std::string& error_message) { |
202 if (permission_check_enabled_) | 404 if (permission_check_enabled_) |
203 matches->clear(); | 405 matches->clear(); |
204 | 406 |
205 // TODO(pneubeck): Remove all certs that the extension doesn't have access to. | 407 // TODO(pneubeck): Remove all certs that the extension doesn't have access to. |
206 callback.Run(matches.Pass(), error_message); | 408 callback.Run(matches.Pass(), error_message); |
207 } | 409 } |
208 | 410 |
209 void PlatformKeysService::RegisterPublicKeyGotPlatformKeys( | |
210 const std::string& extension_id, | |
211 const std::string& public_key_spki_der, | |
212 const base::Closure& callback, | |
213 scoped_ptr<base::ListValue> platform_keys) { | |
214 scoped_ptr<base::StringValue> key_value( | |
215 GetPublicKeyValue(public_key_spki_der)); | |
216 | |
217 DCHECK(platform_keys->end() == platform_keys->Find(*key_value)) | |
218 << "Keys are assumed to be generated and not to be registered multiple " | |
219 "times."; | |
220 platform_keys->Append(key_value.release()); | |
221 SetPlatformKeysOfExtension(extension_id, platform_keys.Pass()); | |
222 callback.Run(); | |
223 } | |
224 | |
225 void PlatformKeysService::InvalidateKey( | |
226 const std::string& extension_id, | |
227 const std::string& public_key_spki_der, | |
228 const base::Callback<void(bool)>& callback, | |
229 scoped_ptr<base::ListValue> platform_keys) { | |
230 scoped_ptr<base::StringValue> key_value( | |
231 GetPublicKeyValue(public_key_spki_der)); | |
232 | |
233 size_t index = 0; | |
234 // If the key is found in |platform_keys|, it's valid for the extension to use | |
235 // it for signing. | |
236 bool key_was_valid = platform_keys->Remove(*key_value, &index); | |
237 | |
238 if (key_was_valid) { | |
239 // Persist that the key is now invalid. | |
240 SetPlatformKeysOfExtension(extension_id, platform_keys.Pass()); | |
241 } | |
242 | |
243 if (permission_check_enabled_) { | |
244 // If permission checks are enabled, pass back the key permission (before | |
245 // it was removed above). | |
246 callback.Run(key_was_valid); | |
247 } else { | |
248 // Otherwise just allow signing with the key (which is enabled for testing | |
249 // only). | |
250 callback.Run(true); | |
251 } | |
252 } | |
253 | |
254 void PlatformKeysService::GotPlatformKeysOfExtension( | 411 void PlatformKeysService::GotPlatformKeysOfExtension( |
255 const std::string& extension_id, | 412 const std::string& extension_id, |
256 const GetPlatformKeysCallback& callback, | 413 const GetPlatformKeysCallback& callback, |
257 scoped_ptr<base::Value> value) { | 414 scoped_ptr<base::Value> value) { |
258 if (!value) | 415 if (!value) |
259 value.reset(new base::ListValue); | 416 value.reset(new base::ListValue); |
260 | 417 |
261 base::ListValue* keys = NULL; | 418 base::ListValue* keys = NULL; |
262 if (!value->GetAsList(&keys)) { | 419 if (!value->GetAsList(&keys)) { |
263 LOG(ERROR) << "Found a value of wrong type."; | 420 LOG(ERROR) << "Found a value of wrong type."; |
264 | 421 |
265 keys = new base::ListValue; | 422 keys = new base::ListValue; |
266 value.reset(keys); | 423 value.reset(keys); |
267 } | 424 } |
268 | 425 |
269 ignore_result(value.release()); | 426 ignore_result(value.release()); |
270 callback.Run(make_scoped_ptr(keys)); | 427 callback.Run(make_scoped_ptr(keys)); |
271 } | 428 } |
272 | 429 |
273 } // namespace chromeos | 430 } // namespace chromeos |
OLD | NEW |