Hello again ![]()
I’ve been reading the difference between TLS 1.2 and TLS 1.3 a bit and I can expand on my previous message.
Cipher Suites
In TLS 1.2 the “cipher suite” concept is a tuple (key exchange, authentication, encryption, hash) e.g. TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
TLS 1.3 reuse the name “cipher suite” and slot in ClientHello/ServerHello but the concept changed, it only is a tuple (encryption, hash) e.g. TLS_AES_256_GCM_SHA384. The authentication and key exchange algorithms are negotiated via dedicated ClientHello/ServerHello extensions.
It means that there are two ways of configuring the same thing.
Either we do it (like now) the TLS 1.2 way, i.e. TLS(Client|Server)Configuration.ciphers holds suites like TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 and TLS 1.3 implementations (e.g. siotls) need to parse those to extract ECDHE with SHA384 => NamedGroup.secp384r1 and ECDSA with SHA384 => SignatureScheme.ecdsa_secp384r1_sha384. I’ve a feeling that’s what OpenSSL is doing.
Either we configure it like siotls, i.e. a list for each, and folks doing TLS 1.2 will need to combine them together to form the long cipher suite.
Or maybe we could support both, i.e. let users instantiate the configuration giving either TLS-1.2 long suites, either all the primitives, and have the other automatically computed inside __init__.
Close Notify
There is currently only one way to close a socket in tlslib and it is the following:
@abstractmethod
def close(self, force: bool = False) -> None:
"""Shuts down the connection and mark the socket closed.
If force is True, this method should send the close_notify alert and shut down
the socket without waiting for the other side.
If force is False, this method should send the close_notify alert and raise
the WantReadError exception until a corresponding close_notify alert has been
received from the other side.
In either case, this method should return WantWriteError if sending the
close_notify alert currently fails."""
The way I read the docstring, I understand that we want to close both sides of the connection, sending and receiving ends. force=True basically is “don’t actively wait for the other to close the connection”.
This is a violation of TLS 1.3 which states the following (emphasis mine):
Each party MUST send a “close_notify” alert before closing its write side of the connection, unless it has already sent some error alert. This does not have any effect on its read side of the connection. Note that this is a change from versions of TLS prior to TLS 1.3 in which implementations were required to react to a “close_notify” by discarding pending writes and sending an immediate “close_notify” alert of their own. That previous requirement could cause truncation in the read side. Both parties need not wait to receive a “close_notify” alert before closing their read side of the connection, though doing so would introduce the possibility of truncation.
https://tlswg.org/tls13-spec/draft-ietf-tls-rfc8446bis.html#section-6.1-4 (8446bis is rfc8446 (TLS-1.3) with all merged erratas, a nice navigation, and a way to pin-down a specific paragraph)
Only fatal alerts in TLS 1.3 ought to close both sides of the connection, and just discard all further messages with no other alerts. Sending a close notify only means we must close the sending end, and receiving a close notify only means we must close the receiving end.
I’ve been trying to think of a solution, but it is getting late (2AM). All I can say is that I’m pretty confident the current close() will prove problematic.
Regards,
Julien