TLS handshake over websockets - ssl

I've set out to handle tls operations manually on a websockets server, due to the cockeyed way php supports listening on secured transports.From RFC6455:
If /secure/ is true, the client MUST perform a TLS handshake over the
connection after opening the connection and before sending the
handshake data [RFC2818]. If this fails (e.g., the server's
certificate could not be verified), then the client MUST Fail the
WebSocket Connection and abort the connection. Otherwise, all
further communication on this channel MUST run through the encrypted
tunnel [RFC5246].
According to this, the first thing I should receive is the clientHello message which signifies the beginning of a TLS handshake.But all I receive on the server is the websocket handshake request, encrypted.
I am baffled by this.Is there no TLS handshake at all?

Related

ClientHello Retransmitted many times followed by TCP DUP ACK during SSL handshake

we have one client and server our application running as bridge between client and server.
our module responsible for forwarding the traffic between client and server.
During SSL handshake i am trying to interrupt the client hello and respond to the client with serverhello.
we are able to interrupt and send the serverhello to the client but SSL handshake is failed.
captured the packets during SSL handshake.
i could see Server hello reached to the client interface but Client machine retransmitting the clienthello again and again could any one help on this what went wrong why the client not processing serverhello.

TLS handshake fail, but communication is not closed

I have TLS program and I did some experiments on it.
I start confidential TLS server session and try to connect to it with pure Telnet client.
As expected, the handshake failed and the server is available to the next client but on the Telnet client side I didn't receive any indication that the handshake failed and that the server is accepting other clients.
I can see in Wireshark that even after the handshake failed the Telnet client can send strings; I see [PSH, ACK] from the client answered by [ACK] from the server.
Adding Wireshark snapshot, Telnet failed the handshake, Telnet keep sending messages, followed by success in the TLS handshake and more Telnet messages:
Why is the server ACKing the Telnet client if the handshake failed and he is accepting other clients?
As expected, the handshake failed ...
I cannot see a failed TLS handshake in the packet capture and I'm not sure how you come to this conclusion.
All I can see that the client on source port 60198 (presumable your telnet) is sending 3 bytes several times and the server just ACK'ing these without sending anything back and without closing the connection. Likely the server is still expecting data in the hope that at some time it will be a complete TLS record. Only then it will be processed by the TLS stack and then it might realize that something is wrong with the client.
... the server is available to the next client
It is pretty normal for a server to handle multiple clients in parallel. In contrary, it would be unusual if the server could not do this.

Does a firewall TCP timeout require a TLS resume?

A firewall is timing out TCP connections after an hour.
Sending a message along this connection from the server results in a [RST, ACK] from the firewall.
Messages sent from the client are simply dropped, as long as they are part of the original connection.
If a new connection is established from the client, it goes through the firewall without a hitch.
This is normal - routers, firewalls, VPNs, NATs, etc.., all time out connections and require you to reconnect with a new handshake or perform a TLS resume. But is there any way to continue using the TLS session without "resuming" it? I say this because the TLS session never ended, only the underlying TCP.
Because the TLS session is independent of TCP, we shouldn't need to resume an already active TLS session just because some intermediary device blocks us. Is there any type of "TCP resume" that we can do along the same socket?
This is called "session resumption" in TLS.
Quoting the latest standard on it (https://www.rfc-editor.org/rfc/rfc8446) :
Although TLS PSKs can be established out of band, PSKs can also be
established in a previous connection and then used to establish a new
connection ("session resumption" or "resuming" with a PSK). Once a
handshake has completed, the server can send the client a PSK
identity that corresponds to a unique key derived from the initial
handshake (see Section 4.6.1). The client can then use that PSK
identity in future handshakes to negotiate the use of the associated
PSK. If the server accepts the PSK, then the security context of the
new connection is cryptographically tied to the original connection
and the key derived from the initial handshake is used to bootstrap
the cryptographic state instead of a full handshake. In TLS 1.2 and
below, this functionality was provided by "session IDs" and "session
tickets" [RFC5077]. Both mechanisms are obsoleted in TLS 1.3.
See sections 2.2 and 4.6.1 of the RFC for details.
It can not be a resumption at the TCP level since the new TCP connection will need to start with a new local port (otherwise any traffic will still be caught by firewall state tracking).

Is mTLS faster when both client and server is authenticated after handshake

Reading mTLS from wikipedia
Is mTLS in microservices and the communication between services faster than if only TLS?
I mean if using only TLS the handshaking occurs each time a communication is being established between client & server.
If mTLS the handshaking only occurs once and the connection is kept to next communication/connection - and therefore faster?
Is this correct?
This is not correct.
Mutual authentication means that a client certificate is requested by the server additionally to the normal TLS handshake in order to authenticate the client. As for keeping the established TS connection open or using session resumption: this is possible for both "normal" TLS and TLS with mutual authentication.

how to verify if java sends the client certificate in a mutual auth scenario

I setup 2way ssl with Camel and CXF using the http conduit element etc.
I make a webservice call to an external party. All certificates are correctly installed (incoming traffic is succesfull, this is configured in Tomcat). After this post about secure renegotiation I finally received a response from the other party: HTTP response 403, forbidden.
I've been debugging with javax.net.debug=all and this excellent explanation.
I can see in the logging that a secure connection is succesfully setup:
*** Finished
verify_data: { 141, 25, 184, 254, 93, 9, 10, 48, 135, 161, 213, 57 }
***
%% Cached client session: [Session-2, SSL_RSA_WITH_RC4_128_MD5]
and no other errors or warnings. How can I verify if my client certificate is sent to the server? (I can't use Wireshark but I have the javax.net.debug logging)
I found the answer in this post and by comparing the javax.net.debug output to the client auth example.
I don't see CertificateVerify in my log, only the one way ssl steps, so there is no client certificate sent.
The cause was that I copied the CXF http conduit example from their website, but somehow the ciphersuite filter it contained was too strict.
I needed to track this down and found the following.
In Java 11, I enabled SSL logging by adding this option to the tomcat server process I was using:
-Djavax.net.debug=ssl:handshake:verbose:keymanager.
Next, I ran my test and studied the logs. The general format of all messages begin like this (so I won't repeat this because it clutters up the important content).
javax.net.ssl|DEBUG|22|http-bio-8443-exec-1|2023-02-06 18:01:35.705 GMT|CertificateMessage.java:366|Produced ClientHello handshake message
Client Side Logs: Successful mutual authentication
The following shows the SSL handshake messages that occurred during a successful two way certificate authentication.
Produced ClientHello handshake message
Consuming ServerHello handshake message
Consuming server Certificate handshake message <<< Receiving Server cert
Consuming ECDH ServerKeyExchange handshake message
Consuming CertificateRequest handshake message <<< Server asking for client cert
Consuming ServerHelloDone handshake message
Produced client Certificate handshake message <<< Sending client cert
Produced ECDHE ClientKeyExchange handshake message
Produced CertificateVerify handshake message
Produced ChangeCipherSpec message
Produced client Finished handshake message
Consuming ChangeCipherSpec message
Consuming server Finished handshake message
I highlighted the lines that show the server cert being received and the client cert being sent. I should note that the above is the logs as viewed on the client side of the connect.
The SSL Spec (See https://www.rfc-editor.org/rfc/rfc5246#section-7.4.6) says:
This [the Client Certificate message] is the first message the client can send after receiving a
ServerHelloDone message. This message is only sent if the server
requests a certificate
And once the ClientKeyExchange message is sent, we know that no client certificate was sent because again the spec says:
This message is always sent by the client. It MUST immediately
follow the client certificate message, if it is sent. Otherwise,
it MUST be the first message sent by the client after it receives
the ServerHelloDone message.
Since the ServerHelloDone message was printed, and then the ClientKeyExchange message was printed, therefore the ClientCertificate message was not sent because if it were being sent it needed to be sent immediately after the SeverHelloDone and before the ClientKeyExchange.
This test was performed using Java 11. I don't have the web libraries handy but this was not a SpringBoot application.
Server Side Logs: Successful mutual authentication with certs
For completeness, the following shows the messages that are logged by the server side of the two way authentication using certificates.
Consuming ClientHello handshake message
Ignore unavailable extension: supported_versions
Produced ServerHello handshake message
Produced server Certificate handshake message <<< Sending server cert
Produced ECDH ServerKeyExchange handshake message
Produced CertificateRequest handshake message <<< Request client send cert
Produced ServerHelloDone handshake message
Consuming client Certificate handshake message << Receiving clients cert
Consuming ECDHE ClientKeyExchange handshake message
Consuming CertificateVerify handshake message
Consuming ChangeCipherSpec message
Consuming client Finished handshake message
Produced ChangeCipherSpec message
Produced server Finished handshake message
Summary
This answer highlights the messages logged for the two way (aka mutual) authentication using X.509 certificates in a Java web application that both received incoming requests (and required mutual authentication) and making a REST call to another server that also required two way authentication.
Some of the log messages shown contain a large amount of additional information such as the actual certificate information and detailed values from the SSL specification. None of that data is shown because it makes it harder to see the important messages and it is not needed to understand the answer.
If you needed to see exactly what was sent in a certificate then the detailed logs provide that information.
Later, I tried this with a SpringBoot application using spring-boot-starter-parent:2.7.3 and it also worked when running with
mvn spring-boot:run -Dspring-boot.run.jvmArguments="-Djavax.net.debug=ssl:handshake:verbose:keymanager"