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

Issue 591415 link

Starred by 5 users

Issue metadata

Status: Assigned
Owner:
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Chrome
Pri: 2
Type: Bug



Sign in to add a comment

ChromeOS chrome.certificateProvider does not call onCertificatesRequested listeners often enough

Reported by goo...@rkeene.org, Mar 2 2016

Issue description

Chrome Version       : 49
OS Version: Chrome OS 49

What steps will reproduce the problem?
    1. I go to a website using HTTPS that requests a client ceritifcate
    2. Chrome calls the chrome.certificateProvider.onCertificatesRequested listeners to list certificates
    3. I select a certificate
    4. Chrome negotiates TLS and uses the certificate I selected
    5. When appropriate chrome.certificateProvider.onSignDigestRequested listeners are called with the selected certificate
    6. The TLS session is established
    7. HTTP data is transferred over the TLS session
    8. The session goes idle and is eventually disconnected
    9. I remove my smartcard and someone else inserts theirs
    10. I visit the same website as #1
    11. We jump to step #4, now the onSignDigestRequested listeners have no way to actually do their job because the certificate object doesn't exist on any smartcard  -- if we had gone to step #2 here then things could work (and would be similar to how NSS does it). 

What is the expected result?
TLS session in #10 fails


What happens instead of that?
Chrome should ask for chrome.certificateProvider's for a list of certificates at the time the TLS session is setup and not assume that because a certificate was available in the past it is still available.  Thus at step #10 the user should be prompted to select a certificate, but since Chrome doesn't know that the certificate isn't available this never happens and the TLS session fails since the onSignDigestRequested listener cannot sign with a certificate whose object is no longer available.
 
Owner: dskaram@chromium.org
Labels: CertProvider
Status: Assigned (was: Unconfirmed)
Cc: rsleevi@chromium.org pneubeck@chromium.org emaxx@chromium.org
Labels: -OS-Linux OS-Chrome
cc Philipp, original author

+Ryan, this probably boils down to our original discussion about how clearing TLS state is infeasible/too expensive. How do we reconcile that conclusion with this case i.e. I take one card out, I plug in another, the system still tries to sign with the old certificate?

What could be a reasonable workaround for the user? Close current tab and open new one?
Cc: dskaram@chromium.org
IIRC:
Back when we designed the certificateProvider API, we decided to let Chrome ask for certificates (pull) instead of letting the extension push certificates.
I.e. currently, Chrome does not know if a certificate is not available anymore, except by re-requesting the current certificate list from an extension.
As Chrome cashes certificate selections, we run into the reported case.

One solution would be to add another API function, that let's an extension flush any previously published certificate list, so that Chrome can taint the certificate store. This tainting (this should map to CertificateRemoved notifications) should lead to Chrome dropping the affected cache of the previously used certificate. If not that's probably a "bug" or unfortunate design of the cache.

Please take this comment with caution, it has been a while that I worked on Chrome.
Cc: davidben@chromium.org mmenke@chromium.org
Components: Internals>Network>SSL
There's a distinct behaviour request different from your summary, dskaram - which is, in the original report, onCertificateRequested is *always* called (e.g. disabling the Chrome TLS client cert cache). That has some real performance implications, but *could* be an acceptable tradeoff for the security considerations.

Closing tabs is not appropriate; you'd have to close Chrome.

I'm not sure if we'd want to add a proactive 'flush' notification - that gets more into what you were talking about, and which I suspect will end up being misused or being a pain (performance/socket wise) even more than "flush on eject" case.

Adding davidben@ and mmenke@ to double check, but I *believe* we should be fine if we just tweaked the HTTP client cert cache (for the ChromeOS + Smartcard Provider) case to always query extensions (that is, some change around the area of https://code.google.com/p/chromium/codesearch#chromium/src/net/ssl/ssl_client_auth_cache.h&l=23 ). That said, *any* changes to this logic is very perf-sensitive, especially for Googlers, so we should definitely discuss approaches before someone starts hacking on a CL.
I believe the way things currently work is:

1)  Server requests cert.
2)  We check the client cert cache.  If not present, fail request.
3)  Tell Chrome the request failed with a cert request.
4)  ResourceLoader calls into the ClientCertStore to select cert (Strangely, the ClientCertStore is a net/ class, but is not consumed by net/).
5)  Extension / user selects cert.
6)  Restart request.

If we always wanted to call into extensions to get certs, we'd have to change that flow.  We'd have to have two calls into the embedder - one for "autonomous" cert selection, before checking the cache, and one for user cert selection, after...  Or we'd need to grab the cached cert, if there is one, and then call into the embedder, to give it the choice to override it (If there wasn't a cached one), or give us a cert (If we didn't have one).

Second option seems preferable.  Either way, we'd need to pretty significantly change how this stuff is hooked up, though I don't think it would be a major project.
Could also make the embedder manage the cache, I suppose.  Choices, choices.  I like the idea of getting this out of the URLRequest::Delegate interface, and reducing the number of cases where we restart a request at the URLRequest layer, as that has always struck me as odd, though others may disagree.
Taking the restart out of URLRequest will probably run into all our usual redirect resumption woes that came up when we were talking about inverting Service Worker.
I'm not following.  In the cached client cert case, we're already bypassing the URLRequest when we restart.

https://code.google.com/p/chromium/codesearch#chromium/src/net/http/http_network_transaction.cc&l=1392&rcl=1457108994
Oh, sorry, I think totally misparsed what you said the first time. Don't mind me. (Somehow I thought you meant create a new URLRequest for the restart.)
Labels: -CertProvider SmartCards
Any chance this gets prioritized? This is exacerbated by the fact that on Chrome OS, closing the browser *does not* terminate existing SSL sessions. It kind of makes sense given the OS is the browser, but that's quite a discrepancy in behavior across platforms.
Owner: marcuskoehler@chromium.org
Labels: Hotlist-Enterprise-Networking

Sign in to add a comment