SocketIO4Net - Error initializing handshake with https://localhost/ - socket.io

I'm trying to use SocketIO4Net to connect with my node.js server via socket.io.
Can't seem to get it to work, when it comes to HTTPS.
Getting this: Error initializing handshake with https://localhost/
Couldn't find a solution in other similar questions.
If you have other solutions to connect to socket.io sockets from C# feel free to share the information.

.NET seems to block my self signed certificate.
Implementing the RemoteCertificateValidationCallback seems to solve the problem.
ServicePointManager.ServerCertificateValidationCallback += new System.Net.Security.RemoteCertificateValidationCallback(pass);
private static bool pass(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error) { return true; }

Related

ASP.NET Core 6 getting Microsoft.AspNetCore.Server.Kestrel.Https.Internal.HttpsConnectionMiddleware[1] Failed to authenticate HTTPS connection

I am building a 5 method Web API application that needs to be secured with TLS in production. I have a gRPC server that works and when I use the same configuration in the Web API app, I am getting the following error:
dbug: Microsoft.AspNetCore.Server.Kestrel.Https.Internal.HttpsConnectionMiddleware[1]
Failed to authenticate HTTPS connection.
System.IO.IOException: Received an unexpected EOF or 0 bytes from the transport stream.
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)
dbug: Microsoft.AspNetCore.Server.Kestrel.Https.Internal.HttpsConnectionMiddleware[1]
Failed to authenticate HTTPS connection.
System.IO.IOException: Received an unexpected EOF or 0 bytes from the transport stream.
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 ripped out all of the gRPC code in the Web API Program.cs file in lieu of trying to configure Kestrel in the launchSettings.json file.
The snippet below shows my current effort:
"Kestrel": {
"Endpoints": {
"HttpsInlineCertFile": {
"Url": "https://localhost:30050",
"Certificate": {
"Path": "D:\\Development\\Certs\\MDevelopment.pfx",
"Password": "xxxxxxxx"
}
}
},
"Certificates": {
"Default": {
"Path": "D:\\Development\\Certs\\MDevelopment.pfx",
"Password": "xxxxxxxx"
}
}
}
The development and production certs work in the gRPC case, and also for securing a mail server I have so I am confident the certs are good. I have tried so many things, I cannot tell you anything else of value.
#Buffoonism, #Alvaro: I tried many things in trying to overcome this error. I did find that the cert that was being used in production was not correct (the node name changed messing everything up...)
What I did was create a new cert to ensure I was using the correct keys to gen the certificate. Then, I changed the way the cert was being applied to the listener as such:
// Get the host name and port number to bind the service to.
kestrelServerOptions.ConfigureHttpsDefaults (httpsConnectionAdapterOptions => {
httpsConnectionAdapterOptions.ServerCertificate = new X509Certificate2 (certPath, certPassword);
httpsConnectionAdapterOptions.SslProtocols = SslProtocols.Tls12;
});
Once I made that change, everything started to work. #Microsoft, you really need to step up your documentation game! All of you examples surround using a dev cert which is easy. Using a production-grade cert requires more handling (such as trusting the cert) which could use waaaaaaay better examples!
I hope that helps!

Connecting to AWS IoT Websocket without MQTT client

I have a client application which runs in the browser which I can't change the implementation of to implement an MQTT client such as mqtt on npm.
The code in the library is as follows and allows me to pass in a socketUrl
const ws = new WebSocket(socketUrl)
I have tried generating a presigned URL for IoT, which seems to work in terms of authenticating (i.e. no Unauthorized response) but I get a 426 Upgrade Required response.
I believe I'm correct in saying that if it were working it'd reply with a 101 Switching protocols but without knowing much about MQTT i'm unsure if this is not happening because I'm doing something wrong or because I'm not using MQTT.
I'm generating a signed URL using the below code (I'll switch to Cognito Identities if I get this working rather than using the fixed key/secret)
const v4 = require('aws-signature-v4')
const crypto = require('crypto')
const socketUrl = v4.createPresignedURL(
'GET',
'myioturl.iot.us-east-1.amazonaws.com',
'/mqtt', // tried just /mytopic, too
'iotdevicegateway',
crypto.createHash('sha256').update('', 'utf8').digest('hex'), {
'key': 'removed',
'secret': 'removed',
'protocol': 'wss',
'region': 'us-east-1'
}
)
The protocols page in the iot documentation seems to suggest that if I point at /mqtt I'm indicating I'll be using MQTT.
mqtt Specifies you will be sending MQTT messages over the WebSocket protocol.
What does this mean if I just specify /foobar? Should I be able to connect to the socket but not using MQTT?
There are quite a few unknowns for me so I'm struggling to work out if it should work at all, and if so, which bit am I doing wrong.

ClientCertificates in WebRequestHandler

I use HttpClient to talk to my WebAPI service. For SSL authentication, I set up the client certificates on the HttpClient using WebRequestHandler -
private static WebRequestHandler CreateWebRequestHandler(List<X509Certificate2> clientCertificates)
{
WebRequestHandler handler = new WebRequestHandler();
if (clientCertificates != null && clientCertificates.Any())
{
handler.ClientCertificateOptions = ClientCertificateOption.Manual;
clientCertificates.ForEach(cert => handler.ClientCertificates.Add(cert));
}
return handler;
}
On the Service, I have a custom DelegatingHandler to validate the client certificates using thumbprint -
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CancellationToken cancellationToken)
{
X509Certificate2 certificate = request.GetClientCertificate();
// Code to validate certificate's Thumbprint with white listed thumbprints
}
From the HttpRequest, I can get only one client certificate.
My question: Why does WebRequestHandler allow a collection of ClientCertificates to be set? Does it present all the client certificates to the server? If yes, then how do I get the list of client certificates in the DelegatingHandler?
Actually, only one certificate is send to server by a client during TLS\SSL handshake which you are obtain on the Server. The process of choosing this certificate is well described here.
Briefly explanation is - the client will choose the best suitable certificate from X509CertificateCollection looking for a match between the list of certificate issuers provided by the server and the client certificate issuer name. The first certificate that matches is sent to the server. If no certificate matches or the certificate collection is empty, then an anonymous credential is sent to the server. The deeper mechanism of TLS\SSL work described in a good manner here

htmlunit 2.11 doesn't work with https

We are using HtmlUnit Version 2.11 i.e. the latest version
If we pass a url with https protocol to webClient.getPage it thows the following exception and fails to work
#Test
public void TC001_VerifyHomePageLaunch() throws Exception {
final WebClient webClient = new WebClient(BrowserVersion.FIREFOX_10);
final HtmlPage page = webClient.getPage("https://localhost/abc/test.jsp");
webClient.closeAllWindows();
}
javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
Please help us with the steps on how to get rid of this error and go ahead with actual testing.
We don't have certificates installed as this is a test machine.
Try the following setting with your WebClient:
webClient.setUseInsecureSSL(true)
Documenation states:
If set to true, the client will accept connections to any host, regardless of whether they have valid certificates or not. This is especially useful when you are trying to connect to a server with expired or corrupt certificates.
Link to source.

Cross Domain Websocket connection causing a NS_ERROR_DOM_SECURITY_ERR

I am trying to connect to a websocket on server.domain.com from trial.domain.com
NS_ERROR_DOM_SECURITY_ERR in Firefox:
"[Exception... "Security error" code: "1000" nsresult: "0x805303e8 (NS_ERROR_DOM_SECURITY_ERR)" location: "https://trial.domain.com/home Line: 454"]"
when I am trying to make a WebSocket Connection:
try {
if (window['MozWebSocket'] !== undefined) {
socket = new MozWebSocket('ws://server.domain.com/chat');
} else {
socket = new WebSocket('ws://server.domain.com/chat');
}
trails = 0;
} catch(err){
trials++;
}
This happens by Browsers that is applying security policy that prevents of use any access to external domain that the page is hosted it self.
This occurs in scenarios when you are trying to get important connections from SSL area to non SSL and another domain (don't know if same domain will solve the problem) - that is your case. But there is more of possible scenarios of this.
This is browser related error, and it is browser who throw this error, and there is no problem with connection it self.
You have to host your WebSockets server under same domain as the http server. If that is not possible, there is few ways you can go:
If software is for inhouse use and settings in browsers can be done for use, then you can disable cross-domain security policies:
Firefox, under "about:config" set s"ecurity.fileuri.strict_origin _policy" to "false".
Chrome, run with flag "--allow-file-access-from-files"
If you have access to DNS settings of your domain, you can create sub forwarder and it will look like you are connecting to the same domain. Not sure about this option on practice, but it looks well.

Resources