Chromium Code Reviews| 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 scoped_ptr<platform_keys::SignRSAParams> params, | |
| 46 const PlatformKeysService::SignCallback& callback, | |
| 47 content::BrowserContext* browser_context, | |
| 48 bool key_is_valid) { | |
| 49 if (!key_is_valid) { | |
| 50 callback.Run(std::string() /* no signature */, | |
| 51 kErrorKeyNotAllowedForSigning); | |
| 52 return; | |
| 53 } | |
| 54 platform_keys::subtle::SignRSA(token_id, params.Pass(), callback, | |
| 55 browser_context); | |
| 56 } | |
| 57 | |
| 58 } // namespace | 34 } // namespace |
| 59 | 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 PermissionUpdateTask(const bool new_permission_value, | |
|
kaliamoorthi
2015/02/09 15:13:15
Document
pneubeck (no reviews)
2015/02/09 15:36:11
Done.
| |
| 56 const std::string& public_key_spki_der, | |
| 57 const std::string& extension_id, | |
| 58 base::Callback<void(Task*)> callback, | |
| 59 PlatformKeysService* service) | |
| 60 : new_permission_value_(new_permission_value), | |
| 61 public_key_spki_der_(public_key_spki_der), | |
| 62 extension_id_(extension_id), | |
| 63 callback_(callback), | |
| 64 service_(service), | |
| 65 weak_factory_(this) {} | |
| 66 | |
| 67 ~PermissionUpdateTask() override {} | |
| 68 | |
| 69 void Start() override { | |
| 70 CHECK(next_step_ == Step::READ_PLATFORM_KEYS); | |
| 71 DoStep(); | |
| 72 } | |
| 73 | |
| 74 bool IsDone() override { return next_step_ == Step::DONE; } | |
| 75 | |
| 76 bool old_permission_value() { return old_permission_value_; } | |
| 77 | |
| 78 private: | |
| 79 void DoStep() { | |
| 80 switch (next_step_) { | |
| 81 case Step::READ_PLATFORM_KEYS: | |
| 82 next_step_ = Step::WRITE_UPDATE_AND_CALLBACK; | |
| 83 ReadPlatformKeys(); | |
| 84 return; | |
| 85 case Step::WRITE_UPDATE_AND_CALLBACK: | |
| 86 next_step_ = Step::DONE; | |
| 87 WriteUpdate(); | |
| 88 if (!callback_.is_null()) { | |
| 89 // Make a local copy of the callback to run as it might be deleted | |
| 90 // during the Run(). | |
| 91 base::ResetAndReturn(&callback_).Run(this); | |
| 92 // |this| might be invalid now. | |
| 93 } | |
| 94 return; | |
| 95 case Step::DONE: | |
| 96 NOTREACHED(); | |
| 97 return; | |
| 98 } | |
| 99 } | |
| 100 | |
| 101 // Reads the PlatformKeys value from the extension's state store and calls | |
| 102 // back to GotPlatformKeys(). | |
| 103 void ReadPlatformKeys() { | |
| 104 service_->GetPlatformKeysOfExtension( | |
| 105 extension_id_, base::Bind(&PermissionUpdateTask::GotPlatformKeys, | |
| 106 weak_factory_.GetWeakPtr())); | |
| 107 } | |
| 108 | |
| 109 void GotPlatformKeys(scoped_ptr<base::ListValue> platform_keys) { | |
| 110 platform_keys_ = platform_keys.Pass(); | |
| 111 DoStep(); | |
| 112 } | |
| 113 | |
| 114 // Returns whether the extension has permission to use the key for signing | |
| 115 // according to the PlatformKeys value read from the extensions state store. | |
| 116 // Invalidates the key if it was found to be valid. | |
| 117 void WriteUpdate() { | |
| 118 scoped_ptr<base::StringValue> key_value( | |
| 119 GetPublicKeyValue(public_key_spki_der_)); | |
| 120 | |
| 121 base::ListValue::const_iterator it = platform_keys_->Find(*key_value); | |
| 122 old_permission_value_ = it != platform_keys_->end(); | |
| 123 if (old_permission_value_ == new_permission_value_) | |
| 124 return; | |
| 125 | |
| 126 if (new_permission_value_) | |
| 127 platform_keys_->Append(key_value.release()); | |
| 128 else | |
| 129 platform_keys_->Remove(*key_value, nullptr); | |
| 130 | |
| 131 service_->SetPlatformKeysOfExtension(extension_id_, platform_keys_.Pass()); | |
| 132 } | |
| 133 | |
| 134 Step next_step_ = Step::READ_PLATFORM_KEYS; | |
| 135 scoped_ptr<base::ListValue> platform_keys_; | |
| 136 bool old_permission_value_ = false; | |
| 137 | |
| 138 const bool new_permission_value_; | |
| 139 const std::string public_key_spki_der_; | |
| 140 const std::string extension_id_; | |
| 141 base::Callback<void(Task*)> callback_; | |
| 142 PlatformKeysService* const service_; | |
| 143 base::WeakPtrFactory<PermissionUpdateTask> weak_factory_; | |
| 144 | |
| 145 DISALLOW_COPY_AND_ASSIGN(PermissionUpdateTask); | |
| 146 }; | |
| 147 | |
| 148 class PlatformKeysService::SignTask : public Task { | |
| 149 public: | |
| 150 enum class Step { | |
| 151 UPDATE_PERMISSION, | |
| 152 SIGN_OR_ABORT, | |
| 153 DONE, | |
| 154 }; | |
| 155 | |
| 156 // This Task will check the permissions of the extension with |extension_id| | |
| 157 // for the key identified by |public_key_spki_der|, then updates the | |
| 158 // permission to prevent any future signing operation of that extension using | |
| 159 // that same key. If the permission check was positive, it will actually sign | |
| 160 // |data| with the key and pass the signature to |callback|. | |
| 161 // If an error occurs, an error message is passed to |callback| instead. | |
| 162 SignTask(const std::string& token_id, | |
| 163 scoped_ptr<platform_keys::SignRSAParams> params, | |
| 164 const std::string& extension_id, | |
| 165 const SignCallback& callback, | |
| 166 PlatformKeysService* service) | |
| 167 : token_id_(token_id), | |
| 168 params_(params.Pass()), | |
| 169 extension_id_(extension_id), | |
| 170 callback_(callback), | |
| 171 service_(service), | |
| 172 weak_factory_(this) {} | |
| 173 ~SignTask() override {} | |
| 174 | |
| 175 void Start() override { | |
| 176 CHECK(next_step_ == Step::UPDATE_PERMISSION); | |
| 177 DoStep(); | |
| 178 } | |
| 179 bool IsDone() override { return next_step_ == Step::DONE; } | |
| 180 | |
| 181 private: | |
| 182 void DoStep() { | |
| 183 switch (next_step_) { | |
| 184 case Step::UPDATE_PERMISSION: | |
| 185 next_step_ = Step::SIGN_OR_ABORT; | |
| 186 UpdatePermission(); | |
| 187 return; | |
| 188 case Step::SIGN_OR_ABORT: | |
| 189 next_step_ = Step::DONE; | |
| 190 if (!service_->permission_check_enabled_ || | |
| 191 permission_update_->old_permission_value()) { | |
| 192 Sign(); | |
| 193 } else { | |
| 194 callback_.Run(std::string() /* no signature */, | |
| 195 kErrorKeyNotAllowedForSigning); | |
| 196 DoStep(); | |
| 197 } | |
| 198 return; | |
| 199 case Step::DONE: | |
| 200 service_->TaskFinished(this); | |
| 201 // |this| might be invalid now. | |
| 202 return; | |
| 203 } | |
| 204 } | |
| 205 | |
| 206 // Reads the current permission of the extension with |extension_id_| for key | |
| 207 // |params_->public_key| and updates the permission to disable further | |
| 208 // signing operations with that key. | |
| 209 void UpdatePermission() { | |
| 210 permission_update_.reset(new PermissionUpdateTask( | |
| 211 false /* new permission value */, params_->public_key(), extension_id_, | |
| 212 base::Bind(&SignTask::DidUpdatePermission, weak_factory_.GetWeakPtr()), | |
| 213 service_)); | |
| 214 permission_update_->Start(); | |
| 215 } | |
| 216 | |
| 217 void DidUpdatePermission(Task* /* task */) { DoStep(); } | |
| 218 | |
| 219 // Starts the actual signing operation and afterwards passes the signature (or | |
| 220 // error) to |callback_|. | |
| 221 void Sign() { | |
| 222 platform_keys::subtle::SignRSA( | |
| 223 token_id_, params_.Pass(), | |
| 224 base::Bind(&SignTask::DidSign, weak_factory_.GetWeakPtr()), | |
| 225 service_->browser_context_); | |
| 226 } | |
| 227 | |
| 228 void DidSign(const std::string& signature, const std::string& error_message) { | |
| 229 callback_.Run(signature, error_message); | |
| 230 DoStep(); | |
| 231 } | |
| 232 | |
| 233 Step next_step_ = Step::UPDATE_PERMISSION; | |
| 234 scoped_ptr<base::ListValue> platform_keys_; | |
| 235 scoped_ptr<PermissionUpdateTask> permission_update_; | |
| 236 | |
| 237 const std::string token_id_; | |
| 238 scoped_ptr<platform_keys::SignRSAParams> params_; | |
| 239 const std::string extension_id_; | |
| 240 const SignCallback callback_; | |
| 241 PlatformKeysService* const service_; | |
| 242 base::WeakPtrFactory<SignTask> weak_factory_; | |
| 243 | |
| 244 DISALLOW_COPY_AND_ASSIGN(SignTask); | |
| 245 }; | |
| 246 | |
| 60 PlatformKeysService::PlatformKeysService( | 247 PlatformKeysService::PlatformKeysService( |
| 61 content::BrowserContext* browser_context, | 248 content::BrowserContext* browser_context, |
| 62 extensions::StateStore* state_store) | 249 extensions::StateStore* state_store) |
| 63 : browser_context_(browser_context), | 250 : browser_context_(browser_context), |
| 64 state_store_(state_store), | 251 state_store_(state_store), |
| 65 weak_factory_(this) { | 252 weak_factory_(this) { |
| 66 DCHECK(state_store); | 253 DCHECK(state_store); |
| 67 } | 254 } |
| 68 | 255 |
| 69 PlatformKeysService::~PlatformKeysService() { | 256 PlatformKeysService::~PlatformKeysService() { |
| 70 } | 257 } |
| 71 | 258 |
| 72 void PlatformKeysService::DisablePermissionCheckForTesting() { | 259 void PlatformKeysService::DisablePermissionCheckForTesting() { |
| 73 permission_check_enabled_ = false; | 260 permission_check_enabled_ = false; |
| 74 } | 261 } |
| 75 | 262 |
| 76 void PlatformKeysService::GenerateRSAKey(const std::string& token_id, | 263 void PlatformKeysService::GenerateRSAKey(const std::string& token_id, |
| 77 unsigned int modulus_length, | 264 unsigned int modulus_length, |
| 78 const std::string& extension_id, | 265 const std::string& extension_id, |
| 79 const GenerateKeyCallback& callback) { | 266 const GenerateKeyCallback& callback) { |
| 80 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 267 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 81 | 268 |
| 82 platform_keys::subtle::GenerateRSAKey( | 269 platform_keys::subtle::GenerateRSAKey( |
| 83 token_id, | 270 token_id, modulus_length, |
| 84 modulus_length, | 271 base::Bind(&PlatformKeysService::GeneratedKey, weak_factory_.GetWeakPtr(), |
| 85 base::Bind(&PlatformKeysService::GenerateRSAKeyCallback, | 272 extension_id, callback), |
| 86 weak_factory_.GetWeakPtr(), | |
| 87 extension_id, | |
| 88 callback), | |
| 89 browser_context_); | 273 browser_context_); |
| 90 } | 274 } |
| 91 | 275 |
| 92 void PlatformKeysService::SignRSA( | 276 void PlatformKeysService::SignRSA( |
| 93 const std::string& token_id, | 277 const std::string& token_id, |
| 94 scoped_ptr<platform_keys::SignRSAParams> params, | 278 scoped_ptr<platform_keys::SignRSAParams> params, |
| 95 const std::string& extension_id, | 279 const std::string& extension_id, |
| 96 const SignCallback& callback) { | 280 const SignCallback& callback) { |
| 97 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 281 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 98 ReadValidityAndInvalidateKey( | 282 StartOrQueueTask(make_scoped_ptr( |
| 99 extension_id, params->public_key(), | 283 new SignTask(token_id, params.Pass(), extension_id, callback, this))); |
| 100 base::Bind(&CheckValidityAndSign, token_id, base::Passed(¶ms), | |
| 101 callback, browser_context_)); | |
| 102 } | 284 } |
| 103 | 285 |
| 104 void PlatformKeysService::SelectClientCertificates( | 286 void PlatformKeysService::SelectClientCertificates( |
| 105 const platform_keys::ClientCertificateRequest& request, | 287 const platform_keys::ClientCertificateRequest& request, |
| 106 const std::string& extension_id, | 288 const std::string& extension_id, |
| 107 const SelectCertificatesCallback& callback) { | 289 const SelectCertificatesCallback& callback) { |
| 108 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 290 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 109 | 291 |
| 110 platform_keys::subtle::SelectClientCertificates( | 292 platform_keys::subtle::SelectClientCertificates( |
| 111 request, | 293 request, |
| 112 base::Bind(&PlatformKeysService::SelectClientCertificatesCallback, | 294 base::Bind(&PlatformKeysService::SelectClientCertificatesCallback, |
| 113 weak_factory_.GetWeakPtr(), extension_id, callback), | 295 weak_factory_.GetWeakPtr(), extension_id, callback), |
| 114 browser_context_); | 296 browser_context_); |
| 115 } | 297 } |
| 116 | 298 |
| 117 void PlatformKeysService::RegisterPublicKey( | 299 void PlatformKeysService::StartOrQueueTask(scoped_ptr<Task> task) { |
| 118 const std::string& extension_id, | 300 tasks_.push(make_linked_ptr(task.release())); |
|
kaliamoorthi
2015/02/09 15:13:15
Is there are reason why linked_ptr is used here ra
pneubeck (no reviews)
2015/02/09 15:36:11
scoped_ptrs don't work in containers as it interna
| |
| 119 const std::string& public_key_spki_der, | 301 if (tasks_.size() == 1) |
| 120 const base::Closure& callback) { | 302 tasks_.front()->Start(); |
| 121 GetPlatformKeysOfExtension( | |
| 122 extension_id, | |
| 123 base::Bind(&PlatformKeysService::RegisterPublicKeyGotPlatformKeys, | |
| 124 weak_factory_.GetWeakPtr(), | |
| 125 extension_id, | |
| 126 public_key_spki_der, | |
| 127 callback)); | |
| 128 } | 303 } |
| 129 | 304 |
| 130 void PlatformKeysService::ReadValidityAndInvalidateKey( | 305 void PlatformKeysService::TaskFinished(Task* task) { |
| 131 const std::string& extension_id, | 306 DCHECK(!tasks_.empty()); |
| 132 const std::string& public_key_spki_der, | 307 DCHECK(task == tasks_.front().get()); |
| 133 const base::Callback<void(bool)>& callback) { | 308 while (!tasks_.empty() && tasks_.front()->IsDone()) |
|
kaliamoorthi
2015/02/09 15:13:15
Can multiple tasks execute at the same time? Eithe
pneubeck (no reviews)
2015/02/09 15:36:11
At most one task is running at a time.
Do you sugg
| |
| 134 GetPlatformKeysOfExtension(extension_id, | 309 tasks_.pop(); |
| 135 base::Bind(&PlatformKeysService::InvalidateKey, | 310 |
| 136 weak_factory_.GetWeakPtr(), | 311 if (!tasks_.empty()) |
| 137 extension_id, | 312 tasks_.front()->Start(); |
| 138 public_key_spki_der, | |
| 139 callback)); | |
| 140 } | 313 } |
| 141 | 314 |
| 142 void PlatformKeysService::GetPlatformKeysOfExtension( | 315 void PlatformKeysService::GetPlatformKeysOfExtension( |
| 143 const std::string& extension_id, | 316 const std::string& extension_id, |
| 144 const GetPlatformKeysCallback& callback) { | 317 const GetPlatformKeysCallback& callback) { |
| 145 state_store_->GetExtensionValue( | 318 state_store_->GetExtensionValue( |
| 146 extension_id, kStateStorePlatformKeys, | 319 extension_id, kStateStorePlatformKeys, |
| 147 base::Bind(&PlatformKeysService::GotPlatformKeysOfExtension, | 320 base::Bind(&PlatformKeysService::GotPlatformKeysOfExtension, |
| 148 weak_factory_.GetWeakPtr(), extension_id, callback)); | 321 weak_factory_.GetWeakPtr(), extension_id, callback)); |
| 149 } | 322 } |
| 150 | 323 |
| 151 void PlatformKeysService::SetPlatformKeysOfExtension( | 324 void PlatformKeysService::SetPlatformKeysOfExtension( |
| 152 const std::string& extension_id, | 325 const std::string& extension_id, |
| 153 scoped_ptr<base::ListValue> platform_keys) { | 326 scoped_ptr<base::ListValue> platform_keys) { |
| 154 state_store_->SetExtensionValue(extension_id, kStateStorePlatformKeys, | 327 state_store_->SetExtensionValue(extension_id, kStateStorePlatformKeys, |
| 155 platform_keys.Pass()); | 328 platform_keys.Pass()); |
| 156 } | 329 } |
| 157 | 330 |
| 158 void PlatformKeysService::GenerateRSAKeyCallback( | 331 void PlatformKeysService::GeneratedKey(const std::string& extension_id, |
| 159 const std::string& extension_id, | 332 const GenerateKeyCallback& callback, |
| 160 const GenerateKeyCallback& callback, | 333 const std::string& public_key_spki_der, |
| 161 const std::string& public_key_spki_der, | 334 const std::string& error_message) { |
| 162 const std::string& error_message) { | |
| 163 if (!error_message.empty()) { | 335 if (!error_message.empty()) { |
| 164 callback.Run(std::string() /* no public key */, error_message); | 336 callback.Run(std::string() /* no public key */, error_message); |
| 165 return; | 337 return; |
| 166 } | 338 } |
| 167 base::Closure wrapped_callback( | 339 |
| 168 base::Bind(&RunGenerateKeyCallback, callback, public_key_spki_der)); | 340 StartOrQueueTask(make_scoped_ptr(new PermissionUpdateTask( |
| 169 RegisterPublicKey(extension_id, public_key_spki_der, wrapped_callback); | 341 true /* new permission value */, public_key_spki_der, extension_id, |
| 342 base::Bind(&PlatformKeysService::DidRegisterGeneratedKey, | |
| 343 base::Unretained(this), callback, public_key_spki_der), | |
| 344 this))); | |
| 345 } | |
| 346 | |
| 347 void PlatformKeysService::DidRegisterGeneratedKey( | |
| 348 const GenerateKeyCallback& callback, | |
| 349 const std::string& public_key_spki_der, | |
| 350 Task* task) { | |
| 351 callback.Run(public_key_spki_der, std::string() /* no error */); | |
|
kaliamoorthi
2015/02/09 15:13:15
Why is this parameter needed if it is empty? If it
pneubeck (no reviews)
2015/02/09 15:36:11
which parameter? the error parameter?
See Generate
| |
| 352 TaskFinished(task); | |
| 170 } | 353 } |
| 171 | 354 |
| 172 void PlatformKeysService::SelectClientCertificatesCallback( | 355 void PlatformKeysService::SelectClientCertificatesCallback( |
| 173 const std::string& extension_id, | 356 const std::string& extension_id, |
| 174 const SelectCertificatesCallback& callback, | 357 const SelectCertificatesCallback& callback, |
| 175 scoped_ptr<net::CertificateList> matches, | 358 scoped_ptr<net::CertificateList> matches, |
| 176 const std::string& error_message) { | 359 const std::string& error_message) { |
| 177 if (permission_check_enabled_) | 360 if (permission_check_enabled_) |
| 178 matches->clear(); | 361 matches->clear(); |
| 179 | 362 |
| 180 // TODO(pneubeck): Remove all certs that the extension doesn't have access to. | 363 // TODO(pneubeck): Remove all certs that the extension doesn't have access to. |
| 181 callback.Run(matches.Pass(), error_message); | 364 callback.Run(matches.Pass(), error_message); |
| 182 } | 365 } |
| 183 | 366 |
| 184 void PlatformKeysService::RegisterPublicKeyGotPlatformKeys( | |
| 185 const std::string& extension_id, | |
| 186 const std::string& public_key_spki_der, | |
| 187 const base::Closure& callback, | |
| 188 scoped_ptr<base::ListValue> platform_keys) { | |
| 189 scoped_ptr<base::StringValue> key_value( | |
| 190 GetPublicKeyValue(public_key_spki_der)); | |
| 191 | |
| 192 DCHECK(platform_keys->end() == platform_keys->Find(*key_value)) | |
| 193 << "Keys are assumed to be generated and not to be registered multiple " | |
| 194 "times."; | |
| 195 platform_keys->Append(key_value.release()); | |
| 196 SetPlatformKeysOfExtension(extension_id, platform_keys.Pass()); | |
| 197 callback.Run(); | |
| 198 } | |
| 199 | |
| 200 void PlatformKeysService::InvalidateKey( | |
| 201 const std::string& extension_id, | |
| 202 const std::string& public_key_spki_der, | |
| 203 const base::Callback<void(bool)>& callback, | |
| 204 scoped_ptr<base::ListValue> platform_keys) { | |
| 205 scoped_ptr<base::StringValue> key_value( | |
| 206 GetPublicKeyValue(public_key_spki_der)); | |
| 207 | |
| 208 size_t index = 0; | |
| 209 // If the key is found in |platform_keys|, it's valid for the extension to use | |
| 210 // it for signing. | |
| 211 bool key_was_valid = platform_keys->Remove(*key_value, &index); | |
| 212 | |
| 213 if (key_was_valid) { | |
| 214 // Persist that the key is now invalid. | |
| 215 SetPlatformKeysOfExtension(extension_id, platform_keys.Pass()); | |
| 216 } | |
| 217 | |
| 218 if (permission_check_enabled_) { | |
| 219 // If permission checks are enabled, pass back the key permission (before | |
| 220 // it was removed above). | |
| 221 callback.Run(key_was_valid); | |
| 222 } else { | |
| 223 // Otherwise just allow signing with the key (which is enabled for testing | |
| 224 // only). | |
| 225 callback.Run(true); | |
| 226 } | |
| 227 } | |
| 228 | |
| 229 void PlatformKeysService::GotPlatformKeysOfExtension( | 367 void PlatformKeysService::GotPlatformKeysOfExtension( |
| 230 const std::string& extension_id, | 368 const std::string& extension_id, |
| 231 const GetPlatformKeysCallback& callback, | 369 const GetPlatformKeysCallback& callback, |
| 232 scoped_ptr<base::Value> value) { | 370 scoped_ptr<base::Value> value) { |
| 233 if (!value) | 371 if (!value) |
| 234 value.reset(new base::ListValue); | 372 value.reset(new base::ListValue); |
| 235 | 373 |
| 236 base::ListValue* keys = NULL; | 374 base::ListValue* keys = NULL; |
| 237 if (!value->GetAsList(&keys)) { | 375 if (!value->GetAsList(&keys)) { |
| 238 LOG(ERROR) << "Found a value of wrong type."; | 376 LOG(ERROR) << "Found a value of wrong type."; |
| 239 | 377 |
| 240 keys = new base::ListValue; | 378 keys = new base::ListValue; |
| 241 value.reset(keys); | 379 value.reset(keys); |
| 242 } | 380 } |
| 243 | 381 |
| 244 ignore_result(value.release()); | 382 ignore_result(value.release()); |
| 245 callback.Run(make_scoped_ptr(keys)); | 383 callback.Run(make_scoped_ptr(keys)); |
| 246 } | 384 } |
| 247 | 385 |
| 248 } // namespace chromeos | 386 } // namespace chromeos |
| OLD | NEW |