[cryptography] binding to channel params to prevent MITM

Marsh Ray marsh at extendedsubset.com
Sun Dec 5 04:46:05 EST 2010


On 12/04/2010 02:50 PM, travis+ml-rbcryptography at subspacefield.org wrote:
> Hey I don't know what it's called, but I'm wondering how one binds a
> challenge/response (or whatever you authenticate with) inside a secure
> tunnel to prevent the peer from relaying it on to another party to
> answer.

Well, the IETF has an entire mailing list devoted to this topic:
> http://www.ietf.org/mail-archive/web/channel-binding/current/maillist.html

There is this general RFC
http://tools.ietf.org/html/rfc5056

> I assume it could be as simple as signing a nonce and some parameter
> of the channel (such as an ephemeral key) and sending that (or something
> derived from it) as the challenge, but curious what the options and
> tradeoffs are.

The very general principle is to ensure that the vital essence, i.e. 
"the meaning" of what both ends of the protocol are intending to 
authenticate becomes inextricably woven into the crytpographic 
computations such that each legitimate party can ensure that the other 
legitimate party are operating under the same beliefs about the subject 
of their authentication.

I know this sounds a bit contorted, I believe that it is because it is 
so general. For too long we thought of authentication as something a 
user did to login to the central system, like flashing an ID to a guard 
as you drive into an office parking lot. In reality, the term 
'authentication' means 'determining whether or not something is 
authentic or genuine'.

In modern networked systems, we usually have a client and a server (or 
at least we can harmlessly attribute those roles to the endpoint which 
originated the connection and which received the connection).

For example, in the telnet days, the user was usually expected to 
authenticate himself to the server with a password. He had no way of 
verifying the server's identity and simply had to trust that the network 
took him to the right place.

At the arrival of SSL/TLS, the situation became reversed. The user was 
able to authenticate the server because the server provided a signed 
certificate, but the client was accepted completely anonymous to the 
server. This was expected to set up an encrypted channel that the user 
would trust enough that he could then authenticate to the server by 
sending his password in plaintext (but through the encrypted channel).

This is an example of an incompletely bound channel. Although SSL can 
bind the negotiated encryption key of the channel with the server's 
strong certificate authentication, it is not commonly used to bind the 
client's authentication with anything useful. So from the server's 
perspective, all he knows about the client is that somewhere in the 
world there is somebody who at one time was willing to give out the 
correct password for no specific reason. Usually the server has no idea 
if he's talking to a legitimate client or if the legitimate client even 
knows he's talking to the legitimate server.

But this still too specific in my view. The term "channel" implies a 
data path, usually an encrypted one. But the need for what we call 
"channel binding" generalizes beyond the secure agreement of a MAC 
and/or encryption key (though that is obviously a very important case).

It really all comes down to authentication. "Authenticate what you mean" 
the experts say. Let's ignore encryption for a second then, it's too 
familiar.

We've all seen the movie plot device where two characters walk into some 
official branch. One character goes to the clerk and makes an official 
request which requires detailed explanation. "I want X Y and Z to be 
done in the name of my wife over there." The clerk says "well we'll need 
to get your spouse's approval first". "Oh she's got a bit of a cold see, 
she's across the room getting a drink of water. Wave honey!" The spouse 
(who's picture is associated with the account) smiles and waves and the 
teller executes the transaction on that basis.

Of course, the gag is that the spouse had no idea what she was approving 
and all teller knew was that the right person was in room expressing 
approval for something. Hilarity ensues when the legitimate party (the 
spouse) finds out that she just gave approval for something completely 
contrary to her expectation.

This screwup can happen equally whether you're approving a one-time 
non-secret transaction, passing login credentials to establish a 
non-MACed-non-encrypted telnet session, or negotiating the parameters 
and keys for a strongly-MACed and strongly-encrypted data channel.

A developer might think "what does it matter that I bind anything into 
the authentication if I'm just setting up a totally insecure telnet 
channel anyway. Any attacker can obviously have his way with it once 
it's established." But that's very dangerous, here's why:
a. An attacker may be able to convince the client and/or server to use 
the insecure protocol instead of the secure one. He could say to each 
end "I don't support the newer version, let's talk the old version 
instead" and be able to downgrade their security.
b. The client and server may both agree that the insecure protocol can 
only be used for inconsequential things (e.g., echo packets or 
discussing the current time). The client may even be willing to 
automatically authenticate with the credentials of the logged in user 
without user intervention in some cases.
c. Some other application protocol may end up using a compatible 
credentials and authentication scheme for things that _do_ intend to 
build up a meaningful level of security. Yet if all the the "meaningful 
data" isn't included in what's authenticated, an attacker may be able to 
take the legitimate endpoint's authentication and use it for some other 
purpose, perhaps on another machine altogether.

As an example of how *not* to do it, look at NTLMv2. It has always been 
wide-open to a credentials forwarding attack:
http://extendedsubset.com/?p=36
(NTLMv1 had a huge dictionary attack vulnerability and v2 has offline 
cracking potential as well, so even this problem is usually overshadowed.)

If you were authenticating a large bank transaction with paper and pen, 
what information would both parties expect to see on the paper before 
they sign it?
Possibly:
   Date, amount
   Source party name, address, phone, source account, bank branch, etc.
   Receiving party name, address, phone, dest account, bank branch, etc.
   Reason, memo, description of item sold, notary describing forms of 
identification, etc.
  * How about the total number of pages in the signed document?
  * Maybe the total number of copies that were signed and to whom they 
are being given?

So what do you "bind" into your authentication?
IMHO, you should include every bit of information that you can find that 
A and B have a common language to discuss. For example:

Server name or other identifier
Client name or other identifier
Minimium supported server protocol version, maximum supported server version
Minimium supported client protocol version, maximum supported client version
The server's TCP port number if available. Perhaps even the existence or 
nonexistence of other protocol versions available on other server ports?
What higher-level application protocol will be carried (possible 
multiple layers of descripion)
What identity naming schemes (plain dns, x509 cert, etc) were proposed 
by the server
What identity naming schemes (plain dns, x509 cert, etc) were proposed 
by the client
Which identity naming scheme (plain dns, x509 cert, etc) was accepted by 
the server.
What MAC schemes were proposed by client and server, and accepted.
MAC secret proposed by both sides.
Random nonces proposed by both sides.

I'm sure I've missed some, and some will be application relevant. Note 
that most of these are listed as 'client' or 'server'. But really each 
of those is doubled again into
* what the client believes about the client's value
* what the server believes about the client's value
* what the client believes about the server's value
* what the server believes about the server's value
So we can't just take data from the network and check it against itself. 
We have to define our expectations and prove that they are met by what 
later comes in across the net.

Authentication is proving that these values match and within the allowed 
range for both endpoints.

Most of the time, today, it's just as important for the server to 
authenticate the identity of the client as it is for the client to 
authenticate the identity of the server. It will eventually become more 
important to authenticate the transmitted information itself rather than 
an identity at the end of some "logged-in session".

Yet with all this information included, be very restrictive on the range 
within which things can be negotiated. In general, whenever the 
authentication depends on a negotiated parameter, the attacker is free 
to select the value most advantageous to himself. Yes, it must be within 
the range of allowed values, but they don't necessarily have to be the 
same for the client and the server!

So given all this relevant information, how do you actually "bind" it 
in? The only sure way is for each endpoint to proving that the handshake 
will fail to succeed if the other endpoint isn't operating from exactly 
the same information. This differs according to the authentication 
mechanism, but usually it involves each side (independently) formatting 
the information in a protocol-specified way and feeding it into a digest 
function, the output of which is then made critical in the overall 
scheme somehow. We might think in terms of simply "signing" it, but 
there's always more to it than that. Often this process is greatly 
complicated by the need to minimize round trips or allow compatibility 
with previous versions.

Note that I left out something optional and sometimes important from 
that list: encryption keys. In my view, the encryption is secondary to 
the authentication. Once you have a solid authentication framework in 
place, setting up an encrypted channel is as simple as Diffie-Hellman or 
RSA (which are obviously nontrivial, but at least it should be 
straightforward). However, going from unauthenticated encryption to 
authenticated is generally no easier than starting over again from scratch.

I think we have this thing called "channel binding" because we started 
taking insecure protocols with marginal authentication and trying to 
secure them by opportunistically dropping them into strongly encrypted 
channels. So we ended up with all these insufficiently-bound channels 
and eventually discovered that we had a need to "bind the channels".

Again, the general idea just goes back to each endpoint having the 
ability to strongly authenticate all the information used as part of the 
negotiation and as the transaction message itself, which may or may not 
involve encryption keys.

But, as you might have noticed, I approach this from the authentication 
side of things. Others will look at it from a different perspective.

- Marsh



More information about the cryptography mailing list