New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 646567 link

Starred by 5 users

Issue metadata

Status: Fixed
Owner:
Closed: Sep 2016
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: 3
Type: Bug
Team-Security-UX



Sign in to add a comment

Missing client certificate errors are confusing.

Project Member Reported by davidben@chromium.org, Sep 13 2016

Issue description

TLS never ended up defining an alert for "you sent no client certificate, but I required one", so everyone ends up sending a generic handshake_failure alert, which we map to ERR_SSL_PROTOCOL_ERROR.

Background for UI folks: this is not the same as the server certificate where all your woes come from. :-) Some deployments, mostly enterprises and schools, set up sites where the user logs in with a certificate. Existing text has been calling them "login certificates". If the user's machine is provisioned with these, they'll get a prompt to select a cert. On desktop platforms, if no certs were provisioned, they won't get a prompt. On Android, they get a confusing blank one but we can't do anything about it because it's part of the Android platform itself.

This results in very confusing errors, like what happens if one tries to load https://diswww.mit.edu/. However, we actually have enough information to map this differently. handshake_failure gets sent:

- If the server couldn't negotiate acceptable options from the ClientHello. We already map that special to ERR_SSL_VERSION_OR_CIPHER_MISMATCH based on whether it came in before ServerHello.

- If we sent no client certificate and the server wanted one. There is no better alert to send here. (Note that if we did send a client certificate and the server disliked it, there are suitable alerts. I do not know whether people send them in practice.)

- If anything else broken happens. Server implementations tend to use it as a random alert when they don't have anything better to send in the handshake. However, all these cases require the server (or us) implement the protocol incorrectly, so I think we can more-or-less discount them.

I propose that we tweak SSLClientSocketImpl to map handshake_failure after an ignored CertificateRequest differently. Specifically if:

- BoringSSL reports a remote handshake_failure alert

- The failure came from SSLClientSocketImpl::Handshake or SSLClientSocketImpl::Read. Read is needed due to False Start, TLS 1.3, or renego. It's a little bit broad, but I think it's fair game to say a server sending *handshake*_failure in response to a failure in the application data protocol is being obtuse and a confusing error message is not our fault. :-)

- ClientCertRequestCallback was called but we sent zero certificates. (One or more, we should assume that servers send one of the appropriate alerts.)

Then we map to ERR_SSL_NO_CLIENT_CERT_SUPPLIED. That error code would have a message (exact phrasing TBD by UI folks) like:

----
This site can't provide a secure connection

example.com requested a login certificate, but none was provided.

Try reloading with a login certificate or contacting the system admin.
----
(This is mostly a variation on ERR_BAD_SSL_CLIENT_AUTH_CERT's message.)

Enamel folks in particular, what do you think? Note that I am intentionally discounting the other handshake_failure cases to give a simpler message because those all require a buggy server (rare). Also false positives will only trigger on sites that use client certs (rare).

Note that some servers are even more obnoxious and just close the connection on us without an alert (ERR_CONNECTION_CLOSED). I do not propose we try to help those in any way since we'll get tons of false positives.
 
(Er, "This results in very confusing errors" in paragraph three refers to paragraph one.)
Sounds like a good idea to me.

> TLS never ended up defining an alert for "you sent no client certificate,
> but I required one"

I take it wikipedia isn't describing actual practice?

Alert #49 Access denied fatal TLS only – e.g. no client certificate has been presented (TLS: Blank certificate message or SSLv3: No Certificate alert), but server is configured to require one.
Correct :) I'm not aware of any major implementation that sends that error status (in a large part, due to how mod_ssl implemented things)
The spec says access_denied is for:

   access_denied
      A valid certificate was received, but when access control was
      applied, the sender decided not to proceed with negotiation.  This
      message is always fatal.

So it's one of the many "you gave me certs, but I didn't like them" alerts. Hilariously, that one has the opposite problem. See  issue #630883 . :-)
Cc: edwardjung@chromium.org
+edwardjung, does this seem reasonable? Also how would I go about resolving the final text? I recall you all had some process here. I'm happy to do the CL since it'll involve some //net changes.
Cc: rachelis@chromium.org
+rachelis for input.

@davidben, from a simplicity standpoint can we not reuse ERR_BAD_SSL_CLIENT_AUTH_CERT and make some changes to the existing text rather than introduce a new error to maintain? 

Seems like you can add something about not having a login certificate to the sentence.
------

This site can’t provide a secure connection

xyz.com didn’t accept your login certificate – it may not have been provided, or your login certificate may have expired.

Try
+ contacting the system admin.
+ reloading with a valid login certificate 

------

Would people know what to do to provide a valid cert? Seems pretty technical. 









Sure, if we slightly generalize ERR_BAD_SSL_CLIENT_AUTH_CERT and tweak the text, yeah, that would work fine too. Whichever. (Although adding a new error code really isn't that expensive. I've already got a draft CL which does it.)

The downside of folding into the same error code is that "I have an old cert provisioned" vs, "I don't have any certs provisioned" are pretty different failure modes, particularly if client certs selections are done with via admin policy so there isn't any prompting.

(A slight problem with that text is it sounds like missing or expired are the only two options, and they aren't. Right now, it says "network-error didn’t accept your login certificate, or your login certificate may have expired".)

> Would people know what to do to provide a valid cert? Seems pretty technical.

If you are in an organization that uses client certificates, probably you would know what to do with it. Failing that, support folks at your organization would be able to help, given this information.

There is nothing more detailed we can show because enrolling in client certificates is very deployment-specific. It's is the difference between showing no useful text vs. showing something of that nature. This is one of those crappy enterprise-only features we support as best we can but should not try to build a perfectly smooth UX around because it's impossible.
Cc: xuannm@chromium.org
Labels: Hotlist-ConOps
Good timing in this bug - ERR_BAD_SSL_CLIENT_AUTH_CERT is currently one of the top 5 error search queries in our global communities and we're not sure exactly how we should help users solve this issue. I'll send a draft your way. 
Oh, sorry, did I link you to the wrong bug in the doc? My bad!  Issue #630883  is the one you want. (This one is unlikely to appear in ConOps' radar since it actually will only come up with folks who use client certs.)
@David, sorry - I think I just found the wrong bug, because of the mention of ERR_SSL_PROTOCOL_ERROR & ERR_BAD_SSL_CLIENT_AUTH_CERT (both top 5 error queries). Thanks for the link to the other bug.
re: #7  I think with some care wordsmithing something would work for both. 

However maybe in light of #8 a separate error might make more sense. If there is a need provide clear suggestions for that specific case.

@rachelis what do you think? 
No need to worry about comment #8. I'll fix  issue #630883  in the same CL so the ConOps flag should hopefully no longer map to ERR_BAD_SSL_CLIENT_AUTH_CERT. (Need to throw together a few tests.)
> (Need to throw together a few tests.)

Er, sentence got swallowed. "I'll send you a CL today or Monday. (Need to throw together a few tests.)"
Owner: davidben@chromium.org
Status: Started (was: Untriaged)
https://codereview.chromium.org/2350483002/
Cc: nyerramilli@chromium.org
 Issue 647910  has been merged into this issue.
 Issue #647910  is an interesting case where the user actually did have a certificate, but it was expired and so we (on Mac) didn't even include it for consideration. That suggests that we indeed don't want to try to separate the two cases and ideally wordsmith one error for both.
Project Member

Comment 17 by bugdroid1@chromium.org, Sep 28 2016

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/fe132d9d1a03966649118030e50715d1a063f73c

commit fe132d9d1a03966649118030e50715d1a063f73c
Author: davidben <davidben@chromium.org>
Date: Tue Sep 27 18:07:21 2016

Improve error pages on client certificate failures.

This makes the following changes:

- Tweak ERR_BAD_SSL_CLIENT_AUTH_CERT's text be suitable for both
  invalid and missing client certs. net_error_list.h actually already
  documents it for this case, but the user-visible error does not.

- Since TLS lacks a dedicated alert for missing client certificates,
  servers often send a generic handshake_failure alert. Detect this case
  and map to ERR_BAD_SSL_CLIENT_AUTH_CERT.

- One of the many bad client cert alerts is access_denied.
  Unfortunately, that was badly named so firewalls sometimes send it,
  giving users a confusing error page. Detect this case too and map it
  to ERR_SSL_PROTOCOL_ERROR, the same error we would use for an unexpected
  alert.

Add a bunch of tests for these cases.

Screenshot of the new ERR_BAD_SSL_CLIENT_AUTH_CERT:
https://drive.google.com/file/d/0Bz14lOW5Hke4ZzRPLXZwUUlzOFk/view?usp=sharing

BUG= 630883 , 646567 

Review-Url: https://codereview.chromium.org/2350483002
Cr-Commit-Position: refs/heads/master@{#421265}

[modify] https://crrev.com/fe132d9d1a03966649118030e50715d1a063f73c/components/error_page_strings.grdp
[modify] https://crrev.com/fe132d9d1a03966649118030e50715d1a063f73c/net/socket/ssl_client_socket_impl.cc
[modify] https://crrev.com/fe132d9d1a03966649118030e50715d1a063f73c/net/socket/ssl_client_socket_impl.h
[modify] https://crrev.com/fe132d9d1a03966649118030e50715d1a063f73c/net/socket/ssl_client_socket_unittest.cc

Labels: M-55
Status: Fixed (was: Started)
Components: -Security>UX UI>Browser>Interstitials

Sign in to add a comment