processone / xmpp

Erlang/Elixir XMPP parsing and serialization library on top of Fast XML

Home Page:http://process-one.net

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Wrong channel-bindings announced

tmolitor-stud-tu opened this issue · comments

The tls-unique channel-binding is only specified for TLS <= 1.2, but not for TLS 1.3 or greater.
The tls-exporter channel-binding on the other hand is only defined for TLS 1.3 or greater, but not for older TLS versions.

--> Ejabberd should only announce one of them, but never both, bug location:

cbind_valid(#state{cb_socket = Sock}, <<"p=tls-unique">>) when Sock /= none ->

Relevant quote from RFC 9266:

The specifications for Salted Challenge Response Authentication
Mechanism (SCRAM) [RFC5802] [RFC7677] and Generic Security Service
Application Program Interface (GSS-API) over Simple Authentication
and Security Layer (SASL) [RFC5801] define "tls-unique" as the
default channel binding to use over TLS.  As "tls-unique" is not
defined for TLS 1.3 (and greater), this document updates [RFC5801],
[RFC5802], and [RFC7677] to use "tls-exporter" as the default channel
binding over TLS 1.3 (and greater).

Theoretically tls-exporter could be possibly with tls1.2 (but i don't think current versions of openssl we use offers it), but indeed i should at least disable offer of tls-unique for tls1.3.

Yes, theoretically tls-exporter can be used with tls 1.2, but only if the extended master secret is used. I'm not sure if Openssl provides an aPI call to detect if an extended master secret is used. In practice all implementations just deactivate tls-exporter for tls 1.2 to be on the safe side.

Theoretically tls-exporter could be possibly with tls1.2 (but i don't think current versions of openssl we use offers it), but indeed i should at least disable offer of tls-unique for tls1.3.

You should only offer channel-bindings on a tls connection if you can verify them on this very connection. Otherwise the client may pick one you won't be able to verify.

I just tested it and your implementation sends back <failure xmlns='urn:xmpp:sasl:2'><not-authorized xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/><text>Invalid channel binding</text></failure> if tls-exporter is used with TLS 1.2

Reiterating that you should not advertise this channel-binding on a connection using TLS 1.2.

@tmolitor-stud-tu, @prefiks: About OpenSSL, there are some people, maybe a talk can be done:

Two tickets are always not solved:

For example, @fabiang waits OpenSSL team to add -PLUS variants:

And other projects wait too.

OpenSSL already provides an exporter API. Code changes to OpenSSL aren't needed for an application to provide RFC 9266.

It is possible we could provide a convenience API for RFC 9266 but it would just be a minor convenience. It is not a lot of code for an application to do it.

@hlandau Yes, the exporter implementation in openssl is just fine :)

Just for clarity: what happens if the tls-exporter implementation of openssl is used with TLS 1.2 (on a connection with or without extended master secret)?
Does it produce valid channel-binding data in these cases (or does it throw an error)?
And if yes: when is it secure to use this channel-binding with TLS 1.2 as implemented in openssl?

@tmolitor-stud-tu tls-exporter binding works fine with TLSv1.2 as long as you have extended master secret and disable renegotiation. my notes say it should be something like this (untested):

	// TLSv1.2 and older require extended master secret for security
	if( SSL_version( ssl ) != TLS1_3_VERSION && SSL_get_extms_support( ssl ) <= 0 )
		return -1;

	// and renegotiation must be disabled
	SSL_set_options(ssl, SSL_OP_NO_RENEGOTIATION);

	memcpy(buf, "tls-exporter:", 13);
	SSL_export_keying_material(ssl, buf+13, 32, "EXPORTER-Channel-Binding", 24, NULL, 0, 1);

Note use_context (last argument to SSL_export_keying_material) must be true to get the correct result for TLSv1.2 which treats a zero-length context differently from having no context, while TLSv1.3 gives the same result for both.

@mvduin great! Do you know what happens if you don't disable renegotiation or are on a connection not using the extended master secret? Will the exporter cb value just be insecure, invalid or not present at all (e.g. null)?

@tmolitor-stud-tu it will work but have vulnerabilities. It's unsafe to rely on SSL_export_keying_material when not using extended master secret:

"If a client or server chooses to continue with a full handshake without the extended master secret extension, then the new session becomes vulnerable to the man-in-the-middle key synchronization attack described in Section 1. Hence, the client or server MUST NOT export any key material based on the new master secret for any subsequent application-level authentication." — RFC2672

I'm actually not entirely sure if allowing renegotiation necessarily leads opens up any vulnerabilities if you do have extended master secret and secure renegotiation but the tls-exporter spec requires it to be disabled (and note that TLSv1.3 doesn't support renegotiation at all anymore).

@mvduin yeah, I'm aware of this paragraph in rfc 2672 (hence my request to not advertise tls-exporter on TLSv1.2 connections when I initially opened this issue),

My question was specifically how openssl behaves in these cases. Does it still return the (unsafe) exporter keying material or does it not change the buffer to write the cb data to at all or somesuch?

I've tested the current ejabberd implementation which always (regardles of extended master secret etc.) advertises tls-exporter using a local build of Monal which enabled the usage of tls-exporter on TLSv1.2, but ejabberd responded with "Invalid channel binding" which made me curious what value ejabberd was checking my cb data against.

@prefiks But whatever it is: the current implementation is definitely broken.

I changed our code in a way that should leads to not offering tls-unique on tls1.3+ and tls-exporter on <tls1.3 only if extended master secret is available.

@tmolitor-stud-tu could you check if this helps with tls1.2 and tls-exporter in monal? Can't make it use anything else than tls-server-end-point. I updated ejabberd master to use this version, so you can test updated code by rebuilding ejabberd from master.

@tmolitor-stud-tu sorry I should have been more clear: by "it will work" I meant SSL_export_keying_material will still return the requested keying material, it does not check whether extended master secret has been negotiated.

@prefiks Sure, I'll test it as soon as Holger has updated his test server (I'm not running my own ejabberd instance to test on, but I already asked him to update so this should be done in ~1 day).

The public version of Monal does not use tls-exporter on TLSv1.2 to be on the safe side, that's why it did not work in your tests. I can give you access to our alpha builds if you want to test it yourself :)

@mvduin Thanks for this clarification! So using the returned data without checking for the EMS is just unsafe but does not result in any errors.

I've now tested the ejabberd tls-exporter implementation on TLSv1.2 with Monal and it works like it should :)

The next release of Monal will implement/allow tls-exporter for TLSv1.2, too.