Subject: New GS2: pulling everything together

From: Nicolas Williams <[email-masked]>
Date: Mon, 16 Mar 2009 13:25:02 -0500

We've had a lot of comments on the new GS2 design.  Time to pull
everything together again.

The new design then consists of:

1) An all-text header prefixed to the client's first authentication
   message and to the application's channel binding (CB) data.

   This header consists of:

   a) a constant for RFC2743 section 3.1 initial context token header
      compression;
   b) a flag for channel binding (see below);
   c) the authzid (because the GSS-API has no equivalent).

   ABNF:

    gs2-rfc2743-compress-flag = "T" / "F"
    gs2-cb-flag = "n" / "y" / "p"
	; 'n' -> client can't and didn't do channel binding
	; 'y' -> client can do CB, but didn't
	; 'p' -> client did channel binding
    gs2-authzid = "a=" saslname ","
	; See SCRAM for definition of saslname

2) No sec layers.

3) Pretty SASL mechnames for GS2.  These must be specified/registered
   when a GSS-API mech is created (all existing standard GSS mechs will
   get one through GS2).  See below.

4) Negotiable channel binding with downgrade detection using mechanism
   name negotiation as a building block for channel binding negotiation.

   Two mechnames are needed for GS2/SCRAM:

    - SCRAM-SHA-1-PLUS
    - SCRAM-SHA-1

   Servers that support channel binding advertise both.  Servers that
   don't support CB advertise only SCRAM-SHA-1.

   The client picks SCRAM-SHA-1-PLUS if advertised, else it picks
   SCRAM-SHA-1, OR, if the client doesn't list server mechs, then it
   picks SCRAM-SHA-1 (and never sets gs2-cb-flag == "y").  The client
   also indicates, in its GS2 first message header, whether it supports
   and/or used channel binding.

   If the client sets its gs2-cb-flag == "y" and the server can do CB
   then authentication fails.

   Note that the two mechanism scheme does not imply any changes to the
   SASL APIs that weren't already implied by the pure SASL SCRAM.  The
   client and server SASL APIs require two additional application
   inputs: a) whether the application and TLS stack support channel
   binding, b) channel binding data from TLS.

ANALYSIS:

 - With regards to the GS2 first client message header:

    - The RFC2743 section 3.1 initial context token header compression
      flag would not be needed for a pure SASL SCRAM.  But it's only a
      constant for SCRAM, therefore it's not a problem.  I believe we
      have consensus on this.

    - The authzid would be lifted out of SCRAM and into the GS2 header.
      This neither adds nor removes complexity and so should not, I
      think, be objectionable.

    - The channel binding flag would be needed inside a pure SASL SCRAM
      anyways, therefore, I think, it should not be objectionable.

 - With regards to the two mechname + gs2-cb-flag approach to negotiable
   channel binding:

    - Client apps that don't negotiate SASL mechs can't negotiate
      channel binding -- they can try it, and authentication will fail
      if the server can't do CB (the client can always re-try).

    - Kurt prefers this approach to doing the negotiation in the mech

    - Chris had comments, but I think those are now satisfied.

    - Jeff and I believe this approach is simple enough.  We can't make
      CB negotiation in GS2 any simpler.  I believe Sam and Simon agree.

    - We need input from the rest of the SASL WG on this.  This is the
      last open issue for the new GS2 design.

Nico
--

---

From: Simon Josefsson <[email-masked]>
Date: Tue, 17 Mar 2009 12:16:01 +0100

> everything together again.

Good summary!

I have one question/observation about GS2 for non-SCRAM mechanisms and

>       constant for SCRAM, therefore it's not a problem.  I believe we

If a server advertise a GS2 SASL mech, that doesn't have a "simple"
name, GS2 clients (that use a GSS-API library) will need to iterate over
all the GSS-API mechanisms supported by the GSS-API library, and compute
the generated SASL mech name and compare that with the server mech list
before it knows whether it supports an offered mechanism or not.  Is my
understanding right?  It seems somewhat sub-optimal, but I don't see how
we can avoid it.

To avoid this, it seems another GSS-API function such as
GSS_Inquire_mech_for_SASLname that return a mech OID for a given SASL
name, is needed.  Thoughts on whether this is worthwhile?

>  - With regards to the two mechname + gs2-cb-flag approach to negotiable
...
>     - Kurt prefers this approach to doing the negotiation in the mech

I prefer it as well.  Sub-negotiation adds complexity.

>       CB negotiation in GS2 any simpler.  I believe Sam and Simon agree.

As far as I understand so far, I agree fully.

Thanks,
/Simon

---

From: Nicolas Williams <[email-masked]>
Date: Tue, 17 Mar 2009 10:02:08 -0500

> > everything together again.

Thanks!

> name, is needed.  Thoughts on whether this is worthwhile?

Sure.

BTW, the RFC2743 header compression constant could even be removed in
the case of SCRAM (since the CB flag will make it unabiguously clear
that the header compression flag had to have the sense that indicates
that the RFC2743 header should have been present).  I.e., the ABNF for
the GS2 header could be:

gs2-header = [ "F" ] ( "n" / "y" / "p" ) [ "a=" saslname ] ","

> I prefer it as well.  Sub-negotiation adds complexity.

I agree in general.  In this specific case I'm not sure your comment
about complexity applies, but I prefer it in this specific case as well.

> As far as I understand so far, I agree fully.

Thanks.

Nico
--

---

From: Jeffrey Hutzelman <[email-masked]>
Date: Tue, 17 Mar 2009 13:15:16 -0400

> name, is needed.  Thoughts on whether this is worthwhile?

You could have such a function, but it wouldn't be any more efficient than 
iterating over all of the mechanisms and computing the generated names, 
since a hash function is used in the name generation.

---

From: Nicolas Williams <[email-masked]>
Date: Tue, 17 Mar 2009 12:16:34 -0500

> since a hash function is used in the name generation.

But it'd be a libgss implementation detail (it can cache the computed
names, persistently even).  It's a utility function, and there's no
reason not to have it (we should also have an _init/_update/_final
variant of gss_pseudo_random() -- can't believe we didn't do that).

---

From: Alexey Melnikov <[email-masked]>
Date: Sat, 21 Mar 2009 08:33:35 -0700

Nico,
This is a good summary, thanks for doing it.

>   binding, b) channel binding data from TLS.
One side question: are we reasonably sure that TLS CB is going to be the 
only CB-type we will use in a foreseeable future?

---

From: Nicolas Williams <[email-masked]>
Date: Sat, 21 Mar 2009 12:59:31 -0500

> only CB-type we will use in a foreseeable future?

In my summary I mentioned TLS specifically, but really, the APIs
shouldn't care what kind of channel it is -- they need the channel
binding type and data.

As to your question: given the SASL apps we have now, yes.  Eventually
we'll have IPsec channel binding too.