Subject: Re: What am I waiting on for gs2?

From: Simon Josefsson <[email-masked]>
Date: Thu, 20 Dec 2007 15:09:14 +0100

Sam Hartman <[email-masked]> writes:

>>>>>> "Sam" == Sam Hartman <[email-masked]> writes:
>
>>>>>> "Simon" == Simon Josefsson <[email-masked]> writes:
>
>     Simon> Sam Hartman <[email-masked]> writes:
>     >>> I seem to have dropped the ball on gs2.  What if anything am I
>     >>> waiting on to align with RFC 5056?
>     >>> 
>     >>> Were the other issues all resolved?
>
>     Simon> As far as I understood, the concern you raised was that GS2
>     Simon> had to supply two fields for the channel binding prefix and
>     Simon> the channel binding data, which was not how I had
>     Simon> understood the channel-binding document.  The
>     Simon> channel-binding document was changed to prefix all data
>     Simon> with the unique prefix, I think.  Thus no change would be
>     Simon> needed for GS2.
>
> Simon, I reviewed the changes and I believe that there is one open
> issue.
>
> The channel binding spec requires applications know about channel
> binding failure.  You added text passing this requirement along, but I
> don't see how your protocol allows the client to detect channel
> binding failure.
>
> We have c->m->s where m is a passive man in the middle that joins the
> TLS stream.  So, the channel bindings are different.  C sends the
> gss_wrap to s using the same qop for channel binding and non-channel
> binding.
> How does s indicate to c that the channel binding from s's standpoint is not the same as what it received from c?
>
> I think you need a bit (possibly as a flag bit xored in with the qop)
> to indicate this.

FYI, I had interpreted the requirement in RFC 5056:

   o  Authentication frameworks and mechanisms that support channel
      binding MUST communicate channel binding failure to applications.

to mean that implementations must let the local applications know about
the situation.  That allows them to abort the connection depending on
local policy.  I didn't read that to mean that protocols are required to
notify the other side of the situation.  The latter requirement is
stronger than the former.  I must admit that I don't see why the
stronger requirement is a useful one.

I have applied the patch below to address your concern.  Updated
document:

http://josefsson.org/sasl-gs2/draft-ietf-sasl-gs2.txt

Changes since the last version:

http://josefsson.org/sasl-gs2/draft-ietf-sasl-gs2-from--09.diff.html

As always, general information available from:

http://josefsson.org/sasl-gs2/

I'll submit this to the IETF in a few days unless there are comments.

/Simon

@@ -802,11 +802,11 @@
    no security layer and instead depend on the session security afforded
    by the bound-in channel.
 
-   In order to accomodate the requirement in [16] "Authentication
+   In order to accomodate the requirement in [8] "Authentication
    frameworks and mechanisms that support channel binding MUST
    communicate channel binding failure to applications" implementations
-   MUST provide a way to communicate channel binding failures to
-   applications.
+   assert bit 7 in the security layer bitmask (see Section 9) on
+   negotiation failures.
 
    Use of no SASL security layers in combination with channel binding
    should provide better performance than using SASL security layers
@@ -1087,7 +1087,8 @@
       token.
 
    o  Local policy reject the attempt.  For example, client and server
-      can't agree on qop proposal.
+      can't agree on qop proposal, or channel binding negotiation
+      failed.
 
    o  (server-side) Authorization of client principal (i.e., src_name in
       GSS_Acecpt_sec_context) to requested authzid failed.
@@ -1195,6 +1195,13 @@
    "server_qop" MUST verify that it corresponds to an acceptable
    security level.
 
+   Whether the channel binding negotiation is successful or not may
+   influence the security layer selection.  Bit 7 is used to signal
+   failed channel binding negotiation.  Implementations MUST set the bit
+   if channel bindings were provided from the other end and a local
+   channel binding is absent or not equal.  Implementation MUST clear
+   the bit otherwise.
+
    The security layers and their corresponding bit-masks are as follows:
 
      1 No security layer
@@ -1202,6 +1209,7 @@
        Sender calls GSS_Wrap with conf_flag set to FALSE
      4 Confidentiality protection.
        Sender calls GSS_Wrap with conf_flag set to TRUE
+     7 Channel binding negotiation failed.
 
    Other bit-masks may be defined in the future; bits which are not
    understood MUST be negotiated off.
@@ -1530,6 +1530,9 @@
    responses.  This is a generic design critera for the GSS-API
    mechanisms used under GS2.
 
+   GS2 permits channel binding negotiation to fail.  Implementation may
+   have a local policy to reject authentication attempts in this case.
+
    When a server or client supports multiple GSS-API mechanisms, each of
    which has a different security strength, it is possible for an active
    attacker to cause a party to use the least secure mechanism

---

From: Simon Josefsson <[email-masked]>
Date: Thu, 20 Dec 2007 15:42:56 +0100

> +     7 Channel binding negotiation failed.

That was incorrect.  I've fixed this (same URL as before), and also
fixed the bitmask examples to have the bit numbers in the reverse order.

/Simon

     1    No security layer.
     2    Integrity protection.
           Sender calls GSS_Wrap with conf_flag set to FALSE.
     4    Confidentiality protection.
           Sender calls GSS_Wrap with conf_flag set to TRUE.
     8-64 Reserved.
     128  Channel binding negotiation failed.
...
   When confidentiality is negotiated, and channel binding negotiation
   failed, the octet will encode an integer 128+4=132 as follows.

       7 6 5 4 3 2 1 0
      +-+-+-+-+-+-+-+-+
      |1|0|0|0|0|1|0|0|
      +-+-+-+-+-+-+-+-+

---

From: Sam Hartman <[email-masked]>
Date: Thu, 20 Dec 2007 10:09:47 -0500

>> The channel binding spec requires applications know about
    >> channel binding failure.  You added text passing this
    >> requirement along, but I don't see how your protocol allows the
    >> client to detect channel binding failure.
    >> 
    >> We have c->m->s where m is a passive man in the middle that
    >> joins the TLS stream.  So, the channel bindings are different.
    >> C sends the gss_wrap to s using the same qop for channel
    >> binding and non-channel binding.  How does s indicate to c that
    >> the channel binding from s's standpoint is not the same as what
    >> it received from c?
    >> 
    >> I think you need a bit (possibly as a flag bit xored in with
    >> the qop) to indicate this.

    Simon> FYI, I had interpreted the requirement in RFC 5056:

    Simon>    o Authentication frameworks and mechanisms that support
    Simon> channel binding MUST communicate channel binding failure to
    Simon> applications.

    Simon> to mean that implementations must let the local
    Simon> applications know about the situation.  That allows them to
    Simon> abort the connection depending on local policy.  I didn't
    Simon> read that to mean that protocols are required to notify the
    Simon> other side of the situation.  The latter requirement is
    Simon> stronger than the former.  I must admit that I don't see
    Simon> why the stronger requirement is a useful one.

Hmm.  You may be right that I was reading more into RFC 5056 than is
actually there.  In GS2 I'd prefer that we do indicate channel binding
failure back because we don't generally want people to abort at least
if they are willing to use a security layer instead.

However if the WG doesn't have consensus behind this change then it
should be backed out.

---

From: Nicolas Williams <[email-masked]>
Date: Thu, 20 Dec 2007 09:48:56 -0600

> stronger requirement is a useful one.

Your interpretation of that requirement is correct.  The stronger
requirement perhaps should have been included.  I think Sam and I never
settled the issue of the Kerberos V GSS mechanism's initiator not having
any idea of whether the server checked or ignore channel bindings when
the server returns and AP-REP token.  Sam?

---

From: Nicolas Williams <[email-masked]>
Date: Thu, 20 Dec 2007 09:59:35 -0600

> However if the WG doesn't have consensus behind this change then it

I'd rather see that bit in the client/server's second wrap token, yes.

---

From: Simon Josefsson <[email-masked]>
Date: Thu, 20 Dec 2007 17:52:18 +0100

> if they are willing to use a security layer instead.

Right.  I think that was already possible, given:

   Note that "client_qop" and "server_qop" MAY indicate a quality of
   protection that was not offered by the server and client,
   respectively.  This SHOULD only be used when the server or client
   (respectively) would otherwise fail the entire authentication
   exchange.  The server/client that receives a "client_qop"/
   "server_qop" MUST verify that it corresponds to an acceptable
   security level.

When deciding whether to permit this or not, it can be useful to know
whether the other side made this choice because of a failed QOP or not.
That isn't possible with -09, and your suggestion fixes it.

It is not possible to verify the chosen QOP against *_qops and *_cbqops
unless you know whether channel binding negotiation was successful or
not.  In -09, you could only verify the chosen QOP against the logical
OR between *_qops and *_cbqops, which is sub-optimal.  Your suggestion
fixes this.

> However if the WG doesn't have consensus behind this change then it

I support the change below.  Others?

/Simon

--- 1/draft-ietf-sasl-gs2-09.txt	2007-12-20 16:30:00.000000000 +0100
+++ 2/draft-ietf-sasl-gs2.txt	2007-12-20 16:30:00.000000000 +0100
@@ -564,25 +564,25 @@
    channel bindings do not match.
 
    Client and servers MUST set the "chan_binding" parameter in the calls
    to GSS_Init_sec_context and GSS_Accept_sec_context, respectively, to
    NULL.
 
    Implementations SHOULD set the "client_cbqops" and "server_cbqops" to
    no security layer and instead depend on the session security afforded
    by the bound-in channel.
 
+   assert a bit in the security layer bitmask (see Section 9) on
+   negotiation failures.
 
    Use of no SASL security layers in combination with channel binding
    should provide better performance than using SASL security layers
    over secure channels, and better security characteristics than using
    no SASL security layers over secure channels without channel binding.
 
    For more discussions of channel bindings, and the syntax of the
    channel binding data for various security protocols, see [8].  For
    easy reference, the channel binding format used for The Transport
    Layer Security (TLS) Protocol [14] is specified in [16].
@@ -749,21 +749,22 @@
 
    o  GSS_Unwrap() returns anything other than GSS_S_COMPLETE.  (There
       can't be supplementary status codes in GS2 at this point, so any
       indications of out of order processing or replays is fatal.)
 
    o  The token returned from GSS_Unwrap fail to parse correctly (e.g.,
       too short, invalid maximum buffer size) as the expected Wrap
       token.

 
 8.  GSS-API Parameters
 
    The implementation MAY set any GSSAPI flags or arguments not
    mentioned in this specification as is necessary for the
    implementation to enforce its security policy.
 
@@ -778,63 +779,80 @@
    layer.
 
    Note that "client_qop" and "server_qop" MAY indicate a quality of
    protection that was not offered by the server and client,
    respectively.  This SHOULD only be used when the server or client
    (respectively) would otherwise fail the entire authentication
    exchange.  The server/client that receives a "client_qop"/
    "server_qop" MUST verify that it corresponds to an acceptable
    security level.
 
+   Whether the channel binding negotiation is successful or not may
+   influence the security layer selection.  The most significant bit is
+   used to signal failed channel binding negotiation.  Implementations
+   MUST set the bit if channel bindings were provided from the other end
+   and a local channel binding is absent or not equal.  Implementation
+   MUST clear the bit otherwise.
+
    The security layers and their corresponding bit-masks are as follows:
 
-     1 No security layer
+     1    No security layer.
      2 Integrity protection.
-       Sender calls GSS_Wrap with conf_flag set to FALSE
+           Sender calls GSS_Wrap with conf_flag set to FALSE.
      4 Confidentiality protection.
-       Sender calls GSS_Wrap with conf_flag set to TRUE
+           Sender calls GSS_Wrap with conf_flag set to TRUE.
+     8-64 Reserved.
+     128  Channel binding negotiation failed.
 
-   Other bit-masks may be defined in the future; bits which are not
-   understood MUST be negotiated off.
+   The bit-masks 8-64 are reserved and may be defined in the future;
+   bits which are not understood MUST be negotiated off.
 
    When decoding any received data with GSS_Unwrap the major_status
    other than the GSS_S_COMPLETE MUST be treated as a fatal error.
 
    For integrity and confidentiality protection, GS2 negotiates the
    maximum size of the output_message to send.  Implementations can use
    the GSS_Wrap_size_limit call to determine the corresponding maximum
    size input_message.
 
 9.1.  Examples
 
    When no security layer is negotiated the octet will encode an integer
    1 as follows.
 
-       0 1 2 3 4 5 6 7
+       7 6 5 4 3 2 1 0
       +-+-+-+-+-+-+-+-+
       |0|0|0|0|0|0|0|1|
       +-+-+-+-+-+-+-+-+
 
    When integrity is negotiated the octet will encode an integer 2 as
    follows.
 
-       0 1 2 3 4 5 6 7
+       7 6 5 4 3 2 1 0
       +-+-+-+-+-+-+-+-+
       |0|0|0|0|0|0|1|0|
       +-+-+-+-+-+-+-+-+
 
-   When confidentiality is negotiated the octet will encode an integer 4
-   as follows.
+   When confidentiality is negotiated, and channel binding negotiation
+   failed, the octet will encode an integer 128+4=132 as follows.
 
-       0 1 2 3 4 5 6 7
+       7 6 5 4 3 2 1 0
       +-+-+-+-+-+-+-+-+
-      |0|0|0|0|0|1|0|0|
+      |1|0|0|0|0|1|0|0|
+      +-+-+-+-+-+-+-+-+
+
+   When a bitmask that indicates that all security layers are
+   acceptable, the octet will encode an integer 1+2+4=7 as follows.
+
+       7 6 5 4 3 2 1 0
+      +-+-+-+-+-+-+-+-+
+      |0|0|0|0|0|1|1|1|
       +-+-+-+-+-+-+-+-+
 
 10.  Non-integrity capable GSS-API mechanisms
 
    Mechanisms that do not support integrity can be used with GS2, but
    some security features cannot be provided, in particular including
    channel bindings, security layers, and integrity protection of the
    authorization identity.
 
    Channel bindings and security layers MUST NOT be negotiated when the
@@ -955,20 +973,23 @@
    GSS-API mechanism widely on the Internet that do not support
    integrity.
 
    Because the negotiation of a particular GSS-API mechanism may be done
    in the clear, it is important for the GSS-API mechanisms to be
    designed such that an active attacker cannot obtain an authentication
    with weaker security properties by modifying the challenges and
    responses.  This is a generic design critera for the GSS-API
    mechanisms used under GS2.
 
+   GS2 permits channel binding negotiation to fail.  Implementation may
+   have a local policy to reject authentication attempts in this case.
+
    When a server or client supports multiple GSS-API mechanisms, each of
    which has a different security strength, it is possible for an active
    attacker to cause a party to use the least secure mechanism
    supported.  This problem and a solution is discussed in section 6.1.2
    of [2], but some additional methods to mitigate the problem include:
 
    1.  Use of an integrity protected transport, such as TLS [14].  To
        protect against certain tunnel attacks [18], channel bindings
        need to be used.

---

From: Nicolas Williams <[email-masked]>
Date: Thu, 20 Dec 2007 10:55:03 -0600

> I'd rather see that bit in the client/server's second wrap token, yes.

We almost already have it.  Since the last wrap token carries the
selected security layer, and that selection is derived from channel
binding success/failure.  Of course, if a given mechanism does not
support confidentiality protection but the underlying channel does and
channel binding failes then we need a way to signal this.  So, yes, I
think we need one more bit in the client/server's last wrap token for
this.