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

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

Issue 2095006: Revert 47347 - (Original patch reviewed at http://codereview.chromium.org/206... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 10 years, 7 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) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 "app/l10n_util.h" 7 #include "app/l10n_util.h"
8 #include "base/utf_string_conversions.h" 8 #include "base/utf_string_conversions.h"
9 #include "chrome/browser/chrome_thread.h" 9 #include "chrome/browser/chrome_thread.h"
10 #include "chrome/browser/load_from_memory_cache_details.h" 10 #include "chrome/browser/load_from_memory_cache_details.h"
(...skipping 10 matching lines...) Expand all
21 #include "chrome/common/pref_names.h" 21 #include "chrome/common/pref_names.h"
22 #include "grit/generated_resources.h" 22 #include "grit/generated_resources.h"
23 #include "net/base/cert_status_flags.h" 23 #include "net/base/cert_status_flags.h"
24 24
25 // static 25 // static
26 void SSLManager::RegisterUserPrefs(PrefService* prefs) { 26 void SSLManager::RegisterUserPrefs(PrefService* prefs) {
27 prefs->RegisterIntegerPref(prefs::kMixedContentFiltering, 27 prefs->RegisterIntegerPref(prefs::kMixedContentFiltering,
28 FilterPolicy::DONT_FILTER); 28 FilterPolicy::DONT_FILTER);
29 } 29 }
30 30
31 // static
32 void SSLManager::OnSSLCertificateError(ResourceDispatcherHost* rdh,
33 URLRequest* request,
34 int cert_error,
35 net::X509Certificate* cert) {
36 DLOG(INFO) << "OnSSLCertificateError() cert_error: " << cert_error <<
37 " url: " << request->url().spec();
38
39 ResourceDispatcherHostRequestInfo* info =
40 ResourceDispatcherHost::InfoForRequest(request);
41 DCHECK(info);
42
43 // A certificate error occurred. Construct a SSLCertErrorHandler object and
44 // hand it over to the UI thread for processing.
45 ChromeThread::PostTask(
46 ChromeThread::UI, FROM_HERE,
47 NewRunnableMethod(new SSLCertErrorHandler(rdh,
48 request,
49 info->resource_type(),
50 info->frame_origin(),
51 info->main_frame_origin(),
52 cert_error,
53 cert),
54 &SSLCertErrorHandler::Dispatch));
55 }
56
57 // static
58 void SSLManager::NotifySSLInternalStateChanged() {
59 NotificationService::current()->Notify(
60 NotificationType::SSL_INTERNAL_STATE_CHANGED,
61 NotificationService::AllSources(),
62 NotificationService::NoDetails());
63 }
64
65 // static
66 std::string SSLManager::SerializeSecurityInfo(int cert_id,
67 int cert_status,
68 int security_bits) {
69 Pickle pickle;
70 pickle.WriteInt(cert_id);
71 pickle.WriteInt(cert_status);
72 pickle.WriteInt(security_bits);
73 return std::string(static_cast<const char*>(pickle.data()), pickle.size());
74 }
75
76 // static
77 bool SSLManager::DeserializeSecurityInfo(const std::string& state,
78 int* cert_id,
79 int* cert_status,
80 int* security_bits) {
81 DCHECK(cert_id && cert_status && security_bits);
82 if (state.empty()) {
83 // No SSL used.
84 *cert_id = 0;
85 *cert_status = 0;
86 *security_bits = -1;
87 return false;
88 }
89
90 Pickle pickle(state.data(), static_cast<int>(state.size()));
91 void * iter = NULL;
92 return pickle.ReadInt(&iter, cert_id) &&
93 pickle.ReadInt(&iter, cert_status) &&
94 pickle.ReadInt(&iter, security_bits);
95 }
96
97 // static
98 std::wstring SSLManager::GetEVCertName(const net::X509Certificate& cert) {
99 // EV are required to have an organization name and country.
100 if (cert.subject().organization_names.empty() ||
101 cert.subject().country_name.empty()) {
102 NOTREACHED();
103 return std::wstring();
104 }
105
106 return l10n_util::GetStringF(IDS_SECURE_CONNECTION_EV,
107 UTF8ToWide(cert.subject().organization_names[0]),
108 UTF8ToWide(cert.subject().country_name));
109 }
110
111 SSLManager::SSLManager(NavigationController* controller) 31 SSLManager::SSLManager(NavigationController* controller)
112 : backend_(controller), 32 : backend_(controller),
113 policy_(new SSLPolicy(&backend_)), 33 policy_(new SSLPolicy(&backend_)),
114 controller_(controller) { 34 controller_(controller) {
115 DCHECK(controller_); 35 DCHECK(controller_);
116 36
117 // Subscribe to various notifications. 37 // Subscribe to various notifications.
118 registrar_.Add(this, NotificationType::FAIL_PROVISIONAL_LOAD_WITH_ERROR, 38 registrar_.Add(this, NotificationType::FAIL_PROVISIONAL_LOAD_WITH_ERROR,
119 Source<NavigationController>(controller_)); 39 Source<NavigationController>(controller_));
120 registrar_.Add(this, NotificationType::RESOURCE_RESPONSE_STARTED, 40 registrar_.Add(this, NotificationType::RESOURCE_RESPONSE_STARTED,
121 Source<NavigationController>(controller_)); 41 Source<NavigationController>(controller_));
122 registrar_.Add(this, NotificationType::RESOURCE_RECEIVED_REDIRECT, 42 registrar_.Add(this, NotificationType::RESOURCE_RECEIVED_REDIRECT,
123 Source<NavigationController>(controller_)); 43 Source<NavigationController>(controller_));
124 registrar_.Add(this, NotificationType::LOAD_FROM_MEMORY_CACHE, 44 registrar_.Add(this, NotificationType::LOAD_FROM_MEMORY_CACHE,
125 Source<NavigationController>(controller_)); 45 Source<NavigationController>(controller_));
126 registrar_.Add(this, NotificationType::SSL_INTERNAL_STATE_CHANGED, 46 registrar_.Add(this, NotificationType::SSL_INTERNAL_STATE_CHANGED,
127 NotificationService::AllSources()); 47 NotificationService::AllSources());
128 } 48 }
129 49
130 SSLManager::~SSLManager() { 50 SSLManager::~SSLManager() {
131 } 51 }
132 52
133 void SSLManager::DidCommitProvisionalLoad(
134 const NotificationDetails& in_details) {
135 NavigationController::LoadCommittedDetails* details =
136 Details<NavigationController::LoadCommittedDetails>(in_details).ptr();
137
138 NavigationEntry* entry = controller_->GetActiveEntry();
139
140 if (details->is_main_frame) {
141 if (entry) {
142 // Decode the security details.
143 int ssl_cert_id, ssl_cert_status, ssl_security_bits;
144 DeserializeSecurityInfo(details->serialized_security_info,
145 &ssl_cert_id,
146 &ssl_cert_status,
147 &ssl_security_bits);
148
149 // We may not have an entry if this is a navigation to an initial blank
150 // page. Reset the SSL information and add the new data we have.
151 entry->ssl() = NavigationEntry::SSLStatus();
152 entry->ssl().set_cert_id(ssl_cert_id);
153 entry->ssl().set_cert_status(ssl_cert_status);
154 entry->ssl().set_security_bits(ssl_security_bits);
155 }
156 backend_.ShowPendingMessages();
157 }
158
159 UpdateEntry(entry);
160 }
161
162 void SSLManager::DidRunInsecureContent(const std::string& security_origin) {
163 policy()->DidRunInsecureContent(controller_->GetActiveEntry(),
164 security_origin);
165 }
166
167 bool SSLManager::ProcessedSSLErrorFromRequest() const { 53 bool SSLManager::ProcessedSSLErrorFromRequest() const {
168 NavigationEntry* entry = controller_->GetActiveEntry(); 54 NavigationEntry* entry = controller_->GetActiveEntry();
169 if (!entry) { 55 if (!entry) {
170 NOTREACHED(); 56 NOTREACHED();
171 return false; 57 return false;
172 } 58 }
173 59
174 return net::IsCertStatusError(entry->ssl().cert_status()); 60 return net::IsCertStatusError(entry->ssl().cert_status());
175 } 61 }
176 62
63 // static
64 void SSLManager::OnSSLCertificateError(ResourceDispatcherHost* rdh,
65 URLRequest* request,
66 int cert_error,
67 net::X509Certificate* cert) {
68 DLOG(INFO) << "OnSSLCertificateError() cert_error: " << cert_error <<
69 " url: " << request->url().spec();
70
71 ResourceDispatcherHostRequestInfo* info =
72 ResourceDispatcherHost::InfoForRequest(request);
73 DCHECK(info);
74
75 // A certificate error occurred. Construct a SSLCertErrorHandler object and
76 // hand it over to the UI thread for processing.
77 ChromeThread::PostTask(
78 ChromeThread::UI, FROM_HERE,
79 NewRunnableMethod(new SSLCertErrorHandler(rdh,
80 request,
81 info->resource_type(),
82 info->frame_origin(),
83 info->main_frame_origin(),
84 cert_error,
85 cert),
86 &SSLCertErrorHandler::Dispatch));
87 }
88
89 void SSLManager::DidDisplayInsecureContent() {
90 policy()->DidDisplayInsecureContent(controller_->GetActiveEntry());
91 }
92
93 void SSLManager::DidRunInsecureContent(const std::string& security_origin) {
94 policy()->DidRunInsecureContent(controller_->GetActiveEntry(),
95 security_origin);
96 }
97
177 void SSLManager::Observe(NotificationType type, 98 void SSLManager::Observe(NotificationType type,
178 const NotificationSource& source, 99 const NotificationSource& source,
179 const NotificationDetails& details) { 100 const NotificationDetails& details) {
180 // Dispatch by type. 101 // Dispatch by type.
181 switch (type.value) { 102 switch (type.value) {
182 case NotificationType::FAIL_PROVISIONAL_LOAD_WITH_ERROR: 103 case NotificationType::FAIL_PROVISIONAL_LOAD_WITH_ERROR:
183 DidFailProvisionalLoadWithError( 104 DidFailProvisionalLoadWithError(
184 Details<ProvisionalLoadDetails>(details).ptr()); 105 Details<ProvisionalLoadDetails>(details).ptr());
185 break; 106 break;
186 case NotificationType::RESOURCE_RESPONSE_STARTED: 107 case NotificationType::RESOURCE_RESPONSE_STARTED:
187 DidStartResourceResponse(Details<ResourceRequestDetails>(details).ptr()); 108 DidStartResourceResponse(Details<ResourceRequestDetails>(details).ptr());
188 break; 109 break;
189 case NotificationType::RESOURCE_RECEIVED_REDIRECT: 110 case NotificationType::RESOURCE_RECEIVED_REDIRECT:
190 DidReceiveResourceRedirect( 111 DidReceiveResourceRedirect(
191 Details<ResourceRedirectDetails>(details).ptr()); 112 Details<ResourceRedirectDetails>(details).ptr());
192 break; 113 break;
193 case NotificationType::LOAD_FROM_MEMORY_CACHE: 114 case NotificationType::LOAD_FROM_MEMORY_CACHE:
194 DidLoadFromMemoryCache( 115 DidLoadFromMemoryCache(
195 Details<LoadFromMemoryCacheDetails>(details).ptr()); 116 Details<LoadFromMemoryCacheDetails>(details).ptr());
196 break; 117 break;
197 case NotificationType::SSL_INTERNAL_STATE_CHANGED: 118 case NotificationType::SSL_INTERNAL_STATE_CHANGED:
198 DidChangeSSLInternalState(); 119 DidChangeSSLInternalState();
199 break; 120 break;
200 default: 121 default:
201 NOTREACHED() << "The SSLManager received an unexpected notification."; 122 NOTREACHED() << "The SSLManager received an unexpected notification.";
202 } 123 }
203 } 124 }
204 125
126 void SSLManager::DispatchSSLVisibleStateChanged() {
127 NotificationService::current()->Notify(
128 NotificationType::SSL_VISIBLE_STATE_CHANGED,
129 Source<NavigationController>(controller_),
130 NotificationService::NoDetails());
131 }
132
133 void SSLManager::UpdateEntry(NavigationEntry* entry) {
134 // We don't always have a navigation entry to update, for example in the
135 // case of the Web Inspector.
136 if (!entry)
137 return;
138
139 NavigationEntry::SSLStatus original_ssl_status = entry->ssl(); // Copy!
140
141 policy()->UpdateEntry(entry);
142
143 if (!entry->ssl().Equals(original_ssl_status))
144 DispatchSSLVisibleStateChanged();
145 }
146
205 void SSLManager::DidLoadFromMemoryCache(LoadFromMemoryCacheDetails* details) { 147 void SSLManager::DidLoadFromMemoryCache(LoadFromMemoryCacheDetails* details) {
206 DCHECK(details); 148 DCHECK(details);
207 149
208 // Simulate loading this resource through the usual path. 150 // Simulate loading this resource through the usual path.
209 // Note that we specify SUB_RESOURCE as the resource type as WebCore only 151 // Note that we specify SUB_RESOURCE as the resource type as WebCore only
210 // caches sub-resources. 152 // caches sub-resources.
211 // This resource must have been loaded with FilterPolicy::DONT_FILTER because 153 // This resource must have been loaded with FilterPolicy::DONT_FILTER because
212 // filtered resouces aren't cachable. 154 // filtered resouces aren't cachable.
213 scoped_refptr<SSLRequestInfo> info = new SSLRequestInfo( 155 scoped_refptr<SSLRequestInfo> info = new SSLRequestInfo(
214 details->url(), 156 details->url(),
215 ResourceType::SUB_RESOURCE, 157 ResourceType::SUB_RESOURCE,
216 details->frame_origin(), 158 details->frame_origin(),
217 details->main_frame_origin(), 159 details->main_frame_origin(),
218 FilterPolicy::DONT_FILTER, 160 FilterPolicy::DONT_FILTER,
219 details->pid(), 161 details->pid(),
220 details->ssl_cert_id(), 162 details->ssl_cert_id(),
221 details->ssl_cert_status()); 163 details->ssl_cert_status());
222 164
223 // Simulate loading this resource through the usual path. 165 // Simulate loading this resource through the usual path.
224 policy()->OnRequestStarted(info.get()); 166 policy()->OnRequestStarted(info.get());
225 } 167 }
226 168
169 void SSLManager::DidCommitProvisionalLoad(
170 const NotificationDetails& in_details) {
171 NavigationController::LoadCommittedDetails* details =
172 Details<NavigationController::LoadCommittedDetails>(in_details).ptr();
173
174 NavigationEntry* entry = controller_->GetActiveEntry();
175
176 if (details->is_main_frame) {
177 if (entry) {
178 // Decode the security details.
179 int ssl_cert_id, ssl_cert_status, ssl_security_bits;
180 DeserializeSecurityInfo(details->serialized_security_info,
181 &ssl_cert_id,
182 &ssl_cert_status,
183 &ssl_security_bits);
184
185 // We may not have an entry if this is a navigation to an initial blank
186 // page. Reset the SSL information and add the new data we have.
187 entry->ssl() = NavigationEntry::SSLStatus();
188 entry->ssl().set_cert_id(ssl_cert_id);
189 entry->ssl().set_cert_status(ssl_cert_status);
190 entry->ssl().set_security_bits(ssl_security_bits);
191 }
192 backend_.ShowPendingMessages();
193 }
194
195 UpdateEntry(entry);
196 }
197
227 void SSLManager::DidFailProvisionalLoadWithError( 198 void SSLManager::DidFailProvisionalLoadWithError(
228 ProvisionalLoadDetails* details) { 199 ProvisionalLoadDetails* details) {
229 DCHECK(details); 200 DCHECK(details);
230 201
231 // Ignore in-page navigations. 202 // Ignore in-page navigations.
232 if (details->in_page_navigation()) 203 if (details->in_page_navigation())
233 return; 204 return;
234 205
235 if (details->main_frame()) 206 if (details->main_frame())
236 backend_.ClearPendingMessages(); 207 backend_.ClearPendingMessages();
(...skipping 23 matching lines...) Expand all
260 // a non-HTTPS resource in the redirect chain, we want to 231 // a non-HTTPS resource in the redirect chain, we want to
261 // trigger mixed content, even if the redirect chain goes back 232 // trigger mixed content, even if the redirect chain goes back
262 // to HTTPS. This is because the network attacker can redirect 233 // to HTTPS. This is because the network attacker can redirect
263 // the HTTP request to https://attacker.com/payload.js. 234 // the HTTP request to https://attacker.com/payload.js.
264 } 235 }
265 236
266 void SSLManager::DidChangeSSLInternalState() { 237 void SSLManager::DidChangeSSLInternalState() {
267 UpdateEntry(controller_->GetActiveEntry()); 238 UpdateEntry(controller_->GetActiveEntry());
268 } 239 }
269 240
270 void SSLManager::UpdateEntry(NavigationEntry* entry) { 241 // static
271 // We don't always have a navigation entry to update, for example in the 242 std::string SSLManager::SerializeSecurityInfo(int cert_id,
272 // case of the Web Inspector. 243 int cert_status,
273 if (!entry) 244 int security_bits) {
274 return; 245 Pickle pickle;
246 pickle.WriteInt(cert_id);
247 pickle.WriteInt(cert_status);
248 pickle.WriteInt(security_bits);
249 return std::string(static_cast<const char*>(pickle.data()), pickle.size());
250 }
275 251
276 NavigationEntry::SSLStatus original_ssl_status = entry->ssl(); // Copy! 252 // static
253 bool SSLManager::DeserializeSecurityInfo(const std::string& state,
254 int* cert_id,
255 int* cert_status,
256 int* security_bits) {
257 DCHECK(cert_id && cert_status && security_bits);
258 if (state.empty()) {
259 // No SSL used.
260 *cert_id = 0;
261 *cert_status = 0;
262 *security_bits = -1;
263 return false;
264 }
277 265
278 policy()->UpdateEntry(entry, controller_->tab_contents()); 266 Pickle pickle(state.data(), static_cast<int>(state.size()));
267 void * iter = NULL;
268 return pickle.ReadInt(&iter, cert_id) &&
269 pickle.ReadInt(&iter, cert_status) &&
270 pickle.ReadInt(&iter, security_bits);
271 }
279 272
280 if (!entry->ssl().Equals(original_ssl_status)) { 273 // static
281 NotificationService::current()->Notify( 274 std::wstring SSLManager::GetEVCertName(const net::X509Certificate& cert) {
282 NotificationType::SSL_VISIBLE_STATE_CHANGED, 275 // EV are required to have an organization name and country.
283 Source<NavigationController>(controller_), 276 if (cert.subject().organization_names.empty() ||
284 NotificationService::NoDetails()); 277 cert.subject().country_name.empty()) {
278 NOTREACHED();
279 return std::wstring();
285 } 280 }
281
282 return l10n_util::GetStringF(IDS_SECURE_CONNECTION_EV,
283 UTF8ToWide(cert.subject().organization_names[0]),
284 UTF8ToWide(cert.subject().country_name));
286 } 285 }
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