Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(656)

Side by Side Diff: chrome/browser/ssl/ssl_manager.cc

Issue 42314: SSLPolicy fix: Step 9. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 11 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/ssl/ssl_manager.h ('k') | chrome/browser/ssl/ssl_policy.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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/ssl/ssl_manager.h" 5 #include "chrome/browser/ssl/ssl_manager.h"
6 6
7 #include "base/message_loop.h" 7 #include "base/message_loop.h"
8 #include "base/string_util.h" 8 #include "base/string_util.h"
9 #include "chrome/browser/browser_process.h" 9 #include "chrome/browser/browser_process.h"
10 #include "chrome/browser/load_from_memory_cache_details.h" 10 #include "chrome/browser/load_from_memory_cache_details.h"
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 // Delegate API method. 199 // Delegate API method.
200 bool SSLManager::DidMarkHostAsBroken(const std::string& host) const { 200 bool SSLManager::DidMarkHostAsBroken(const std::string& host) const {
201 return ssl_host_state_->DidMarkHostAsBroken(host); 201 return ssl_host_state_->DidMarkHostAsBroken(host);
202 } 202 }
203 203
204 // Delegate API method. 204 // Delegate API method.
205 void SSLManager::DenyCertForHost(net::X509Certificate* cert, 205 void SSLManager::DenyCertForHost(net::X509Certificate* cert,
206 const std::string& host) { 206 const std::string& host) {
207 // Remember that we don't like this cert for this host. 207 // Remember that we don't like this cert for this host.
208 ssl_host_state_->DenyCertForHost(cert, host); 208 ssl_host_state_->DenyCertForHost(cert, host);
209 DispatchSSLInternalStateChanged();
210 } 209 }
211 210
212 // Delegate API method. 211 // Delegate API method.
213 void SSLManager::AllowCertForHost(net::X509Certificate* cert, 212 void SSLManager::AllowCertForHost(net::X509Certificate* cert,
214 const std::string& host) { 213 const std::string& host) {
215 ssl_host_state_->AllowCertForHost(cert, host); 214 ssl_host_state_->AllowCertForHost(cert, host);
216 DispatchSSLInternalStateChanged();
217 } 215 }
218 216
219 // Delegate API method. 217 // Delegate API method.
220 net::X509Certificate::Policy::Judgment SSLManager::QueryPolicy( 218 net::X509Certificate::Policy::Judgment SSLManager::QueryPolicy(
221 net::X509Certificate* cert, const std::string& host) { 219 net::X509Certificate* cert, const std::string& host) {
222 return ssl_host_state_->QueryPolicy(cert, host); 220 return ssl_host_state_->QueryPolicy(cert, host);
223 } 221 }
224 222
225 // Delegate API method. 223 // Delegate API method.
226 void SSLManager::AllowMixedContentForHost(const std::string& host) { 224 void SSLManager::AllowMixedContentForHost(const std::string& host) {
227 ssl_host_state_->AllowMixedContentForHost(host); 225 ssl_host_state_->AllowMixedContentForHost(host);
228 DispatchSSLInternalStateChanged();
229 } 226 }
230 227
231 // Delegate API method. 228 // Delegate API method.
232 bool SSLManager::DidAllowMixedContentForHost(const std::string& host) const { 229 bool SSLManager::DidAllowMixedContentForHost(const std::string& host) const {
233 return ssl_host_state_->DidAllowMixedContentForHost(host); 230 return ssl_host_state_->DidAllowMixedContentForHost(host);
234 } 231 }
235 232
236 bool SSLManager::ProcessedSSLErrorFromRequest() const { 233 bool SSLManager::ProcessedSSLErrorFromRequest() const {
237 NavigationEntry* entry = controller_->GetActiveEntry(); 234 NavigationEntry* entry = controller_->GetActiveEntry();
238 if (!entry) { 235 if (!entry) {
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 URLRequest* request, 496 URLRequest* request,
500 MessageLoop* ui_loop) { 497 MessageLoop* ui_loop) {
501 ResourceDispatcherHost::ExtraRequestInfo* info = 498 ResourceDispatcherHost::ExtraRequestInfo* info =
502 ResourceDispatcherHost::ExtraInfoForRequest(request); 499 ResourceDispatcherHost::ExtraInfoForRequest(request);
503 DCHECK(info); 500 DCHECK(info);
504 501
505 // We cheat here and talk to the SSLPolicy on the IO thread because we need 502 // We cheat here and talk to the SSLPolicy on the IO thread because we need
506 // to respond synchronously to avoid delaying all network requests... 503 // to respond synchronously to avoid delaying all network requests...
507 if (!SSLPolicy::IsMixedContent(request->url(), 504 if (!SSLPolicy::IsMixedContent(request->url(),
508 info->resource_type, 505 info->resource_type,
509 info->main_frame_origin)) 506 info->filter_policy,
507 info->frame_origin))
510 return true; 508 return true;
511 509
512 510
513 ui_loop->PostTask(FROM_HERE, 511 ui_loop->PostTask(FROM_HERE,
514 NewRunnableMethod(new MixedContentHandler(rdh, request, 512 NewRunnableMethod(new MixedContentHandler(rdh, request,
515 info->resource_type, 513 info->resource_type,
516 info->frame_origin, 514 info->frame_origin,
517 info->main_frame_origin, 515 info->main_frame_origin,
518 ui_loop), 516 ui_loop),
519 &MixedContentHandler::Dispatch)); 517 &MixedContentHandler::Dispatch));
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 NotificationService::NoDetails()); 564 NotificationService::NoDetails());
567 } 565 }
568 566
569 void SSLManager::DispatchSSLVisibleStateChanged() { 567 void SSLManager::DispatchSSLVisibleStateChanged() {
570 NotificationService::current()->Notify( 568 NotificationService::current()->Notify(
571 NotificationType::SSL_VISIBLE_STATE_CHANGED, 569 NotificationType::SSL_VISIBLE_STATE_CHANGED,
572 Source<NavigationController>(controller_), 570 Source<NavigationController>(controller_),
573 NotificationService::NoDetails()); 571 NotificationService::NoDetails());
574 } 572 }
575 573
576 void SSLManager::InitializeEntryIfNeeded(NavigationEntry* entry) { 574 void SSLManager::UpdateEntry(NavigationEntry* entry) {
577 DCHECK(entry); 575 // We don't always have a navigation entry to update, for example in the
576 // case of the Web Inspector.
577 if (!entry)
578 return;
578 579
579 // If the security style of the entry is SECURITY_STYLE_UNKNOWN, then it is a 580 NavigationEntry::SSLStatus original_ssl_status = entry->ssl(); // Copy!
580 // fresh entry and should get the default style.
581 if (entry->ssl().security_style() == SECURITY_STYLE_UNKNOWN) {
582 entry->ssl().set_security_style(
583 delegate()->GetDefaultStyle(entry->url()));
584 }
585 }
586 581
587 void SSLManager::NavigationStateChanged() { 582 delegate()->UpdateEntry(this, entry);
588 NavigationEntry* active_entry = controller_->GetActiveEntry();
589 if (!active_entry)
590 return; // Nothing showing yet.
591 583
592 // This might be a new entry we've never seen before. 584 if (!entry->ssl().Equals(original_ssl_status))
593 InitializeEntryIfNeeded(active_entry); 585 DispatchSSLVisibleStateChanged();
594 } 586 }
595 587
596 void SSLManager::DidLoadFromMemoryCache(LoadFromMemoryCacheDetails* details) { 588 void SSLManager::DidLoadFromMemoryCache(LoadFromMemoryCacheDetails* details) {
597 DCHECK(details); 589 DCHECK(details);
598 590
599 // Simulate loading this resource through the usual path. 591 // Simulate loading this resource through the usual path.
600 // Note that we specify SUB_RESOURCE as the resource type as WebCore only 592 // Note that we specify SUB_RESOURCE as the resource type as WebCore only
601 // caches sub-resources. 593 // caches sub-resources.
594 // This resource must have been loaded with FilterPolicy::DONT_FILTER because
595 // filtered resouces aren't cachable.
602 scoped_refptr<RequestInfo> info = new RequestInfo( 596 scoped_refptr<RequestInfo> info = new RequestInfo(
603 this, 597 this,
604 details->url(), 598 details->url(),
605 ResourceType::SUB_RESOURCE, 599 ResourceType::SUB_RESOURCE,
606 details->frame_origin(), 600 details->frame_origin(),
607 details->main_frame_origin(), 601 details->main_frame_origin(),
602 FilterPolicy::DONT_FILTER,
608 details->ssl_cert_id(), 603 details->ssl_cert_id(),
609 details->ssl_cert_status()); 604 details->ssl_cert_status());
610 605
611 // Simulate loading this resource through the usual path. 606 // Simulate loading this resource through the usual path.
612 delegate()->OnRequestStarted(info.get()); 607 delegate()->OnRequestStarted(info.get());
613 } 608 }
614 609
615 void SSLManager::DidCommitProvisionalLoad( 610 void SSLManager::DidCommitProvisionalLoad(
616 const NotificationDetails& in_details) { 611 const NotificationDetails& in_details) {
617 NavigationController::LoadCommittedDetails* details = 612 NavigationController::LoadCommittedDetails* details =
618 Details<NavigationController::LoadCommittedDetails>(in_details).ptr(); 613 Details<NavigationController::LoadCommittedDetails>(in_details).ptr();
619 614
620 // Ignore in-page navigations, they should not change the security style or 615 // Ignore in-page navigations, they should not change the security style or
621 // the info-bars. 616 // the info-bars.
622 if (details->is_in_page) 617 if (details->is_in_page)
623 return; 618 return;
624 619
625 // Decode the security details. 620 NavigationEntry* entry = controller_->GetActiveEntry();
626 int ssl_cert_id, ssl_cert_status, ssl_security_bits;
627 DeserializeSecurityInfo(details->serialized_security_info,
628 &ssl_cert_id, &ssl_cert_status, &ssl_security_bits);
629 621
630 bool changed = false;
631 if (details->is_main_frame) { 622 if (details->is_main_frame) {
632 // Update the SSL states of the pending entry.
633 NavigationEntry* entry = controller_->GetActiveEntry();
634 if (entry) { 623 if (entry) {
624 // Decode the security details.
625 int ssl_cert_id, ssl_cert_status, ssl_security_bits;
626 DeserializeSecurityInfo(details->serialized_security_info,
627 &ssl_cert_id,
628 &ssl_cert_status,
629 &ssl_security_bits);
630
635 // We may not have an entry if this is a navigation to an initial blank 631 // We may not have an entry if this is a navigation to an initial blank
636 // page. Reset the SSL information and add the new data we have. 632 // page. Reset the SSL information and add the new data we have.
637 entry->ssl() = NavigationEntry::SSLStatus(); 633 entry->ssl() = NavigationEntry::SSLStatus();
638 InitializeEntryIfNeeded(entry); // For security_style.
639 entry->ssl().set_cert_id(ssl_cert_id); 634 entry->ssl().set_cert_id(ssl_cert_id);
640 entry->ssl().set_cert_status(ssl_cert_status); 635 entry->ssl().set_cert_status(ssl_cert_status);
641 entry->ssl().set_security_bits(ssl_security_bits); 636 entry->ssl().set_security_bits(ssl_security_bits);
642 changed = true;
643 } 637 }
644
645 ShowPendingMessages(); 638 ShowPendingMessages();
646 } 639 }
647 640
648 // An HTTPS response may not have a certificate for some reason. When that 641 UpdateEntry(entry);
649 // happens, use the unauthenticated (HTTP) rather than the authentication
650 // broken security style so that we can detect this error condition.
651 if (net::IsCertStatusError(ssl_cert_status) &&
652 !details->is_content_filtered) {
653 changed |= SetMaxSecurityStyle(SECURITY_STYLE_AUTHENTICATION_BROKEN);
654 if (!details->is_main_frame &&
655 !details->entry->ssl().has_unsafe_content()) {
656 details->entry->ssl().set_has_unsafe_content();
657 changed = true;
658 }
659 } else if (details->entry->url().SchemeIsSecure() && !ssl_cert_id) {
660 if (details->is_main_frame) {
661 changed |= SetMaxSecurityStyle(SECURITY_STYLE_UNAUTHENTICATED);
662 } else {
663 // If the frame has been blocked we keep our security style as
664 // authenticated in that case as nothing insecure is actually showing or
665 // loaded.
666 if (!details->is_content_filtered &&
667 !details->entry->ssl().has_mixed_content()) {
668 details->entry->ssl().set_has_mixed_content();
669 changed = true;
670 }
671 }
672 }
673
674 if (changed) {
675 // Only send the notification when something actually changed.
676 NotificationService::current()->Notify(
677 NotificationType::SSL_VISIBLE_STATE_CHANGED,
678 Source<NavigationController>(controller_),
679 NotificationService::NoDetails());
680 }
681 } 642 }
682 643
683 void SSLManager::DidFailProvisionalLoadWithError( 644 void SSLManager::DidFailProvisionalLoadWithError(
684 ProvisionalLoadDetails* details) { 645 ProvisionalLoadDetails* details) {
685 DCHECK(details); 646 DCHECK(details);
686 647
687 // Ignore in-page navigations. 648 // Ignore in-page navigations.
688 if (details->in_page_navigation()) 649 if (details->in_page_navigation())
689 return; 650 return;
690 651
691 if (details->main_frame()) 652 if (details->main_frame())
692 ClearPendingMessages(); 653 ClearPendingMessages();
693 } 654 }
694 655
695 void SSLManager::DidStartResourceResponse(ResourceRequestDetails* details) { 656 void SSLManager::DidStartResourceResponse(ResourceRequestDetails* details) {
696 DCHECK(details); 657 DCHECK(details);
697 658
698 scoped_refptr<RequestInfo> info = new RequestInfo( 659 scoped_refptr<RequestInfo> info = new RequestInfo(
699 this, 660 this,
700 details->url(), 661 details->url(),
701 details->resource_type(), 662 details->resource_type(),
702 details->frame_origin(), 663 details->frame_origin(),
703 details->main_frame_origin(), 664 details->main_frame_origin(),
665 details->filter_policy(),
704 details->ssl_cert_id(), 666 details->ssl_cert_id(),
705 details->ssl_cert_status()); 667 details->ssl_cert_status());
706 668
707 // Notify our delegate that we started a resource request. Ideally, the 669 // Notify our delegate that we started a resource request. Ideally, the
708 // delegate should have the ability to cancel the request, but we can't do 670 // delegate should have the ability to cancel the request, but we can't do
709 // that yet. 671 // that yet.
710 delegate()->OnRequestStarted(info.get()); 672 delegate()->OnRequestStarted(info.get());
711 } 673 }
712 674
713 void SSLManager::DidReceiveResourceRedirect(ResourceRedirectDetails* details) { 675 void SSLManager::DidReceiveResourceRedirect(ResourceRedirectDetails* details) {
714 // TODO(abarth): Make sure our redirect behavior is correct. If we ever see 676 // TODO(abarth): Make sure our redirect behavior is correct. If we ever see
715 // a non-HTTPS resource in the redirect chain, we want to 677 // a non-HTTPS resource in the redirect chain, we want to
716 // trigger mixed content, even if the redirect chain goes back 678 // trigger mixed content, even if the redirect chain goes back
717 // to HTTPS. This is because the network attacker can redirect 679 // to HTTPS. This is because the network attacker can redirect
718 // the HTTP request to https://attacker.com/payload.js. 680 // the HTTP request to https://attacker.com/payload.js.
719 } 681 }
720 682
721 void SSLManager::ShowPendingMessages() { 683 void SSLManager::ShowPendingMessages() {
722 std::vector<SSLMessageInfo>::const_iterator iter; 684 std::vector<SSLMessageInfo>::const_iterator iter;
723 for (iter = pending_messages_.begin(); 685 for (iter = pending_messages_.begin();
724 iter != pending_messages_.end(); ++iter) { 686 iter != pending_messages_.end(); ++iter) {
725 ShowMessageWithLink(iter->message, iter->link_text, iter->action); 687 ShowMessageWithLink(iter->message, iter->link_text, iter->action);
726 } 688 }
727 ClearPendingMessages(); 689 ClearPendingMessages();
728 } 690 }
729 691
730 void SSLManager::DidChangeSSLInternalState() { 692 void SSLManager::DidChangeSSLInternalState() {
731 // TODO(abarth): We'll need to do something here in the next step. 693 UpdateEntry(controller_->GetActiveEntry());
732 } 694 }
733 695
734 void SSLManager::ClearPendingMessages() { 696 void SSLManager::ClearPendingMessages() {
735 pending_messages_.clear(); 697 pending_messages_.clear();
736 } 698 }
737 699
738 // static 700 // static
739 std::string SSLManager::SerializeSecurityInfo(int cert_id, 701 std::string SSLManager::SerializeSecurityInfo(int cert_id,
740 int cert_status, 702 int cert_status,
741 int security_bits) { 703 int security_bits) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
788 } 750 }
789 751
790 if (ca_name) { 752 if (ca_name) {
791 // TODO(wtc): should we show the root CA's name instead? 753 // TODO(wtc): should we show the root CA's name instead?
792 *ca_name = l10n_util::GetStringF( 754 *ca_name = l10n_util::GetStringF(
793 IDS_SECURE_CONNECTION_EV_CA, 755 IDS_SECURE_CONNECTION_EV_CA,
794 UTF8ToWide(cert.issuer().organization_names[0])); 756 UTF8ToWide(cert.issuer().organization_names[0]));
795 } 757 }
796 return true; 758 return true;
797 } 759 }
OLDNEW
« no previous file with comments | « chrome/browser/ssl/ssl_manager.h ('k') | chrome/browser/ssl/ssl_policy.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698