Subject: [Ietf-krb-wg] Channel bindings -- interop issue with GSS_C_AF_* choices?

From: Thomas Maslen <[email-masked]>
Date: Tue, 7 Jun 2011 04:49:38 +0000

[This may be a more generic kitten issue, but at present it manifests itself most clearly in the Kerberos mechanism, so I'm starting out here in krb-wg].

Looking at RFC 5554 and its friends (2743, 2744, 4121, ye olde 1964), it seems to me that there are two scenarios where the proper values for initiator-address-type (and acceptor-address-type) are underspecified and may lead to interop problems between implementations.

The first issue -- how to represent an IPv6 address in a channel binding -- was discussed in 2009 in this kitten thread

    http://www.ietf.org/mail-archive/web/kitten/current/msg01594.html

and the general opinion seemed to be that the issue is moot because addresses in channel bindings were a mistake and these days you should pretty much always be using addressless channel bindings.

So, onward to the second issue:

In an addressless channel binding, what is the correct address-type value to use?  Is it 0 (GSS_C_AF_UNSPEC), or is it 255 (GSS_C_AF_NULLADDR)?

The GSS_C_AF_NULLADDR camp seems to include:

    The Java GSSAPI implementation in Java SE from Sun / Oracle  (I haven't checked IBM's implementation)

    The Java GSSAPI implementation from the company that I work for

    The "Oracle Solaris Security for Developers Guide":

        http://download.oracle.com/docs/cd/E19253-01/816-4863/overview-52/index.html

        http://download.oracle.com/docs/cd/E19253-01/816-4863/reference-9/index.html

The GSS_C_AF_UNSPEC camp seems to include:

    Microsoft Windows (e.g. the channel bindings generated for SPNEGO over HTTPS)

The "could go either way" camp includes Heimdal and MIT Kerberos.

I say "could go either way" because, given how channel bindings are specified in the GSSAPI C bindings (the Java bindings are rather different), the responsibility for correctly populating the gss_channel_bindings_struct is punted to the caller, and then e.g. the MIT Kerberos kg_checksum_channel_bindings() function just happily hashes whatever address-type values the caller put in the initiator_addrtype and acceptor_addrtype fields.  If the caller diligently sets the address type to GSS_C_AF_NULLADDR (per that Solaris security documentation) then you get 255.  However, if the caller gets cute and e.g. uses malloc() or memset() to produce a gss_channel_bindings_struct initialized to all zeroes and then just sets the application_data buffer, then effectively you would end up with GSS_C_AF_UNSPEC.

So it seems to me that this is an interoperability problem for channel bindings (at least for the Kerberos mechanism), but maybe I'm missing something?
_______________________________________________
ietf-krb-wg mailing list
[email-masked]
https://lists.anl.gov/mailman/listinfo/ietf-krb-wg

---

From: Martin Rex <[email-masked]>
Date: Tue, 7 Jun 2011 18:44:11 +0200 (MEST)

Thomas Maslen wrote:
> 
> and the general opinion seemed to be that the issue is moot because
> addresses in channel bindings were a mistake and these days you should
> pretty much always be using addressless channel bindings.

This matches my personal opinion about address-based channel bindings.
They would intefere with firewall traversal, NAT-traversal and any
kind of application-level backend-internal load-balancing and
communication forwarding at protocol levels below GSS-API.

> In an addressless channel binding, what is the correct address-type
> value to use?  Is it 0 (GSS_C_AF_UNSPEC), or is it 255 (GSS_C_AF_NULLADDR)?

I'm confused.  An application that doesn't want address-based channel
bindings would likely supply GSS_C_NO_CHANNEL_BINDINGS.  Mine does.

-Martin

---

From: Thomas Maslen <[email-masked]>
Date: Tue, 7 Jun 2011 17:05:12 +0000

Martin Rex wrote:
> [...]

Sorry, I probably wasn't clear.  What I meant by "addressless channel binding"
was a channel binding where you don't want to specify initiator_address (or
acceptor_address) but you _do_ want to specify nonempty application_data
(e.g. one of the RFC 5929 types), so GSS_C_NO_CHANNEL_BINDINGS
isn't applicable.
_______________________________________________
ietf-krb-wg mailing list
[email-masked]
https://lists.anl.gov/mailman/listinfo/ietf-krb-wg

---

From: Martin Rex <[email-masked]>
Date: Tue, 7 Jun 2011 20:31:23 +0200 (MEST)

> (e.g. one of the RFC 5929 types), so GSS_C_NO_CHANNEL_BINDINGS

I've never thought about doing this, but when looking at the definition
of the constants in rfc2744 section 3.11

    http://tools.ietf.org/html/rfc2744#page-18

if you do _not_ supply addresses, i.e. gss_buffer_desc with lengths of 0,
then you should use GSS_C_AF_NULLADDR.

IMO, GSS_C_AF_UNSPEC would imply non-empty address fields other than
those currently defined.

Strange that neither rfc5929 nor rfc5056 describe how to pass
opaque (=non-address) bindings to GSS-API.

-Martin

---

From: Martin Rex <[email-masked]>
Date: Tue, 7 Jun 2011 21:00:56 +0200 (MEST)

> opaque (=non-address) bindings to GSS-API.
 
The last paragraph of rfc-2744 section 3.11 reads:

                                                  Portable applications
   should therefore ensure that they either provide correct information
   for the address fields, or omit addressing information, specifying
   GSS_C_AF_NULLADDR as the address-types.

Which is what applies to your situation.

-Martin

---

From: Thomas Maslen <[email-masked]>
Date: Tue, 7 Jun 2011 20:00:52 +0000

> > opaque (=non-address) bindings to GSS-API.

Agreed.  Perhaps RFC 5554 would be a good place.

> Which is what applies to your situation.

Mea culpa, somehow I contrived to overlook that.

However:

(1) At least one major implementation of the GSSAPI Kerberos mechanism with
TLS channel bindings -- Microsoft "Extended Protection for Authentication" -- seems
to be implicitly using GSS_C_AF_UNSPEC, not GSS_C_AF_NULLADDR.

(2) The C language binding for channel bindings makes it dangerously easy to
write code that implicitly uses GSS_C_AF_UNSPEC;  you will only end up with
the correct value (GSS_C_AF_NULLADDR) if you carefully set initiator_addrtype
and acceptor_addrtype to that value.

(3) SASL GS2 mechanisms (including, presumably, GS2-KRB5-PLUS) are
implicitly required to use GSS_C_AF_UNSPEC (RFC 5801 section 5.1,
"The initiator-address-type and acceptor-address-type [...] MUST be set to 0").

The effect of (3), I think, is that if you're using a GSSAPI mechanism as a SASL
GS2 mechanism then you must use GSS_C_AF_UNSPEC, but if you are using
a GSSAPI mechanism directly (i.e. without SASL) then you should follow 
RFC 2744 and use GSS_C_AF_NULLADDR.

Ugh.  If you are using the C language bindings then this is nasty but you can
make it work.  However, if you are using the Java language bindings then I suspect
the only way to make this work might be to have two implementations of a
GSSAPI mechanism, one for use in GS2 (using GSS_C_AF_UNSPEC to compute
the channel-binding hash) and a second one for bare nekkid GSSAPI use, per
RFC 2744 (using GSS_C_AF_NULLADDR).
_______________________________________________
ietf-krb-wg mailing list
[email-masked]
https://lists.anl.gov/mailman/listinfo/ietf-krb-wg

---

From: Nico Williams <[email-masked]>
Date: Tue, 7 Jun 2011 16:14:49 -0500

> communication forwarding at protocol levels below GSS-API.

Correct.

> bindings would likely supply GSS_C_NO_CHANNEL_BINDINGS.  Mine does.

You forget about the "application_data" field, which is where we put
the TLS (or whatever) channel bindings data.

See RFCs 5056 and 5554.  Oddly enough, I don't think we ever specified
which GSS_C_AF_* to use.  I think the right answer is: memset() the
gss_channel_bindings_struct to zero, then set the application_data
field.  In other words, GSS_C_AF_UNSPEC.

Dear KITTEN WG: do we have to update RFC5554 about this??  Or should
we file an erratum?

Nico
--

---

From: Simon Josefsson <[email-masked]>
Date: Tue, 07 Jun 2011 23:19:32 +0200

> RFC 2744 (using GSS_C_AF_NULLADDR).

If we understand how to resolve this, I think we could clarify this
aspect in GS2 with an errata.  It sounds to me that this may be
(another) instance of bad interaction between the abstract GSS-API
interface and the C bindings.  Certainly this aspect had not been clear
to me.

/Simon

---

From: Nico Williams <[email-masked]>
Date: Tue, 7 Jun 2011 16:23:48 -0500

> interface and the C bindings.  Certainly this aspect had not been clear

Perhaps all of RFCs 5056, 5554, and 5801 require a clarification or
erratum for this.

I think I never thought of this because I've always seen the RFC2744
channel bindings structure first memset() to zero then filled in...

Nico

---

From: Martin Rex <[email-masked]>
Date: Wed, 8 Jun 2011 18:02:29 +0200 (MEST)

> channel bindings structure first memset() to zero then filled in...

In retrospect, assigning GSS_C_AF_NULLADDR the code point 255
instead of 0 may have not been a good choice.  But it's been like that in
rfc-1509 (GSS-APIv1) already.

The issue we are facing now seems to be an installed base that doesn't
follow the guidance in the GSS-API (v2) spec rfc-2744 when using
address-less channel bindings.

There's little we can do at this point, besides gathering what
implementations in the installed are doing and documenting it,
filing spec amendmends through the errata process with the results.

-Martin

---

From: Sam Hartman <[email-masked]>
Date: Wed, 08 Jun 2011 12:57:07 -0400

I think RFC 2744 chose the wrong constant for nulladdr; it should have
been 0 not 255.  I think we need to update RFC 2744 and 5554.
I believe that

1) Mechanism implementations should collapse unspecified address with no
actual data and null address together

2) The Kerberos mechanism should do so in a manner compatible with
Microsoft

3) We need to explicitly specify what applications should do here.

If someone argues that we cannot make incompatible changes to 2744, I
respond that compatibility with the implementations we know about is
more important to me than compatibility with the spec and if forced to
choose I will choose the implementations.
_______________________________________________
ietf-krb-wg mailing list
[email-masked]
https://lists.anl.gov/mailman/listinfo/ietf-krb-wg

---

From: Nico Williams <[email-masked]>
Date: Wed, 8 Jun 2011 12:05:28 -0500

> been 0 not 255.  I think we need to update RFC 2744 and 5554.

I'm agnostic as to that.  I don't mind saying "must use
GSS_C_AF_UNSPEC and null addresses" and leaving RFC2744 alone.

> 2) The Kerberos mechanism should do so in a manner compatible with

Agreed, though (2) subsumes (1).

> choose I will choose the implementations.

+1

Nico

---

From: Nico Williams <[email-masked]>
Date: Wed, 8 Jun 2011 12:16:30 -0500

Another possibility is that we fix only RFC5554 to say that when null
addresses are provided then the address families must be a specific
one and that mechanisms must coerce those to that one specific family
if the application supplied the wrong one.  We then need only
determine which one Windows is using now.

Nico

---

From: Thomas Maslen <[email-masked]>
Date: Wed, 8 Jun 2011 17:38:36 +0000

Nico Williams wrote:
>
> [...] We then need only determine which one Windows is using now.

My understanding -- based both on some Microsoft documentation and on
tweaking our implementation to validate a CB hash generated by a Windows
HTTPS-SPNEGO client -- is that Microsoft does exactly the same thing that
you specified in RFC5801:  set the address-type to zero (and of course the
address-length is also zero).

And I agree with Sam + you:  we shouldn't break Microsoft's implementation,
nor should we break RFC5801.  Instead we should update RFC2744 /
RFC5554 / whatever to use 0, not 255, as the address-type for omitted addresses.
_______________________________________________
ietf-krb-wg mailing list
[email-masked]
https://lists.anl.gov/mailman/listinfo/ietf-krb-wg

---

From: Nico Williams <[email-masked]>
Date: Wed, 8 Jun 2011 12:44:23 -0500

> address-length is also zero).

Thanks, this is great information.

> RFC5554 / whatever to use 0, not 255, as the address-type for omitted addresses.

RFC5554 is basically an update to RFC2743 adding to the abstract API
what RFC2744 had effectively done.  So I think an update or erratum to
RFC5554 will suffice.  An erratum to RFC2744 would not hurt though.
_______________________________________________
ietf-krb-wg mailing list
[email-masked]
https://lists.anl.gov/mailman/listinfo/ietf-krb-wg

---

From: Martin Rex <[email-masked]>
Date: Wed, 8 Jun 2011 21:50:46 +0200 (MEST)

> choose I will choose the implementations.

In case I my messages were conceived as ambiguous:

I'm OK with updating the relevant specs to formally allow _and_ document
what the current installed base is doing, for all of the specs that
we know about.

Changing rfc2744 in a backwards incompatible fashion would be a bad idea,
but I don't think that is necessary.  Relaxing rfc-2744 should be
sufficient.

Two things should go into rfc-2744.

- We need to allow taggging an absent address
  (i.e. OctetString of size zero) with GSS_C_AF_UNSPEC(0).
  The current wording of rfc-2744 implies that absent address data
  needs to be tagged with GSS_C_AF_NULLADDR(255).

- We need to document which specs are going to require
  GSS_C_AF_UNSPEC(0) with absent network addresses and
  non-empty application_data channel bindings to match actual
  implementation practice and for interoperability with the
  installed base of that specs.

-Martin