Subject: Re: TLS endpoint channel bindings in SCRAM

From: Nicolas Williams <[email-masked]>
Date: Wed, 1 Apr 2009 17:52:20 -0500

On Tue, Mar 24, 2009 at 10:37:37PM +0000, Dave Cridland wrote:
> Having carefully examined the tls-server-end-point channel binding,  
> I've a bit of a concern.

We should probably be having this discussion on the
[email-masked] list (cc'ed).  Also cc'ed are folks who
participated in the registration of tls-server-end-point.

> One of the sticking points of the tls-unique channel binding is how  
> easy it is to get at the data - OpenSSL provides an API, however it's  
> often not exposed to language bindings such as Python, etc, and other  
> TLS implementations may not provide it at all.

File bugs against them!  If you have a list of such bindings I'll
volunteer to help file and track these bugs.

> I can't find any way of getting at the on-wire representation of the  
> server's certificate, and I can't immediately find a way of  
> discovering which hash algorithm to use, either, in the vast majority  
> of bindings.
> 
> So rather than expect all TLS implementations and bindings to change,  
> I'd like to propose an alternate binding, for use where the server's  
> certificate is an X.509v3 one.
> 
> Specifically, I'd like to use a fixed hash algorithm over the  
> DER-encoded form of the certificate - I'll call this  
> "tls-x509-end-point"

Questions:

1) Do many/most/all TLS implementations output the DER-encoded form of
   the server cert?  Which ones do/don't?

2) Is the cert used on the wire generally NOT DER-encoded?  If so, how
   hard would it be to change this?  (e.g., re-encode the cert and
   restart apps?)

Notes:

 - By hard-coding a hash function we'd lose hash agility.  Hash agility
   is one of the features of the registered tls-server-end-point channel
   binding type.  OTOH, as you note, for SCRAM this is solved by the
   existing SCRAM hash agility approach (add a new mech).

 - We can't really negotiate which type of channel binding to use.  It's
   relatively easy to choose between unique and server-end-point, but to
   choose between two types of server-end-point bindings is much harder
   (unless it's a choice made at specification time, in this case for
   SASL/SCRAM).

   Neither modifying tls-server-end-point nor introducing a different
   variant of it seem particularly appealing.  The former may well be
   out of the barn's doors, which would leave us only with the latter
   choice (or fix the TLS frameworks :)

> The DER form of the certificate is readily available through most  
> bindings, in many cases in a single call, and gives exactly  
> equivalent hash-input as the on-wire format, which is very likely  
> [but not mandated, as far as I can find] to be DER anyway.
> 
> Fixing a hash algorithm simply makes this even easier - the current  
> channel binding uses SHA-256 as a "minimum hash", I'd prefer to use  
> SHA-1, as we're certain to have it for SCRAM.

True.

> Finally, I'd propose that SCRAM mandates support for the  
> 'tls-x509-end-point' channel binding for the applicable cases as a  
> reasonable fallback when support for the more flexible and  
> future-proof tls-server-end-point binding is not available.
> 
> Now I'll wait to get shot down in flames. :-)

No flames.  I think we could do a channel binding type just for SCRAM
(we did one just for TELNET, after all).  But I think I'd want "DER" in
the name, that and the hash function name too.

Comments?

> Dave.
> -- 
> Dave Cridland - mailto:[email-masked] - xmpp:[email-masked]
>  - acap://acap.dave.cridland.net/byowner/user/dwd/bookmarks/
>  - http://dave.cridland.net/
> Infotrope Polymer - ACAP, IMAP, ESMTP, and Lemonade

Nico
--

---

From: Simon Josefsson <[email-masked]>
Date: Thu, 02 Apr 2009 10:27:18 +0200

> the name, that and the hash function name too.

I don't think that will work -- TLS isn't just X.509.  TLS supports
OpenPGP server certs.  Generally, TLS can support other forms of server
authentication too.

I don't want to see SCRAM require use of X.509 server certificates if we
can avoid it.

It seems simple to avoid that here: just request the necessary features
from TLS stacks.  If we don't do that now, we likely won't do it next
time we need a channel binding for some application protocol, and then
TLS interfaces will never have this feature.  Nico volunteered to help
with this for OpenSSL, and I can volunteer to do it for GnuTLS.  We knew
from the start that channel bindings would require changes to TLS
stacks.  The major native C libraries have already been adapted, I
believe, so what remains are any language bindings.  That seems like
Just A Simple Matter Of Programming.

The alternative is to make channel binding type negotiable, something I
recall discussing at lengths earlier.  Nothing came out of that, so RFC
5056 does not support any negotiation.  I'm not sure how well it would
work to add that feature for SCRAM?  But it could be explored.

/Simon

---

From: Dave Cridland <[email-masked]>
Date: Thu, 02 Apr 2009 12:32:21 +0100

>    the server cert?  Which ones do/don't?
Somewhere between many and most. I suspect all the low-level TLS  
stacks (OpenSSL etc) will do. It's the bindings and suchlike I'm more  
concerned with.

In the bindings, however, it's pretty trivial to find a function  
which either hands back the DER form, or else hands back PEM (base64  
of DER), which developers can also use.

>    hard would it be to change this?  (e.g., re-encode the cert and
I have absolutely no idea. If I could rely on the cert being DER on  
the wire, we could reduce this to implementation notes, aside from  
the hash issue. I have no idea how to extract that hash algorithm,  
currently, but I could probably figure that out eventually.

If it turns out that tls-server-endpoint *can* be readily implemented  
at least for the common case of X.509 certificates, then I'd be very  
much happier with this outcome.

>    existing SCRAM hash agility approach (add a new mech).
Yes - it's not ideal, but I'm hoping that by the time hash agility  
becomes an issue, then we'll have support for the more generic form  
of the channel binding.

>    (unless it's a choice made at specification time, in this case  
But clients must stipulate which they have used.

>    choice (or fix the TLS frameworks :)

I think tls-server-end-point is a fine binding.

My problem is that it'll be years before it's available on many  
platforms, and I think we can provide more immediately implementable  
security than that.

Dave.

---

From: Nicolas Williams <[email-masked]>
Date: Thu, 2 Apr 2009 11:21:23 -0500

Jeff Hutzelman points out that we can't introduce multiple variants of
tls-server-endpoint on a per-mechanism basis.  We can do that for SASL
apps generally, say, but not just for SCRAM.

Simon points out that TLS supports non-PKIX certificates.

I agree with these points.  Therefore I have to say that it's best to
stick with tls-server-endpoint and not define any new ones, nor to seek
any changes to tls-server-endpoint.

Implementations of TLS that don't provide application access to the
server cert as it appears on the wire in TLS should just be extended.

Nico
--

---

From: Nicolas Williams <[email-masked]>
Date: Thu, 2 Apr 2009 16:40:44 -0500

> Simon points out that TLS supports non-PKIX certificates.

Actually, that's true, but the way RFC5081 adds support for OpenPGP
certs happens to not work with tls-server-end-point bindings because
there's no certificate_list field in the Certificate message when
OpenPGP certs are negotiated.  It would not be difficult to change
tls-server-end-point to cover the use of OpenPGP certs.

Aside: if I read RFC5081 correctly it seems that you can't negotiate the
use of OpenPGP certs for user certs but not for server certs, and vice
versa.  Odd!

---

From: Simon Josefsson <[email-masked]>
Date: Fri, 03 Apr 2009 02:40:30 +0200

> tls-server-end-point to cover the use of OpenPGP certs.

Does that mean SCRAM will require server certs?  I think that is
unfortunate -- why can't SCRAM over TLS-anon or TLS-PSK or TLS-SRP with
tls-unique be supported?

> use of OpenPGP certs for user certs but not for server certs, and vice

That is right.  It also does not permit negotiating X.509 on one side
and OpenPGP on the other.  There is a -bis effort in progress, but I
don't think it addresses these concerns.

/Simon

---

From: Nicolas Williams <[email-masked]>
Date: Thu, 2 Apr 2009 23:58:42 -0500

> unfortunate -- why can't SCRAM over TLS-anon or TLS-PSK or TLS-SRP with

No, no.

The idea is that when the TLS channel used server certs then the client
MUST use tls-server-end-point bindings.  Otherwise it MUST use
tls-unique bindings.

The reason is this: tls-server-end-point bindings can work with existing
TLS concentrators (and with implementations that separate TLS in an
stunnel-like fashion), therefore it's preferable, BUT, because
tls-server-end-point isn't always available but tls-unique is, we
REQUIRE falling back on tls-unique when tls-server-end-point is not
available.

> don't think it addresses these concerns.

Well, it should.  I think it makes sense to use PKIX for the server cert
and OpenPGP for the user cert.  I'm not sure that I care enough to go
comment on this.

Nico
--

---

From: Simon Josefsson <[email-masked]>
Date: Fri, 03 Apr 2009 12:21:56 +0200

> MUST use tls-server-end-point bindings.  Otherwise it MUST use

Got it.  Is this in SCRAM or GS2 now?  I don't recall texts like that.

> REQUIRE falling back on tls-unique when tls-server-end-point is not

How is that negotiated?  Couldn't it be that the client has access to
tls-server-end-point but not the server, or vice versa?

/Simon

---

From: Dave Cridland <[email-masked]>
Date: Fri, 03 Apr 2009 12:03:46 +0100

> Got it.  Is this in SCRAM or GS2 now?  I don't recall texts like  

It's in the latest SCRAM.

> tls-server-end-point but not the server, or vice versa?

Then the client provides a tls-server-end-point (or not, because it  
can't, see previous mails) and the server just ignores it, being  
unable to verify it, or else rejects the authentication. This would  
only happen when the server is not behind a concentrator, but can  
only do tls-unique due to TLS API limitations, though - if the server  
is behind a concentrator and hasn't been configured with its own TLS  
identity, then one assumes it'd not offer -PLUS.

Equally interesting is if the server can only do  
tls-server-end-point, due to being behind a concentrator, but the  
client can only do tls-unique because it doesn't have a TLS stack  
which'll provide it with the relevant data.

One assumes the client should just use tls-unique, and the server  
will, again, ignore it or reject it.

Dave.

---

From: Dave Cridland <[email-masked]>
Date: Fri, 03 Apr 2009 12:03:33 +0100

> apps generally, say, but not just for SCRAM.
Right, I agree. Luckily, we can mandate server-side support for  
additional channel bindings across the board.

> Simon points out that TLS supports non-PKIX certificates.
Absolutely. However, I'd also state that the prevelant use of TLS is  
with X.509 certificates, and whilst I'm not arguing that this should  
be mandated, I do think we ought to take this into account, and  
indeed take advantage of it to promote deployment of channel binding.

> I agree with these points.

As do I.

>   Therefore I have to say that it's best to
I fail to see where you get this conclusion from.

> server cert as it appears on the wire in TLS should just be  

Will sir be needing to borrow a forklift to help with his upgrade?

Dave.

---

From: <[email-masked]>
Date: Fri, 3 Apr 2009 14:33:47 +0200

>    hard would it be to change this?  (e.g., re-encode the cert and

Although the TLS spec doesn't explicitly say this, the on-the-wire
certificate is DER encoded. There's no field specifying what the
encoding is, so if you attempt sending PER or XER, it simply won't
work.

Some implementations might accept some limited subset of BER (to
work around CA bugs), but even in those cases, nobody's going to
re-encode it to DER (most likely the CA calculated the signature over
BER encoded version -- violating all possible standards -- and the
API would return the octets sent on the wire).

So I don't see any problem in using the tls-server-end-point channel
binding... (and it seems it would work for OpenPGP, too)

Best regards,
Pasi

---

From: Nicolas Williams <[email-masked]>
Date: Fri, 3 Apr 2009 09:52:12 -0500

> Got it.  Is this in SCRAM or GS2 now?  I don't recall texts like that.

Ah, it's in SCRAM -- I need to copy that text to GS2.

> tls-server-end-point but not the server, or vice versa?

That would what you call a bug or configuration error.

If a server cert was used then the server should know.  If there's a TLS
concentrator then the server needs to know that and what cert was used,
which creates a bit of a problem in the virtualization case: the server
needs to know which cert was used, but this can be solved and it's a
much smaller problem, I think, than modifying concentrators to provide
tls-unique bindings to servers.

Nico
--

---

From: Nicolas Williams <[email-masked]>
Date: Fri, 3 Apr 2009 09:47:52 -0500

> encoding is, so if you attempt sending PER or XER, it simply won't

Right, I doubt anyone re-encodes certs in PER or XER :)

It's BER that one should worry about.

> API would return the octets sent on the wire).

OK, thanks.

> binding...

Excellent.  Thanks!

>            (and it seems it would work for OpenPGP, too)

It could be made to, but tls-server-end-point refers to the first cert
in the 'certificate_list' field of the server's Certificate message --
there's no such field in the OpenPGP case.  It'd be a trivial updat to
tls-server-end-point to allow the use of a server's OpenPGP cert though.

Nico
--

---

From: Nicolas Williams <[email-masked]>
Date: Fri, 3 Apr 2009 10:01:58 -0500

> unable to verify it, or else rejects the authentication. This would  

The GSS-API does allow the acceptor to ignore channel bindings by not
providing any.  Well, actually, the GSS-API specs are a bit fuzzy on
this point, but for years the MIT krb5 implementation of the krb5 mech
actually worked that way, so there's precedent...  But one could have
mechanisms that don't allow the acceptor to ignore the channel binding
(imagine mixing the channel binding into a key derivation step).

IF we're going to allow the server/acceptor-may-ignore-client-channel-
bindings-by-providing-none semantic then we must provide some indication
that this happened in the server's last message.  But because we need
this to be communicated to the client at the GS2 layer too, and securely
so, we'd be complicating GS2 significantly -- I don't think we want
that.

> identity, then one assumes it'd not offer -PLUS.

Correct -- the server must know if it is behind a concentrator, and it
must know its server cert.  Virtualization -> more communication between
the concentrator and the server than just manual configuration.

> which'll provide it with the relevant data.

In that case the client either must force the use of anon-anon TLS
cipher suites or it must not use channel binding.

> will, again, ignore it or reject it.

No.  That wouldn't work: the client and the server would both use
different channel bindings and authentication must then fail.  (This
case is distinguished from the case where the server doesn't know the
channel binding and so ignores it.)

Nico
--

---

From: Nicolas Williams <[email-masked]>
Date: Fri, 3 Apr 2009 10:10:25 -0500

> so, we'd be complicating GS2 significantly -- I don't think we want

Actually, there's a simple way to make that possible: put the mechanism
name in the GS2 channel binding data header.  If the name ends in -PLUS
then the server can't ignore the channel bindings because it must have
advertised that it supports them.  Whereas if the name does not end in
-PLUS then the server is free to ignore the client's channel bindings.

Comments?

Nico
--

---

From: Nicolas Williams <[email-masked]>
Date: Fri, 3 Apr 2009 10:15:48 -0500

> additional channel bindings across the board.

Yes, but I don't think we should.  Pasi points out that TLS
implementations generally put the DER encoded cert on the wire.  So I
think the premise of your request for a variant of tls-server-end-point
is in question...  Can you comment on Pasi's comment?

> Will sir be needing to borrow a forklift to help with his upgrade?

If Pasi is right, then no, I won't be :)

Nico
--

---

From: Jeffrey Hutzelman <[email-masked]>
Date: Fri, 03 Apr 2009 12:05:29 -0400

> Got it.  Is this in SCRAM or GS2 now?  I don't recall texts like that.

It doesn't belong in either.
SCRAM and GS2 are SASL mechanisms; they operate below the SASL abstraction. 
Their job is to convey and verify the channel bindings provided by the 
application protocol.  They don't get to specify what channel bindings are 
used.  This is very important.

Whether to use channel bindings and which bindings to use is determined by 
the protocol operating above the SASL abstraction.  We can perhaps develop 
guidelines for how such protocols should behave, but they don't belong in a 
mechanism document.

Remember, the point of the abstraction is that individual users of SASL do 
not need to know about or understand individual mechanisms.  This breaks if 
there is any mechanism that attempts to apply mechanism-specific 
requirements to the protocol operating above the abstraction.

-- Jeff

---

From: Jeffrey Hutzelman <[email-masked]>
Date: Fri, 03 Apr 2009 12:08:34 -0400

> -PLUS then the server is free to ignore the client's channel bindings.

We had an agreement before San Franscisco as to how CB negotation should 
work.  I carefuly analyzed that approach to be sure that it works 
correctly, allows CB to be used when possible, allows interoperability when 
CB cannot be used, and prevents downgrade attacks.

I lack the time to think about whether what you just described is 
semantically equivalent to the previous agreement and whether it still 
meets the requirements and remains secure.

Can we _please_ stop changing this?

-- Jeff

---

From: Nicolas Williams <[email-masked]>
Date: Fri, 3 Apr 2009 11:58:20 -0500

On Fri, Apr 03, 2009 at 12:08:34PM -0400, Jeffrey Hutzelman wrote:
> We had an agreement before San Franscisco as to how CB negotation
> should work.  I carefuly analyzed that approach to be sure that it
> works correctly, allows CB to be used when possible, allows
> interoperability when CB cannot be used, and prevents downgrade
> attacks.
> 

In this particular case I think so, because Dave's concern can be
addressed differently by saying "don't do that", where "that" ->
code/configure your server to advertise -PLUS and then not be able to
use the required channel binding type for the given situation.

Nico
--

---

From: Nicolas Williams <[email-masked]>
Date: Fri, 3 Apr 2009 11:55:06 -0500

> It doesn't belong in either.

I agree.  We need to update RFC4422 to specify the channel binding
semantics of SASL, the -PLUS thing, and the rules for selecting TLS
channel binding types.

(I also knew we'd have to do that eventually, but wanted to wait until
the dust settled on SCRAM/GS2 -- which has happened, pretty much -- to
bring that up.  It was important to settle these matters in the context
of SCRAM/GS2 _first_, but it is also important to document these in the
context of an update to SASL.)

Nico
--

---

From: Jeffrey Hutzelman <[email-masked]>
Date: Fri, 03 Apr 2009 13:26:50 -0400

> use the required channel binding type for the given situation.

In fact, that is the only thing you can do.
You can't give the server license to ignore the client's channel bindings 
if they're the wrong type, because that enables a MitM attack where the 
attackers channels from the client and to the server are of different types.

-- Jeff

---

From: Nicolas Williams <[email-masked]>
Date: Fri, 3 Apr 2009 12:28:58 -0500

> attackers channels from the client and to the server are of different types.

I wasn't proposing that.  Instead I was proposing that in the case where
the client did not negotiate mechanisms but used channel binding and the
server couldn't, then the server could ignore those channel bindings IFF
the client used a non-PLUS mechanism name.  (In GSS terms the SCRAM GSS
mech's GSS_Accept_sec_context() with GSS_C_NO_CHANNEL_BINDINGS would
ignore the client's channel bindings, just like the MIT krb5 mech
implementation used to, but GS2 would protect against downgrade by
protecting the SASL mechname used by the client and failing
authentication if the client used the -PLUS name and the server had no
channel bindings.)

---

From: Jeffrey Hutzelman <[email-masked]>
Date: Fri, 03 Apr 2009 14:19:49 -0400

--On Friday, April 03, 2009 12:28:58 PM -0500 Nicolas Williams 
<[email-masked]> wrote:

>> You can't give the server license to ignore the client's channel
>> bindings  if they're the wrong type, because that enables a MitM attack
>> where the  attackers channels from the client and to the server are of
>> different types.
>

Except I think that's the wrong way; the server must fail authentication if 
it advertised channel bindings and the client reports that it did not see 
such an advertisement.

There are only three cases:

- client saw advertisement and uses CB
- client saw advertisement and does not use CB
- client did not see advertisement

In the third case, if the server advertised CB at all it must fail.
In the first case, if the client's CB is the wrong type it must fail.

If the server could not use CB, it should not have advertised -plus.

The only possible reason to do what you describe is to allow a server to 
advertise -plus, but defer the determination as to whether it supports CB 
until after the client sends them.  That's fine, but not if the decision is 
made based on the type of CB the client sent, which is what you'd need for 
negotiation but breaks the protocol.

-- Jeff

---

From: Nicolas Williams <[email-masked]>
Date: Fri, 3 Apr 2009 14:19:56 -0500

> it advertised channel bindings and the client reports that it did not see 

It's worse than that -- GS2 always uses GSS channel bindings, so that
semantic from MIT krb5 wouldn't help anyways.

> negotiation but breaks the protocol.

Right, forget all about this.

Nico
--

---

From: Jeffrey Hutzelman <[email-masked]>
Date: Fri, 03 Apr 2009 16:00:39 -0400

--On Friday, April 03, 2009 02:19:56 PM -0500 Nicolas Williams 
<[email-masked]> wrote:

>> Except I think that's the wrong way; the server must fail authentication
>> if  it advertised channel bindings and the client reports that it did
>> not see  such an advertisement.
>

I think you misinterpreted.  Let me try again.

If the server advertised support for -PLUS, indicating that it could do CB, 
but the client reports that it saw no such advertisement, then that 
indicates an attacker modified the advertisement en route, and the server 
MUST fail authentication at the SASL layer.  This happens without ever 
calling GSS.

-- Jeff