Subject: Or: simplifying GS2 (Re: Poll: pure SCRAM versa SCRAM-as-GS2)

From: Nicolas Williams <[email-masked]>
Date: Tue, 17 Feb 2009 16:44:16 -0600

Perhaps we can just simplify GS2 enough that all concerns go away.

The primary differences between the GSS-API and SASL:

a) one is message-oriented (GSS), the other is stream-oriented (SASL);

b) SASL client apps must send the name of the mech being used before
   using it, while the GSS-API includes the "name" of the selected mech
   in the first authentication message;

c) SASL authentication message exchanges negotiate what security layers
   will be used and maximum message sizes; the GSS-API does no such
   negotiations;

d) the GSS-API has channel binding, but it's all or nothing, and it's
   optional; SASL has never had channel binding.

e) terminology :)

(a) is easy to address in a SASL/GSS bridge.
(b) is easy to address in a SASL/GSS bridge.
(c) is easy to addres by replacing security layers with channel binding
    to TLS, which has the added advantage of simplifying mechanisms and
    making (a) not matter.
(d) matters only if we want channel binding in SASL, and I think we long
    ago agreed we did, and if we re-open that question I believe we'll
    again conclude that we want it.
(e) we can ignore :)

So what makes GS2 not simple?  The fact that we chose to make the GS2
channel binding semantics different from the GSS-API's: we chose to make
channel binding success/failure affect the negotiation of security
layers.

If we reconsider that one choice we could simplify GS2 enough that a
single specification of SCRAM-as-a-GSS-API mechanism will satisfy all.

Nico
--

---

From: Jeffrey Hutzelman <[email-masked]>
Date: Wed, 18 Feb 2009 17:17:19 -0500

>     to TLS, which has the added advantage of simplifying mechanisms and

I'm certainly willing to do this.

> single specification of SCRAM-as-a-GSS-API mechanism will satisfy all.

Personally, I'm fine with saying that channel binding must succeed if the 
application provided bindings.  Does anyone recall the use case for 
allowing CB to fail and falling back to a security layer even in the 
presence of a channel?

-- Jeff

---

From: Nicolas Williams <[email-masked]>
Date: Wed, 18 Feb 2009 16:17:52 -0600

> I'm certainly willing to do this.

Me too, as is Chris Newman (I checked with him off-line).

> allowing CB to fail and falling back to a security layer even in the 

I don't recall, but it'd sure simplify everything.

Nico
--

---

From: Alexey Melnikov <[email-masked]>
Date: Thu, 19 Feb 2009 11:49:34 +0000

>   in the first authentication message;
This might be a minor detail, but if understand correctly, GSS-API is 
using OIDs for naming, while SASL typically doesn't.

>(b) is easy to address in a SASL/GSS bridge.
I am not entirely sure what you call "bridge" in this case, but I tend 
to agree with your conclusion ;-).

>    to TLS,
As a side note: we shouldn't be requiring TLS to be the only channel 
binding, even though we can recommend it.

>which has the added advantage of simplifying mechanisms and
>    making (a) not matter.
>  
>
Agreed.
I think draft-newman-auth-scram-gs2-00.txt already made the same choice.

>    again conclude that we want it.
Agreed.

>(e) we can ignore :)
I think this is mostly an editorial issue, which might require quite a 
bit of work.
But I agree it should be ignored for now.

>single specification of SCRAM-as-a-GSS-API mechanism will satisfy all.
I agree that would make GS2 simpler, but I am not convinced that that 
would be enough to make SCRAM-as-GS2 satisfy Chris Newman's requirement 
on simplicity. But anyway, I am willing to participate and see what the 
result would be.

I think the extra complexity lies is the need to have authorization 
identity separate from the rest of SCRAM data (because it is transported 
by GS2 itself), this requires an extra hash for protecting it. The same 
applies to the channel binding data, but your proposal above addresses 
this to some extend.

---

From: Alexey Melnikov <[email-masked]>
Date: Thu, 19 Feb 2009 12:03:53 +0000

Jeffrey Hutzelman wrote:

> Personally, I'm fine with saying that channel binding must succeed if 
> the application provided bindings.

What should happen if the other end can't verify them, because it has no 
API for doing that?
I think this is going to be a very real problem in short to medium term, 
because TLS APIs suck (or undocumented, which is close to being the same 
thing).

So, I am Ok with the following semantics: if a channel bind is provided 
by one end and can be verified by the other end, then any failure to 
verify it causes authentication failure, but if the other end doesn't 
have the ability to verify channel bindings, then ignoring them is fine.

> Does anyone recall the use case for allowing CB to fail and falling 
> back to a security layer even in the presence of a channel?

I can see a marginal advantage of falling back to a security layer in 
such case, but it might be just simpler to either ignore channel 
bindings and not have a security layer, or to always negotiate a 
security layer irrespective of providing channel bindings.

---

From: Jeffrey Hutzelman <[email-masked]>
Date: Thu, 19 Feb 2009 09:50:22 -0500

> What should happen if the other end can't verify them, because it has no

The purist in me says "get a better TLS implementation".

The part of me that backports security fixes to OpenSSL 0.9.7 because 
upgrading would be more pain than I have time for recognizes that that is 
probably still impractical.

> have the ability to verify channel bindings, then ignoring them is fine.

I would be OK with that, too, provided we're talking about the behavior 
depending on whether or not the application passed channel binding 
information down through SASL.  Thus, the question of whether to use 
channel bindings remains with the application, and individual applications 
can either require that channel bindings be used all the time or allow them 
to be skipped under some circumstances.

Unfortunately, this doesn't actually work in both directions.  A GSS-API 
acceptor can decide whether to pass channel binding information down to the 
mechanism, but it must make that decision before it has any way of knowing 
whether the initiator sent any.  If the initiator provides channel bindings 
but the acceptor does not, then the context might be established 
successfully, depending in part on the mechanism and possibly on the 
particular mechanism implementation.  If the acceptor provides channel 
bindings and the initiator does not, context establishment will fail.

What Nico is trying to do is propose that we simplify GS2 significantly by 
declaring that its channel binding failure semantics are exactly the same 
as those of GSS-API.  This allows GS2 channel bindings to be provided using 
those of the underlying GSS-API mechanism, rather than as a separate GSS 
MIC token which, depending on the mechanism, may require an extra round 
trip.  It simplifies things considerably by making GS2 into a much thinner 
wrapper.

I cannot think of any way to provide the semantics you describe (in which 
channel binding must succeed, but only if both ends provide data) for all 
GS2 mechanisms without retaining the complexity Nico is trying to remove. 
However, I think we _can_ provide that behavior for SCRAM, or for any other 
particular GSS-API mechanism, by specifying that the mechanism verifies 
channel bindings only if data is provided by both ends.  Whether we 
_should_ do that is another question entirely.

Excuse me for a moment while I delve a bit deeper into GSS-API specifics...

It seems to me that we could define a mechanism property which indicates 
that the mechanism handles channel bindings as described above, verifying 
them only when provided by both initiator and acceptor.  SCRAM would have 
this feature, and GS2 would be defined to make use of the feature when it 
is available (as determined by extended mechanism inquiry), and implement 
GS2 channel bindings in terms of GSS MIC tokens when it is not.  This would 
have the effect of keeping GS2+SCRAM simple while allowing GS2+RFC4121 to 
have the desired channel binding semantics even though Kerberos does not.

Possibly, we'd want to invent a new acceptor API, to allow an acceptor to 
indicate whether it wants to use this functionality or not.  I'd prefer to 
avoid this, because it would delay both GS2 and SCRAM, since they would 
notionally actually have to use the new interface (it wouldn't delay 
_implementaton_ of pure-SASL SCRAM, though).

> such case, but it might be just simpler to either ignore channel bindings
> and not have a security layer, or to always negotiate a security layer
> irrespective of providing channel bindings.

Yeah, I think the question of whether to negotiate a security layer ought 
to be independent of whether channel bindings succeed.  IMHO the simplest 
way to do this is to declare that neither GS2 nor SCRAM provides security 
layers, and that SASL applications ought to use TLS (or some other 
appropriate channel) and channel bindings.

-- Jeff