Subject: tcp-expansion issues

From: Jeffrey Hutzelman <[email-masked]>
Date: Fri, 01 Sep 2006 21:08:38 -0400

In the process of preparing my writeup of the TCP expansion mechanism to go 
to the IESG, I found several issues that need to be resolved before this 
document can move forward.  The two most significant issues relate to ways 
in which the protocol is underspecified such that interoperability might be 
difficult to achieve.  I have proposed solutions to these problems as well 
as a couple of enhancements, and would like to see discussion from the 
working group as to how we should proceed.

-- Jeff

(1) The use of extensions is indicated by the high bit in the request
    length field, and in that case, the remaining bits indicate what
    extensions are in use.  However, there is no description of what
    should follow this initial 32-bit value.  That means that if a client
    requests an unsupported extension, there is no way for the KDC to
    determine how much data to ignore before reading the client's next
    request.

    I would suggest some combination of the following changes:

    a) Follow the extension request field with another 32-bit value,
       indicating the number of octets of extension data (which may
       be zero), followed by that many octets of data.

    b) Follow the extension data by a normal Kerberos request with a
       request length (high bit must be clear) and data.  In the case
       where the requested extension is not associated with any request,
       the request length can be zero.

    c) Allow for more than 31 extensions by allowing the extension
       request field to span multiple 32-bit fields, each with the
       high bit set.  Then the first field with the high bit clear is
       the extension-length field described in (a).  In the case of a
       PROBE, the client sends as many fields of 0x80000000 as needed
       to represent the extensions it is interested in (followed by two
       fields of 0x00000000 (extension-length and request-length); the
       KDC responds with exactly the same number of extension-request
       fields as were sent by the client.

    Note that the KDC's reply need not follow the same structure; the
    set of extensions requested can determine whether extension data is
    needed in the reply, whether an explicit length is needed, and
    whether the KDC also sends a Kerberos message (with length).

    I believe that (1a) or some alternate solution is required for this
    document to move forward.  I think (1b) and (1c) are good ideas, but
    they are not essential; the approach taken by the current document
    (reserve an extension bit for future expansion, and (apparently) do
    not include a normal Kerberos message with an extension request) are
    also acceptable.

(2) The KDC's reply to a PROBE or to an unsupported extension request is
    well-defined: it returns a 32-bit field indicating what extensions it
    supports.  According to section 4 of this draft taken together with
    section 7.2.2 of RFC 4120, a KDC not supporting this mechanism can
    be expected to send a KRB-ERROR message and/or close the connection.
    A KRB-ERROR message would be preceeded by a length field (with the
    high-order bit clear).

    So, it is easy to determine from a PROBE what extensions are supported
    by a KDC.  Either the KDC supports the extension method and will send
    a 32-bit value with the high-bit set, or it does not and will do
    something else.

    However, it is not so easy to determine what is going on when a client
    requests an extension (that is, sends a value with the high bit set
    other than a PROBE).  If the KDC supports the extension, then its reply
    needs to be distinguishable from an unsupported-extension reply, which
    presumably means it needs to start with a 32-bit value whose high bit
    is clear.  However, such a value is indistinguishable from that which
    would be sent by an RFC4120-compliant KDC which does not understand the
    extension method (i.e. the length of a KRB-ERROR reply).  This is bad.

    To remedy this problem, I would recommend the following change:

    a) The response to a PROBE remains as before - a 32-bit field with
       the high bit set and the remaining bits indicating which extensions
       are supported by the KDC.

    b) The response to an extension request specifying an unsupported
       extension or combination of extensions is 0x80000000; that is, a
       value with the high bit set and no others.

    c) The response to an extension request specifying a supported
       extension or combination of extensions consists of a 32-bit value
       whose high bit is set and whose remaining bits represent some
       nonzero value, followed by any additional data required by the
       negotiated extensions.  IMHO, the "nonzero" value should be used
       to indicate which of the requested extensions are accepted by the
       KDC; this would allow extensions to be specified such that in some
       cases the KDC has the freedom to accept some extensions and reject
       others.

    d) The response to any extension request MAY be a KRB-ERROR, preceded
       as usual by a 32-bit length value with the high bit clear.  This is
       the expected response from KDC's which do not support the extension
       mechanism (followed by closing the connection).

    e) If (1c) above is adopted, then the PROBE response would include as
       many 32-bit fields as requested by the client.  Responses in cases
       (b) and (c) could be defined either to use a single field or the
       same number used by the client.

    An alternative solution is acceptable, but it must be possible for
    clients to reliably distinguish between a KDC supporting the requested
    extension(s), a KDC rejecting the requested extension(s), and a KDC
    which does not support the extension method at all.

(3) IMHO, the last paragraph of section 3 should explicitly allow for the
    case where the successful negotiation of an extension replaces the
    protocol running over the TCP connection with something different,
    such as TLS or some alternative framing.

(4) The security considerations notes that an attacker can force a downgrade
    by making it appear that one peer does not support the extension method.
    It should also note that an attacker can interfere with the negotiation
    of which extensions are supported, which may also result in downgrade.

---

From: Simon Josefsson <[email-masked]>
Date: Wed, 06 Sep 2006 14:05:13 +0200

Jeffrey Hutzelman <[email-masked]> writes:

> In the process of preparing my writeup of the TCP expansion mechanism
> to go to the IESG, I found several issues that need to be resolved
> before this document can move forward.  The two most significant
> issues relate to ways in which the protocol is underspecified such
> that interoperability might be difficult to achieve.  I have proposed
> solutions to these problems as well as a couple of enhancements, and
> would like to see discussion from the working group as to how we
> should proceed.

Thank you for the constructive feedback!

>    determine how much data to ignore before reading the client's next

Let me explain how I intended the protocol to work, because I believe
that will solves this problem.  I agree that the document may not have
been completely clear on how I intended it to work, and the
description could be improved.  We can then discuss whether my
intended behaviour is the best possible idea or not, and possibly use
one of your ideas instead.

The intention was that, after sending the first 32-bit value, the
client waits for the server to respond.  The problem you bring up that
the KDC doesn't know how much data to ignore then is a non-issue.  The
KDC doesn't ignore any data at all, because the client doesn't send
any.

After the client has sent 4 bytes, and no more than 4 bytes, it is
possible to determine if the KDC follows RFC 4120 or this extension
mechanism, by looking at the response from the KDC.

If the KDC follows RFC 4120, it will send a KRB_ERR_FIELD_TOOLONG
error and close the connection.

If the KDC supports this extension mechanism, there are three cases to
consider.

First is if the request is a PROBE, then the KDC respond with a
bit-field (high bit set) indicating what it supports, and wait for the
client to send another 4 bytes (and no more than 4 bytes).

Second is if the request contains set bits that refer to unsupported
extensions.  This result in the same behaviour as the PROBE scenario;
the KDC responds with a bit-field (high bit set) indicating what it
supports, and wait for the client to send another 4 bytes.

Third is if the KDC support the negotiated extension.  The response
then depends on the particular extension.  It follows that all
extensions MUST have the KDC send a particular packet in this
situation, since the client is waiting for a response.  The client
need to determine if the KDC supports the extension or not.  It also
follows that the first bit of this data must not be set, or it will be
interpreted by the client as a response to a PROBE or failed extension
negotiation.  In any other details of the additional data was
intentionally left unspecified, but some guidance may be appropriate
here.  I note that your second concern relates to exactly this case.

>       be zero), followed by that many octets of data.

This sounds like a good idea.  It saves one round-trip compared to how
I intended it to work.

>       the request length can be zero.

This can be satisfied by defining an extension type that sends a
Kerberos request as the additional data.

>       fields as were sent by the client.

This sounds complicated, but seems like a good idea if we anticipate
there will be many extensions.  We had that discussion earlier -- my
original proposal was to support 2^32-2 different extensions, but it
was reduced to only 32-2 extensions after that discussion.

I think the conclusion was that there would not be that many
extensions, and if for some reasons there would be, there is always
the reserved bit 30 that can be used for further extensions.

>    whether the KDC also sends a Kerberos message (with length).

Right.

>    not include a normal Kerberos message with an extension request) are

I agree that 1a seems useful, and unless there are objections, I'll
add it.  I don't see a strong requirement behind 1b or 1c, but I'd
agree they are nice ideas.  My main preference here is simplicity.  We
have no indication that anything more advanced is necessary, and we've
made sure that it is possible to support more advanced behaviours,
including 1b and 1c, if that need ever arise.  That seems sufficient
to me.

>    extension method (i.e. the length of a KRB-ERROR reply).  This is bad.

Good catch.

One solution would be to send a 4 byte 0x00000000 string in this
situation.  A KRB-ERROR packet can never be that small, so it cannot
be returned by an RFC 4120 compliant KDC.

>       value with the high bit set and no others.

That is indistinguishable from a KDC that supports the extension
mechanism but no extensions.  We could easily solve that by saying
that this extension mechanism MUST NOT be used when the implementation
does not support any extension mechanisms.

>       negotiated extensions.

Isn't that indistinguishable from a)?

>       IMHO, the "nonzero" value should be used to indicate which of
>       the requested extensions are accepted by the KDC; this would
>       allow extensions to be specified such that in some cases the
>       KDC has the freedom to accept some extensions and reject
>       others.

While not as flexible, this can be supported today by having related
extensions define how such negotiations happens.

I intentionally wanted to avoid such negotiations, because it
complicates the protocol, and there is no apparent need for it.  But
if it turns out to be simple to achieve, why not.

>    which does not support the extension method at all.

What do you think about sending 0x00000000 as an alternative solution?

>    such as TLS or some alternative framing.

I changed it to:

      <t>Each extension MUST describe the structure of protocol data
	beyond the length field, and the behaviour of the client and
	KDC.  If an extension mechanism reserve multiple bits, it MUST
	describe how they interact.  In particular, the structure may
	be a protocol with its own message framing.</t>

Is this OK, or do you want an explicit reference to TLS?

>    of which extensions are supported, which may also result in downgrade.

Right, good catch.  I changed it into:

      <t>Because the initial length field is not protected, it is
	possible for an active attacker (i.e., one that is able to
	modify traffic between the client and the KDC) to make it
	appear to the client that the server does not support this
	extension mechanism (a downgrade attack).  Further, active
	attackers can also inferfere with the negotiation of which
	extensions are supported, which may also result in a downgrade
	attack.  This problem can be solved by having a policy in the
	clients and in the KDC to reject connections that does not
	have the desired properties.</t>

Comments?

Thanks,
Simon

---

From: Jeffrey Hutzelman <[email-masked]>
Date: Thu, 07 Sep 2006 22:57:07 -0400

> This sounds like a good idea.  It saves one round-trip compared to how

It does, but your approach works as well.  However, if we stay with your 
approach, I think the spec needs to explicitly say that clients requesting 
extensions must wait to see the server's response before going ahead with 
any data beyond the initial 32-bit extension request.

> Kerberos request as the additional data.

Yes, that's true.

> the reserved bit 30 that can be used for further extensions.

Right; I seem to recall the discussion about using a bitmask rather than 
numbered extensions, and agreement that supporting a very large number of 
extensions would not be required.  My (1c) was intended to be taken in the 
context of larger changes that I thought would be necessary to resolve the 
problems described in (1a) and (2); in that context, I expected (1c) to 
make things somewhat simpler.  Without the larger changes, (1c) clearly 
adds complexity rather than removing it.

> including 1b and 1c, if that need ever arise.  That seems sufficient

I agree.  Given that you've demonstrated the (1a) fix is not necessary as 
long as you describe what you intended, I would not add it unless there are 
other people in the WG who speak up in support of going in that direction. 
This is post-last-call, and we shouldn't be making any substantive changes 
without buy-in from the group.

>>    other than a PROBE).  If the KDC supports the extension, then its
>>    reply needs to be distinguishable from an unsupported-extension
>>    reply, which presumably means it needs to start with a 32-bit value
>>    whose high bit is clear.  However, such a value is indistinguishable
>>    from that which would be sent by an RFC4120-compliant KDC which does
>>    not understand the extension method (i.e. the length of a KRB-ERROR
>>    reply).  This is bad.
>
> Good catch.
>

Yes, I believe that approach will work fine.

> Isn't that indistinguishable from a)?

The fundamental premise of a/b/c was that a KDC would indicate the complete 
set of extensions it supports _only_ in response to an explicit probe (that 
is, an extension request with no extensions requested); this is case a.  In 
other cases (b and c), it would indicate the intersection of extensions it 
supports with extensions requested by the client; for case b, that happens 
to be the empty set.  The idea here was to insure that the response from a 
KDC that does support the extension mechanism would always be 
distinguishable from the response from a KDC which does not.

> complicates the protocol, and there is no apparent need for it.

True.  It was entirely a side-benefit of a/b/c, which was the simplest 
solution I could think of to the problem I saw.  However, you seem to have 
come up with a simpler solution.

> What do you think about sending 0x00000000 as an alternative solution?

I like it; it's considerably simpler than anything I could think of.

> Is this OK, or do you want an explicit reference to TLS?

That text satisfies my concern.

>> (4) The security considerations notes that an attacker can force a
>> downgrade by making it appear that one peer does not support the
>>    extension method. It should also note that an attacker can interfere
>>    with the negotiation of which extensions are supported, which may
>>    also result in downgrade.
>

Looks good.

OK; now, I want to see comments from other WG members on...

(1) Simon's solution to the how-much-data-to-skip problem (having the
    client wait for an ACK before sending extension data), vs the
    length count described in (1a).
(2) Simon's solution to the successful-KDC-response problem (having
    all successful responses begin with 0x00000000).
(3) The additional textual changes described above.

Hopefully some people will weigh in within the next couple of days.

-- Jeff

---

From: Simon Josefsson <[email-masked]>
Date: Wed, 13 Sep 2006 15:24:01 +0200

Thank you for the additional comments.  Pending any other discussions
on the proposed solutions, I have updated the document.  I have
submitted it to the I-D editor, but it hasn't been announced yet.
Meanwhile, it is available from:

http://josefsson.org/krb5starttls/draft-ietf-krb-wg-tcp-expansion.txt

The important change is to clarify how the protocol works, and to add
the 0x00000000 stuff.

I believe -01 addresses all of Jeff's comments, but I may very well
have misunderstood or forgotten something, so please check it.

If there are no further comments on the changes in -01, what is the
next step?

Thanks,
Simon

---

From: Nicolas Williams <[email-masked]>
Date: Wed, 13 Sep 2006 16:38:16 -0500

I'm rather confused about points (1) and (2).

I think I read Jeff's note as saying that we should want:

 - to not constrain extensions from leveraging others specified
   concurrently or earlier
 - optimistic extension negotiation that does not result in connection
   closure when the KDC does not support the extension that the client
   wants but supports this draft.
 - an open set of extensions

And the concern is that the draft as it stands does not meet these
requirements/desires.

Therefore I propose:

i) a probe message (0x80000000) to which the KDC should respond with a
   bitmask of supported extensions
ii) a message requesting a SINGLE* extension(0x80000000 | <extension's
    bitmask>), followed by a framed extension data (Jeff's (1a) suggestion).

* Here, by "single extension" I mean one or more bits set which,
  together, form a well-defined extension.  I would expect this to
  always be a single bit in practice, as I expect very few extensions
  here.

iii) Text that says what Jeff proposes in (3).

This way there is never any ambiguity and we get optimistic extension
negotiation with KDCs that support this draft.

I would also like to:

iv) reserve one extension bit for negotiating extensions beyond 30.

>    such as TLS or some alternative framing.

Sure.  As long as the initial client request on a given connection for a
given extension includes that length of extension data.

>    of which extensions are supported, which may also result in downgrade.

Well, yes.

Nico
--

---

From: Simon Josefsson <[email-masked]>
Date: Thu, 14 Sep 2006 10:56:02 +0200

>    bitmask of supported extensions

As far as I understand what you propose, this is already in the
document (both -00 and -01).  Perhaps I misunderstand what you are
looking for here.

>     bitmask>),

This is too.

> followed by a framed extension data (Jeff's (1a) suggestion).

This is not in the document, but this seem to only be a roundtrip
optimization issue.  It could be added.

>   always be a single bit in practice, as I expect very few extensions

That's my understanding as well.

> iii) Text that says what Jeff proposes in (3).

I believe this was addressed by -01.

> iv) reserve one extension bit for negotiating extensions beyond 30.

The IANA section says:

   Bit #                                             Reference
   -----                                             ---------
   0..29         AVAILABLE for registration.
   30            RESERVED.                           RFC XXXX

/Simon

---

From: Nicolas Williams <[email-masked]>
Date: Thu, 14 Sep 2006 16:54:24 -0500

On Thu, Sep 14, 2006 at 10:56:02AM +0200, Simon Josefsson wrote:
> > [...]

See, I was confused :)

> optimization issue.  It could be added.

OK.

> That's my understanding as well.

It must be clear.

> > iv) reserve one extension bit for negotiating extensions beyond 30.

So I've proposed nothing new, and Jeff confused me -- only two changes
were needed then, yes?  Support for optimistic negotiation of extensions
with KDCs that support your draft, and text for Jeff's items (3) and
(4), and, maybe, just maybe, a clarification relating to the "single
extension" comment I made.

Nico
--

---

From: Simon Josefsson <[email-masked]>
Date: Fri, 15 Sep 2006 11:57:03 +0200

>> That's my understanding as well.

Both -00 and -01 says:

   The behaviour when more than one non-high bit is set depends on the
   particular extension mechanisms.  If a requested extension (bit X)
   does not specify how it interact with another requested extensions
   (bit Y), the KDC MUST treat the request as a PROBE or unsupported
   extension, and proceed as above.

Is this sufficient?

The text implies that most extensions will probably be single bit
extensions.  If some extension has a need to use multiple bits, it can
do so, if the specification describes how they interact.  I'm not sure
this will ever be used, but I see no harm in permitting this.

> were needed then, yes?

Yes, I've made two concrete changes (to address Jeff's (3) and (4)),
and clarified how the protocol works, including the 0x00000000
response, which I believe solves Jeff's issues (1) and (2).

> Support for optimistic negotiation of extensions with KDCs that
> support your draft

What do you mean here?  Having the client propose an extension without
first sending a PROBE?  If so, that was part of -00, but may be
somewhat clearer in -01.

> and text for Jeff's items (3) and (4),

That's fixed.

> and, maybe, just maybe, a clarification relating to the "single

If the paragraph in -00/-01, also first in this post, is sufficient
for you, I believe all issues are addressed.

/Simon

---

From: Sam Hartman <[email-masked]>
Date: Fri, 29 Sep 2006 16:37:45 -0400

>>>>> "Jeffrey" == Jeffrey Hutzelman <[email-masked]> writes:

    Jeffrey> Right; I seem to recall the discussion about using a
    Jeffrey> bitmask rather than numbered extensions, and agreement
    Jeffrey> that supporting a very large number of extensions would
    Jeffrey> not be required.  My (1c) was intended to be taken in the
    Jeffrey> context of larger changes that I thought would be
    Jeffrey> necessary to resolve the problems described in (1a) and
    Jeffrey> (2); in that context, I expected (1c) to make things
    Jeffrey> somewhat simpler.  Without the larger changes, (1c)
    Jeffrey> clearly adds complexity rather than removing it.

I didn't follow that discussion , so feel free to ignore these
comments.

I agree that there is not a lot of need for a huge number of
extensions.  I am however concerned that we're adding a lot of
complexity to deal with multiple extensions at the same time and I
wonder whether that is beneficial.

--Sam

---

From: Jeffrey Hutzelman <[email-masked]>
Date: Fri, 29 Sep 2006 16:45:06 -0400

> wonder whether that is beneficial.

I don't think we are.  We agreed to essentially treat a combination of 
extensions as a distinct extension with distinct semantics that must be 
specified (presumably by one or more of the specifications for the 
extensions involved) in order to be valid.  In fact, you can effectively 
treat the extension bitmask as an extension number, with only one extension 
in use at a time -- if you don't understand the value you see, then treat 
it as unsupported.  It's only necessary to treat it as a bitmask for the 
purpose of indicating what extensions the KDC supports.

-- Jeff