-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure while using .NET Core #28473
Comments
@bartonjs Please can you provide your inputs on this issue. |
IIRC, |
@bartonjs:Thank you for the response,the server had closed the connection because the client hadn't provided the certificate even after the server requested for the certificate. |
IIRC: if Wireshark/et-al will of course say whether or not the client sent one. Otherwise, I'm not sure. @davidsh? |
HasPrivateKey value is true.I did check that |
Actually, "it's always sent" is not true. HttpClient and SslStream will still filter the collection of client certificates to find one meets all criteria to be sent. So, for example, If the certificate has EKU attribute, then it must contain 'Client Authentication'. And similarly for KU attribute, it must have 'Digital Signature', etc.
Wireshark can detect this usually but I thought that the sending of the client certificate is done after the channel is encrypted. So, unless you have TLS decryption you wouldn't see this. You can turn on System.Net tracing and it should indicate information about client certificates being sent: |
In TLS 1.2 the optional client certificate is one of the last things before the ChangeCipherSpec. In TLS 1.3 both certs are after the first ChangeCipherSpec, making it much harder to debug with Wireshark 😄. |
@davidsh Please can you provide a way to debug on Linux |
@davidsh @bartonjs X509Store personalStore = new X509Store(StoreName.Root, StoreLocation.CurrentUser);
personalStore.Open(OpenFlags.ReadWrite);
X509Certificate2Collection personalStoreCertificateCollection = (X509Certificate2Collection)personalStore.Certificates;
int i = 0;
foreach (X509Certificate2 x509 in personalStoreCertificateCollection)
{
personalStore.Remove(x509);
++i;
}
X509Certificate2 certificate1 = new X509Certificate2("client.p12", "12345");
//Create a collection and add two of the certificates.
X509Certificate2Collection collection = new X509Certificate2Collection();
collection.Add(certificate1);
//Add certificates to the store.
**personalStore.Add(certificate1);
personalStore.AddRange(collection);**
X509Certificate2Collection collection2 = new X509Certificate2Collection();
collection2.Import("client.p12", "12345", X509KeyStorageFlags.PersistKeySet);
foreach (X509Certificate2 cert in collection2)
{
personalStore.Add(cert);
} By adding the following couple of lines it started working on
|
Having the same issue running on docker with MyHttpClientHandler : public class MyHttpClientHandler : HttpClientHandler
{
public MyHttpClientHandler(List<X509Certificate2> certificates)
{
ClientCertificateOptions = ClientCertificateOption.Manual;
SslProtocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12;
ServerCertificateCustomValidationCallback = delegate { return true; };
foreach (var certificate in certificates)
{
ClientCertificates.Add(certificate);
}
}
} Program: class Program
{
static async Task Main(string[] args)
{
try
{
var path = Path.Combine(Directory.GetCurrentDirectory(), @"certs/mycert.pfx");
var certificates = new List<X509Certificate2>()
{
new X509Certificate2(path, "password")
};
var httpClient = new HttpClient(new MyHttpClientHandler(certificates));
var payload = /*my payload*/;
var httpContent = new StringContent(payload, Encoding.UTF8, "application/json");
var response = await httpClient.PostAsync("https://mysecreturl.com", httpContent);
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
catch (System.Exception ex)
{
Console.WriteLine($"Failed - {ex.Message}");
var innerException = ex.InnerException;
while(innerException != null)
{
Console.WriteLine($"Inner - {innerException.Message}");
innerException = innerException.InnerException;
}
return;
}
Console.WriteLine("Works!!!!!");
}
} Output:
Same code runs fine on Windows 10. PS: getting a similar response when using |
@helder-goncalves-cko @ramsubbaraoc can you please try it out on 3.0 if it is still a problem? Thank you! |
Is there any update @helder-goncalves-cko @ramsubbaraoc ? It seems like this did not update for quite a while. Note that if you use self-signed certificate on server, OpenSSL is more strict about EKU and it will fail to connect unless expected flags are set. |
To clarify, it is not just about EKU field. It is about KU field (Key Usage). See this ASP.NET issue for a full analysis of best-practices for using self-signed certificates on Linux. |
Closing, since there is no response for a long time. On Linux, proper certificate extensions must be used (see linked issue). This is a platform limitation we will not be able to address. |
I would not define it as adding a proper certificate extension, but define it by adding the proper certificate to the store... I think it is a documentation issue (and possibly an ifdef between systems windows and Linux) where a note needs to be made to do this... and how to do it properly in a dokerfile (that is generated in docker via VS context menu)... |
https://github.com/dotnet/docs would be the right repo to track that unless @bartonjs or @davidsh have other suggestions. |
I get the following error during Authentication on Linux:
I had added the certificates using the following code:
The error occurs during authentication and during the following call
stream.AuthenticateAsClient(SERVERNAME, currentClientCerts, sslProtocol, sslCertRevocationCheck);
The text was updated successfully, but these errors were encountered: