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

Side by Side Diff: content/browser/ssl/ssl_policy.cc

Issue 2395663002: Collapse SSLPolicy/SSLPolicyBackend into SSLManager (Closed)
Patch Set: remove accidentally added temp file... oops... Created 4 years, 2 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
« no previous file with comments | « content/browser/ssl/ssl_policy.h ('k') | content/browser/ssl/ssl_policy_backend.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "content/browser/ssl/ssl_policy.h"
6
7 #include "base/base_switches.h"
8 #include "base/bind.h"
9 #include "base/command_line.h"
10 #include "base/memory/singleton.h"
11 #include "base/metrics/histogram_macros.h"
12 #include "base/strings/string_piece.h"
13 #include "base/strings/string_util.h"
14 #include "content/browser/frame_host/navigation_entry_impl.h"
15 #include "content/browser/renderer_host/render_process_host_impl.h"
16 #include "content/browser/renderer_host/render_view_host_impl.h"
17 #include "content/browser/site_instance_impl.h"
18 #include "content/browser/ssl/ssl_error_handler.h"
19 #include "content/browser/web_contents/web_contents_impl.h"
20 #include "content/common/security_style_util.h"
21 #include "content/public/browser/content_browser_client.h"
22 #include "content/public/browser/ssl_status.h"
23 #include "content/public/browser/web_contents.h"
24 #include "content/public/common/resource_type.h"
25 #include "content/public/common/url_constants.h"
26 #include "net/ssl/ssl_info.h"
27 #include "url/gurl.h"
28
29 namespace content {
30
31 namespace {
32
33 // Events for UMA. Do not reorder or change!
34 enum SSLGoodCertSeenEvent {
35 NO_PREVIOUS_EXCEPTION = 0,
36 HAD_PREVIOUS_EXCEPTION = 1,
37 SSL_GOOD_CERT_SEEN_EVENT_MAX = 2
38 };
39
40 void OnAllowCertificate(SSLErrorHandler* handler,
41 const SSLPolicy* const policy,
42 CertificateRequestResultType decision) {
43 DCHECK(handler->ssl_info().is_valid());
44 switch (decision) {
45 case CERTIFICATE_REQUEST_RESULT_TYPE_CONTINUE:
46 // Note that we should not call SetMaxSecurityStyle here, because
47 // the active NavigationEntry has just been deleted (in
48 // HideInterstitialPage) and the new NavigationEntry will not be
49 // set until DidNavigate. This is ok, because the new
50 // NavigationEntry will have its max security style set within
51 // DidNavigate.
52 //
53 // While AllowCertForHost() executes synchronously on this thread,
54 // ContinueRequest() gets posted to a different thread. Calling
55 // AllowCertForHost() first ensures deterministic ordering.
56 policy->backend()->AllowCertForHost(*handler->ssl_info().cert.get(),
57 handler->request_url().host(),
58 handler->cert_error());
59 handler->ContinueRequest();
60 return;
61 case CERTIFICATE_REQUEST_RESULT_TYPE_DENY:
62 handler->DenyRequest();
63 return;
64 case CERTIFICATE_REQUEST_RESULT_TYPE_CANCEL:
65 handler->CancelRequest();
66 return;
67 }
68 }
69
70 } // namespace
71
72 SSLPolicy::SSLPolicy(SSLPolicyBackend* backend)
73 : backend_(backend) {
74 DCHECK(backend_);
75 }
76
77 void SSLPolicy::OnCertError(std::unique_ptr<SSLErrorHandler> handler) {
78 bool expired_previous_decision = false;
79 // First we check if we know the policy for this error.
80 DCHECK(handler->ssl_info().is_valid());
81 SSLHostStateDelegate::CertJudgment judgment =
82 backend_->QueryPolicy(*handler->ssl_info().cert.get(),
83 handler->request_url().host(),
84 handler->cert_error(),
85 &expired_previous_decision);
86
87 if (judgment == SSLHostStateDelegate::ALLOWED) {
88 handler->ContinueRequest();
89 return;
90 }
91
92 // For all other hosts, which must be DENIED, a blocking page is shown to the
93 // user every time they come back to the page.
94 int options_mask = 0;
95 switch (handler->cert_error()) {
96 case net::ERR_CERT_COMMON_NAME_INVALID:
97 case net::ERR_CERT_DATE_INVALID:
98 case net::ERR_CERT_AUTHORITY_INVALID:
99 case net::ERR_CERT_WEAK_SIGNATURE_ALGORITHM:
100 case net::ERR_CERT_WEAK_KEY:
101 case net::ERR_CERT_NAME_CONSTRAINT_VIOLATION:
102 case net::ERR_CERT_VALIDITY_TOO_LONG:
103 case net::ERR_CERTIFICATE_TRANSPARENCY_REQUIRED:
104 if (!handler->fatal())
105 options_mask |= OVERRIDABLE;
106 else
107 options_mask |= STRICT_ENFORCEMENT;
108 if (expired_previous_decision)
109 options_mask |= EXPIRED_PREVIOUS_DECISION;
110 OnCertErrorInternal(std::move(handler), options_mask);
111 break;
112 case net::ERR_CERT_NO_REVOCATION_MECHANISM:
113 // Ignore this error.
114 handler->ContinueRequest();
115 break;
116 case net::ERR_CERT_UNABLE_TO_CHECK_REVOCATION:
117 // We ignore this error but will show a warning status in the location
118 // bar.
119 handler->ContinueRequest();
120 break;
121 case net::ERR_CERT_CONTAINS_ERRORS:
122 case net::ERR_CERT_REVOKED:
123 case net::ERR_CERT_INVALID:
124 case net::ERR_SSL_WEAK_SERVER_EPHEMERAL_DH_KEY:
125 case net::ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN:
126 if (handler->fatal())
127 options_mask |= STRICT_ENFORCEMENT;
128 if (expired_previous_decision)
129 options_mask |= EXPIRED_PREVIOUS_DECISION;
130 OnCertErrorInternal(std::move(handler), options_mask);
131 break;
132 default:
133 NOTREACHED();
134 handler->CancelRequest();
135 break;
136 }
137 }
138
139 void SSLPolicy::DidRunInsecureContent(NavigationEntryImpl* entry,
140 const GURL& security_origin) {
141 if (!entry)
142 return;
143
144 SiteInstance* site_instance = entry->site_instance();
145 if (!site_instance)
146 return;
147
148 backend_->HostRanInsecureContent(security_origin.host(),
149 site_instance->GetProcess()->GetID());
150 }
151
152 void SSLPolicy::DidRunContentWithCertErrors(NavigationEntryImpl* entry,
153 const GURL& security_origin) {
154 if (!entry)
155 return;
156
157 SiteInstance* site_instance = entry->site_instance();
158 if (!site_instance)
159 return;
160
161 backend_->HostRanContentWithCertErrors(security_origin.host(),
162 site_instance->GetProcess()->GetID());
163 }
164
165 void SSLPolicy::OnRequestStarted(const GURL& url,
166 bool has_certificate,
167 net::CertStatus cert_status) {
168 if (has_certificate && url.SchemeIsCryptographic() &&
169 !net::IsCertStatusError(cert_status)) {
170 // If the scheme is https: or wss: *and* the security info for the
171 // cert has been set (i.e. the cert id is not 0) and the cert did
172 // not have any errors, revoke any previous decisions that
173 // have occurred. If the cert info has not been set, do nothing since it
174 // isn't known if the connection was actually a valid connection or if it
175 // had a cert error.
176 SSLGoodCertSeenEvent event = NO_PREVIOUS_EXCEPTION;
177 if (backend_->HasAllowException(url.host())) {
178 // If there's no certificate error, a good certificate has been seen, so
179 // clear out any exceptions that were made by the user for bad
180 // certificates. This intentionally does not apply to cached resources
181 // (see https://crbug.com/634553 for an explanation).
182 backend_->RevokeUserAllowExceptions(url.host());
183 event = HAD_PREVIOUS_EXCEPTION;
184 }
185 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl.good_cert_seen", event,
186 SSL_GOOD_CERT_SEEN_EVENT_MAX);
187 }
188 }
189
190 void SSLPolicy::UpdateEntry(NavigationEntryImpl* entry,
191 WebContents* web_contents) {
192 DCHECK(entry);
193
194 WebContentsImpl* web_contents_impl =
195 static_cast<WebContentsImpl*>(web_contents);
196
197 InitializeEntryIfNeeded(entry);
198
199 if (entry->GetSSL().security_style == SECURITY_STYLE_UNAUTHENTICATED)
200 return;
201
202 if (!web_contents_impl->DisplayedInsecureContent())
203 entry->GetSSL().content_status &= ~SSLStatus::DISPLAYED_INSECURE_CONTENT;
204
205 if (web_contents_impl->DisplayedInsecureContent())
206 entry->GetSSL().content_status |= SSLStatus::DISPLAYED_INSECURE_CONTENT;
207
208 if (!web_contents_impl->DisplayedContentWithCertErrors())
209 entry->GetSSL().content_status &=
210 ~SSLStatus::DISPLAYED_CONTENT_WITH_CERT_ERRORS;
211
212 if (web_contents_impl->DisplayedContentWithCertErrors())
213 entry->GetSSL().content_status |=
214 SSLStatus::DISPLAYED_CONTENT_WITH_CERT_ERRORS;
215
216 SiteInstance* site_instance = entry->site_instance();
217 // Note that |site_instance| can be NULL here because NavigationEntries don't
218 // necessarily have site instances. Without a process, the entry can't
219 // possibly have insecure content. See bug http://crbug.com/12423.
220 if (site_instance &&
221 backend_->DidHostRunInsecureContent(
222 entry->GetURL().host(), site_instance->GetProcess()->GetID())) {
223 entry->GetSSL().security_style =
224 SECURITY_STYLE_AUTHENTICATION_BROKEN;
225 entry->GetSSL().content_status |= SSLStatus::RAN_INSECURE_CONTENT;
226 }
227
228 if (site_instance &&
229 backend_->DidHostRunContentWithCertErrors(
230 entry->GetURL().host(), site_instance->GetProcess()->GetID())) {
231 entry->GetSSL().security_style = SECURITY_STYLE_AUTHENTICATION_BROKEN;
232 entry->GetSSL().content_status |= SSLStatus::RAN_CONTENT_WITH_CERT_ERRORS;
233 }
234 }
235
236 ////////////////////////////////////////////////////////////////////////////////
237 // Certificate Error Routines
238
239 void SSLPolicy::OnCertErrorInternal(std::unique_ptr<SSLErrorHandler> handler,
240 int options_mask) {
241 bool overridable = (options_mask & OVERRIDABLE) != 0;
242 bool strict_enforcement = (options_mask & STRICT_ENFORCEMENT) != 0;
243 bool expired_previous_decision =
244 (options_mask & EXPIRED_PREVIOUS_DECISION) != 0;
245
246 WebContents* web_contents = handler->web_contents();
247 int cert_error = handler->cert_error();
248 const net::SSLInfo& ssl_info = handler->ssl_info();
249 const GURL& request_url = handler->request_url();
250 ResourceType resource_type = handler->resource_type();
251 GetContentClient()->browser()->AllowCertificateError(
252 web_contents, cert_error, ssl_info, request_url, resource_type,
253 overridable, strict_enforcement, expired_previous_decision,
254 base::Bind(&OnAllowCertificate, base::Owned(handler.release()), this));
255 }
256
257 void SSLPolicy::InitializeEntryIfNeeded(NavigationEntryImpl* entry) {
258 if (entry->GetSSL().security_style != SECURITY_STYLE_UNKNOWN)
259 return;
260
261 entry->GetSSL().security_style = GetSecurityStyleForResource(
262 entry->GetURL(), !!entry->GetSSL().certificate,
263 entry->GetSSL().cert_status);
264 }
265
266 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/ssl/ssl_policy.h ('k') | content/browser/ssl/ssl_policy_backend.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698