Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC 9266: Channel Bindings for TLS 1.3 support #462

Open
Neustradamus opened this issue Nov 15, 2023 · 25 comments
Open

RFC 9266: Channel Bindings for TLS 1.3 support #462

Neustradamus opened this issue Nov 15, 2023 · 25 comments
Assignees

Comments

@Neustradamus
Copy link

Can you add the support of RFC 9266: Channel Bindings for TLS 1.3?

Little details, to know easily:

  • tls-unique for TLS =< 1.2
  • tls-server-end-point
  • tls-exporter for TLS = 1.3

I think that you have seen the jabber.ru MITM and Channel Binding is the solution:

Thanks in advance.

Linked to:

@kazu-yamamoto
Copy link
Collaborator

I will probably spend time to improve tls for the next two months.
First I need to understand this RFC.

@Neustradamus
Copy link
Author

Neustradamus commented Dec 1, 2023

@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:

@kazu-yamamoto
Copy link
Collaborator

@Neustradamus Is it enough to revert 9b23d2a?
Or should I provide a wrapper function to specify "EXPORTER-Channel-Binding", "" and 32 to it?

@Neustradamus
Copy link
Author

@kazu-yamamoto: I am not sure about it, I am not an Haskell dev...

But there are 3 parts which must be possible:

  • tls-unique for TLS =< 1.2
  • tls-server-end-point
  • tls-exporter for TLS = 1.3

Haskell devs from 2 XMPP projects:

@kazu-yamamoto
Copy link
Collaborator

@epoberezkin I guess that you have an opinion on this.

@jappeace
Copy link

jappeace commented Dec 22, 2023

afaik supercede dropped xmpp and that package is depracated.

@kazu-yamamoto
Copy link
Collaborator

8795ab6 implements getTLSExporter and add a document to `getFinished'.
Let's close this.

@Neustradamus
Copy link
Author

@kazu-yamamoto: Good job!

Now it supports 3 parts?

  • tls-unique for TLS =< 1.2
  • tls-server-end-point
  • tls-exporter for TLS = 1.3

@kazu-yamamoto
Copy link
Collaborator

getFinished for (1) and getTLSExporter for (3) but no (2).
Should I implement (2), too?

@Neustradamus
Copy link
Author

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

@kazu-yamamoto kazu-yamamoto reopened this Dec 25, 2023
@kazu-yamamoto
Copy link
Collaborator

@epoberezkin I have implemented getTLSUnique which automatically selects the first Finished (see 1428994).
getFinished and getPeerFinished are deprecated in tls v2.0

@Neustradamus
Copy link
Author

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

@kazu-yamamoto
Copy link
Collaborator

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.

@Neustradamus
Copy link
Author

@kazu-yamamoto
Copy link
Collaborator

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

@kazu-yamamoto
Copy link
Collaborator

@Neustradamus About comments. The binding name were already there. I added RFC stuff in their comments.

@Neustradamus
Copy link
Author

Thanks @kazu-yamamoto!
All of this will not be added in a build before 2.0?

@kazu-yamamoto
Copy link
Collaborator

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.

@kazu-yamamoto
Copy link
Collaborator

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.

@kazu-yamamoto
Copy link
Collaborator

What I'm not convinced yet:

  • Does the calculation of "tls-unique" exclude HandshakeType and the length of the Handshake struct?
  • Does the calculation of "tls-server-end-point" exclude HandshakeType and the length of the Handshake struct?
  • How to apply "tls-server-end-point" for TLS 1.3?

@Neustradamus
Copy link
Author

@kazu-yamamoto: I have sent you an email

@kazu-yamamoto
Copy link
Collaborator

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

@kazu-yamamoto
Copy link
Collaborator

@epoberezkin Would you tell me whether or not getFinished is inter-operable with OpenSSL?

@epoberezkin
Copy link
Contributor

epoberezkin commented Jan 10, 2024

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

@kazu-yamamoto
Copy link
Collaborator

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants