SSL alert number 46. Alert certificate unknown. How to ignore this exceptions? - node.js

I have some opensource project, that has WebUI based on NodeJS. When I want to access it I can observe this logs in WebUI:
error: httpsServer Exception: on clientError:Error:
140446233978688:error:14094416:SSL routines:ssl3_read_bytes:sslv3
alert certificate unknown:s3_pkt.c:1487:SSL alert number 46 Aug 19
11:49:41 node[18614]: 140446233978688:error:140940E5:SSL
routines:ssl3_read_bytes:ssl handshake failure:s3_pkt.c:1210:
This issue observed only using Google Chrome (Using Firefox or Safari didn't generate this exceptions in logs). All browsers marked self-signed root certificate as invalid. My question - How can I make WebUI to ignore this exceptions? This WebUI only accessible from local net and I don't want to sign certificates for money. Thanks.

You cannot ignore this exception in your application since the problem is not caused by the application itself. Instead this alert is generated by the browser during the TLS handshake: the browser tells the server this way that it will not accept the certificate sent by the server. After this alert is sent the browser will close the connection. Even if you somehow ignore this exception in your node.js code you will not able to communicate with the browser - because it is the browser which is refusing the communication.
The only way to fix this problem is to use a certificate trusted by the browser. In case of a self-signed certificate this means that you either have to import the certificate into the browser as trusted (in which case Subject Alternative Names in certificate must match the URL) or you add an explicit exception at the warning dialog you get when visiting the site.

Related

ERR_SSL_PROTOCOL_ERROR only for some users (nodejs, express)

Only some (not all) users are receiving ERR_SSL_PROTOCOL_ERROR in Chrome when attempting to visit my express site. I am not receiving this error, so it is proving a pain to debug.
I am creating a https server using a PFX file I downloaded from my provider (1&1):
var options = {
pfx: fs.readFileSync('./mysite_private_key.pfx'),
passphrase: 'MYPASSPHRASE',
};
https.createServer(options, app).listen(443);
https://whatsmychaincert.com tells me that the chain is correct but complains about the handshake:
[mysite] has the correct chain.
[mysite]: TLS handshake error:
error:14077438:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert
internal error SSL Labs might be able to tell you what went wrong
I've googled this with no success, does anyone know what the problem could be? Ty.
In the end I ditched 1&1 and used GoDaddy's CA service and the problem went away.
A possible source of failed handshake could be the lack of an intermediate certificate, ca option of tls.createSecureContext. It should by public on your provider's website.
Hope this helps.
nowadays , when our server (e.g. 1&1) is securely configured , only tls v1.2 and tls v1.3 are supported ..
so how you debug this:
scan your site with SSL Labs Test too see which ciphers are supported , or alternately see in our nginx/apache config
tail -f the server logs , especially the catchall/other_vhosts log files,since ssl protocol errors might be in the site logs and the generic catchall log when the server cannot decide on the name
try to update the users chrome to support at least tls 1.2
chrome has the some command line switches to change its cipher behaviour:
--ssl-version-max Specifies the maximum SSL/TLS version ("tls1.2" or "tls1.3"). ↪
--ssl-version-min Specifies the minimum SSL/TLS version ("tls1", "tls1.1", "tls1.2", or "tls1.3"). ↪
DANGER ZONE:
as last resort you could try to accept legacy ciphers in your nginx-config ( ssl_ciphers directive) like socat OR (very last resort) socat23 to check which version your clients support,
remember to disable everything below tls v1.2 in production environment

How to tell if a TLS server requested a client certificate

I'm making TLS client connections in Node.js. Some servers I communicate with request a client certificate. I'd like to be able to detect when this has been requested, so I can log it. At the protocol level I believe this is sent along with the TLS server hello, so the data is there, but I'm not sure how I can get at it.
I'm never actually providing a client certificate for now, I'm just aiming to report which servers requested one.
I think there's probably two cases here:
A cert has been requested, not provided, and the server has accepted the connection anyway (and then probably given my some kind of 'not authenticated' response).
A cert has been requested, not provided, and the server has rejected the TLS connection entirely.
At the moment I can't detect either case, solutions for either or both very welcome.

IIS 7.5 Secure Communication Error - The underlying connection was closed: Could not establish secure channel for SSL/TLS

We are experiencing the following error when trying to use an external web service from our application deploy under IIS 7.5.
Error - The underlying connection was closed: Could not establish secure channel for SSL/TLS.
This works from other servers, but on this particular one it fails. This started happening when the server we are trying to connect with disallowed SSL connections and is only accepting TLS. As described in this link http://support.microsoft.com/kb/915599 we changed the registry, but are still seeing the error. Please see the attached image of the registry to make sure this was done properly. It seems like IIS is still trying to use the SSL protocol. I'm a bit confused where in the communication process IIS selects the protocol, SSL vs TLS. Maybe there's something that needs to be done to ensure TLS is selected? Other ideas?
This was fixed at the code level by adding the following line -
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;

Security & TLS handshake when client is authenticated

In a TLS handshake configured with a client authentication, there is a step where the server receives the client's certificate and choose to trust it or not (for instance, in Java it is done via a TrustManager).
I would like to know if the eventual "trust failure" message from the server is sent before or after the server made sure that the client really own that public key (for example, by receiving first some messages from the handshake encoded with the client's private key).
The purpose of my question is to see if it is possible for a third party to check if the server trust a client, by pretending to be this client and by using his public key.
Note: The risk is real when TLS is used in a context with specific security requirements. For instance, let's suppose a P2P application which uses TLS between peers, and which use the TrustManager as a way to authenticate peers from his contact list. This contact list is supposed to be private. An ISP can list the IPs with who a node communicates, then get his public certificate by starting a TLS handshake with it, then he can try to connect each another nodes on the IP list. In the end, the ISP can get a big part of the contact list which was supposed to be private.
OpenSSL verifies the client certificate, too, immediately upon receiving it in the Client Certificate message.
But it is as Eugene says, if the server sends meaningful alerts, then it does not matter if you send bad_certificate right away or only after having verified the signature in the Certificate Verify message. This would only prevent someone from finding out whether a certificate is trusted or not if they additionally send a malformed signature (e.g. by using the wrong key). But if a server were implemented that way, all you had to do is sign your Certificate Verify message with a private key you just generated. Then the signature will be valid and the server will then dutifully validate the certificate you sent, revealing the same information as before.
To mitigate this situation you would really have to use a customized server that does not send the corresponding alert at all, but rather something less revealing.
This depends on implementation. Our implementation sends the error immediately, as for other implementations - I guess most do the same.
However it doesn't matter: the server sends specific error code (BadCertificate) if the certificate is not valid, so no matter when this code is sent, the attacker would know that the certificate has not been accepted. Protecting the server from this attack would require the server send a different error code and this would confuse legitimate clients.
The risk (or unpleasant consequences) of detecting that the certificate is accepted by the server or not is questionable. If this matters to you, you can change the error code and build your custom version of OpenSSL or other SSL server module you use.

Is it possible to do a TLS handshake event in Tomcat?

I'm running an application (web service) in tomcat with TLS enabled (with certificates both for the client and the server).
I want that my application will be able to send audit message (logging) when TLS handshake fails. For example I want to log when:
the client certificate is expired,
the client certificate is unknown (not in the server trust store)
any other handshake failure
Is there any event that I can catch and handle in order to do that?
My application is web service based and is running in tomcat. Tomcat is handling all network and the TLS layers, and the application does not aware of that.
As I don't open any socket myself, where should I catch this Exception?
I'm not aware of anything you can add to Tomcat.
Put an Apache HTTPD in front and use a separate, configured, SSL log.
Since I spent the past week debugging Tomcat's SSL configuration, I am pretty sure catching javax.net.ssl.SSLHandshakeException in your code and logging it should take care of all three of those errors.
When you instantiate a new webservice connection in your application, that is when the exception will occur.

Resources