| 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" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 namespace content { | 28 namespace content { |
| 29 | 29 |
| 30 namespace { | 30 namespace { |
| 31 | 31 |
| 32 // Events for UMA. Do not reorder or change! | 32 // Events for UMA. Do not reorder or change! |
| 33 enum SSLGoodCertSeenEvent { | 33 enum SSLGoodCertSeenEvent { |
| 34 NO_PREVIOUS_EXCEPTION = 0, | 34 NO_PREVIOUS_EXCEPTION = 0, |
| 35 HAD_PREVIOUS_EXCEPTION = 1, | 35 HAD_PREVIOUS_EXCEPTION = 1, |
| 36 SSL_GOOD_CERT_SEEN_EVENT_MAX = 2 | 36 SSL_GOOD_CERT_SEEN_EVENT_MAX = 2 |
| 37 }; | 37 }; |
| 38 |
| 39 void OnAllowCertificate(SSLErrorHandler* handler, |
| 40 const SSLPolicy* const policy, |
| 41 CertificateRequestResultType decision) { |
| 42 DCHECK(handler->ssl_info().is_valid()); |
| 43 switch (decision) { |
| 44 case CERTIFICATE_REQUEST_RESULT_TYPE_CONTINUE: |
| 45 // Note that we should not call SetMaxSecurityStyle here, because |
| 46 // the active NavigationEntry has just been deleted (in |
| 47 // HideInterstitialPage) and the new NavigationEntry will not be |
| 48 // set until DidNavigate. This is ok, because the new |
| 49 // NavigationEntry will have its max security style set within |
| 50 // DidNavigate. |
| 51 // |
| 52 // While AllowCertForHost() executes synchronously on this thread, |
| 53 // ContinueRequest() gets posted to a different thread. Calling |
| 54 // AllowCertForHost() first ensures deterministic ordering. |
| 55 policy->backend()->AllowCertForHost(*handler->ssl_info().cert.get(), |
| 56 handler->request_url().host(), |
| 57 handler->cert_error()); |
| 58 handler->ContinueRequest(); |
| 59 return; |
| 60 case CERTIFICATE_REQUEST_RESULT_TYPE_DENY: |
| 61 handler->DenyRequest(); |
| 62 return; |
| 63 case CERTIFICATE_REQUEST_RESULT_TYPE_CANCEL: |
| 64 handler->CancelRequest(); |
| 65 return; |
| 66 } |
| 38 } | 67 } |
| 39 | 68 |
| 69 } // namespace |
| 70 |
| 40 SSLPolicy::SSLPolicy(SSLPolicyBackend* backend) | 71 SSLPolicy::SSLPolicy(SSLPolicyBackend* backend) |
| 41 : backend_(backend) { | 72 : backend_(backend) { |
| 42 DCHECK(backend_); | 73 DCHECK(backend_); |
| 43 } | 74 } |
| 44 | 75 |
| 45 void SSLPolicy::OnCertError(SSLErrorHandler* handler) { | 76 void SSLPolicy::OnCertError(std::unique_ptr<SSLErrorHandler> handler) { |
| 46 bool expired_previous_decision = false; | 77 bool expired_previous_decision = false; |
| 47 // First we check if we know the policy for this error. | 78 // First we check if we know the policy for this error. |
| 48 DCHECK(handler->ssl_info().is_valid()); | 79 DCHECK(handler->ssl_info().is_valid()); |
| 49 SSLHostStateDelegate::CertJudgment judgment = | 80 SSLHostStateDelegate::CertJudgment judgment = |
| 50 backend_->QueryPolicy(*handler->ssl_info().cert.get(), | 81 backend_->QueryPolicy(*handler->ssl_info().cert.get(), |
| 51 handler->request_url().host(), | 82 handler->request_url().host(), |
| 52 handler->cert_error(), | 83 handler->cert_error(), |
| 53 &expired_previous_decision); | 84 &expired_previous_decision); |
| 54 | 85 |
| 55 if (judgment == SSLHostStateDelegate::ALLOWED) { | 86 if (judgment == SSLHostStateDelegate::ALLOWED) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 68 case net::ERR_CERT_WEAK_KEY: | 99 case net::ERR_CERT_WEAK_KEY: |
| 69 case net::ERR_CERT_NAME_CONSTRAINT_VIOLATION: | 100 case net::ERR_CERT_NAME_CONSTRAINT_VIOLATION: |
| 70 case net::ERR_CERT_VALIDITY_TOO_LONG: | 101 case net::ERR_CERT_VALIDITY_TOO_LONG: |
| 71 case net::ERR_CERTIFICATE_TRANSPARENCY_REQUIRED: | 102 case net::ERR_CERTIFICATE_TRANSPARENCY_REQUIRED: |
| 72 if (!handler->fatal()) | 103 if (!handler->fatal()) |
| 73 options_mask |= OVERRIDABLE; | 104 options_mask |= OVERRIDABLE; |
| 74 else | 105 else |
| 75 options_mask |= STRICT_ENFORCEMENT; | 106 options_mask |= STRICT_ENFORCEMENT; |
| 76 if (expired_previous_decision) | 107 if (expired_previous_decision) |
| 77 options_mask |= EXPIRED_PREVIOUS_DECISION; | 108 options_mask |= EXPIRED_PREVIOUS_DECISION; |
| 78 OnCertErrorInternal(handler, options_mask); | 109 OnCertErrorInternal(std::move(handler), options_mask); |
| 79 break; | 110 break; |
| 80 case net::ERR_CERT_NO_REVOCATION_MECHANISM: | 111 case net::ERR_CERT_NO_REVOCATION_MECHANISM: |
| 81 // Ignore this error. | 112 // Ignore this error. |
| 82 handler->ContinueRequest(); | 113 handler->ContinueRequest(); |
| 83 break; | 114 break; |
| 84 case net::ERR_CERT_UNABLE_TO_CHECK_REVOCATION: | 115 case net::ERR_CERT_UNABLE_TO_CHECK_REVOCATION: |
| 85 // We ignore this error but will show a warning status in the location | 116 // We ignore this error but will show a warning status in the location |
| 86 // bar. | 117 // bar. |
| 87 handler->ContinueRequest(); | 118 handler->ContinueRequest(); |
| 88 break; | 119 break; |
| 89 case net::ERR_CERT_CONTAINS_ERRORS: | 120 case net::ERR_CERT_CONTAINS_ERRORS: |
| 90 case net::ERR_CERT_REVOKED: | 121 case net::ERR_CERT_REVOKED: |
| 91 case net::ERR_CERT_INVALID: | 122 case net::ERR_CERT_INVALID: |
| 92 case net::ERR_SSL_WEAK_SERVER_EPHEMERAL_DH_KEY: | 123 case net::ERR_SSL_WEAK_SERVER_EPHEMERAL_DH_KEY: |
| 93 case net::ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN: | 124 case net::ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN: |
| 94 if (handler->fatal()) | 125 if (handler->fatal()) |
| 95 options_mask |= STRICT_ENFORCEMENT; | 126 options_mask |= STRICT_ENFORCEMENT; |
| 96 if (expired_previous_decision) | 127 if (expired_previous_decision) |
| 97 options_mask |= EXPIRED_PREVIOUS_DECISION; | 128 options_mask |= EXPIRED_PREVIOUS_DECISION; |
| 98 OnCertErrorInternal(handler, options_mask); | 129 OnCertErrorInternal(std::move(handler), options_mask); |
| 99 break; | 130 break; |
| 100 default: | 131 default: |
| 101 NOTREACHED(); | 132 NOTREACHED(); |
| 102 handler->CancelRequest(); | 133 handler->CancelRequest(); |
| 103 break; | 134 break; |
| 104 } | 135 } |
| 105 } | 136 } |
| 106 | 137 |
| 107 void SSLPolicy::DidRunInsecureContent(NavigationEntryImpl* entry, | 138 void SSLPolicy::DidRunInsecureContent(NavigationEntryImpl* entry, |
| 108 const GURL& security_origin) { | 139 const GURL& security_origin) { |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 // Minor errors don't lower the security style to | 214 // Minor errors don't lower the security style to |
| 184 // SECURITY_STYLE_AUTHENTICATION_BROKEN. | 215 // SECURITY_STYLE_AUTHENTICATION_BROKEN. |
| 185 if (net::IsCertStatusError(cert_status) && | 216 if (net::IsCertStatusError(cert_status) && |
| 186 !net::IsCertStatusMinorError(cert_status)) { | 217 !net::IsCertStatusMinorError(cert_status)) { |
| 187 return SECURITY_STYLE_AUTHENTICATION_BROKEN; | 218 return SECURITY_STYLE_AUTHENTICATION_BROKEN; |
| 188 } | 219 } |
| 189 | 220 |
| 190 return SECURITY_STYLE_AUTHENTICATED; | 221 return SECURITY_STYLE_AUTHENTICATED; |
| 191 } | 222 } |
| 192 | 223 |
| 193 void SSLPolicy::OnAllowCertificate(scoped_refptr<SSLErrorHandler> handler, | |
| 194 CertificateRequestResultType decision) { | |
| 195 DCHECK(handler->ssl_info().is_valid()); | |
| 196 switch (decision) { | |
| 197 case CERTIFICATE_REQUEST_RESULT_TYPE_CONTINUE: | |
| 198 // Note that we should not call SetMaxSecurityStyle here, because the | |
| 199 // active | |
| 200 // NavigationEntry has just been deleted (in HideInterstitialPage) and the | |
| 201 // new NavigationEntry will not be set until DidNavigate. This is ok, | |
| 202 // because the new NavigationEntry will have its max security style set | |
| 203 // within DidNavigate. | |
| 204 // | |
| 205 // While AllowCertForHost() executes synchronously on this thread, | |
| 206 // ContinueRequest() gets posted to a different thread. Calling | |
| 207 // AllowCertForHost() first ensures deterministic ordering. | |
| 208 backend_->AllowCertForHost(*handler->ssl_info().cert.get(), | |
| 209 handler->request_url().host(), | |
| 210 handler->cert_error()); | |
| 211 handler->ContinueRequest(); | |
| 212 return; | |
| 213 case CERTIFICATE_REQUEST_RESULT_TYPE_DENY: | |
| 214 handler->DenyRequest(); | |
| 215 return; | |
| 216 case CERTIFICATE_REQUEST_RESULT_TYPE_CANCEL: | |
| 217 handler->CancelRequest(); | |
| 218 return; | |
| 219 } | |
| 220 } | |
| 221 | |
| 222 //////////////////////////////////////////////////////////////////////////////// | 224 //////////////////////////////////////////////////////////////////////////////// |
| 223 // Certificate Error Routines | 225 // Certificate Error Routines |
| 224 | 226 |
| 225 void SSLPolicy::OnCertErrorInternal(SSLErrorHandler* handler, | 227 void SSLPolicy::OnCertErrorInternal(std::unique_ptr<SSLErrorHandler> handler, |
| 226 int options_mask) { | 228 int options_mask) { |
| 227 bool overridable = (options_mask & OVERRIDABLE) != 0; | 229 bool overridable = (options_mask & OVERRIDABLE) != 0; |
| 228 bool strict_enforcement = (options_mask & STRICT_ENFORCEMENT) != 0; | 230 bool strict_enforcement = (options_mask & STRICT_ENFORCEMENT) != 0; |
| 229 bool expired_previous_decision = | 231 bool expired_previous_decision = |
| 230 (options_mask & EXPIRED_PREVIOUS_DECISION) != 0; | 232 (options_mask & EXPIRED_PREVIOUS_DECISION) != 0; |
| 233 |
| 234 WebContents* web_contents = handler->web_contents(); |
| 235 int cert_error = handler->cert_error(); |
| 236 const net::SSLInfo& ssl_info = handler->ssl_info(); |
| 237 const GURL& request_url = handler->request_url(); |
| 238 ResourceType resource_type = handler->resource_type(); |
| 231 GetContentClient()->browser()->AllowCertificateError( | 239 GetContentClient()->browser()->AllowCertificateError( |
| 232 handler->GetManager()->controller()->GetWebContents(), | 240 web_contents, cert_error, ssl_info, request_url, resource_type, |
| 233 handler->cert_error(), handler->ssl_info(), handler->request_url(), | 241 overridable, strict_enforcement, expired_previous_decision, |
| 234 handler->resource_type(), overridable, strict_enforcement, | 242 base::Bind(&OnAllowCertificate, base::Owned(handler.release()), this)); |
| 235 expired_previous_decision, | |
| 236 base::Bind(&SSLPolicy::OnAllowCertificate, base::Unretained(this), | |
| 237 make_scoped_refptr(handler))); | |
| 238 } | 243 } |
| 239 | 244 |
| 240 void SSLPolicy::InitializeEntryIfNeeded(NavigationEntryImpl* entry) { | 245 void SSLPolicy::InitializeEntryIfNeeded(NavigationEntryImpl* entry) { |
| 241 if (entry->GetSSL().security_style != SECURITY_STYLE_UNKNOWN) | 246 if (entry->GetSSL().security_style != SECURITY_STYLE_UNKNOWN) |
| 242 return; | 247 return; |
| 243 | 248 |
| 244 entry->GetSSL().security_style = GetSecurityStyleForResource( | 249 entry->GetSSL().security_style = GetSecurityStyleForResource( |
| 245 entry->GetURL(), entry->GetSSL().cert_id, entry->GetSSL().cert_status); | 250 entry->GetURL(), entry->GetSSL().cert_id, entry->GetSSL().cert_status); |
| 246 } | 251 } |
| 247 | 252 |
| 248 } // namespace content | 253 } // namespace content |
| OLD | NEW |