Subject: comments on 2478bis (SPNEGO) I-D

From: Nicolas Williams <[email-masked]>
Date: Wed, 15 Dec 2004 05:25:36 -0600

[My comments take into account the changes agreed to in the thread
started by Sam about his comments.]

 - section 3.1, third paragraph: the GSS_Set/Get_neg_mechs() functions
   deal in SET OF OBJECT IDENTIFIER, not SEQUENCE OF, therefore
   applications cannot specify preference order through
   GSS_Set_neg_mechs().

   GSS_Set/Get_neg_mechs() could not be changed to use SEQUENCE OF
   OBJECT IDENTIFIER because of language bindings issues (unless there
   exist no implementations, I suppose) since SEQUENCE OF is not used
   anywhere in RFC2743 none of the language bindings have appropriate
   bindings for that type.

   I suggest either extensions for specifying policy or else that this
   paragraph be re-written to remove at least the reference to appendix
   A.

 - section 3.1, next to last paragraph: should that not read: "Lastly,
   MIC tokens MAY, and sometimes MUST be exchanged ...?"

 - section 3.2, first paragraph: if integrity protection is not
   available then what?  Presumably the context can be established
   anyhow as neither the initiator would offer nor the acceptor accept
   such a mech if they really want a protected negotiation.

 - section 3.2, (c), (III): s/depending on if at least.*\./according to
   the status of the negotiated mechanism's context./

   Similarly, for section 3.2, (c), (II), there may or may not be a
   mechanism token in the negotiation token when the state is
   request_mic -- if the mechanism outputs a token then it should be
   included in the negotiation token (except in the error token case, in
   which it should be optional).

 - section 3.2, (d): encapsulated with what?  NegTokenResp?

 - section 3.2, first paragraph after (e): s/i.e.,.*\./i.e., these flag
   input parameters and state output parameters are passed by SPNEGO
   unmodified between the application and the mechanism./

 - section 3.2, last paragraph:  I think this should be re-written
   thusly:

      When a GSS-API credential is acquired for the SPNEGO mechanism the
      implementation SHOULD produce a credential element for the SPNEGO
      mechanism which internally contains GSS-API credential elements
      for all mechanisms for which the principal has credentials
      available, except for any mechanisms which are not to be
      negotiated, either as per implementation-, site- or
      application-specific policy.  See Appendix A for interfaces for
      expressing application policy.

 - section 4.2, first paragraph: s/are not/MUST NOT be/

 - section 4.2.1, if reqFlags has no impact on the negotiation, what's
   the point?  Why not deprecate that field recommend that it be left
   out?  Besides, what would an acceptor do with those flags?
   GSS_Accept_sec_context() doesn't have a flags input parameter...  And
   the final output flags from the SPNEGO GSS_Accept_sec_context()
   should, one would think, correspond to those of the negotiated
   mechanism's (minus prot_ready prior to full context establishment).

 - section 4.2.2: ENUMERATED can have extensibility markers too.  If the
   negResult enumeration gets such a marker then section 6 will have to
   explain what implementors are to do about unknown negResults; IMO the
   answer is: derive actual state from the negotiated context state or,
   if that's not possible, quit with an error.

 - section 4.2.2: Add: "When negResult is absent the actual state should
   be inferred from the state of the negotiated mechanism context."

 - section 5, what happens when a mechListMIC is sent when it is
   OPTIONAL?  The receipient should have to process it, IMO, and that
   should be a MUST, no?

 - section 5, (b), (I), the initiator MUST output a negotiation token
   with a mechListMIC, no?  I.e., RFC2119 key words are needed.

 - section 5, (b), (II): s/terminated.  GSS.*\.//terminated;
   GSS_S_DEFECTIVE_TOKEN MUST be indicated as the major status./

   I.e., this applies not just to GSS_Accept_sec_context() but also to
   GSS_Init_sec_context().

   Similarly for section 5, (b), (IV).

 - section 5, (c): I'm with Sam on this; I've not seen a response from
   Larry about.  The initiator has to send a mechListMIC if the acceptor
   selected a mechanism other than the initiator's preference even if
   the acceptor did not request a mecListMIC.

 - section 5, (c): GSS_Init_sec_context() should not, presumably,
   indicate GSS_S_CONTINUE_NEEDED if the intiator offers only one
   mechanism, an optimistic token is included and the mechanism is a
   one-token mechanism (i.e., it indicates GSS_S_COMPLETE immediately),
   right?

 - section 5, (c), (I), again, RFC2119 key words are needed:
   s/contains/MUST include/ (and the token MUST be output!)

 - section 5, (c), (I), when the acceptor's mechListMIC cannot be
   verified by the initiator GSS_Init_sec_context() should (MUST)
   indicate GSS_S_DEFECTIVE_TOKEN.

 - section 5, (c), (III):  It may be useful to explain why.

 - section 5, (c), (III):  s/contains/MUST contain/  (and the token MUST
   be output!).

 - section 6, second paragraph, third sentence: s/ but instead.*\.//

 - section 7, given the attack in the even-numbered mechanism token
   exchange case where the initiator can end up fully established while
   the acceptor fails to establish, isn't there an issue where an
   attacker could cause a downgrade to a mechanism for which it could
   impersonate the acceptor through other attacks?

It's late, but I think I'm done.

Nico
-- 

_______________________________________________
Kitten mailing list
[email-masked]
https://www1.ietf.org/mailman/listinfo/kitten

---

From: Sam Hartman <[email-masked]>
Date: Wed, 15 Dec 2004 10:19:46 -0500

I think Nico wants somewhat more RFC 2119 language than I think is
strictly necessary.  Note that things other than 2119 language can
place normative requirements on an implementation.

I don't object to his proposed changes in this regard, I simply think
some of of them are not required.  I take no position on whether they
would improve the spec.

>>>>> "Nicolas" == Nicolas Williams <[email-masked]> writes:

    Nicolas> [My comments take into account the changes agreed to in

    Nicolas>    Similarly, for section 3.2, (c), (II), there may or
    Nicolas> may not be a mechanism token in the negotiation token
    Nicolas> when the state is request_mic -- if the mechanism outputs
    Nicolas> a token then it should be included in the negotiation
    Nicolas> token (except in the error token case, in which it should
    Nicolas> be optional).

Why is an error token optional?

---

From: Nicolas Williams <[email-masked]>
Date: Wed, 15 Dec 2004 12:01:51 -0600

> some of of them are not required.  I take no position on whether they

Hmmm, well, I don't have a strong position on that matter -- I
understood what the text said and meant, so if that's enough for you
then we can drop this.

> Why is an error token optional?

IIRC you've wanted error tokens and/or useful information in them to be
optional and, anyways, initiators already have to be prepared to never
hear from acceptors again, even in the middle of a context token
exchange.

Nico
--

---

From: Sam Hartman <[email-masked]>
Date: Wed, 15 Dec 2004 14:23:22 -0500

Nicolas> Similarly, for section 3.2, (c), (II), there may or may
    Nicolas> not be a mechanism token in the negotiation token when
    Nicolas> the state is request_mic -- if the mechanism outputs a
    Nicolas> token then it should be included in the negotiation token
    Nicolas> (except in the error token case, in which it should be
    Nicolas> optional).
    >>  Why is an error token optional?

    Nicolas> IIRC you've wanted error tokens and/or useful information
    Nicolas> in them to be optional and, anyways, initiators already
    Nicolas> have to be prepared to never hear from acceptors again,
    Nicolas> even in the middle of a context token exchange.

In application protocols yes.  In this instance, if the acceptor sends
anything it should send the final token from the mechanism though even
if it is an error token.

---

From: Nicolas Williams <[email-masked]>
Date: Wed, 15 Dec 2004 14:18:29 -0600

>    MIC tokens MAY, and sometimes MUST be exchanged ...?"

Larry points out that this should not be normative text, so lower case
the 'may'.

>    such a mech if they really want a protected negotiation.

So, what I'm asking for here is for security considerations text that
uses rfc2119 key words to say that peers should not offer/accept such
mechanisms if they want negotiation protection.

>    which it should be optional).

Larry agrees to this and has made the change.

>  - section 3.2, (d): encapsulated with what?  NegTokenResp?

Larry agrees and has fixed.

>    unmodified between the application and the mechanism./

Larry points out that this is implicit and also that a SPNEGO
implementation might want to modify *_req_flags, so, no change is needed
here and I agree.

>       expressing application policy.

Larry agrees to this change.

>  - section 4.2, first paragraph: s/are not/MUST NOT be/

Larry agrees and has fixed this.

>    mechanism's (minus prot_ready prior to full context establishment).

Larry agrees and added a comment in the structure explaining that this
field is there for compatibility but SHOULD be left out.

>    if that's not possible, quit with an error.

For simplicity's sake I'm withdrawing this comment.  This field suffers
from being mostly redundant, except for the request_mic value.

(BTW, are underscores allowed in ASN.1 value symbols?)

>    be inferred from the state of the negotiated mechanism context."

Larry agrees, and has fixed this.

>    OPTIONAL?  The receipient should have to process it, IMO, and that

Larry points out that this is covered in section 5, (b) (I) and (c) (I),
but note that there's no normative rfc2119 key words about that.

Larry rejects this.  I don't mind.

>    with a mechListMIC, no?  I.e., RFC2119 key words are needed.

Larry rejects this.  I don't mind.

>    Similarly for section 5, (b), (IV).

Larry agrees and has fixed this.

>    the acceptor did not request a mecListMIC.

Larry says that this has been addressed already -- either I missed it or
it was addressed off-list.

>    one-token mechanism (i.e., it indicates GSS_S_COMPLETE immediately),

Larry disagrees and considers this an optimization for a case where apps
should not use SPNEGO anyways (to negotiate from a list of one
mechanism).  I withdraw the comment.

>    s/contains/MUST include/ (and the token MUST be output!)

Larry rejects this comment.  I don't mind.

>    indicate GSS_S_DEFECTIVE_TOKEN.

Larry rejects this comment claiming that this is implied.  I agree it's
impled and don't mind if it isn't fixed.

>  - section 5, (c), (III):  It may be useful to explain why.

This isn't a big deal, but my point is that someone who is not familiar
with SPNEGO may legitimately wonder why there's that final negotiation
message when the mechListMIC was not needed.  In other words this text
may be confusing to others, though not to me.

Larry does not want to make a change.  I don't mind.

>  - section 5, (c), (III):  s/contains/MUST contain/  (and the token MUST

Larry rejects this comment.  I don't mind.

>  - section 6, second paragraph, third sentence: s/ but instead.*\.//

Larry agrees and has fixed this.

>    impersonate the acceptor through other attacks?

Larry points out that the next to last paragraph in section 7 covers
this.  I withdraw this comment.

Done.

Nico
--

---

From: Nicolas Williams <[email-masked]>
Date: Wed, 15 Dec 2004 14:25:47 -0600

> anything it should send the final token from the mechanism though even

But that makes the negotiation token an error token also, and
negotiation error tokens have to be as optional as error tokens are for
any mechanism.

---

From: Martin Rex <[email-masked]>
Date: Thu, 16 Dec 2004 20:06:31 +0100 (MET)

> Larry rejects this.  I don't mind.

The decision whether a supplied mechListMIC must be processed
is clear from the situation, the decision is *NOT* at the discretion
of the receiver.

If a mechListMIC is created and sent for a security context where
the final lag results in a context establishment failure, then the
mechListMIC can obviously *not* be processed, because gss_verify_mic()
can not be called.

If a mechListMIC is created and sent for a security context that
is successfully established, then the receiver MUST process the
mechListMIC and call gss_verify_mic() in order to keep the
message protection sequencing facilities in sync with the peer.
Otherwise the application will run into message sequencing errors.

> Larry rejects this comment.  I don't mind.

There are already too many things implied in our specs.  I would
really appreciate if things were spelled out more often, and in
particular when someone involved in the spec discussion thinks that
an explanation would help!

I'm not an SPNEGO implementor and I'm sufficiently *un*familiar with
the protocol to *not* recognize those parts of the spec that might
make implementors wonder.

When SPNEGO was originally discussed in ietf-cat, then I complained
that it did only contain ASN.1 descriptions and no bits-and-bytes
description.  If there had been bits&bytes in the spec, there would
never have been confusion about which bytes go into the mechListMIC.
Unfortunately those implementors that were involved in the discussion
and review (Denis Pinkas/Bull and Mike Swift/Microsoft) weren't sufficiently
experienced with ASN.1 to see the problem, and unfortunately they didn't
seem to have realized the problem while implementing, because they
didn't complain...

-Martin

---

From: Nicolas Williams <[email-masked]>
Date: Thu, 16 Dec 2004 13:23:09 -0600

> seem to have realized the problem while implementing, because they

If only the bits that went into the MIC were all they'd gotten wrong...
Then this work item would be much simpler.  The other things they
got wrong were not due to spec vagueness, I don't think.

Nico
--

---

From: Martin Rex <[email-masked]>
Date: Thu, 16 Dec 2004 21:33:52 +0100 (MET)

> negotiation error tokens have to be as optional as error tokens are for

Error tokens are dangerous, because the can cause quite some confusion
and interoperability problems.  I think they should be avoided
entirely.

In case that the security context establishment fails when the final
security context token is processed, then the sender has already
returned GSS_S_COMPLETE and is therefore not expecting another
context level (error) token, and the application level protocol
may not have sufficient provisions to tag the token correctly...

If gss_init_sec_context() or gss_accept_sec_context() returns a fatal
routine error, then the calling applicatoin is likely to terminate
the communication with the peer (and entirely ignore any token returned
by the call).  If the gssapi mechanism camouflages the error token by
returning (GSS_S_CONTINUE_NEEDED|GSS_S_COMPLETE) plus an error token,
then this will result in an interoperability problems and possible
confusion if (a) the handling of error tokens is insufficiently
standardized in the mechanism spec or (b) the error happened when
processing the final context token and the peer is not expecting
another context level (error) token.

Microsoft's Kerberos implementation creates camouflaged context level
error tokens in several situations, and legacy MIT Kerberos chokes
on them.

-Martin

---

From: Jeffrey Altman <[email-masked]>
Date: Thu, 16 Dec 2004 17:28:34 -0500

> seem to have realized the problem while implementing, because they

I agree that I would rather error on the side of too much explanatory
text then not enough.  Especially in a protocol specification which is
attempting to correct for the flaws of the past.

The WGLC is over on this document.  I will issue my determination on
whether to send it to the IESG tomorrow.  In either case, if there are
further editorial changes which would help prevent confusion for 
implementors they can be submitted as IETF Last Call comments or 
incorporated into a new draft before it is sent to the IESG.

Thanks.

Jeffrey Altman

---

From: Martin Rex <[email-masked]>
Date: Mon, 20 Dec 2004 19:29:21 +0100 (MET)

>    anywhere in RFC2743 none of the language bindings have appropriate

I have a different understanding of rfc2478 and rfc2743.

rfc2478 uses the same terminology to describe GSS_Set_mechs/GSS_Get_mechs
function parameters as rfc2743.  However the "SET OF OBJECT IDENTIFIER"
is **NOT** meant to imply all of the ASN.1 semantics of a SET.

In the GSS-API C-Bindings, the gss_OID_set has always been an
array of OIDs, and for those API calls where order makes sense,
the oder of OIDs in the array indicates a preference,
e.g. the gss_OID_set returned by gss_indicate_mechs().

Therefore, the definition of GSS_Set/Get_neg_mechs() is fine with rfc2743/44
and provides a means to indicate an order of preference.

-Martin

---

From: Nicolas Williams <[email-masked]>
Date: Mon, 20 Dec 2004 12:36:06 -0600

> e.g. the gss_OID_set returned by gss_indicate_mechs().

RFC2744 has this to say about the subject in the description of
gss_add_oid_set_member():

               The routine may add the new member OID anywhere within
   the elements array, and implementations should verify that the new
   member_oid is not already contained within the elements array; if the
   member_oid is already present, the oid_set should remain unchanged.

> and provides a means to indicate an order of preference.

See above; OID sets are _sets_ not sequences, in the C bindings.

And I note that rfc2743 does not use 'SEQUENCE OF' at all while rfc2744
does not specify any sort of array type.  Together with the rfc2744
text on OID sets I think the evidence is resounding that the C-bindings
simply do not provide for any mapping of a generic 'SEQUENCE OF' to C
constructs.

Nico
--

---

From: Sam Hartman <[email-masked]>
Date: Mon, 20 Dec 2004 15:55:17 -0500

I'd recommend rephrasing your argument without reference to ASN.1.  It
will I think avoid unnecessary confusion.

---

From: Martin Rex <[email-masked]>
Date: Tue, 21 Dec 2004 00:55:20 +0100 (MET)

>    member_oid is already present, the oid_set should remain unchanged.

The GSS-API spec uses only a single data type to pass more than
a single OID between gssapi mechanism and application, and that
data type is called "SET OF OBJECT IDENTIFIER" by rfc2743.

In most cases, this should be considered a SET, meaning that if you
want to check for a particular OID, you'll have to check all members.

However, this convention was never meant to preclude the (ab)use of
this datatype to convey a list of OIDs ordered by preference.
And, in fact, this has been done from the days of GSS-API v1 for the
return parameter of gss_indicate_mechs() and the input parameter to
gss_acquire_cred() by several gssapi mechanisms.
That includes MIT Kerberos 5.

The definition of GSS_Set_mechs/GSS_Get_mechs in rfc2478 may be
the first place where a gss_OID_set is explicitly treated as
an ordered list at the spec level, but it is certainly not
the first such use.  And there was no suprize or contention about
that kind of use among the CAT participants when SPNEGO was
discussed, simply because everyone was used to doing it.

> See above; OID sets are _sets_ not sequences, in the C bindings.

Nope.

The C-Bindings define the gss_OID_set type as a top-level data-structure
pointing to an array of gss_OIDs.

   typedef struct gss_OID_set_desc_struct {
      size_t    count;
      gss_OID   elements;
   } gss_OID_set_desc, *gss_OID_set;

Except for __implementations__ of gss_add_oid_set_member(),
applications and gssapi mechanisms are neither required nor expected
to "enforce" any kind of "SET" semantics on gss_OID_set data types
passed through GSS-API calls.  I.e. an application may pass along
a gss_OID_set with duplicate OIDs or gss_OID_set ordered by preference.

Do you think that CAT should have created a seperate data type
and forked gss_indicate_mechs() and gss_acquire_cred() into two
seperate API calls?  I certainly don't!

> simply do not provide for any mapping of a generic 'SEQUENCE OF' to C

Huh?  Quoting rfc2744:

3.4. Object Identifier Sets

   Certain GSS-API procedures take parameters of the type gss_OID_set.
   This type represents one or more object identifiers (section 2.3).  A
   gss_OID_set object has the following structure:

   typedef struct gss_OID_set_desc_struct {
      size_t    count;
      gss_OID   elements;
   } gss_OID_set_desc, *gss_OID_set;

   The count field contains the number of OIDs within the set.  The
   elements field is a pointer to an array of gss_OID_desc objects, each
   of which describes a single OID. gss_OID_set values are used to name
   the available mechanisms supported by the GSS-API, to request the use
   of specific mechanisms, and to indicate which mechanisms a given
   credential supports.

   All OID sets returned to the application by GSS-API are dynamic
   objects (the gss_OID_set_desc, the "elements" array of the set, and
   the "elements" array of each member OID are all dynamically
   allocated), and this storage must be deallocated by the application
   using the gss_release_oid_set() routine.

Above is the entire definition of gss_OID_set.  Take note that it
does *NOT* require a gss_OID_set not to contain duplicates!
(the requirement to not create duplicate OIDs within a gss_OID_set
 is **ONLY** for implementations of gss_add_oid_set_member(),
 a new and hardly used call for GSS-API v2).

GSS-API (v1) already defined the set of OIDs data type.  There are
several uses where the set is treated as an ordered set, and there
never was and still isn't a restriction in GSS-API that precludes this.

RFC-2478 makes explicit uses of the fact that the GSS-API data type
"SET OF OIDS" may be treated as a an ordered list ("sequence"),
and noone from the ietf-cat wg had a problem with that.

Quoting a reply from Denis Pinkas (the rfc2478 document author):

: From: [email-masked] (Denis Pinkas)
: Date: Thu, 16 Mar 1995 17:56:00 +0100 (NFT)
: To: [email-masked] (Doug Rosenthal)
: Cc: [email-masked], [email-masked], [email-masked]
: Subject: Re: Simple GSS-API Negotiation Mechanism
 [...]
:
: [email-masked] wrote:
: : - Also wrt the ordered list of mechanism type/option pairs, it appears
: :   that there is no way for the application to influence the ordering,
: :   i.e. that the ordering is defined by the GSSAPI implementation.
:
: This is wrong. The GSS_set_neg_mechs is just there to do what you want.

Nobody from the ietf-cat wg objected to the use of gss_OID_set as an
ordered list for GSS_set/get_neg_mechs, simply because most of the
participants have been doing it themselves and were quite used to
the concept.

-Martin

---

From: Nicolas Williams <[email-masked]>
Date: Mon, 20 Dec 2004 18:05:32 -0600

> this datatype to convey a list of OIDs ordered by preference.

Abuse indeed.  To build a gss_OID_set without resorting to
gss_add_oid_set_member() means not being able to use
gss_release_oid_set() to release it, and re-ordering a set's elements
array after building it with gss_add_oid_set_member() is icky.

> That includes MIT Kerberos 5.

Those don't care about order in gss OID sets though, do they?

> discussed, simply because everyone was used to doing it.

RFC2478 was wrong to do this.

> seperate API calls?  I certainly don't!

GSS_Indicate_mechs() and GSS_Acquire_cred() do not care about order in
OID sets.

> does *NOT* require a gss_OID_set not to contain duplicates!

But the presecribed method for creating OID sets is
gss_add_oid_set_member() and we know what that has to say about order.

>  a new and hardly used call for GSS-API v2).

"Hardly?"

> participants have been doing it themselves and were quite used to

I object now.

Providing a C binding for SEQUENCE OF OBJECT IDENTIFIER seems like a
perfectly worthwhile task for KITTEN.

Nico
--

---

From: Martin Rex <[email-masked]>
Date: Tue, 21 Dec 2004 01:54:05 +0100 (MET)

> array after building it with gss_add_oid_set_member() is icky.

No-one in their right minds uses gss_add_oid_set_member().
I mean that.  For most purposes an automatic or static gss_OID_set
is perfectly sufficient.  Just think about the complex error handling
that gss_* API calls require.

And if an application is truely portable, then it will be able to
run on top of GSS-API v1 mechanisms as well -- and there it doesn't
have gss_add_oid_set_member().  And once an application needs to
supply it's own code to compose those gss_OID_set that it needs,
it would be outright stupid to call gss_add_oid_set_member() on
those few occasion where it was available.

> Those don't care about order in gss OID sets though, do they?

THEY DO.

> GSS_Indicate_mechs() and GSS_Acquire_cred() do not care about order in

The spec for those calls doesn't care.
But many gssapi mechanisms and some applications *DO* care,
whether you like it or not.

> gss_add_oid_set_member() and we know what that has to say about order.

NOPE.  The definition of gss_add_oid_set_member() only defines how
this particular new call modifies only those gss_OID_sets created
by gss_create_empty_oid_set(), *NOTHING* else.

> >  a new and hardly used call for GSS-API v2).

Yes, exactly.

> perfectly worthwhile task for KITTEN.

That's entirely silly.

gss_OID_set covers both, sets and ordered lists in the existing specs
and the installed base.

-Martin

---

From: Martin Rex <[email-masked]>
Date: Tue, 21 Dec 2004 02:17:40 +0100 (MET)

> array after building it with gss_add_oid_set_member() is icky.

As I've explained before, sane applications will roll those few (if any)
gss_OID_set that they need without gss_add_oid_set_member() resulting
in significantly less code, and portable gssapi based applications
(performing dynamic runtime loading) are not going to use those
calls anyway.

> RFC2478 was wrong to do this.

RFC2478 received consensus from the cat-ietf working group
for doing it the way it does.

> perfectly worthwhile task for KITTEN.

GSS-API also uses a gss_buffer_t to pass both, binary blobs (tokens)
and printable strings between application and gssapi mechanism.

It dependes on the context and situation whether the contents of
the gss_buffer_t are interpreted as strings or as binary blobs.

Same goes for gss_OID_set.  A gss_OID_set is an array of OIDs.
What the OIDs mean and whether the order of the OIDs in the array
is relevant depends on the particular API call and the purpose
of the OID array.

-Martin

---

From: Nicolas Williams <[email-masked]>
Date: Mon, 20 Dec 2004 23:09:37 -0600

> > Those don't care about order in gss OID sets though, do they?

They don't.  Nothing about the text of RFC2743 about
GSS_Indicate_mechs(), GSS_Acquire_cred(), GSS_Add_cred() or
GSS_Inquire*() says anything about order in the SET OF OBJECT IDENTIFIER
input or output parameters, never mind its significance.

As to the SPNEGO interfaces, if we want order to matter (we do) and if
there aren't any implementations of the rfc2478 interfaces or none that
apps developers are likely to encounter then we should either change
those interfaces to use SEQUENCE OF or deprecate and replace them with
interfaces that use SEQUENCE OF.

And while we're at it we should provide C, and other language, bindings
for those interfaces and/or rules for determining the language bindings
of the generic interfaces for any of the relevant programming languages.

Regardless of whether the C-bindings gss_OID_set_desc type was meant for
dual use or was abused now that we know we need SEQUENCE OF for SPNEGO's
interfaces we do need to clarify the use of SET OF vs.  SEQUENCE OF in
the C bindings.

Nico
--

---

From: Sam Hartman <[email-masked]>
Date: Tue, 21 Dec 2004 01:39:23 -0500

>>>>> "Nicolas" == Nicolas Williams <[email-masked]> writes:

    Nicolas> On Tue, Dec 21, 2004 at 01:54:05AM +0100, Martin Rex
    Nicolas> wrote:
    Nicolas> As to the SPNEGO interfaces, if we want order to matter
    Nicolas> (we do) and if there aren't any implementations of the
    Nicolas> rfc2478 interfaces or none that apps developers are
    Nicolas> likely to encounter then we should either change those
    Nicolas> interfaces to use SEQUENCE OF or deprecate and replace
    Nicolas> them with interfaces that use SEQUENCE OF.

Since when did GSSAPI use ASN.1 as its data model?  This claim seems
missing from the text in the same way that any specific reference to
order of oid set members is missing.

>From my point of view, I can think of several implications of assuming
that GSS-API does not use ASN.1 as its data model.  First, allowing
the set type to be ordered might be a reasonable thing to do.  Second,
it means we should be more explicit both in our descriptions both on
the list and in our documents of what the properties of abstract data
types we use are.

I'm not proposing a specific solution for the document, but I am
proposing that we be more explicit of what we mean by a certain data
type in our on-list discussions.

---

From: Martin Rex <[email-masked]>
Date: Tue, 21 Dec 2004 16:24:21 +0100 (MET)

> input or output parameters, never mind its significance.

A lot of things in GSS-API are "a local matter", i.e. unspecified
at the generic level and left up to individual gssapi implementations.

When a gssapi mechanism implements more than a single mechanism
or mechanism variant, i.e. when gss_indicate_mechs() returns more
than a single mechanism OID, then all mechanisms that I know put
"their" preferred mechanism OID as the first entry in the gss_OID_set.

All gssapi mechanism that I've seen which offer more than a single
gssapi mechanism OID do that, including MIT Kerberos 5.

There has been an expectation that an application which picks a
mechanism OID from the list returned by gss_indicate_mechs() might
process the list of OIDs from the beginning, checking whether
it recognizes/likes the OID.  Portable applications that ask
for the default mechanism will supply GSS_C_NO_OID_SET to gss_acquire_cred()
or GSS_C_NO_OID to gss_init_sec_context() and leave the selection
entirely up to the gssapi mechanism implementation.

Similarily, a gssapi mechanism _may_ honor the order of mechanism OIDs
in a gss_OID_set passed to gss_acquire_cred() as a local matter.
There is no requirement for either behaviour in the spec, permitting both.
And for gssapi multimechanisms that have no negotiation capabilities,
using the first mechanism OID from the list of OIDs supplied by the
application would be a sensible choice for a gssapi mechanism.

> interfaces that use SEQUENCE OF.

The Sesame guys (which authored the SNEGO document) have
an implementation, even if they don't speak up here.   

But I really don't understand your problem with the current definition.
There's really no need to be formally anal about the language that
rfc2743/44 used to describe an array of OIDs.  You are artificially
creating problems where there are none in reality.

If there was a SEQUENCE OF data type, then logically one would expect
misc functions similar to gss_add_oid_set_member() to go with it,
and that would be excessive spec and code bloat.

> interfaces we do need to clarify the use of SET OF vs.  SEQUENCE OF in

It's actually not abuse, but creative use.

All of the flexibility in GSS-API that permitted to define v2 in
a backward compatible fashion to v1 was from *NOT* being anal about
elements already in the spec.

The guideline behind GSS-API architecture is to define rules ONLY
where absolutely necessary for interoperability, and to leave everything
else to the creativity of the implementors ("local matter").

The use of gss_OID_set for both, mathematical unordered sets or for
ordered lists depending on the context where they're used and whether
it makes sense is in perfect harmony with GSS-API traditions.

-Martin

---

From: Nicolas Williams <[email-masked]>
Date: Tue, 21 Dec 2004 11:06:28 -0600

> the list and in our documents of what the properties of abstract data

RFC2743 treats SET OF as just that: a set.  The constructor for SET OF
specifically describes set semantics.

Either the original API used the word "SET" to mean "list" or "SEQUENCE"
or what have you and a mistake was made in later adding text that
supported set semantics, or folks have been sloppy in allowing for list
semantics where the spec called for set semantics.

> type in our on-list discussions.

We should, indeed, be more careful around set vs. list types and
semantics.  At minimum I'd like to see C bindings for the SPNEGO
functions.

Nico
--

---

From: Nicolas Williams <[email-masked]>
Date: Tue, 21 Dec 2004 11:33:15 -0600

> at the generic level and left up to individual gssapi implementations.

Sure, and order in gss_OID_set's output by the GSS framework in some GSS
implementation is, indeed one of those, since there must be an order,
but that applies only to the C binding of the generic SET OF.

What about other languages, ones that provide native types suitable for
use in modelling sets, ones which may not provide a canonical order of a
set's elements or whose canonical order is not what you might expect?
How might a designer translate SET OF from rfc2743 to some new
programming language?

> "their" preferred mechanism OID as the first entry in the gss_OID_set.

What if there is no preferred mechanism?

> gssapi mechanism OID do that, including MIT Kerberos 5.

MIT offers two OIDs for the same mechanism.  And though one of those is
obsolete, which makes the other preferred, it is still the same
mechanism.

There are better examples.  Solaris' libgss' gss_indicate_mechs()
outputs an OID set where order reflects the order of entries in the
/etc/gss/mech configuration file -- talk about local policy!  In this
example the order is left not to the implementor but to the site.

Moreover, on Solaris it is actually possible to have credentials for
more than one mechanism be available for any one principal/user, in
which case knowing which is preferred tells you nothing about which
mechanism your peers might have credentials for.

Order really is not relevant to the gss_indicate_mechs().  (MIT's krb5
gss mechanism should really stop indicating the old OID.  And if you
bring SPKM, with its three variants, into the picture, then I will argue
that the application needs a priori knowledge of the difference between
them to pick one or it can pick one blindly, with or without "local"
help.)

> entirely up to the gssapi mechanism implementation.

The first part is true of C applications.  In other languages set
enumeration might non-deterministic, and the same can be simulated in C.

I agree as to the second part, that rfc2743 is clear as to what
GSS_C_NULL_OID means, that a local default may be used as a result, and
it is clear that SET OF means 'set'.

> application would be a sensible choice for a gssapi mechanism.

Applications can negotiate too.  Examples of Internet protocols that do
include NFSv3 and v4 and Secure Shell version 2.

Thanks.

> creating problems where there are none in reality.

There are more programming language bindings for the GSS-API than those
standardized at the IETF (e.g., Perl5 bindings).  Developers of such
bindings may not understand that you want list semantics out of
rfc2743's SET OF because none of the text in the spec indicates as much.
That's a problem, and I think we should fix it.

> and that would be excessive spec and code bloat.

I wouldn't mind a SET OF type that can be safely typecast to SEQUENCE
OF, both in the generic API and in the C bindings.  Or at least
clarification of what rfc2743 means by SET OF.

Nico
--

---

From: Sam Hartman <[email-masked]>
Date: Tue, 21 Dec 2004 12:49:01 -0500

>>>>> "Martin" == Martin Rex <[email-masked]> writes:

    Martin> Nicolas Williams wrote:
    >>  > The GSS-API spec uses only a single data type to pass more
    >> than > a single OID between gssapi mechanism and application,
    >> and that > data type is called "SET OF OBJECT IDENTIFIER" by
    >> rfc2743.
    >> > 
    >> > In most cases, this should be considered a SET, meaning that
    >> if you > want to check for a particular OID, you'll have to
    >> check all members.
    >> > 
    >> > However, this convention was never meant to preclude the
    >> (ab)use of > this datatype to convey a list of OIDs ordered by
    >> preference.
    >> 
    >> gss_release_oid_set() to release it, and re-ordering a set's
    >> elements array after building it with gss_add_oid_set_member()
    >> is icky.

    Martin> No-one in their right minds uses gss_add_oid_set_member().
    Martin> I mean that.  For most purposes an automatic or static
    Martin> gss_OID_set is perfectly sufficient.  

I think Nico and I have both worked on code bases that use
gss_add_oid_set_member.  In my case it was ssh.  I believe that was
clearly the right decision for that code base.

I think I'm in my right mind, although I'll realize that sometimes you
probably disagree.;)

---

From: Nicolas Williams <[email-masked]>
Date: Tue, 21 Dec 2004 12:06:15 -0600

> clearly the right decision for that code base.

SSHv2, SPNEGO, SASL, internally libgss, mech_krb5; RPCSEC_GSS and NFS
code bases could make use of it, and probably should.

> I think I'm in my right mind, although I'll realize that sometimes you

:)

Nico
--

---

From: Nicolas Williams <[email-masked]>
Date: Tue, 21 Dec 2004 12:22:54 -0600

> clarification of what rfc2743 means by SET OF.

I would also be happy to leave RFC2743 mostly as is and clarify that for
some language bindings OID sets order may be significant and clarify
that for the C bindings it is.  This would resolve the SPNEGO issue for
me.

Nico
--

---

From: Jeffrey Altman <[email-masked]>
Date: Tue, 21 Dec 2004 14:38:43 -0500

To the participants of the Kitten Working Group:

I would like to take some of the heat out of this discussion.
I believe that there is too much talking at each other going on
and not enough talking to each other.

There is clearly a significant difference of viewpoint in this
discussion.  In my opinion, the differences of viewpoint are
similar to what happens when Congress passes a law and then
prosecutors attempt to apply it a century later.  The context
has changed and therefore the modern interpretation of the law
clashes with the intentions of the original authors.  When
applying laws it is therefore crucial for judges to review the
original discussions surrounding the passing of the law; the
original context within which the law was applied; and the
cases to which the law was applied.  This is done to determine
the actual intention of the law which is just as important as
the words which make up the text of the law.

In our world of protocol and api design we have documents
which have revision history and implementation history.  Only
by examining the current documents within their historical
context can we determine what the true meanings of the words
are.  The vast majority of our protocol documents have unwritten
assumptions in them which can only be determined by looking at
the implementations based upon the documents available at a
specific point in time.

One of our challenges in this space is that the vast majority
of us working on these documents (1) do not have access to the
old implementations in order to see what assumptions were made;
and (2) do not have the benefit of being involved in the discussions
surrounding their publication.  For this we *must* defer to those
participants who have greater historical knowledge to inform us
when the assumptions we are making clash with the assumptions
which were made when the documents were originally published.
Martin is our connection to the past and I would appreciate it
if people would respect that role he is providing for us.  It
really is an important one.

I also ask Martin to respect that the viewpoints of the rest of
us are colored by our lack of intimate knowledge with the
implementation history of gss api v1 and the assumptions which
were made at that time and throughout the update process to gss api
v2.

It is my opinion that conversations in this space devolve into
long threads in talking at each other because the basis for the
conversation from each party are unspoken assumptions which in
many cases have no overlap.

<end of monologue>

I believe that by reading between the lines of this thread it
is possible to put the conversation back on track.

Martin has highlighted the fact that in certain contexts within
GSSAPIv1 and its successors, the order of OIDs did matter.  At
the time all "SET OF" constructions were static in nature.

Martin has pointed out that gss_add_oid_set_member() was added
in v2.  Nico points out that gss_add_oid_set_member() does not
provide for the creation of ordered "SET OF" constructions.

Martin has stated that this oversight in the addition of 
gss_add_oid_set_member() is acceptable because it is not used in
practice.

Here is where things begin to breakdown badly and the discussion
has taken a turn into the use or abuse of ASN.1 types and C data
structures; whether new types are needed; whether the use of old
types for multiple semantic contexts was right or wrong; etc.

It sounds to me that we are suffering here from there being
undocumented assumptions on various GSSAPI operations which can
only be determined by historical review of the documents and
the implementations which were based on them.

Before we can have a rationale discussion we need to know from
the historical context:

1) which GSS API functions consider the order of OIDs in a SET OF
    to be important?

2) for what explicit purpose as gss_add_oid_set_member() added.
    if it was never meant to be used it would not have been added,
    therefore the addition must have had some purpose in mind.
    what were the undocumented restrictions on the use of this
    function?

3) are the undocumented restrictions on gss_add_oid_set_member()
    in conflict with the gss api functions included in (1) above?

4) was the data model for GSS API meant to be that of ASN.1?
    if not, what was the data model?

Next, the discussion has taken a turn to focus on types and
whether or not the use of types in the past was poor judgment
and whether or not we need new ones.  It seems apparent to me
that there was a decision (conscious or not) to reuse existing
types to represent both ordered and unordered lists of OIDs.

I wonder if the group should be discussing the need to add a
new function gss_add_oid_set_member_at_pos() which would allow
for the construction of dynamic ordered lists using the existing
data structures instead of the currently produced unordered sets.

Jeffrey Altman

P.S. - I apologize for the length of this e-mail.

---

From: Nicolas Williams <[email-masked]>
Date: Tue, 21 Dec 2004 14:10:37 -0600

Indeed, the normative GSS-APIv2u1 spec (rfc2743) doesn't speak about the
relevance of order in OID sets, but the historical context of the C
bindings supports the notion that sometimes the order of elements in the
C bindings type for OID sets does matter.

I think we should consider clarifying when and where in the generic API
the order of the elements of a set of OIDs matters, may matter or does
not matter.

I think we should provide guidance for those who want to develop new
bindings of the generic API.

SPNEGO's generic interfaces should require that order matter.  I would
like that to be emphasized by use of "SEQUENCE OF" or, if you prefer,
and to emphasize that ASN.1 is not a normative model, "LIST OF," instead
of "SET OF."  Further, and to avoid confusion, I think the language
bindings, for C and Java at least, of those generic SPNEGO interfaces
should be included, either in Larry's I-D or in a separate I-D so that
there is no confusion as to what "SEQUENCE OF" maps to in those
languages.

Nico
--

---

From: Jeffrey Altman <[email-masked]>
Date: Tue, 21 Dec 2004 15:35:55 -0500

> bindings of the generic API.

I agree with both of these shoulds but they are not going to occur in
time for SPNEGO.

> there is no confusion as to what "SEQUENCE OF" maps to in those

I agree that we have made decisions which require that the order of the 
OIDs in the mechList matters.  I can certainly imagine a SPNEGO in which 
the order does not matter.  However, that is not an issue here as 2478
clearly states that the mechList is an ordered list.

I agree that to avoid confusion that providing C and Java Bindings
either as part of this document or as part of an associated document
would be a good idea.  Let's start with providing them as a secondary
"SPNEGO C, Java, and C# Language Bindings" document and see how quickly 
we can come to consensus on it.

Jeffrey Altman

---

From: Nicolas Williams <[email-masked]>
Date: Tue, 21 Dec 2004 15:06:08 -0600

> I agree with both of these shoulds but they are not going to occur in

If we agree to pursue language bindings for the SPNEGO interfaces then
we can avoid delaying SPNEGO for other generic clarifications.

Thanks.

Nico
--

---

From: Sam Hartman <[email-masked]>
Date: Tue, 21 Dec 2004 19:06:38 -0500

Martin> Sam Hartman wrote:
    >> gss_add_oid_set_member.  In my case it was ssh.  I believe that
    >> was clearly the right decision for that code base.
    >> 
    >> I think I'm in my right mind, although I'll realize that
    >> sometimes you probably disagree.;)
 
    Martin> I'm sorry for my language.  It was definitely
    Martin> inapproriate.

I did not take offense and did not think any was intended.  I was
mostly trying to point out that there seem to be multiple different
sets of people using GSS-API with different sets of assumptions.  As
we work through these specs we are going to run into cases where
something that is obvious to some of us is not obvious to others.

I think what we should do in these instances is:

1) Revise specs to document all the ways of doing things we are aware of.

2) If after considering the options it seems like we want to recommend
    one of them, do so.

I find these discussions quite interesting because it helps us all
understand how GSS-API is used.  It also reminds us that we'll never
know all the uses to which our technologies are put.

---

From: Martin Rex <[email-masked]>
Date: Wed, 22 Dec 2004 00:53:43 +0100 (MET)

> I think I'm in my right mind, although I'll realize that sometimes you
 
I'm sorry for my language.
It was definitely inapproriate.

What I actually meant to say is, that if gss_add_oid_set_member is not
part of your own codebase which you always link directly, then you're
much better off by rolling gss_OID_sets on your own -- and in most
cases you will not need them to be dynamic anyways.

As soon as you write code that may or will get used with arbitrary
gssapi mechanisms (i.e. a portable application), then it would not
be wise to reject a gssapi v1 mechanism only because it doesn't
offer gss_create_empty_oid_set/gss_add_oid_set_member/gss_test_oid_set_member
API calls, simply because those calls are entirely mechanism *in*dependent.

I agree that they might be useful *IF* one fiddles around with gss_OID_set
quite a lot, but quite often, a much smaller, less complex and always
available (directly linked) approach makes more sense (for apps).

A mechanism or a mechanism glue layer that implements and exposes those
fuctions is likely going to use them itself.  (Although I would
discourage to call exposed API functions from inside of a module, at least
for more complex functions than those OID_set support routines).

-Martin