Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SSLStream should support cancelling certificate chain building with cancellation token #35839

Closed
davidfowl opened this issue May 5, 2020 · 16 comments
Assignees
Milestone

Comments

@davidfowl
Copy link
Member

Certificate chain building and verification should be cancellable AuthenticateAs* on OSX and Linux:

@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added area-System.Security untriaged New issue has not been triaged by the area owner labels May 5, 2020
@ghost
Copy link

ghost commented May 5, 2020

Tagging subscribers to this area: @bartonjs, @vcsjones, @krwq
Notify danmosemsft if you want to be subscribed.

@bartonjs
Copy link
Member

bartonjs commented May 5, 2020

It's certainly not cancellable on macOS, since neither SecTrustEvaluate or SecTrustEvaluateWithError are capable of being cancelled.

@bartonjs
Copy link
Member

bartonjs commented May 5, 2020

Well, SslStream could build the chain via Task.Run, I suppose.

@ghost
Copy link

ghost commented May 5, 2020

Tagging subscribers to this area: @dotnet/ncl
Notify danmosemsft if you want to be subscribed.

@stephentoub
Copy link
Member

Well, SslStream could build the chain via Task.Run, I suppose.

That would effectively cancel the wait but not the actual operation.

When the caller gets back control after the resulting OperationCanceledException, what happens if they then dispose stuff that's being used? Does anything break, or is everything properly protected by SafeHandles?

Or what happens if they retry the operation while the previous operation is still in flight?

Also, how long do these operations typically take, and are they parallelizable? If you are considering using async-over-sync, I'm wondering if it makes sense to use one or more dedicated threads rather than using the thread pool.

@bartonjs
Copy link
Member

bartonjs commented May 5, 2020

When the caller gets back control after the resulting OperationCanceledException, what happens if they then dispose stuff that's being used?

Any certificates used as input should be being used as SafeHandles inside the execution already to prevent system corruption from a parallel/external dispose. Disposing the chain object will do nothing if it hasn't yet completed.

Or what happens if they retry the operation while the previous operation is still in flight?

If it's on the same X509Chain instance, both operations will then assign the ChainElements, ChainStatus, and SafeHandle properties. So the same object should not be reused (aka it's definitely not thread safe).

how long do these operations typically take

Sub-hundred milliseconds. Except when they need the network. Then sub-hundred-milliseconds + network time (where E(x) is low, but Theta(x) is chainPolicy.UrlRetrievalTimeout (default: effectively infinite) ... except UrlRetrievalTimeout isn't respected on macOS).

are they parallelizable?

Yep

@davidfowl
Copy link
Member Author

The manual fetches (on OSX and Linux) could also be fully asynchronous in the SSL Stream case but I didn't want to pollute this issue with that 😄

@bartonjs
Copy link
Member

bartonjs commented May 5, 2020

There aren't manual fetches on macOS. Only Linux.

@wfurt
Copy link
Member

wfurt commented Jun 16, 2020

should we close this in favor of #35844? If we have options to pass complete chain to SslStream this should not be big issue, right?

@davidfowl
Copy link
Member Author

We can avoid making the call completely right? We can also set a timeout if we choose to resolve ourselves yes?

@wfurt
Copy link
Member

wfurt commented Jun 17, 2020

yes, I think so, at least for cases in our control. X509ChainPolicy.UrlRetrievalTimeout is what you can use to control timeout if you choose X509Chain to build/fetch it for you. I did quick search through runtime repo and I did not see test verifying the expiration.
I think we can fix that before closing this issue. But there would be no need for new API so I would do it as time permits.

@vcsjones
Copy link
Member

I don't know if this is still correct but I was under the impression that UrlRetrievalTimeout is ignored on MacOS.

https://github.com/dotnet/runtime/blob/4f9ae42d861fcb4be2fcd5d3d55d5f227d30e723/docs/design/features/cross-platform-cryptography.md#x509chain

macOS does not support a user-initiated timeout on CRL/OCSP/AIA downloading, so X509ChainPolicy.UrlRetrievalTimeout is ignored.

@wfurt
Copy link
Member

wfurt commented Jun 17, 2020

may not be "in our control". That still may not matter if full chain is provided.

@karelz
Copy link
Member

karelz commented Jun 18, 2020

Triage: Verify it works correctly, then close.

@karelz karelz removed the untriaged New issue has not been triaged by the area owner label Jun 18, 2020
@karelz karelz added this to the 5.0.0 milestone Jun 18, 2020
@karelz karelz added the test-bug Problem in test source code (most likely) label Jun 18, 2020
@wfurt wfurt removed the test-bug Problem in test source code (most likely) label Jul 15, 2020
@karelz karelz added the test-enhancement Improvements of test source code label Jul 28, 2020
@wfurt
Copy link
Member

wfurt commented Aug 10, 2020

I was planning to close this with #35844 "pre-validated immutable full certificate chain" and add test to verify that once certificate context was built. (Both calls to BuildNewChain @davidfowl mentioned are gone)

That proved to be challenging as even if the server does not do I/O, client will and there is no good way how to separate client and server with current test infrastructure.
Also #35844 is focused on server part e.g. loading chain from a file or pushing responsibility to caller.
However recent incident brought up case with client certificates. Since that is out of server's domain, it can be anything, possibly forcing server to contact malicious server.

I think this should be revisited beyond just the cancelation. I think we should find a better way how to expose verification options. Perhaps adding option to just give certificate to callback or exposing Timeout (and making that as xplat as we can)
Since the main use case was address with #35844 and there is currently no good technical way how to pass cancellation around and make that reasonably platform agnostic, I'm going to push it out of 5.0.

@wfurt
Copy link
Member

wfurt commented Jul 15, 2022

Client and server now have option to pass in X509ChainPolicy via CertificateChainPolicy in ssl options. If present, chain constructed inside SslStream will respect the setting including DisableCertificateDownloads and UrlRetrievalTimeout .

@wfurt wfurt closed this as completed Jul 15, 2022
@wfurt wfurt modified the milestones: Future, 7.0.0 Jul 15, 2022
@ghost ghost locked as resolved and limited conversation to collaborators Aug 15, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

7 participants