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 // 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 scoped_ptr<platform_keys::SignRSAParams> params, | |
| 171 const std::string& extension_id, | |
| 172 const SignCallback& callback, | |
| 173 PlatformKeysService* service) | |
| 174 : token_id_(token_id), | |
| 175 params_(params.Pass()), | |
| 176 extension_id_(extension_id), | |
| 177 callback_(callback), | |
| 178 service_(service), | |
| 179 weak_factory_(this) {} | |
| 180 ~SignTask() override {} | |
| 181 | |
| 182 void Start() override { | |
| 183 CHECK(next_step_ == Step::UPDATE_PERMISSION); | |
| 184 DoStep(); | |
| 185 } | |
| 186 bool IsDone() override { return next_step_ == Step::DONE; } | |
| 187 | |
| 188 private: | |
| 189 void DoStep() { | |
| 190 switch (next_step_) { | |
| 191 case Step::UPDATE_PERMISSION: | |
| 192 next_step_ = Step::SIGN_OR_ABORT; | |
| 193 UpdatePermission(); | |
| 194 return; | |
| 195 case Step::SIGN_OR_ABORT: | |
| 196 next_step_ = Step::DONE; | |
| 197 if (!service_->permission_check_enabled_ || | |
| 198 permission_update_->old_permission_value()) { | |
| 199 Sign(); | |
| 200 } else { | |
| 201 callback_.Run(std::string() /* no signature */, | |
| 202 kErrorKeyNotAllowedForSigning); | |
| 203 DoStep(); | |
| 204 } | |
| 205 return; | |
| 206 case Step::DONE: | |
| 207 service_->TaskFinished(this); | |
| 208 // |this| might be invalid now. | |
| 209 return; | |
| 210 } | |
| 211 } | |
| 212 | |
| 213 // Reads the current permission of the extension with |extension_id_| for key | |
| 214 // |params_->public_key| and updates the permission to disable further | |
| 215 // signing operations with that key. | |
| 216 void UpdatePermission() { | |
| 217 permission_update_.reset(new PermissionUpdateTask( | |
| 218 false /* new permission value */, params_->public_key(), extension_id_, | |
| 219 base::Bind(&SignTask::DidUpdatePermission, weak_factory_.GetWeakPtr()), | |
| 220 service_)); | |
| 221 permission_update_->Start(); | |
| 222 } | |
| 223 | |
| 224 void DidUpdatePermission(Task* /* task */) { DoStep(); } | |
| 225 | |
| 226 // Starts the actual signing operation and afterwards passes the signature (or | |
| 227 // error) to |callback_|. | |
| 228 void Sign() { | |
| 229 platform_keys::subtle::SignRSA( | |
| 230 token_id_, params_.Pass(), | |
| 231 base::Bind(&SignTask::DidSign, weak_factory_.GetWeakPtr()), | |
| 232 service_->browser_context_); | |
| 233 } | |
| 234 | |
| 235 void DidSign(const std::string& signature, const std::string& error_message) { | |
| 236 callback_.Run(signature, error_message); | |
| 237 DoStep(); | |
| 238 } | |
| 239 | |
| 240 Step next_step_ = Step::UPDATE_PERMISSION; | |
| 241 scoped_ptr<base::ListValue> platform_keys_; | |
| 242 scoped_ptr<PermissionUpdateTask> permission_update_; | |
| 243 | |
| 244 const std::string token_id_; | |
| 245 scoped_ptr<platform_keys::SignRSAParams> params_; | |
| 246 const std::string extension_id_; | |
| 247 const SignCallback callback_; | |
| 248 PlatformKeysService* const service_; | |
| 249 base::WeakPtrFactory<SignTask> weak_factory_; | |
| 250 | |
| 251 DISALLOW_COPY_AND_ASSIGN(SignTask); | |
| 252 }; | |
| 253 | |
| 60 PlatformKeysService::PlatformKeysService( | 254 PlatformKeysService::PlatformKeysService( |
| 61 content::BrowserContext* browser_context, | 255 content::BrowserContext* browser_context, |
| 62 extensions::StateStore* state_store) | 256 extensions::StateStore* state_store) |
| 63 : browser_context_(browser_context), | 257 : browser_context_(browser_context), |
| 64 state_store_(state_store), | 258 state_store_(state_store), |
| 65 weak_factory_(this) { | 259 weak_factory_(this) { |
| 66 DCHECK(state_store); | 260 DCHECK(state_store); |
| 67 } | 261 } |
| 68 | 262 |
| 69 PlatformKeysService::~PlatformKeysService() { | 263 PlatformKeysService::~PlatformKeysService() { |
| 70 } | 264 } |
| 71 | 265 |
| 72 void PlatformKeysService::DisablePermissionCheckForTesting() { | 266 void PlatformKeysService::DisablePermissionCheckForTesting() { |
| 73 permission_check_enabled_ = false; | 267 permission_check_enabled_ = false; |
| 74 } | 268 } |
| 75 | 269 |
| 76 void PlatformKeysService::GenerateRSAKey(const std::string& token_id, | 270 void PlatformKeysService::GenerateRSAKey(const std::string& token_id, |
| 77 unsigned int modulus_length, | 271 unsigned int modulus_length, |
| 78 const std::string& extension_id, | 272 const std::string& extension_id, |
| 79 const GenerateKeyCallback& callback) { | 273 const GenerateKeyCallback& callback) { |
| 80 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 274 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 81 | 275 |
| 82 platform_keys::subtle::GenerateRSAKey( | 276 platform_keys::subtle::GenerateRSAKey( |
| 83 token_id, | 277 token_id, modulus_length, |
| 84 modulus_length, | 278 base::Bind(&PlatformKeysService::GeneratedKey, weak_factory_.GetWeakPtr(), |
| 85 base::Bind(&PlatformKeysService::GenerateRSAKeyCallback, | 279 extension_id, callback), |
| 86 weak_factory_.GetWeakPtr(), | |
| 87 extension_id, | |
| 88 callback), | |
| 89 browser_context_); | 280 browser_context_); |
| 90 } | 281 } |
| 91 | 282 |
| 92 void PlatformKeysService::SignRSA( | 283 void PlatformKeysService::SignRSA( |
| 93 const std::string& token_id, | 284 const std::string& token_id, |
| 94 scoped_ptr<platform_keys::SignRSAParams> params, | 285 scoped_ptr<platform_keys::SignRSAParams> params, |
| 95 const std::string& extension_id, | 286 const std::string& extension_id, |
| 96 const SignCallback& callback) { | 287 const SignCallback& callback) { |
| 97 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 288 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 98 ReadValidityAndInvalidateKey( | 289 StartOrQueueTask(make_scoped_ptr( |
| 99 extension_id, params->public_key(), | 290 new SignTask(token_id, params.Pass(), extension_id, callback, this))); |
| 100 base::Bind(&CheckValidityAndSign, token_id, base::Passed(¶ms), | |
| 101 callback, browser_context_)); | |
| 102 } | 291 } |
| 103 | 292 |
| 104 void PlatformKeysService::SelectClientCertificates( | 293 void PlatformKeysService::SelectClientCertificates( |
| 105 const platform_keys::ClientCertificateRequest& request, | 294 const platform_keys::ClientCertificateRequest& request, |
| 106 const std::string& extension_id, | 295 const std::string& extension_id, |
| 107 const SelectCertificatesCallback& callback) { | 296 const SelectCertificatesCallback& callback) { |
| 108 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 297 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 109 | 298 |
| 110 platform_keys::subtle::SelectClientCertificates( | 299 platform_keys::subtle::SelectClientCertificates( |
| 111 request, | 300 request, |
| 112 base::Bind(&PlatformKeysService::SelectClientCertificatesCallback, | 301 base::Bind(&PlatformKeysService::SelectClientCertificatesCallback, |
| 113 weak_factory_.GetWeakPtr(), extension_id, callback), | 302 weak_factory_.GetWeakPtr(), extension_id, callback), |
| 114 browser_context_); | 303 browser_context_); |
| 115 } | 304 } |
| 116 | 305 |
| 117 void PlatformKeysService::RegisterPublicKey( | 306 void PlatformKeysService::StartOrQueueTask(scoped_ptr<Task> task) { |
| 118 const std::string& extension_id, | 307 tasks_.push(make_linked_ptr(task.release())); |
| 119 const std::string& public_key_spki_der, | 308 if (tasks_.size() == 1) |
| 120 const base::Closure& callback) { | 309 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 } | 310 } |
| 129 | 311 |
| 130 void PlatformKeysService::ReadValidityAndInvalidateKey( | 312 void PlatformKeysService::TaskFinished(Task* task) { |
| 131 const std::string& extension_id, | 313 DCHECK(!tasks_.empty()); |
| 132 const std::string& public_key_spki_der, | 314 DCHECK(task == tasks_.front().get()); |
| 133 const base::Callback<void(bool)>& callback) { | 315 // Remove all finished tasks from the queue (should be at most one). |
| 134 GetPlatformKeysOfExtension(extension_id, | 316 while (!tasks_.empty() && tasks_.front()->IsDone()) |
| 135 base::Bind(&PlatformKeysService::InvalidateKey, | 317 tasks_.pop(); |
| 136 weak_factory_.GetWeakPtr(), | 318 |
| 137 extension_id, | 319 // Now either the queue is empty or the next task is not finished yet and it |
| 138 public_key_spki_der, | 320 // can be started. |
| 139 callback)); | 321 if (!tasks_.empty()) |
| 322 tasks_.front()->Start(); | |
| 140 } | 323 } |
| 141 | 324 |
| 142 void PlatformKeysService::GetPlatformKeysOfExtension( | 325 void PlatformKeysService::GetPlatformKeysOfExtension( |
| 143 const std::string& extension_id, | 326 const std::string& extension_id, |
| 144 const GetPlatformKeysCallback& callback) { | 327 const GetPlatformKeysCallback& callback) { |
| 145 state_store_->GetExtensionValue( | 328 state_store_->GetExtensionValue( |
| 146 extension_id, kStateStorePlatformKeys, | 329 extension_id, kStateStorePlatformKeys, |
| 147 base::Bind(&PlatformKeysService::GotPlatformKeysOfExtension, | 330 base::Bind(&PlatformKeysService::GotPlatformKeysOfExtension, |
| 148 weak_factory_.GetWeakPtr(), extension_id, callback)); | 331 weak_factory_.GetWeakPtr(), extension_id, callback)); |
| 149 } | 332 } |
| 150 | 333 |
| 151 void PlatformKeysService::SetPlatformKeysOfExtension( | 334 void PlatformKeysService::SetPlatformKeysOfExtension( |
| 152 const std::string& extension_id, | 335 const std::string& extension_id, |
| 153 scoped_ptr<base::ListValue> platform_keys) { | 336 scoped_ptr<base::ListValue> platform_keys) { |
| 154 state_store_->SetExtensionValue(extension_id, kStateStorePlatformKeys, | 337 state_store_->SetExtensionValue(extension_id, kStateStorePlatformKeys, |
| 155 platform_keys.Pass()); | 338 platform_keys.Pass()); |
| 156 } | 339 } |
| 157 | 340 |
| 158 void PlatformKeysService::GenerateRSAKeyCallback( | 341 void PlatformKeysService::GeneratedKey(const std::string& extension_id, |
| 159 const std::string& extension_id, | 342 const GenerateKeyCallback& callback, |
| 160 const GenerateKeyCallback& callback, | 343 const std::string& public_key_spki_der, |
| 161 const std::string& public_key_spki_der, | 344 const std::string& error_message) { |
| 162 const std::string& error_message) { | |
| 163 if (!error_message.empty()) { | 345 if (!error_message.empty()) { |
| 164 callback.Run(std::string() /* no public key */, error_message); | 346 callback.Run(std::string() /* no public key */, error_message); |
| 165 return; | 347 return; |
| 166 } | 348 } |
| 167 base::Closure wrapped_callback( | 349 |
| 168 base::Bind(&RunGenerateKeyCallback, callback, public_key_spki_der)); | 350 StartOrQueueTask(make_scoped_ptr(new PermissionUpdateTask( |
| 169 RegisterPublicKey(extension_id, public_key_spki_der, wrapped_callback); | 351 true /* new permission value */, public_key_spki_der, extension_id, |
| 352 base::Bind(&PlatformKeysService::DidRegisterGeneratedKey, | |
| 353 base::Unretained(this), callback, public_key_spki_der), | |
| 354 this))); | |
| 355 } | |
| 356 | |
| 357 void PlatformKeysService::DidRegisterGeneratedKey( | |
|
kaliamoorthi
2015/02/09 16:02:10
nit: How about RegisteredGeneratedKey? I see other
pneubeck (no reviews)
2015/02/15 09:25:57
Done.
| |
| 358 const GenerateKeyCallback& callback, | |
| 359 const std::string& public_key_spki_der, | |
| 360 Task* task) { | |
| 361 callback.Run(public_key_spki_der, std::string() /* no error */); | |
| 362 TaskFinished(task); | |
| 170 } | 363 } |
| 171 | 364 |
| 172 void PlatformKeysService::SelectClientCertificatesCallback( | 365 void PlatformKeysService::SelectClientCertificatesCallback( |
| 173 const std::string& extension_id, | 366 const std::string& extension_id, |
| 174 const SelectCertificatesCallback& callback, | 367 const SelectCertificatesCallback& callback, |
| 175 scoped_ptr<net::CertificateList> matches, | 368 scoped_ptr<net::CertificateList> matches, |
| 176 const std::string& error_message) { | 369 const std::string& error_message) { |
| 177 if (permission_check_enabled_) | 370 if (permission_check_enabled_) |
| 178 matches->clear(); | 371 matches->clear(); |
| 179 | 372 |
| 180 // TODO(pneubeck): Remove all certs that the extension doesn't have access to. | 373 // TODO(pneubeck): Remove all certs that the extension doesn't have access to. |
| 181 callback.Run(matches.Pass(), error_message); | 374 callback.Run(matches.Pass(), error_message); |
| 182 } | 375 } |
| 183 | 376 |
| 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( | 377 void PlatformKeysService::GotPlatformKeysOfExtension( |
| 230 const std::string& extension_id, | 378 const std::string& extension_id, |
| 231 const GetPlatformKeysCallback& callback, | 379 const GetPlatformKeysCallback& callback, |
| 232 scoped_ptr<base::Value> value) { | 380 scoped_ptr<base::Value> value) { |
| 233 if (!value) | 381 if (!value) |
| 234 value.reset(new base::ListValue); | 382 value.reset(new base::ListValue); |
| 235 | 383 |
| 236 base::ListValue* keys = NULL; | 384 base::ListValue* keys = NULL; |
| 237 if (!value->GetAsList(&keys)) { | 385 if (!value->GetAsList(&keys)) { |
| 238 LOG(ERROR) << "Found a value of wrong type."; | 386 LOG(ERROR) << "Found a value of wrong type."; |
| 239 | 387 |
| 240 keys = new base::ListValue; | 388 keys = new base::ListValue; |
| 241 value.reset(keys); | 389 value.reset(keys); |
| 242 } | 390 } |
| 243 | 391 |
| 244 ignore_result(value.release()); | 392 ignore_result(value.release()); |
| 245 callback.Run(make_scoped_ptr(keys)); | 393 callback.Run(make_scoped_ptr(keys)); |
| 246 } | 394 } |
| 247 | 395 |
| 248 } // namespace chromeos | 396 } // namespace chromeos |
| OLD | NEW |