netty differentiate client tcp from tls connection - ssl

I am writing a netty server. The first thing in the channelpipeline is a sslhandler, and the last thing is app level handler.
//note that sslCtx is instantiated before this part of code'
// SslHandler
pipeline.addLast(sslCtx.newHandler(ch.alloc()));
...
// Application handler
pipeline.addLast(new MyHandler());
The client may initiate a TCP or TLS connection.
- In case of TCP, I want to log that it's only a TCP connection from peer X, and stop processing further.
- In case of TLS, I want to log that it's a TLS connection from peerX with Y ciphersuite, and Z protocol version, and move onto the application handler.
Is it even possible using netty?

Related

How does SSL session caching and expiry works

In order to understand how connection is established in rest web service, I am learning about handshakes (TCP & SSL).
I am trying to figure out about the additional overheads with respect to time when it comes to SSL handshaking and TCP Handshaking.
So what I know is that SSL Handshaking happens over TCP layer. And TCP layer communication again happens using TCP Handshaking.
So lets say first TCP handshaking happens, and then there must be some time for which that handshake remains valid.
So in this, SSL handshake happens, so that also must have some validity and expiry.
So how does this connection breaks. Due to TCP session expiry.
How do I identify the default timings for these session validity and can they be updated?
I might be asking wrong questions as well. These questions I had in my mind based on my limited understanding of TCP protocol and SSL.
Any guidance is appreciated.
.. there must be some time for which that handshake remains valid.
There is no such thing as an expiration for the TCP or SSL handshake. A TCP connection ends with a explicit TCP shutdown (i.e. packet with FIN flag) and similar a SSL "connection" is properly finished with an explicit SSL shutdown (i.e. "SSL shutdown alert"). As long as nothing is explicitly closed it is considered open.
Even though TCP protocol as such does not have expiry for a connection after it is established, sometimes intermediate routers/proxies etc can expire a connection, the interval is specific to each device, but typically would not be less than an hour.
To avoid this, you can use the TCP keep alive feature or send some ping requests at the application layer itself.
SSL connections will remain valid until you explicitly shutdown the session.

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).

How TCP and SSL/TLS interacts?

SSL/TLS runs over the TCP layer. Suppose TCP connection is terminated before SSL/TLS session was closed. How would SSL/TLS get to know about this ?
A TLS session is mostly independent from the underlying TCP connections.
For example you can have multiple TCP connections all using the same TLS session and these can coexist even in parallel. This is actually used in practice, for example with web browsers. It is even required in some implementations of FTPS where the control and data connections (different TCP connections) are expected to (re)use the same TLS session. Note that the session does not simply gets continued inside another TCP connection - there is still a TLS handshake required to start the "continuation" of a session, but only an abbreviated handshake.
Similar you can have multiple TLS sessions inside a single TCP connection but only after each other: initiate one TLS session, shutdown it, initiate the next etc. While this is not commonly used it is actually not uncommon that the TLS session does only start after some plain data has been transferred (STARTTLS in SMTP, AUTH TLS in FTPS) or that TLS gets shutdown and then more data are transferred in plain (CCC in FTPS).
How would SSL/TLS get to know about this ?
The exact details depend on the TLS stack and the API provided by this stack. But usually if the underlying TCP connection is closed this is somehow signaled to the TLS stack. For example with OpenSSL a SSL_read will return a value of equal or less than 0 and you need to call SSL_get_error to get more details on what happened. And again, a TCP close does not implicitly invalidate the TLS session.
SSL/TLS runs over the TCP layer.
Correct.
Suppose TCP connection is terminated before SSL/TLS session was closed.
Then (a) the TCP connection has ended, and (b ) the SSL/TLS session persists.
How would SSL/TLS get to know about this?
It doesn't need to know about this. It only needs to know about the end of the TCP connection, which is signalled by the TLS close_notify message, and the end of the session, which happens when it is invalidated. TLS sessions can long outlive TCP connections, and vice versa.
There is a heartbeat protocol that is used by SSL/TLS to check that the connection is still alive or not. So for a heartbeat request a closed connection will response negative. Hence SSL/TLS will know that TCP connection is closed.

TLS handshake over websockets

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?

determine if TCP connection uses SSL

Perhaps some server can handle both non-secure and secure protocols.
Is there known way to determine if existing TCP connection secure or not?
(I believe it is possible just monitor traffic and check if some text is readable, but maybe there is better or maybe more detailed suggestions?)
If you're using .Net you can use an existing TCP connection as the basis for an SSL connection. To programatically check whether a server port implements SSL would be a matter of establishing a TCP connection and then attempting to create an SSL connection on top of it. If the SSL handshake fails, which will throw an exception, then you will know SSL is not available on that port.
The code would be along the lines of:
TcpClient tcpClient = new TcpClient();
tcpClient.Connect(remoteEndPoint);
SslStream sslStream = new SslStream(tcpClient.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
sslStream.AuthenticateAsClient(serverCN);
Exception means no SSL.