[cryptography] binding to channel params to prevent MITM
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
Well, the IETF has an entire mailing list devoted to this topic:
There is this general RFC
> 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
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:
(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?
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
* 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
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.
More information about the cryptography