Subject: Re: Poll: use of TLS channel bindings in SCRAM

From: Nicolas Williams <[email-masked]>
Date: Wed, 3 Jun 2009 00:07:32 -0500

On Fri, May 29, 2009 at 08:29:42PM +0200, Simon Josefsson wrote:
>                         ...  The changes can be summarized into:
> 
> 1) Add text to say that with 'p' one cb type name is included (normally
> tls-unique)
> 
> 2) Add text to say that with 'y' a list of cb type names supported by
> the client is included

There is a slightly better way that would simplify the client: define
new GS2 CB flags to go with the 'n', 'y', and 'p' that we have now
(which would stay as they have been, w/o any additional GS2 header
fields).  The three flags we have now:

 - 'n' (client can't do CB)
 - 'y' (client can only do tls-unique but thinks the server can't do CB)
 - 'p' (client used CB of the default type)

plus two new ones that today's servers would have to understand but
today's clients wouldn't have to:

 - 'Y' and a list of CB types in GS2 header (client can do CB and CB
   type negotiation and thinks the server advertives the given, possibly
   empty list of CB types)

 - 'P' and a single CB type in GS2 header (client used CB of the given
   type)

This way the server needs to know about the new bits in GS2 for future
downgrade protection in the face of CB type nego, but the client doesn't
have to know anything at all about future CB type nego.

Simplifying the client strikes me as a good thing.

Nico
--

---

From: Simon Josefsson <[email-masked]>
Date: Wed, 03 Jun 2009 07:31:45 +0200

> Simplifying the client strikes me as a good thing.

It adds more text to the specification, and some complexity, but it
seems like a reasonable compromise to simplify client implementations.

Before I update GS2 with that, what is the chance of making these
changes to SCRAM?  Alexey?

/Simon

---

From: Nicolas Williams <[email-masked]>
Date: Wed, 3 Jun 2009 08:28:37 -0500

On Wed, Jun 03, 2009 at 07:31:45AM +0200, Simon Josefsson wrote:
> > ...

It does add more text to the spec, but server-side complexity is not
really changed, and the client is simplified.  I'm OK with either plan,
though I think I prefer this one.

> changes to SCRAM?  Alexey?

We'll know soon enough.  The poll ends this week.

Nico
--

---

From: Nicolas Williams <[email-masked]>
Date: Wed, 3 Jun 2009 13:39:14 -0500

Huh, I think we can do something far simpler still: just add enough ABNF
to define non-critical GS2 header extensions.  (That's what I get for
posting late at night instead of sleeping on the idea.)

;; Non-critical GS2 extension headers; servers MUST ignore if they don't
;; understand them
gs2-ext-attr     = "gs2-" 1*ALPHA
gs2-ext-attr-val = gs2-ext-attr "=" value
gs2-ext-attrs    = gs2-ext-attr-val *("," gs2-ext-attr-val)

;; GS2 header
gs2-cbind-flag   = "n" / "y" / "p"
gs2-header       = gs2-cbind-flag [ authzid ] "," [ gs2-ext-attrs "," ]
                                                  ^^^^^^^^^^^^^^^^^^^^^

Or something like that.  (One might prefer something slightly different
that makes it easier to find the end of the GS2 header.)

So today SCRAM/GS2 would be essentially unmodified from what we had
going into this poll.  Later, when we add CB type negotiation we can add
an attribute for listing the CB types that the client saw in the 'y' and
'p' cases, and an attribute for specifying the CB type chosen by the
client in the 'p' case.

(And if we really wanted to we could add critical GS2 header extensions,
which, if present, cause the server to reply with an error if the server
doesn't understand the extension, else with a normal GSS context token
prefixed with a small header to distinguish from such errors.  Then even
Kurt's multi-level negotiation scheme could be added.)

Nico
--

---

From: Simon Josefsson <[email-masked]>
Date: Thu, 04 Jun 2009 10:08:19 +0200

> gs2-header       = gs2-cbind-flag [ authzid ] "," [ gs2-ext-attrs "," ]

Right, you need a reliable way to identify the end of the gs2-header.  I
also dislike the complexity in a parser that always will have to ignore
any number of gs2-* parameters, so how about this instead:

string     = 1*(UTF8-char-safe / "=2C" / "=3D")
gs2-authzid  = "a=" string
gs2-cbind-flag   = "n" / "y" / "p"
gs2-nonstd-flag = "F"
gs2-header       = [gs2-nonstd-flag "," ] gs2-cbind-flag "," [ gs2-authzid ] "," [ "gs2-ext" "=" string ] ","

Servers that doesn't understand a gs2-ext token MUST fail
authentication.

Having thought about this proposal (briefly), I don't think an extension
idea is a good idea.  What you propose is an extension mechanism inside
a SASL mechanism.  I have a fairly strong general preference against
that -- SASL is an extensible protocol, and the way to negotiate
extensions is to specify a new SASL mechanism name and have clients
prefer that mechanism.  The new mechanism can be a cut'n'paste of the
old mechanism, plus some new wording.  I don't see a need for an
extension mechanism inside GS2 here?

So, my preferences are:

1) GS2 -13 but remove tls-server-end-point and only support tls-unique.

2) GS2 -13 plus the changes I proposed earlier to send a list of channel
binding types.  This allows tls-server-end-point to work if there is
someone that is willing to do the work (specify an outer negotiation
protocol) for that.

3/4) GS2 -13.
3/4) GS2 plus your Y/P proposal.
  Not sure how to rate these two against each other.  The Y/P scheme is
  close to an extension scheme.

5) GS2 plus the above extension scheme.

/Simon

---

From: Nicolas Williams <[email-masked]>
Date: Thu, 4 Jun 2009 10:43:40 -0500

> Servers that doesn't understand a gs2-ext token MUST fail

The extension doesn't have to be critical to do what we want it to.
More importantly, we don't have an error message defiedn so any failure
could only be communicated through the SASL outcome of authentication
message, and that need not provide machine-readable mechanism-specific
information, so the mechanism on the client can't use any failure
information for, say, Kurt's multi-level negotiation proposal (though I
am not sure that he meant that seriously -- I certainly don't take it
seriously).

So I think "MUST ignore unknown" is good enough.

> extension mechanism inside GS2 here?

This is not an extension in that sense -- we're not negotiating new
features.  We're merely providing future downgrade protection against a
future negotiation that could be done via SASL mech name nego.

---

From: Alexey Melnikov <[email-masked]>
Date: Fri, 05 Jun 2009 22:46:15 +0100

>On Fri, May 29, 2009 at 08:29:42PM +0200, Simon Josefsson wrote:
 [...]

>>Check the examples, they are updated and hopefully give you a quick idea
>>of how the protocol will look like.
>>
>>Thoughts?
>>    
>>
>Awesome.  Thanks!
>
>Alexey, can you adapt Simon's changes to GS2 to SCRAM?
>  
>
Yes, your proposal seems fine to me. (I might have some minor comments 
later).

---

From: Alexey Melnikov <[email-masked]>
Date: Fri, 05 Jun 2009 22:51:27 +0100

[...]

>>Also, I like your ABNF.  I had in mind using something like t=<type> and
>>t=<type>[:<type>[:...]], but your approach strikes me as better.
>>    
>>
>I'm glad you like it.  I'm not entirely happy with it: you can't parse
>it using a var[=value] parser, you need to inspect the string character
>by character in the beginning.  One alternative would be (compare with
>the examples in the document):
>
>Example #1: n,a=someuser,...
>Example #2: n,...
>Example #3: F,n,...
>  
>
I think we need comma after "n" (for consistency and ease of parsing) 
and we don't need a comma after F.

>Example #4: p=tls-unique,a=someuser,...
>Example #5: p=tls-unique,...
>Example #6: p=tls-server-end-point,...
>Example #7: y=tls-unique:tls-server-end-point,a=someuser,...
>
>However I didn't want to make unrelated changes at this point.
>
>Also, that SCRAM uses var[=value] doesn't mean GS2 needs to.
>
>I'm not sure.
>
>Thoughts?
>  
>

---

From: Alexey Melnikov <[email-masked]>
Date: Fri, 05 Jun 2009 22:53:33 +0100

Jeffrey Hutzelman wrote:

> --On Friday, May 29, 2009 10:59:17 PM +0200 Simon Josefsson 
> <[email-masked]> wrote:

 [...]

> I see a couple of problems with the grammar.  One is that in the 'p' 
> and 'y' cases, you get two consecutive commas if there is no authzid.

-1. I think it would be better to use 2 commas, because this is a sure 
sign that the GS2 header has ended.

> The other is that in the 'n' case, you get no comma before the 
> authzid, if there is one.

+1.

> I think it would be better to always have a comma after the [pny] 
> field, and another after the a=authzid iff it is present.
>
> I have no objection to the [py]= syntax you suggest; that might make 
> parsing easier, and we're changing the format of that field anyway.
>
> I see no reason to include a comma after the 'F' prefix.

+1.

---

From: Alexey Melnikov <[email-masked]>
Date: Fri, 05 Jun 2009 22:56:40 +0100

>>changes to SCRAM?  Alexey?
Simon, I suggest you do changes to GS2 (hopefully taking into 
consideration a couple of minor comments I've just sent out), then I 
copy them to SCRAM.
If I dislike something, I will complain :-)

---

From: Kurt Zeilenga <[email-masked]>
Date: Sun, 7 Jun 2009 05:12:20 -0700

After some additional thought and consideration, I change my  
preference to:

4a (just change the text to require tls-unique)
5 (adds some words that additional text that channel bind type agility  
is provided via mechanism name).

I have decided not to support providing any channeling binding  
"downgrade" protection in the mechanism.  This because I believe the  
mechanism downgrade mechanism is sufficient to protect against attacks  
I think would be likely, and the suggested approaches not necessarily  
sufficient to cover attacks that might eventual come.   For instance,  
if we were to not only have a channel binding type negotiation  
facility (such as what Jeffrey proposed) but a Security Label  
negotiation facility, and maybe a hash algorithm negotiation facility,  
or maybe a combined "mechanism property" negotiation facility, I would  
want that negotiation facility to provide a downgrade protection.  Off  
hand, I cannot think of how to deal with downgrade now without  
discussing the particulars of the negotiation facility, so I rather  
defer this (and just hope we have enough extension capability in GS2/ 
SCRAM) to deal with such).

-- Kurt

On May 28, 2009, at 2:49 PM, Alexey Melnikov wrote:

>
> I've discussed channel bindings with Nico in jabber and we agreed  
> that we need to get WG consensus on how TLS channel bindings should  
> be used with SCRAM.
> Please provide an orded list of alternatives you find acceptable  
> from the choices listed below. (Please restrict discussions of  
> variants of these choices at the moment. I will do another poll on  
> such choices later, depending on the outcome of this poll. Also,  
> please read notes for the choices before answering). Please answer  
> the poll by the end of June 7th.
>
> 1). SCRAM should just use a single allowed TLS channel binding and  
> don't have any negotiation of other TLS channel bindings (*) (**)
> a). the default is tls-unique
> b). the default is tls-server-end-point
> 2). SCRAM should just use tls-server-end-point, fallback to tls- 
> unique, no negotiation of other TLS channel bindings (*)
> 3). SCRAM should always use channel binding negotiation (*)
> 4). SCRAM should have a default TLS channel binding with optional  
> negotiation of TLS channel bindings (*)
> a). the default is tls-unique
> b). the default is
> 5). I have another opinion [this is for the case when there is some  
> valid choice which you think should be considered by the WG]
>
> Notes:
> (*) - whether such negotiation happens inside or outside of SCRAM
> (**) - channel binding negotiation can be added later on
>

---

From: Sam Hartman <[email-masked]>
Date: Mon, 08 Jun 2009 10:21:31 -0400

>>>>> "Kurt" == Kurt Zeilenga <[email-masked]> writes:

    Kurt> After some additional thought and consideration, I change my
    Kurt> preference to:

    Kurt> 4a (just change the text to require tls-unique) 

As I indicate, I believe support for channel binding types other than
tls-unique is an absolute requirement.  While I prefer for us to have
downgrade protection, I don't see that as an absolute requirement.
So, I think we at least need a mechanism to say what channel binding
type we've used if it is not tls-unique.  That's not downgrade
protection; it is consistency with 5056.

    Kurt> 5 (adds some
    Kurt> words that additional text that channel bind type agility is
    Kurt> provided via mechanism name).

I'm fairly strongly against this option.

    Kurt> I have decided not to support providing any channeling
    Kurt> binding "downgrade" protection in the mechanism.  

As I indicated, I believe this would be a good idea, and would
certainly rather the WG consensus be that we had such a mechanism, but
understand if we don't go there.

---

From: Nicolas Williams <[email-masked]>
Date: Mon, 8 Jun 2009 11:03:57 -0500

> protection; it is consistency with 5056.

Technically we don't even need that much, but I'd very much like to have
at least that much.

I too think that future downgrade protection is not critical right now.
In fact, I can think of ways to do all three (or is it four?) proposed
future CB type nego schemes without adding downgrade protection now
(it's just that to me the security analysis seemed easier with explicit
downgrade protection).

Nico
--