Open Neustradamus opened 10 months ago
I will probably spend time to improve tls
for the next two months.
First I need to understand this RFC.
@kazu-yamamoto: Good :)
Please read the RFC5929 before:
It is important to support previous TLS versions and TLS 1.3.
For example, XMPP needs some XEPs in more the main RFC6120 with SCRAM-SHA-*-PLUS variants:
All SCRAM RFCs, I-Ds:
@Neustradamus Is it enough to revert 9b23d2ad5d1fb7f21b4d641a889bb00e00bf3890? Or should I provide a wrapper function to specify "EXPORTER-Channel-Binding", "" and 32 to it?
@kazu-yamamoto: I am not sure about it, I am not an Haskell dev...
But there are 3 parts which must be possible:
Haskell devs from 2 XMPP projects:
@epoberezkin I guess that you have an opinion on this.
afaik supercede dropped xmpp and that package is depracated.
8795ab6 implements getTLSExporter
and add a document to `getFinished'.
Let's close this.
@kazu-yamamoto: Good job!
Now it supports 3 parts?
getFinished
for (1) and getTLSExporter
for (3) but no (2).
Should I implement (2), too?
Yes for tls-server-end-point, it is needed, it is in:
And it is in SASL2 I-D: Extensible Simple Authentication and Security Layer (SASL): https://datatracker.ietf.org/doc/html/draft-melnikov-sasl2
@epoberezkin I have implemented getTLSUnique
which automatically selects the first Finished (see 1428994).
getFinished
and getPeerFinished
are deprecated in tls
v2.0
@kazu-yamamoto: Thanks!
You will remove the support of TLS 1.2 in 2.0?
Important: "tls-server-end-point" is needed too: it is in several XEPs and it will be in next SASL2 IETF RFC, an RFC which will replace: https://datatracker.ietf.org/doc/html/rfc4422.
You can look in all links cited in my previous comment.
The last comment was to @epoberezkin which implemented getFinished
.
I'm now thinking how to implement "tls-server-end-point".
tls
v2.0 supports both TLS 1.2 and TLS 1.3.
@kazu-yamamoto: Ah sorry, too quick to read :)
Can you add comments in the code about "tls-unique" and RFC5929, "tls-server-end-point" and RFC5929, "tls-exporter" and RFC9266? It is easy to look in the code.
Example in GnuTLS code:
The old default for Extended Master Secret of TLS 1.2 was allowed. But I changed it to required in 4cabdf3 to prevent triple handshake attack to "tls-unique".
@Neustradamus About comments. The binding name were already there. I added RFC stuff in their comments.
Thanks @kazu-yamamoto! All of this will not be added in a build before 2.0?
No.
Haskell tls
does not have long term support versions like other Haskell libraries.
The Haskell community has a culture where libraries are very small and updated frequently.
I have implemented getTLSServerEndPoint
. Both for TLS 1.2 and TLS 1.3, a channel binding is created with a certificate chain with the used hash.
What I'm not convinced yet:
@kazu-yamamoto: I have sent you an email
@Neustradamus Yes. I have read the mail. Thank you. But I don't think the email answers to my questions above.
I tried to read the code of OpenSSL but I don't understand SSL_get_finished
yet.
@epoberezkin Would you tell me whether or not getFinished
is inter-operable with OpenSSL?
@kazu-yamamoto sorry for slow replies!
tlsunique should be available for TLS 1.3 too - we use exactly that now. While it was defined for TLS 1.2 it can be used with some caveats for TLS 1.3 too - it's just a digest over client's handshake.
@epoberezkin I have implemented getTLSUnique which automatically selects the first Finished (see https://github.com/haskell-tls/hs-tls/commit/1428994477a3fd6831cbd9a16c3d743fbfee42ec). getFinished and getPeerFinished are deprecated in tls v2.0
You really need both to get tlsunique binding in both client and server, I believe they should not be deprecated, because which one to use depends on client/server role and in any case they can be useful for debugging.
I am not sure what "the first Finished" means, if you want to have tlsunique available to both sides via a single then it should be getPeerFinished in the server and getFinished in the client.
Also, I believe tlsunique should not be used when session resumption is allowed (that was the motivation to offer new bindings for TLS 1.3 spec) - just looked briefly at this commit, so maybe you can make the new function throw exception unless resumption is disabled.
Does the calculation of "tls-unique" exclude HandshakeType and the length of the Handshake struct?
tlsunique is client's Finished value, as it's defined in TLS handshake, it should not be calculated differently
@epoberezkin Would you tell me whether or not getFinished is inter-operable with OpenSSL?
Good question. We did not test that.
@epoberezkin
(1) tls-server-end-point
The problem is that the structure of TLS 1.3 certificate is different from that of TLS 1.2:
TLS 1.2:
struct {
ASN.1Cert certificate_list<0..2^24-1>;
} Certificate;
TLS 1.3:
struct {
opaque certificate_request_context<0..2^8-1>;
Extension extensions<2..2^16-1>;
} CertificateRequest;
Some guys say "just use the entire of TLS 1.3 certificate" while others say "encode it into TLS 1.2 certificate".
(2) tls-unique
See the following figure to understand which is the first and which is the second.
Client Server
ClientHello -------->
ServerHello
Certificate*
ServerKeyExchange*
CertificateRequest*
<-------- ServerHelloDone
Certificate*
ClientKeyExchange
CertificateVerify*
[ChangeCipherSpec]
Finished(1) -------->
[ChangeCipherSpec]
<-------- Finished(2)
Application Data <-------> Application Data
getTLSUnique
returns the first Finished regardless of its role.
getFinished
and getPeerFinished
are error-prone because users must take care of its role.
The TLS message is composed as follows:
TLS record header
Handshake message header
Finished (verify_data)
RFC 5929 says:
note: the Finished struct, not the TLS record layer message containing it
If the handshake message header is not included, the spec should say so explicitly.
Anyway, the current specifications look ambiguous to me. So, inter-operability test is important.
Can you add the support of RFC 9266: Channel Bindings for TLS 1.3?
Little details, to know easily:
I think that you have seen the jabber.ru MITM and Channel Binding is the solution:
Thanks in advance.
Linked to: