Authentication failed because the remote party has closed the transport stream - c#

This happens on the sslStream.AuthenticateAsServer(serverCertificate,
true, SslProtocols.Default, true);
call.
I'm trying to do client authentification. I control both client and server, both are c# via sslstream.
When I use a nodejs server, it works perfectly. But I just cant get the serverside to reliably work in c# for some reason. Clearly the ssl authentification needs to wait for the client to choose the client certificate, but apparently this is not a built in feature for c# sslstream class?
I already tried doing this before the call, but it still immediately errors out on the call:
I dont mind the security question in IE. That's fine. I'm concerned with the fact how sslstream does not seem to work at all with such a basic szenario.
Error from wcf trace:
System.Net Error: 0 : [7928] Exception in AppDomain#13869071::UnhandledExceptionHandler - Authentication failed because the remote party has closed the transport stream..
at System.Net.Security.SslState.ValidateCreateContext(Boolean isServer, String targetHost, SslProtocols enabledSslProtocols, X509Certificate serverCertificate, X509CertificateCollection clientCertificates, Boolean remoteCertRequired, Boolean checkCertRevocationStatus, Boolean checkCertName)
at System.Net.Security.SslStream.AuthenticateAsServer(X509Certificate serverCertificate, Boolean clientCertificateRequired, SslProtocols enabledSslProtocols, Boolean checkCertificateRevocation)

Adding the below code helped me overcome the issue (I'm running the app in .NET 4.5.1).
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11;

Related

Angular local SSL with universal does not work

I created an angular universal app and followed the following tutorial to use SSL for local development with SSR:
https://medium.com/#dnlcyan/local-angular-ssr-with-https-b9d305dc620d
The certificate is trusted in the browser and also the requests work on browser level. But for request coming from the node server the API throws the following exception:
Microsoft.AspNetCore.Server.Kestrel.Https.Internal.HttpsConnectionMiddleware
Failed to authenticate HTTPS connection. System.IO.IOException:
Received an unexpected EOF or 0 bytes from the transport stream. at
System.Net.Security.SslStream.g__InternalFillHandshakeBufferAsync|189_0[TIOAdapter](TIOAdapter
adap, ValueTask`1 task, Int32 minSize) at
System.Net.Security.SslStream.ReceiveBlobAsync[TIOAdapter](TIOAdapter
adapter) at
System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](TIOAdapter
adapter, Boolean receiveFirst, Byte[] reAuthenticationData, Boolean
isApm) at
Microsoft.AspNetCore.Server.Kestrel.Https.Internal.HttpsConnectionMiddleware.OnConnectionAsync(ConnectionContext
context)
I read something about that the certificate might not be trusted, but I added it to windows and also the browser indicates that it's correct. I tried to create a new certificate according to this tutorial but it doesn't work as well: https://fmoralesdev.com/2020/01/03/serve-angular-app-over-https-using-angular-cli/
Does anyone know what the issue might be here?

Remote certificate rejected when connecting to SQL Server from Linux host

I have been provided a certificate for a SQL Server, which has been successfully installed and activated. I can confirm this from the logs:
The certificate [Cert Hash(sha1) "xxxxxxxxxxxxxxxxxxE5C050F7D75F58E4E2F"] was successfully loaded for encryption.
Connecting to the database using SSMS is successful, simply by encrypting the connection without trusing the server certificate.
I wanted to replicate this using WSL and later on - docker.
I am testing this with a simple .net 6 console application:
var con = new SqlConnection("Server=domain.host.eu,50730;Database=databasename;User Id=user;Password='password';");
await con.OpenAsync();
var version = con.ExecuteScalar<string>("SELECT ##VERSION");
Console.WriteLine(version);
This works, if I add Trust Server Certificate=True; to the connection string. Without it, the connection fails:
Unhandled exception. Microsoft.Data.SqlClient.SqlException (0x80131904): A connection was successfully established with the server, but then an error occurred during the pre-login handshake. (provider: TCP Provider, error: 35 - An internal exception was caught)
---> System.Security.Authentication.AuthenticationException: The remote certificate was rejected by the provided RemoteCertificateValidationCallback.
at System.Net.Security.SslStream.SendAuthResetSignal(ProtocolToken message, ExceptionDispatchInfo exception)
at System.Net.Security.SslStream.CompleteHandshake(SslAuthenticationOptions sslAuthenticationOptions)
at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](TIOAdapter adapter, Boolean receiveFirst, Byte[] reAuthenticationData, Boolean isApm)
at System.Net.Security.SslStream.AuthenticateAsClient(SslClientAuthenticationOptions sslClientAuthenticationOptions)
at System.Net.Security.SslStream.AuthenticateAsClient(String targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, Boolean checkCertificateRevocation)
I wanted to extract the certificate from the pfx:
openssl pkcs12 -in host.domain.eu.pem.pfx -clcerts -nokeys -out host.domain.eu.crt
sudo cp host.domain.eu.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates
Unfortunately, this fails with the same error messages and I don't know where I went wrong. I can only assume, that my handling of the certs on Linux is wrong.
If you're connecting to something unimportant, I was experiencing this error connecting from my dotnetcore API, to a microsoft sql server contained in a docker container (all locally) for dev work. My solution was putting encrypt=False at the end of my connection string like so (within appsettings.json):
"DefaultConnection": "server=localhost;database=newcomparer;trusted_connection=false;User Id=sa;Password=reallyStrongPwd123;Persist Security Info=False;Encrypt=False"
I double blindsided myself and got distracted by 2 mishaps at the same time.
After importing a certificate into the SQL Configuration Manager, you can choose from 2 nigh on identical entries. The difference beeing one having a friendly name of host.domain (FQDN), while the other has no friendly name.
Naturally I have not double checked and just stayed with the one without the FQDN as the friendly name, which was pre-selected after the import and looked valid.
The second mistake was to not realize, that WSL was not part of our domain and could not resolve the database name. So I used to the FQDN to reach it. This caused the mismatch between host, which the database instance expected and host.domain, which the client from inside WSL used.
After this I borrowed an Ubuntu vm inside our domain and verified, that using only the host,port schema in the connection string works.
And to make it explicit and work inside wsl I switched the certificates around to require the FQDN as the friendly namae while connecting, so connections can be made from inside the domain, as well as "outside" (from wsl).
tl;dr: One possible explanation for the exception The remote certificate was rejected by the provided RemoteCertificateValidationCallback. is, that the instance name in the connection string and the expected name from the instance do not match.

SSL handshake fails in Xamarin

I'm trying to access my RESTful API to retrieve data from a MySQL database. Everything is set up and works perfectly on my C# WPF project. But when using the exact same code in Xamarin Forms (built for Android) I cannot get a successful SSL handshake with my server.
Server details
Let's Encrypt SSL certificate (definitely valid)
Apache BasicAuth (.htaccess)
HTTPS only (Rewrite HTTP on), so port 443
REST API: php-crud-api (by mevdschee) to access MariaDB 10.3
I'm using Flurl.Http (uses HttpClient) to establish the connection, but get an exception on jsonReader.Wait():
var jsonReader = "https://example.com/my_api/api.php/records/my_table?order=id,desc&size=10"
.WithHeader("Accept", "application/json")
.WithBasicAuth("username", "password")
.GetJsonAsync<JsonRootObject>();
// Wait for completion.
jsonReader.Wait();
This is my AggregateException:
System.AggregateException: One or more errors occurred. (Call failed. An error occurred while sending the request
GET https://example.com/my_api/api.php/records/my_table?order=id,desc&size=10) ---> Flurl.Http.FlurlHttpException: Call failed. An error occurred while sending the request
GET https://example.com/my_api/api.php/records/my_table?order=id,desc&size=10 ---> System.Net.Http.HttpRequestException: An error occurred while sending the request
---> System.Net.WebException: Error: TrustFailure (Authentication failed, see inner exception.) ---> System.Security.Authentication.AuthenticationException:
Authentication failed, see inner exception. ---> Mono.Btls.MonoBtlsException: Ssl error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED
at /Users/builder/jenkins/workspace/xamarin-android-d16-1/xamarin-android/external/mono/external/boringssl/ssl/handshake_client.c:1132
at Mono.Btls.MonoBtlsContext.ProcessHandshake () [0x00038] in <74989b9daab94528ac2c4b7da235b9c5>:0
at Mono.Net.Security.MobileAuthenticatedStream.ProcessHandshake (Mono.Net.Security.AsyncOperationStatus status, System.Boolean renegotiate) [0x000a1] in <74989b9daab94528ac2c4b7da235b9c5>:0
at (wrapper remoting-invoke-with-check) Mono.Net.Security.MobileAuthenticatedStream.ProcessHandshake(Mono.Net.Security.AsyncOperationStatus,bool)
at Mono.Net.Security.AsyncHandshakeRequest.Run (Mono.Net.Security.AsyncOperationStatus status) [0x00006] in <74989b9daab94528ac2c4b7da235b9c5>:0
at Mono.Net.Security.AsyncProtocolRequest.ProcessOperation (System.Threading.CancellationToken cancellationToken) [0x000ff] in <74989b9daab94528ac2c4b7da235b9c5>:0
at Mono.Net.Security.AsyncProtocolRequest.StartOperation (System.Threading.CancellationToken cancellationToken) [0x0008b] in <74989b9daab94528ac2c4b7da235b9c5>:0
What I've tried / what I know
Code works perfectly in WPF
Exact same code (copy-paste) does not work in Xamarin Forms (tested on Android Pie)
does not work in emulator nor dedicated device
accessing the REST API via browser works and delivers results as expected (tested on my PC, the emulator in Chrome and my dedicated Android)
changing the HttpClient implementation or SSL/TLS implementation under Project properties -> Android Options -> Advanced does not help
Why is my SSL handshake failing? What is Xamarin doing differently than WPF?
It turned out to be an Apache configuration error. I checked my domain and noticed an error. This was fixed by adding the certificate's chain-file in my Apache Directives:
SSLCertificateFile /etc/letsencrypt/live/example.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/example.com/chain.pem
The last line was the missing one. Weird that browsers and WPF trusted the certificate even without the chain-file. Anyway, now it also works on Android.
In the meantime I've been using this piece of code to disable the SSL validation in my app:
// This disables the SSL certificate validity check.
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
That code is unsafe and should only be used for testing.
your Flurl.Http can fail due to the usage of 2 different project types (.net standard vs class library - I had exactly the same problem with http client I wrote)
try a different http client for .net standard.
in any case, you can write your own http client and debug - that is my recommendation.
if you still stuck - write back I'll help.

MQTT Timeout when trying to connect to TLS enabled broker in unity3d

I am building an AR app in Unity and I need to connect to an MQTT broker with TLS protocol enabled. I am able to connect to non TLS enabled MQTT brokers successfully(In unity), and I can use the certificate the admin gave me with this program http://www.mqttfx.org/ to connect to the TLS enabled broker successfully. But when I attempt to connect to the TLS enabled server with the m2mqtt library for c# in Unity, I get a timeout exception and never receive a response from the broker. This is the code I am using to test the connection. I am just attempting to make a successful connection then disconnect.
X509Certificate certificate = X509Certificate.CreateFromCertFile("filePath");
// Connect to this broker address at port 1883 with tls enabled
client = new MqttClient(brokerAddress, port, true, certificate);
// Generate a client id
string clientId = Guid.NewGuid().ToString();
// Connect to the client with credentials
byte code = client.Connect(clientId, username, password;
// Disconnect
client.Disconnect ();
This exception occurs during connect:
MqttCommunicationException: An application exception has occurred.
uPLibrary.Networking.M2Mqtt.MqttClient.SendReceive (System.Byte[] msgBytes, Int32 timeout) (at Assets/MQTT/scripts/MqttClient.cs:953)
uPLibrary.Networking.M2Mqtt.MqttClient.SendReceive (uPLibrary.Networking.M2Mqtt.Messages.MqttMsgBase msg, Int32 timeout) (at Assets/MQTT/scripts/MqttClient.cs:976)
uPLibrary.Networking.M2Mqtt.MqttClient.SendReceive (uPLibrary.Networking.M2Mqtt.Messages.MqttMsgBase msg) (at Assets/MQTT/scripts/MqttClient.cs:964)
uPLibrary.Networking.M2Mqtt.MqttClient.Connect (System.String clientId, System.String username, System.String password, Boolean willRetain, Byte willQosLevel, Boolean willFlag, System.String willTopic, System.String willMessage, Boolean cleanSession, UInt16 keepAlivePeriod) (at Assets/MQTT/scripts/MqttClient.cs:456)
uPLibrary.Networking.M2Mqtt.MqttClient.Connect (System.String clientId, System.String username, System.String password, Boolean cleanSession, UInt16 keepAlivePeriod) (at Assets/MQTT/scripts/MqttClient.cs:395)
ConnectionManager.connectToMQTTBroker () (at Assets/Scripts/ConnectionManager.cs:55)
Any help would be greatly appreciated. I have been stuck on this for days.
M2Mqtt does not Support TLS_V2 , Because of what we cant use certificates with unity. This is due to .Net FrameWork Version Support . For Certificates we use TLSV_2 QOS Level for connecting which is supported from .Net 4 and above , But Unity has support for only .Net 3.5 Version.

Issue running SSL-enabled TCP server under mono

I'm developing an application which requires SSL encryption between the client and server, and needs to run under Windows and in Ubuntu under Mono. At the moment, the server and client pair works fine in Windows, but when the client connects to the server, the server returns this error:
Error: The authentication or decryption has failed. at
Mono.Security.Protocol.Tls.SslStreamBase.AsyncHandshakeCallback
(IAsyncResult asyncResult) [0x00000] in :0
I'm loading the certificate like this:
X509Certificate2 cert = new X509Certificate2("server.pfx", "<password>");
Current Mono versions do not support SSL connections as server without client certificates.
Either use a client certificate or apply a patch to the source code.
You can find an example of how to do that in my answer to this question.

Categories