On 07/08/18 22:34, Bruce Momjian wrote:
On Thu, Jul 12, 2018 at 11:26:30AM +0300, Heikki Linnakangas wrote:
On 12/07/18 07:14, Michael Paquier wrote:
On Wed, Jul 11, 2018 at 03:01:03PM +0300, Heikki Linnakangas wrote:
I started digging into this more closely, and ran into a little problem. If
channel binding is not used, the client sends a flag to the server to
indicate if it's because the client doesn't support channel binding, or
because it thought that the server doesn't support it. This is the
gs2-cbind-flag. How should the flag be set, if the server supports channel
binding type A, while client supports only type B? The purpose of the flag
is to detect downgrade attacks, where a man-in-the-middle removes the PLUS
variants from the list of supported mechanisms. If we treat incompatible
channel binding types as "client doesn't support channel binding", then the
downgrade attack becomes possible (the attacker can replace the legit PLUS
variants with bogus channel binding types that the client surely doesn't
support). If we treat it as "server doesn't support channel binding", then
we won't downgrade to the non-channel-binding variant, in the legitimate
case that the client and server both support channel binding, but with
incompatible types.

What we'd really want, is to include the full list of server's supported
mechanisms as part of the exchange, not just a boolean "y/n" flag. But
that's not what the spec says :-(.

Let's not break the spec :)  I understand from it that the client is in
charge of the choice, so we are rather free to choose the reaction the
client should have.  In the second phase of the exchange, the client
communicates back to the server the channel binding it has decided to
choose, it is not up to the server to pick up one if the client thinks
that it can use multiple ones.

The case where the client and the server both support the same channel
binding type, we're OK. The problematic case is when e.g. the server only
supports tls-unique and the client only supports tls-server-end-point. What
we would (usually) like to happen, is to fall back to not using channel
binding. But it's not clear how to make that work, and still protect from
downgrade attacks. If the client responds "y", meaning "the client supports
channel binding, but it looks like the server doesn't", then the server will
reject the authentication, because it did actually support channel binding.
Just not the same one that the client did. If the client could reply "y",
and also echo back the server's list of supported channel bindings in the
same message, that would solve the problem. But the spec doesn't do that.
                 ----------------------------

I know this is an academic question now, but I am not sure this is true.
A man-in-the-middle attacker could say they don't support channel
binding to the real client and real server and pretend to be the real
server.  What would work is to hash the secret in with the supported
channel binding list.  This is how TLS works --- all previous messages
are combined with the secret into a transmitted hash to prevent a MITM
from changing it.

Yeah, that is what I meant. Currently, when client chooses to not use channel binding, it the sends a single flag, y/n, to indicate whether it thinks the server supports channel binding or not. That flag is included in the hashes used in the authentication, so if a MITM tries to change it, the authentication will fail. If instead of a single flag, it included a list of channel binding types supported by the server, that would solve the problem with supporting multiple channel binding types.

- Heikki

Reply via email to