1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/ssl/ssl_manager.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/utf_string_conversions.h"
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/load_from_memory_cache_details.h"
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/net/url_request_tracking.h"
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/ssl/ssl_cert_error_handler.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/ssl/ssl_policy.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/ssl/ssl_request_info.h"
13dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
14dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/resource_dispatcher_host.h"
15dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/resource_dispatcher_host_request_info.h"
16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/browser/renderer_host/resource_request_details.h"
17dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/navigation_controller.h"
18dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/navigation_entry.h"
19dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/provisional_load_details.h"
20dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents.h"
21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_service.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h"
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/cert_status_flags.h"
2472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h"
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SSLManager::OnSSLCertificateError(ResourceDispatcherHost* rdh,
2821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                       net::URLRequest* request,
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                       int cert_error,
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                       net::X509Certificate* cert) {
31731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DVLOG(1) << "OnSSLCertificateError() cert_error: " << cert_error
32731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick           << " url: " << request->url().spec();
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ResourceDispatcherHostRequestInfo* info =
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ResourceDispatcherHost::InfoForRequest(request);
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(info);
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // A certificate error occurred.  Construct a SSLCertErrorHandler object and
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // hand it over to the UI thread for processing.
40731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::PostTask(
41731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      BrowserThread::UI, FROM_HERE,
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewRunnableMethod(new SSLCertErrorHandler(rdh,
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                request,
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                info->resource_type(),
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                cert_error,
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                cert),
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        &SSLCertErrorHandler::Dispatch));
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SSLManager::NotifySSLInternalStateChanged() {
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NotificationService::current()->Notify(
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationType::SSL_INTERNAL_STATE_CHANGED,
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationService::AllSources(),
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationService::NoDetails());
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string SSLManager::SerializeSecurityInfo(int cert_id,
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                              int cert_status,
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                              int security_bits,
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                              int ssl_connection_status) {
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Pickle pickle;
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pickle.WriteInt(cert_id);
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pickle.WriteInt(cert_status);
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pickle.WriteInt(security_bits);
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pickle.WriteInt(ssl_connection_status);
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return std::string(static_cast<const char*>(pickle.data()), pickle.size());
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool SSLManager::DeserializeSecurityInfo(const std::string& state,
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         int* cert_id,
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         int* cert_status,
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         int* security_bits,
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         int* ssl_connection_status) {
773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK(cert_id && cert_status && security_bits && ssl_connection_status);
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (state.empty()) {
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // No SSL used.
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *cert_id = 0;
814a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // The following are not applicable and are set to the default values.
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *cert_status = 0;
834a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    *security_bits = -1;
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    *ssl_connection_status = 0;
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Pickle pickle(state.data(), static_cast<int>(state.size()));
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void * iter = NULL;
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return pickle.ReadInt(&iter, cert_id) &&
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         pickle.ReadInt(&iter, cert_status) &&
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         pickle.ReadInt(&iter, security_bits) &&
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         pickle.ReadInt(&iter, ssl_connection_status);
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
973f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenstring16 SSLManager::GetEVCertName(const net::X509Certificate& cert) {
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // EV are required to have an organization name and country.
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (cert.subject().organization_names.empty() ||
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      cert.subject().country_name.empty()) {
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED();
1023f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    return string16();
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1053f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  return l10n_util::GetStringFUTF16(
1063f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      IDS_SECURE_CONNECTION_EV,
1073f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      UTF8ToUTF16(cert.subject().organization_names[0]),
1083f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      UTF8ToUTF16(cert.subject().country_name));
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochSSLManager::SSLManager(NavigationController* controller)
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : backend_(controller),
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      policy_(new SSLPolicy(&backend_)),
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      controller_(controller) {
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(controller_);
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Subscribe to various notifications.
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::FAIL_PROVISIONAL_LOAD_WITH_ERROR,
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 Source<NavigationController>(controller_));
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::RESOURCE_RESPONSE_STARTED,
1213f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                 Source<RenderViewHostDelegate>(controller_->tab_contents()));
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::RESOURCE_RECEIVED_REDIRECT,
1233f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                 Source<RenderViewHostDelegate>(controller_->tab_contents()));
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::LOAD_FROM_MEMORY_CACHE,
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 Source<NavigationController>(controller_));
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::SSL_INTERNAL_STATE_CHANGED,
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 NotificationService::AllSources());
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochSSLManager::~SSLManager() {
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SSLManager::DidCommitProvisionalLoad(
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const NotificationDetails& in_details) {
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NavigationController::LoadCommittedDetails* details =
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      Details<NavigationController::LoadCommittedDetails>(in_details).ptr();
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NavigationEntry* entry = controller_->GetActiveEntry();
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (details->is_main_frame) {
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (entry) {
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Decode the security details.
1433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      int ssl_cert_id, ssl_cert_status, ssl_security_bits,
1443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          ssl_connection_status;
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DeserializeSecurityInfo(details->serialized_security_info,
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                              &ssl_cert_id,
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                              &ssl_cert_status,
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                              &ssl_security_bits,
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                              &ssl_connection_status);
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // We may not have an entry if this is a navigation to an initial blank
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // page. Reset the SSL information and add the new data we have.
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      entry->ssl() = NavigationEntry::SSLStatus();
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      entry->ssl().set_cert_id(ssl_cert_id);
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      entry->ssl().set_cert_status(ssl_cert_status);
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      entry->ssl().set_security_bits(ssl_security_bits);
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      entry->ssl().set_connection_status(ssl_connection_status);
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateEntry(entry);
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SSLManager::DidRunInsecureContent(const std::string& security_origin) {
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  policy()->DidRunInsecureContent(controller_->GetActiveEntry(),
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                  security_origin);
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool SSLManager::ProcessedSSLErrorFromRequest() const {
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NavigationEntry* entry = controller_->GetActiveEntry();
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!entry) {
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED();
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return net::IsCertStatusError(entry->ssl().cert_status());
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SSLManager::Observe(NotificationType type,
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                         const NotificationSource& source,
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                         const NotificationDetails& details) {
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Dispatch by type.
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  switch (type.value) {
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::FAIL_PROVISIONAL_LOAD_WITH_ERROR:
1853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      // Do nothing.
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::RESOURCE_RESPONSE_STARTED:
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DidStartResourceResponse(Details<ResourceRequestDetails>(details).ptr());
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::RESOURCE_RECEIVED_REDIRECT:
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DidReceiveResourceRedirect(
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          Details<ResourceRedirectDetails>(details).ptr());
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::LOAD_FROM_MEMORY_CACHE:
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DidLoadFromMemoryCache(
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          Details<LoadFromMemoryCacheDetails>(details).ptr());
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::SSL_INTERNAL_STATE_CHANGED:
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DidChangeSSLInternalState();
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    default:
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NOTREACHED() << "The SSLManager received an unexpected notification.";
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SSLManager::DidLoadFromMemoryCache(LoadFromMemoryCacheDetails* details) {
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Simulate loading this resource through the usual path.
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Note that we specify SUB_RESOURCE as the resource type as WebCore only
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // caches sub-resources.
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This resource must have been loaded with no filtering because filtered
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // resouces aren't cachable.
212513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  scoped_refptr<SSLRequestInfo> info(new SSLRequestInfo(
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      details->url(),
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ResourceType::SUB_RESOURCE,
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      details->pid(),
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      details->ssl_cert_id(),
217513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      details->ssl_cert_status()));
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Simulate loading this resource through the usual path.
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  policy()->OnRequestStarted(info.get());
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SSLManager::DidStartResourceResponse(ResourceRequestDetails* details) {
224513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  scoped_refptr<SSLRequestInfo> info(new SSLRequestInfo(
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      details->url(),
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      details->resource_type(),
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      details->origin_child_id(),
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      details->ssl_cert_id(),
229513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      details->ssl_cert_status()));
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Notify our policy that we started a resource request.  Ideally, the
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // policy should have the ability to cancel the request, but we can't do
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // that yet.
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  policy()->OnRequestStarted(info.get());
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SSLManager::DidReceiveResourceRedirect(ResourceRedirectDetails* details) {
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(abarth): Make sure our redirect behavior is correct.  If we ever see a
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //               non-HTTPS resource in the redirect chain, we want to trigger
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //               insecure content, even if the redirect chain goes back to
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //               HTTPS.  This is because the network attacker can redirect the
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //               HTTP request to https://attacker.com/payload.js.
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SSLManager::DidChangeSSLInternalState() {
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateEntry(controller_->GetActiveEntry());
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SSLManager::UpdateEntry(NavigationEntry* entry) {
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We don't always have a navigation entry to update, for example in the
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // case of the Web Inspector.
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!entry)
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NavigationEntry::SSLStatus original_ssl_status = entry->ssl();  // Copy!
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  policy()->UpdateEntry(entry, controller_->tab_contents());
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!entry->ssl().Equals(original_ssl_status)) {
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NotificationService::current()->Notify(
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        NotificationType::SSL_VISIBLE_STATE_CHANGED,
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        Source<NavigationController>(controller_),
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        NotificationService::NoDetails());
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
266