| 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/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
| 9 #include "base/callback.h" | 9 #include "base/callback.h" |
| 10 #include "base/values.h" | 10 #include "base/values.h" |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 197 void DoStep() { | 197 void DoStep() { |
| 198 switch (next_step_) { | 198 switch (next_step_) { |
| 199 case Step::GET_EXTENSION_PERMISSIONS: | 199 case Step::GET_EXTENSION_PERMISSIONS: |
| 200 next_step_ = Step::SIGN_OR_ABORT; | 200 next_step_ = Step::SIGN_OR_ABORT; |
| 201 GetExtensionPermissions(); | 201 GetExtensionPermissions(); |
| 202 return; | 202 return; |
| 203 case Step::SIGN_OR_ABORT: { | 203 case Step::SIGN_OR_ABORT: { |
| 204 next_step_ = Step::DONE; | 204 next_step_ = Step::DONE; |
| 205 bool sign_granted = | 205 bool sign_granted = |
| 206 extension_permissions_->CanUseKeyForSigning(public_key_); | 206 extension_permissions_->CanUseKeyForSigning(public_key_); |
| 207 LOG(ERROR) << "sign_granted " << sign_granted; |
| 207 if (sign_granted) { | 208 if (sign_granted) { |
| 208 Sign(); | 209 Sign(); |
| 209 } else { | 210 } else { |
| 210 callback_.Run(std::string() /* no signature */, | 211 callback_.Run(std::string() /* no signature */, |
| 211 kErrorKeyNotAllowedForSigning); | 212 kErrorKeyNotAllowedForSigning); |
| 212 DoStep(); | 213 DoStep(); |
| 213 } | 214 } |
| 214 return; | 215 return; |
| 215 } | 216 } |
| 216 case Step::DONE: | 217 case Step::DONE: |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 377 // |error_message| contain an error message. | 378 // |error_message| contain an error message. |
| 378 void GotMatchingCerts(scoped_ptr<net::CertificateList> matches, | 379 void GotMatchingCerts(scoped_ptr<net::CertificateList> matches, |
| 379 const std::string& error_message) { | 380 const std::string& error_message) { |
| 380 if (!error_message.empty()) { | 381 if (!error_message.empty()) { |
| 381 next_step_ = Step::DONE; | 382 next_step_ = Step::DONE; |
| 382 callback_.Run(nullptr /* no certificates */, error_message); | 383 callback_.Run(nullptr /* no certificates */, error_message); |
| 383 DoStep(); | 384 DoStep(); |
| 384 return; | 385 return; |
| 385 } | 386 } |
| 386 | 387 |
| 387 // If the type field does not contain any entries, certificates of all types | 388 for (scoped_refptr<net::X509Certificate>& certificate : *matches) { |
| 388 // shall be returned. | 389 const std::string public_key_spki_der( |
| 389 if (request_.certificate_key_types.size() == 0) { | 390 platform_keys::GetSubjectPublicKeyInfo(certificate)); |
| 390 matches_.swap(*matches); | 391 LOG(ERROR) |
| 391 DoStep(); | 392 << "user can grant permissions: " |
| 392 return; | 393 << key_permissions_->CanUserGrantPermissionFor(public_key_spki_der) |
| 393 } | 394 << "can use for signing " |
| 395 << extension_permissions_->CanUseKeyForSigning(public_key_spki_der) |
| 396 << " " << public_key_spki_der.size(); |
| 397 // Skip this key if the user cannot grant any permission for it, except if |
| 398 // this extension can already use it for signing. |
| 399 if (!key_permissions_->CanUserGrantPermissionFor(public_key_spki_der) && |
| 400 !extension_permissions_->CanUseKeyForSigning(public_key_spki_der)) { |
| 401 continue; |
| 402 } |
| 394 | 403 |
| 395 // Filter the retrieved certificates returning only those whose type is | 404 // Filter the retrieved certificates returning only those whose type is |
| 396 // equal to one of the entries in the type field of the certificate request. | 405 // equal to one of the entries in the type field of the certificate |
| 397 for (scoped_refptr<net::X509Certificate>& certificate : *matches) { | 406 // request. |
| 398 net::X509Certificate::PublicKeyType actual_key_type = | 407 // If the type field does not contain any entries, certificates of all |
| 399 net::X509Certificate::kPublicKeyTypeUnknown; | 408 // types shall be returned. |
| 400 size_t unused_key_size = 0; | 409 if (!request_.certificate_key_types.empty()) { |
| 401 net::X509Certificate::GetPublicKeyInfo( | 410 net::X509Certificate::PublicKeyType actual_key_type = |
| 402 certificate->os_cert_handle(), &unused_key_size, &actual_key_type); | 411 net::X509Certificate::kPublicKeyTypeUnknown; |
| 403 const std::vector<net::X509Certificate::PublicKeyType>& accepted_types = | 412 size_t unused_key_size = 0; |
| 404 request_.certificate_key_types; | 413 net::X509Certificate::GetPublicKeyInfo( |
| 405 if (std::find(accepted_types.begin(), accepted_types.end(), | 414 certificate->os_cert_handle(), &unused_key_size, &actual_key_type); |
| 406 actual_key_type) != accepted_types.end()) { | 415 const std::vector<net::X509Certificate::PublicKeyType>& accepted_types = |
| 407 matches_.push_back(certificate.Pass()); | 416 request_.certificate_key_types; |
| 417 if (std::find(accepted_types.begin(), accepted_types.end(), |
| 418 actual_key_type) == accepted_types.end()) { |
| 419 continue; |
| 420 } |
| 408 } | 421 } |
| 422 |
| 423 matches_.push_back(certificate.Pass()); |
| 409 } | 424 } |
| 410 DoStep(); | 425 DoStep(); |
| 411 } | 426 } |
| 412 | 427 |
| 413 // Calls |service_->select_delegate_->Select()| to select a cert from | 428 // Calls |service_->select_delegate_->Select()| to select a cert from |
| 414 // |matches_|, which will be stored in |selected_cert_|. | 429 // |matches_|, which will be stored in |selected_cert_|. |
| 415 // Will call back to |GotSelection()|. | 430 // Will call back to |GotSelection()|. |
| 416 void SelectCerts() { | 431 void SelectCerts() { |
| 417 CHECK(interactive_); | 432 CHECK(interactive_); |
| 418 if (matches_.empty()) { | 433 if (matches_.empty()) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 445 platform_keys::GetSubjectPublicKeyInfo(selected_cert_)); | 460 platform_keys::GetSubjectPublicKeyInfo(selected_cert_)); |
| 446 extension_permissions_->SetUserGrantedPermission(public_key_spki_der); | 461 extension_permissions_->SetUserGrantedPermission(public_key_spki_der); |
| 447 DoStep(); | 462 DoStep(); |
| 448 } | 463 } |
| 449 | 464 |
| 450 // Filters from all matches (if not interactive) or from the selection (if | 465 // Filters from all matches (if not interactive) or from the selection (if |
| 451 // interactive), the certificates that the extension has unlimited sign | 466 // interactive), the certificates that the extension has unlimited sign |
| 452 // permission for. Passes the filtered certs to |callback_|. | 467 // permission for. Passes the filtered certs to |callback_|. |
| 453 void FilterSelectionByPermission() { | 468 void FilterSelectionByPermission() { |
| 454 scoped_ptr<net::CertificateList> selection(new net::CertificateList); | 469 scoped_ptr<net::CertificateList> selection(new net::CertificateList); |
| 470 LOG(ERROR) << "int " << interactive_ << " sel " << selected_cert_; |
| 455 if (interactive_) { | 471 if (interactive_) { |
| 456 if (selected_cert_) | 472 if (selected_cert_) |
| 457 selection->push_back(selected_cert_); | 473 selection->push_back(selected_cert_); |
| 458 } else { | 474 } else { |
| 459 selection->assign(matches_.begin(), matches_.end()); | 475 selection->assign(matches_.begin(), matches_.end()); |
| 460 } | 476 } |
| 461 | 477 |
| 462 scoped_ptr<net::CertificateList> filtered_certs(new net::CertificateList); | 478 scoped_ptr<net::CertificateList> filtered_certs(new net::CertificateList); |
| 463 for (scoped_refptr<net::X509Certificate> selected_cert : *selection) { | 479 for (scoped_refptr<net::X509Certificate> selected_cert : *selection) { |
| 464 const std::string public_key_spki_der( | 480 const std::string public_key_spki_der( |
| 465 platform_keys::GetSubjectPublicKeyInfo(selected_cert)); | 481 platform_keys::GetSubjectPublicKeyInfo(selected_cert)); |
| 466 | 482 |
| 483 LOG(ERROR) << "can use for signing " |
| 484 << extension_permissions_->CanUseKeyForSigning( |
| 485 public_key_spki_der) |
| 486 << " " |
| 487 << public_key_spki_der.size(); |
| 488 |
| 467 if (!extension_permissions_->CanUseKeyForSigning(public_key_spki_der)) | 489 if (!extension_permissions_->CanUseKeyForSigning(public_key_spki_der)) |
| 468 continue; | 490 continue; |
| 469 | 491 |
| 470 filtered_certs->push_back(selected_cert); | 492 filtered_certs->push_back(selected_cert); |
| 471 } | 493 } |
| 472 // Note: In the interactive case this should have filtered exactly the | 494 // Note: In the interactive case this should have filtered exactly the |
| 473 // one selected cert. Checking the permissions again is not striclty | 495 // one selected cert. Checking the permissions again is not striclty |
| 474 // necessary but this ensures that the permissions were updated correctly. | 496 // necessary but this ensures that the permissions were updated correctly. |
| 497 LOG(ERROR) << "size " << filtered_certs->size(); |
| 498 if (filtered_certs->size() > 0) |
| 499 LOG(ERROR) << "first " << filtered_certs->front(); |
| 475 CHECK(!selected_cert_ || (filtered_certs->size() == 1 && | 500 CHECK(!selected_cert_ || (filtered_certs->size() == 1 && |
| 476 filtered_certs->front() == selected_cert_)); | 501 filtered_certs->front() == selected_cert_)); |
| 477 callback_.Run(filtered_certs.Pass(), std::string() /* no error */); | 502 callback_.Run(filtered_certs.Pass(), std::string() /* no error */); |
| 478 DoStep(); | 503 DoStep(); |
| 479 } | 504 } |
| 480 | 505 |
| 481 Step next_step_ = Step::GET_EXTENSION_PERMISSIONS; | 506 Step next_step_ = Step::GET_EXTENSION_PERMISSIONS; |
| 482 | 507 |
| 483 net::CertificateList matches_; | 508 net::CertificateList matches_; |
| 484 scoped_refptr<net::X509Certificate> selected_cert_; | 509 scoped_refptr<net::X509Certificate> selected_cert_; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 495 DISALLOW_COPY_AND_ASSIGN(SelectTask); | 520 DISALLOW_COPY_AND_ASSIGN(SelectTask); |
| 496 }; | 521 }; |
| 497 | 522 |
| 498 PlatformKeysService::SelectDelegate::SelectDelegate() { | 523 PlatformKeysService::SelectDelegate::SelectDelegate() { |
| 499 } | 524 } |
| 500 | 525 |
| 501 PlatformKeysService::SelectDelegate::~SelectDelegate() { | 526 PlatformKeysService::SelectDelegate::~SelectDelegate() { |
| 502 } | 527 } |
| 503 | 528 |
| 504 PlatformKeysService::PlatformKeysService( | 529 PlatformKeysService::PlatformKeysService( |
| 530 PrefService* profile_prefs, |
| 531 bool profile_is_managed, |
| 532 policy::PolicyService* profile_policies, |
| 505 content::BrowserContext* browser_context, | 533 content::BrowserContext* browser_context, |
| 506 extensions::StateStore* state_store) | 534 extensions::StateStore* state_store) |
| 507 : browser_context_(browser_context), | 535 : browser_context_(browser_context), |
| 508 key_permissions_(state_store), | 536 key_permissions_(profile_prefs, |
| 537 profile_is_managed, |
| 538 profile_policies, |
| 539 state_store), |
| 509 weak_factory_(this) { | 540 weak_factory_(this) { |
| 510 DCHECK(state_store); | 541 DCHECK(state_store); |
| 511 } | 542 } |
| 512 | 543 |
| 513 PlatformKeysService::~PlatformKeysService() { | 544 PlatformKeysService::~PlatformKeysService() { |
| 514 } | 545 } |
| 515 | 546 |
| 516 void PlatformKeysService::SetSelectDelegate( | 547 void PlatformKeysService::SetSelectDelegate( |
| 517 scoped_ptr<SelectDelegate> delegate) { | 548 scoped_ptr<SelectDelegate> delegate) { |
| 518 select_delegate_ = delegate.Pass(); | 549 select_delegate_ = delegate.Pass(); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 578 while (!tasks_.empty() && tasks_.front()->IsDone()) | 609 while (!tasks_.empty() && tasks_.front()->IsDone()) |
| 579 tasks_.pop(); | 610 tasks_.pop(); |
| 580 | 611 |
| 581 // Now either the queue is empty or the next task is not finished yet and it | 612 // Now either the queue is empty or the next task is not finished yet and it |
| 582 // can be started. | 613 // can be started. |
| 583 if (!tasks_.empty()) | 614 if (!tasks_.empty()) |
| 584 tasks_.front()->Start(); | 615 tasks_.front()->Start(); |
| 585 } | 616 } |
| 586 | 617 |
| 587 } // namespace chromeos | 618 } // namespace chromeos |
| OLD | NEW |