Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/browser/ssl/ssl_policy.h" | 5 #include "content/browser/ssl/ssl_policy.h" |
| 6 | 6 |
| 7 #include "base/base_switches.h" | 7 #include "base/base_switches.h" |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/memory/singleton.h" | 10 #include "base/memory/singleton.h" |
| 11 #include "base/metrics/histogram_macros.h" | 11 #include "base/metrics/histogram_macros.h" |
| 12 #include "base/strings/string_piece.h" | 12 #include "base/strings/string_piece.h" |
| 13 #include "base/strings/string_util.h" | 13 #include "base/strings/string_util.h" |
| 14 #include "content/browser/frame_host/navigation_entry_impl.h" | 14 #include "content/browser/frame_host/navigation_entry_impl.h" |
| 15 #include "content/browser/renderer_host/render_process_host_impl.h" | 15 #include "content/browser/renderer_host/render_process_host_impl.h" |
| 16 #include "content/browser/renderer_host/render_view_host_impl.h" | 16 #include "content/browser/renderer_host/render_view_host_impl.h" |
| 17 #include "content/browser/site_instance_impl.h" | 17 #include "content/browser/site_instance_impl.h" |
| 18 #include "content/browser/ssl/ssl_cert_error_handler.h" | 18 #include "content/browser/ssl/ssl_cert_error_handler.h" |
| 19 #include "content/browser/ssl/ssl_request_info.h" | 19 #include "content/browser/ssl/ssl_request_info.h" |
| 20 #include "content/browser/web_contents/web_contents_impl.h" | 20 #include "content/browser/web_contents/web_contents_impl.h" |
| 21 #include "content/public/browser/content_browser_client.h" | 21 #include "content/public/browser/content_browser_client.h" |
| 22 #include "content/public/browser/web_contents.h" | |
| 22 #include "content/public/common/resource_type.h" | 23 #include "content/public/common/resource_type.h" |
| 23 #include "content/public/common/ssl_status.h" | 24 #include "content/public/common/ssl_status.h" |
| 24 #include "content/public/common/url_constants.h" | 25 #include "content/public/common/url_constants.h" |
| 25 #include "net/ssl/ssl_info.h" | 26 #include "net/ssl/ssl_info.h" |
| 26 | 27 #include "url/gurl.h" |
| 27 | 28 |
| 28 namespace content { | 29 namespace content { |
| 29 | 30 |
| 30 namespace { | 31 namespace { |
| 31 | 32 |
| 32 // Events for UMA. Do not reorder or change! | 33 // Events for UMA. Do not reorder or change! |
| 33 enum SSLGoodCertSeenEvent { | 34 enum SSLGoodCertSeenEvent { |
| 34 NO_PREVIOUS_EXCEPTION = 0, | 35 NO_PREVIOUS_EXCEPTION = 0, |
| 35 HAD_PREVIOUS_EXCEPTION = 1, | 36 HAD_PREVIOUS_EXCEPTION = 1, |
| 36 SSL_GOOD_CERT_SEEN_EVENT_MAX = 2 | 37 SSL_GOOD_CERT_SEEN_EVENT_MAX = 2 |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 131 // certificates. | 132 // certificates. |
| 132 backend_->RevokeUserAllowExceptions(info->url().host()); | 133 backend_->RevokeUserAllowExceptions(info->url().host()); |
| 133 event = HAD_PREVIOUS_EXCEPTION; | 134 event = HAD_PREVIOUS_EXCEPTION; |
| 134 } | 135 } |
| 135 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.good_cert_seen", event, | 136 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.good_cert_seen", event, |
| 136 SSL_GOOD_CERT_SEEN_EVENT_MAX); | 137 SSL_GOOD_CERT_SEEN_EVENT_MAX); |
| 137 } | 138 } |
| 138 } | 139 } |
| 139 | 140 |
| 140 void SSLPolicy::UpdateEntry(NavigationEntryImpl* entry, | 141 void SSLPolicy::UpdateEntry(NavigationEntryImpl* entry, |
| 141 WebContentsImpl* web_contents) { | 142 WebContents* web_contents) { |
| 142 DCHECK(entry); | 143 DCHECK(entry); |
| 143 | 144 |
| 144 InitializeEntryIfNeeded(entry); | 145 InitializeEntryIfNeeded(entry); |
| 145 | 146 |
| 146 if (!entry->GetURL().SchemeIsCryptographic()) | 147 if (entry->GetSSL().security_style == SECURITY_STYLE_UNAUTHENTICATED) |
| 147 return; | 148 return; |
| 148 | 149 |
| 149 if (!web_contents->DisplayedInsecureContent()) | 150 if (!web_contents->DisplayedInsecureContent()) |
| 150 entry->GetSSL().content_status &= ~SSLStatus::DISPLAYED_INSECURE_CONTENT; | 151 entry->GetSSL().content_status &= ~SSLStatus::DISPLAYED_INSECURE_CONTENT; |
| 151 | 152 |
| 152 // An HTTPS response may not have a certificate for some reason. When that | |
| 153 // happens, use the unauthenticated (HTTP) rather than the authentication | |
| 154 // broken security style so that we can detect this error condition. | |
| 155 if (!entry->GetSSL().cert_id) { | |
| 156 entry->GetSSL().security_style = SECURITY_STYLE_UNAUTHENTICATED; | |
| 157 return; | |
| 158 } | |
| 159 | |
| 160 if (web_contents->DisplayedInsecureContent()) | 153 if (web_contents->DisplayedInsecureContent()) |
| 161 entry->GetSSL().content_status |= SSLStatus::DISPLAYED_INSECURE_CONTENT; | 154 entry->GetSSL().content_status |= SSLStatus::DISPLAYED_INSECURE_CONTENT; |
| 162 | 155 |
| 163 if (net::IsCertStatusError(entry->GetSSL().cert_status)) { | 156 if (entry->GetSSL().security_style == SECURITY_STYLE_AUTHENTICATION_BROKEN) |
| 164 // Minor errors don't lower the security style to | |
| 165 // SECURITY_STYLE_AUTHENTICATION_BROKEN. | |
| 166 if (!net::IsCertStatusMinorError(entry->GetSSL().cert_status)) { | |
| 167 entry->GetSSL().security_style = | |
| 168 SECURITY_STYLE_AUTHENTICATION_BROKEN; | |
| 169 } | |
| 170 return; | 157 return; |
| 171 } | |
| 172 | 158 |
| 173 SiteInstance* site_instance = entry->site_instance(); | 159 SiteInstance* site_instance = entry->site_instance(); |
| 174 // Note that |site_instance| can be NULL here because NavigationEntries don't | 160 // Note that |site_instance| can be NULL here because NavigationEntries don't |
| 175 // necessarily have site instances. Without a process, the entry can't | 161 // necessarily have site instances. Without a process, the entry can't |
| 176 // possibly have insecure content. See bug http://crbug.com/12423. | 162 // possibly have insecure content. See bug http://crbug.com/12423. |
| 177 if (site_instance && | 163 if (site_instance && |
| 178 backend_->DidHostRunInsecureContent( | 164 backend_->DidHostRunInsecureContent( |
| 179 entry->GetURL().host(), site_instance->GetProcess()->GetID())) { | 165 entry->GetURL().host(), site_instance->GetProcess()->GetID())) { |
| 180 entry->GetSSL().security_style = | 166 entry->GetSSL().security_style = |
| 181 SECURITY_STYLE_AUTHENTICATION_BROKEN; | 167 SECURITY_STYLE_AUTHENTICATION_BROKEN; |
| 182 entry->GetSSL().content_status |= SSLStatus::RAN_INSECURE_CONTENT; | 168 entry->GetSSL().content_status |= SSLStatus::RAN_INSECURE_CONTENT; |
| 183 return; | 169 return; |
| 184 } | 170 } |
| 185 } | 171 } |
| 186 | 172 |
| 173 // Static | |
| 174 SecurityStyle SSLPolicy::GetSecurityStyleForResource(const GURL& url, | |
| 175 const SSLStatus& ssl) { | |
| 176 // An HTTPS response may not have a certificate for some reason. When that | |
| 177 // happens, use the unauthenticated (HTTP) rather than the authentication | |
| 178 // broken security style so that we can detect this error condition. | |
| 179 if (!url.SchemeIsCryptographic() || !ssl.cert_id) | |
| 180 return SECURITY_STYLE_UNAUTHENTICATED; | |
| 181 | |
| 182 if (net::IsCertStatusError(ssl.cert_status)) { | |
| 183 // Minor errors don't lower the security style to | |
| 184 // SECURITY_STYLE_AUTHENTICATION_BROKEN. | |
| 185 if (!net::IsCertStatusMinorError(ssl.cert_status)) | |
|
davidben
2015/07/22 20:56:57
Nit: You can fold this to
// Minor blah blah
if (
estark
2015/07/22 22:56:55
Done.
| |
| 186 return SECURITY_STYLE_AUTHENTICATION_BROKEN; | |
| 187 } | |
| 188 | |
| 189 return SECURITY_STYLE_AUTHENTICATED; | |
| 190 } | |
| 191 | |
| 187 void SSLPolicy::OnAllowCertificate(scoped_refptr<SSLCertErrorHandler> handler, | 192 void SSLPolicy::OnAllowCertificate(scoped_refptr<SSLCertErrorHandler> handler, |
| 188 bool allow) { | 193 bool allow) { |
| 189 DCHECK(handler->ssl_info().is_valid()); | 194 DCHECK(handler->ssl_info().is_valid()); |
| 190 if (allow) { | 195 if (allow) { |
| 191 // Default behavior for accepting a certificate. | 196 // Default behavior for accepting a certificate. |
| 192 // Note that we should not call SetMaxSecurityStyle here, because the active | 197 // Note that we should not call SetMaxSecurityStyle here, because the active |
| 193 // NavigationEntry has just been deleted (in HideInterstitialPage) and the | 198 // NavigationEntry has just been deleted (in HideInterstitialPage) and the |
| 194 // new NavigationEntry will not be set until DidNavigate. This is ok, | 199 // new NavigationEntry will not be set until DidNavigate. This is ok, |
| 195 // because the new NavigationEntry will have its max security style set | 200 // because the new NavigationEntry will have its max security style set |
| 196 // within DidNavigate. | 201 // within DidNavigate. |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 244 break; | 249 break; |
| 245 default: | 250 default: |
| 246 NOTREACHED(); | 251 NOTREACHED(); |
| 247 } | 252 } |
| 248 } | 253 } |
| 249 | 254 |
| 250 void SSLPolicy::InitializeEntryIfNeeded(NavigationEntryImpl* entry) { | 255 void SSLPolicy::InitializeEntryIfNeeded(NavigationEntryImpl* entry) { |
| 251 if (entry->GetSSL().security_style != SECURITY_STYLE_UNKNOWN) | 256 if (entry->GetSSL().security_style != SECURITY_STYLE_UNKNOWN) |
| 252 return; | 257 return; |
| 253 | 258 |
| 254 entry->GetSSL().security_style = entry->GetURL().SchemeIsCryptographic() | 259 entry->GetSSL().security_style = |
| 255 ? SECURITY_STYLE_AUTHENTICATED | 260 GetSecurityStyleForResource(entry->GetURL(), entry->GetSSL()); |
|
davidben
2015/07/22 20:56:57
Do you know if this code can ever run, now that se
estark
2015/07/22 22:56:55
I think the only way it can run right now is 1. a
| |
| 256 : SECURITY_STYLE_UNAUTHENTICATED; | |
| 257 } | 261 } |
| 258 | 262 |
| 259 void SSLPolicy::OriginRanInsecureContent(const std::string& origin, int pid) { | 263 void SSLPolicy::OriginRanInsecureContent(const std::string& origin, int pid) { |
| 260 GURL parsed_origin(origin); | 264 GURL parsed_origin(origin); |
| 261 if (parsed_origin.SchemeIsCryptographic()) | 265 if (parsed_origin.SchemeIsCryptographic()) |
| 262 backend_->HostRanInsecureContent(parsed_origin.host(), pid); | 266 backend_->HostRanInsecureContent(parsed_origin.host(), pid); |
| 263 } | 267 } |
| 264 | 268 |
| 265 } // namespace content | 269 } // namespace content |
| OLD | NEW |