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