Updates:
Cc:
rsl...@chromium.org w...@chromium.org
Comment #4 on issue 122498 by
pal...@chromium.org: The error message for
Crawling up the deep and convoluted call stack, we seem ultimately to
arrive at this code from URLRequestHttpJob::OnStartCompleted:
708 } else if (IsCertificateError(result)) {
709 // We encountered an SSL certificate error. Ask our delegate to
decide
710 // what we should do.
711
712 TransportSecurityState::DomainState domain_state;
713 const bool fatal =
714 context_->transport_security_state() &&
715 context_->transport_security_state()->GetDomainState(
716 request_info_.url.host(),
717
SSLConfigService::IsSNIAvailable(context_->ssl_config_service()),
718 &domain_state);
719
NotifySSLCertificateError(transaction_->GetResponseInfo()->ssl_info, fatal);
Then to URLRequest::NotifySSLCertificateError; then to
delegate_->OnSSLCertificateError; then to void
SSLManager::OnSSLCertificateError; then to new SSLCertErrorHandler. Then
to SSLCertErrorHandler::OnDispatched; then to
manager_->policy()->OnCertError. Conveniently, the meaning of fatal is
reversed to mean "overridable" (line 67 below); it is here that the 1 bit
of information ("has TSS metadata, i.e. 'fatal'?") decays to less than 1
bit ("overridable or not, for whatever reason"). :)
46 void SSLPolicy::OnCertError(SSLCertErrorHandler* handler) {
47 // First we check if we know the policy for this error.
48 net::CertPolicy::Judgment judgment =
49 backend_->QueryPolicy(handler->ssl_info().cert,
50 handler->request_url().host());
51
52 if (judgment == net::CertPolicy::ALLOWED) {
53 handler->ContinueRequest();
54 return;
55 }
56
57 // The judgment is either DENIED or UNKNOWN.
58 // For now we handle the DENIED as the UNKNOWN, which means a blocking
59 // page is shown to the user every time he comes back to the page.
60
61 switch (handler->cert_error()) {
62 case net::ERR_CERT_COMMON_NAME_INVALID:
63 case net::ERR_CERT_DATE_INVALID:
64 case net::ERR_CERT_AUTHORITY_INVALID:
65 case net::ERR_CERT_WEAK_SIGNATURE_ALGORITHM:
66 case net::ERR_CERT_WEAK_KEY:
67 OnCertErrorInternal(handler, !handler->fatal());
68 break;
69 case net::ERR_CERT_NO_REVOCATION_MECHANISM:
70 // Ignore this error.
71 handler->ContinueRequest();
72 break;
73 case net::ERR_CERT_UNABLE_TO_CHECK_REVOCATION:
74 // We ignore this error but will show a warning status in the
location
75 // bar.
76 handler->ContinueRequest();
77 break;
78 case net::ERR_CERT_CONTAINS_ERRORS:
79 case net::ERR_CERT_REVOKED:
80 case net::ERR_CERT_INVALID:
81 case net::ERR_CERT_NOT_IN_DNS:
82 OnCertErrorInternal(handler, false);
83 break;
84 default:
85 NOTREACHED();
86 handler->CancelRequest();
87 break;
88 }
89 }
OnCertErrorInternal goes on to call
content::GetContentClient()->browser()->AllowCertificateError, which in
turn calls new SSLBlockingPage, where the error string is erroneously added
(due to interpreting "overridable" as "not fatal, i.e. not having TSS
metadata").
Thus, one could argue that the bug is in SSLPolicy::OnCertError, where the
once-clear meaning of "fatal" ("is there a DomainState entry") is degraded.
We could fix it by giving OnCertErrorInternal and its callees more
information, such as distinguishing overridable from has-TSS-metadata by
passing it a second bool. But I don't know if that is a really good way to
do it. I do know that the error message should be included exactly when
fatal = true, so passing fatal through to the callees seems like a direct,
even if not elegant, fix. Directness is good...
rsleevi, wtc, any preferences as to a fix strategy? I believe the direct
approach is likely to require a small, simple CL.