Closed denisvasilik closed 2 years ago
Tagging subscribers to this area: @dotnet/ncl, @vcsjones See info in area-owners.md if you want to be subscribed.
Author: | denisvasilik |
---|---|
Assignees: | - |
Labels: | `area-System.Net.Security`, `untriaged` |
Milestone: | - |
What site are you connecting to @denisvasilik ? Does your peer provide list of CAs? Perhaps you can post packet capture of the handshake.
For testing purposes I am trying to connect to mail.denisvasilik.com
. In this case the server provides a Let's Encrypt server certificate and accepts a private PKI client certificate issued by denisvasilik-sa-root1-client1
or denisvasilik-ca-root1
.
CN=denisvasilik-sa-root1-client1, O=denisvasilik, L=Munich, S=Bavaria, C=DE
CN=denisvasilik-ca-root1, O=denisvasilik, L=Munich, S=Bavaria, C=DE
Exception: No credentials are available in the security package
Note: I provided a dummy client certificate and key in the repository so it's not possible to finish the handshake successfully, but it's enough to retrieve the acceptable issuers.
Exception: No credentials are available in the security package
Here are no acceptableIssuers
are provided.
I added a trace of the TLS handshake to the repro repository.
Thank you for your support, if you need further information just let me know.
I check and it seems like the server sends two names:
Distinguished Name: (id-at-commonName=denisvasilik-sa-root1-client1,id-at-organizationName=denisvasilik,id-at-localityName=Munich,id-at-stateOrProvinceName=Bavaria,id-at-countryName=DE)
Distinguished Name: (id-at-commonName=denisvasilik-ca-root1,id-at-organizationName=denisvasilik,id-at-localityName=Munich,id-at-stateOrProvinceName=Bavaria,id-at-countryName=DE)
This will need some deeper investigation. The mechanism on Linux is probably different. We will probably need to call SSL_get0_peer_CA_list()
(or equivalent) to get it.
Triage: Rare scenario, likely won't happen in 6.0. We should take a look later though, add a test and fix it.
When #45456 is done, we will be able to write tests for this. (without external dependency) We may do the get/set CA list together.
Sounds great to me, I am looking forward working together on this issue.
The fundamental problem is that the callback runs before the server sends the list. When I run the repro, remoteCertificate is also null
and it should not be.
From archeology prospective @bartonjs started with https://github.com/dotnet/corefx/pull/3736 back then in 1.0. Then it was fixed with https://github.com/dotnet/corefx/commit/d3be6bbe9aee8f748f2688fb7bb00c577ac4b11e for HTTP. (and probably not SslStream) and then eventually removed as dead code in https://github.com/dotnet/runtime/pull/43793 when CurlHandler was removed.
To make it work, we will need to bring back CryptoNative_SslCtxSetClientCertCallback
. (or something similar)
The fact that remoteCertificate
is somewhat more concerning.
Hi, I am also currently encountering this issue on Linux and OSX (works fine on windows). However, I am running .NET Core 3.1. (customer requires compliance with .NET Standard 2.1) is there a way to backport this fix onto 3.1 once it is fixed?
Many thanks in advance! JR
All .NET 3.1+ versions are compliant with .NET Standard 2.1. Why exactly does it force you to use .NET Core 3.1 and not something newer - e.g. .NET 6 which is also LTS?
Hi, Thanks for your comment! You are of course right, I was under the illusion, that we would need to stick with 3.1, but now, that you mentioned it, I fail to recall my thought process. Sorry for the inconvenience, I'm looking forward to this fix!
Edit: assuming I'll use .NET 6.0 - will this fix be present there (the current milestone is indicating 7.0.0)
I'm using a mTLS setup and wanted to get a list of
acceptableIssuers
from theLocalCertificateSelectionCallback
at the client application. This works great on Windows, but fails on Ubuntu 20.04. Here is a sample application I used for reproduction and a snippet of the relevant location:Configuration
Working configuration:
Errornous configuration:
Quick Analysis
During debugging I figured out that on Windows the method InitializeSecurityContext returns
SecurityStatusPalErrorCode.CredentialsNeeded
(when appropriate). As a consequence, theLocalCertificateSelectionCallback
is called a second time with proper content of acceptable issuers. When looking at the InitializeSecurityContext or HandshakeInternal routine on Linux, it never returnsSecurityStatusPalErrorCode.CredentialsNeeded
. Instead it returnsSecurityStatusPalErrorCode.ContinueNeeded
which does not triggerLocalCertificateSelectionCallback
. Hence, there's no second invocation ofLocalCertificateSelectionCallback
providing the acceptable issuers.If this is a bug (and not a configuration issue) I would like to work on it in order to provide a fix.