Subject: RE: generic token framing in gssapi-cfx-02

From: "Liqiang(Larry) Zhu" <[email-masked]>
Date: Wed, 8 Oct 2003 15:01:06 -0700

Martin Rex wrote:
>> OK, I'm partly wrong.  I was misled by how EncryptMessage() works;

>> DecryptMessage() always only gets a single token.

>> Take a look at how SSPI's EncryptMessage() works on W2K Kerberos:
>> It takes 3 (three) seperate Input Buffers:
>> (1) SECBUFFER_TOKEN, (2) SECBUFFER_DATA, (3) SECBUFFER_PADDING
 
>> Therefore a GSS-API compliant wrapper to SSPI will always have
>> to reassemble those three distinct output buffers from
EncryptMessage()
>> into a single buffer before passing it to the application caller in a
>> single buffer.

You can pass in as a single buffer with buffer type STREAM, or you can
pass in the resulting 3 buffers at the same time too.  In fact, we think
the most general and extensible approach is to use 4 buffers: header,
data, padding, and trailer.

Most native SSPI applications do NOT re-assemble the buffers into one
single buffer.

Thank you for all your contributions over the years improving MS
platforms, but let's focus on this draft here.  Subscribers of this list
might not care the progress that NTLM SSP has made to be consistent with
Kerberos SSP.

>> There is an issues which the official Microsoft Support hasn't
>> been able to resolve so far: 

>> We have a customer who uses SmartCards for the Windows/Domain-Logon
>> with his W2K Machines.  However when doing that, SSPI will fail
>> AcquireCredentialsHandle() when being passed the users official
>> Kerberos user and realm name (no password) via an AUTH_IDENTITY_ANSI
>> structure.

You can not do that on win2k. On WinXp and beyond, this can be done via
the CREDMAN APIs. Basically you need to use a username that is in fact a
mangling of the thumb print of the cert for the smartcard (obtained via
the documented APIs).

MS support can not help you if you ask for internal details or
functionalities that do not exist in the OS you are using.

But again, it might be more prudent to discuss these off the list.

Larry

-----Original Message-----
From: [email-masked]
[mailto:[email-masked]] On Behalf Of Martin Rex
Sent: Wednesday, October 08, 2003 9:08 AM
To: [email-masked]
Cc: [email-masked]; [email-masked]; [email-masked]
Subject: Re: generic token framing in gssapi-cfx-02

Liqiang\ wrote:
> 
> Context establishment tokens do retain the framing in this draft

Well, in that case I'd like you to rewrite section
4.1. Initial Context Tokens
because it is using extremely weird terminology that differs
from every other gss-api related spec in the IETF.

The current wording in draft-ietf-krb-wg-gssapi-cfx-02.txt reads:

4.1. Initial Context Tokens

   Per [RFC-2743], all context initiation tokens emitted by the
   Kerberos V5 GSS-API mechanism will have the framing shown below:

There is no such thing as "initial context tokens".
The tokens that are exchanged during security context establishment
are called "context-level tokens" and "context establishment tokens"
by rfc2743 section 1.1.2 , and they're called "context establishment
tokens"
by rfc1964 section 1.1.

Per rfc2743 section 1.1.2 the first context-level token emitted by
GSS_Init_sec_context() is special in that it requires a special
framing(header) described in rfc2743 section 3.1.

rfc-1964 calls this first context-level token "InitialContextToken",
and clearly distinguishes it from the second context-level token
(which it calls Response Token) which is sent from Acceptor to
Initiator as a result of passing the InitialContextToken to
gss_accept_sec_context().

Quoting from rfc-1964 section 1.1 Context establishment tokens:

   The above GSS-API framing shall be applied to all tokens emitted by
   the Kerberos V5 GSS-API mechanism, including KRB_AP_REP, KRB_ERROR,
   context-deletion, and per-message tokens, not just to the initial
   token in a context establishment sequence.  While not required by
   RFC-1508, this enables implementations to perform enhanced error-
   checking.

I would appreciate that if a successor/update to rfc-1964 would
re-use the terminology of rfc-1964/rfc-2743 and *NOT* drop any of
the relevant paragraphs from rfc-1964.

Context deletion tokens have already been optional and hardly
implemeneted
by mechanisms and hardly used by applications, so they were deprecated
in GSS-API v2.  The logical step for a successor to rfc-1964 would be
NOT
add new variants of context deletion tokens, but to deprecate them as
well.

The only portable way to signal the end of a secure communication
is what the FTP with GSS-API extensions draft does: transfer a
zero-length protected message.

> 
> >> Creating two seperate code pathes is not what *I* consider clean;
> >> it increased code complexity and maintenance.  For backwards
> >> compatibility you must retain the existing code path (because of
> >> reusing the rfc-1964 mechanism OID).
> 
> Your perception is not shared by the implementer communities,
> unfortunately.  Dropping the oid from non-initial token was done with
> relative ease by at least two independent implementations at this
point.

That's a funny way to put it.

Of course it is more work to add that framing/header than not having it
at all.  But adding it only conditionally is definitely more error-prone
than adding it always.

If Microsoft had requested such a change to leave off the generic
framing
earlier, then they wouldn't have had to fix KERB_ERROR message in
W2K Beta in 1999 which were lacking the generic framing (which rfc-1964
explicitly requires).

I did quite a lot of interoperability testing with MIT Kerberos while
W2K
was in Beta and reported a lot of serious problems and bugs that
fortunately got fixed before W2K finally shipped.  

> 
> >> In Microsoft's SSPI the "token header" on protected messages has
> >> been implemented as a seperate "trailer", leaving the correct
> reassembly
> >> into a single buffer for a GSS-API-compliant API to wrapping code
> >> like my gsskrb5.dll.  I don't know whether Microsoft does that
> >> reassembly in any of their native protocols or whether they simply
> >> ignore that trailer -- my assumption was that they ignore it
already.
> 
> I really do not see how you reach this conclusion.

OK, I'm partly wrong.  I was misled by how EncryptMessage() works;
DecryptMessage() always only gets a single token.

Take a look at how SSPI's EncryptMessage() works on W2K Kerberos:
It takes 3 (three) seperate Input Buffers:
(1) SECBUFFER_TOKEN, (2) SECBUFFER_DATA, (3) SECBUFFER_PADDING
 
Therefore a GSS-API compliant wrapper to SSPI will always have
to reassemble those three distinct output buffers from EncryptMessage()
into a single buffer before passing it to the application caller in a
single buffer.

> 
> >> My concern is interoperability problems, and Microsoft doesn't
> >> have a very good track record concering interoperability when
> >> it comes to software updates...
> 
> If you referred to windowsupdate, let's discuss it off the list.  It
> should not be relevant to this draft or its implementation.

No, I was referring to a Microsoft colleague who upgraded his
machine from Windows 2000 to W2K3 and suddenly my gsskrb5.dll
didn't work for him anymore.  There were also new bugs added to
64-bit Windows NT for which I had to build workarounds into
gsskrb5.dll and the forgotten QueryContextAttributes(NATIVE_NAMES)
in the 32-bit Emulation layer in Win64 (some people on the list
might remember my complaint...).

> 
> >> The mechanism selection in SSPI is by name rather than by OID as in
> >> GSS-API.  Although I did select "Kerberos", I seem to end up with
> >> a different mechanism (OID) in W2K3 -- OUCH!
> >> Unfortunately this strange change in behaviour completely break
> >> interoperability with my existing gsskrb5.dll wrapper and
> >> regular rfc1964-Kerberos.
> 
> this is the result of some misunderstanding of SSPI. The "Kerberos"
> package acts as a container of a number of OIDs, you should not
> anticipate any particular OID, and if you do, you break the
abstraction.

Now that's another funny way to put it: I'm breaking the abstraction.
No, Microsoft is breaking the abstraction, and for that matter it is
breaking it all over the place.  Even Microsoft's SSPI code samples
in MSDN from the NT4 time (targetting NTLM) were unable to work with 
W2K Kerberos. So much about abstraction.  

You probably don't realize how seriously broken SSPI is and how
unaligned Microsoft's implementation are to their own documentation
on it (it reads like a spec but obviously isn't).

NO, I'm not breaking any abstraction, Microsoft has silently changed
the rules and doesn't care about breaking third-party software.

From April 1997 (Memphis IETF) until 2000 I had a confirmation by
Microsoft (Peter Brundrett and Mike Swift) that Microsoft's Kerberos
was supposed to be fully interoperable with rfc-1964 Kerberos and
the API should offer sufficient functionality to provide such
interoperability to applications.  The addition of
QueryContextAttributes(NATIVE_NAMES) was one of the things I
specifically requested to achieve this and it was implemented.

With W2K3 Microsoft seems to have changed the behaviour of
the "Kerberos SSP" significantly to break such interoperability.
rfc-1964 is crystal clear:  unidirectional authentication: 1 token,
mutual authentication: 2 tokens.  The "context deletion"
of a failed unidirectional or the reply token of a failed mutual
authentication may be a KERB_ERROR token.  But there is never
more than one token in each direction.  (Technically, this makes
the behaviour of W2K Kerberos in some error situations
non-conforming to rfc-1964, since it returns a KERB_ERROR
token along with CONTINUE_NEEDED from AcceptSecurityContext).

The token that you can see in the hex-dump is clearly not rfc-1964
interoperable, so the change in W2K3 clearly breaks the interoperability
for existing applications.

Now what is the approach to request strict rfc-1964 conforming
behaviour in W2K3 so that I can add yet another workaround to
gsskrb5.dll?

Concerning SSPI abstraction:

Did you ever try to use QueryCredentialsAttribute(NAMES) on the NTLM
SSP?
It's wasn't implemented for w9x/nt4.  Do you know what the NTLM SSP in
the
DCOM-Update for Win9x finally returns when querying the acceptor creds?
<hostname>\<logon-domain>  probably because it was realized that there
was NO API-call to find out the domain for which pass-through
authentication
was configured.

Or how about lifetimes of credentials and security contexts.
The SSPI documentation has always said they localtime and NTLM
uses localtime.  Did you ever observe what times are reported
for credentials and contexts with NTLM SSP?
Fortunately W2K Kerberos SSP uses GMT/UTC, otherwise interoperability
with Unix-based Kerberi would be a major PITA.  Guess what this does
to SSPI's abstraction...

And how about the fallback guest authentication in NTLM which
combined with the LSA caching bug in NT4 (that I reported in 1998 and
that got never fixed) causes QueryContextAttributes(NAMES) to
return a name "<hostname>\<requested-username>" instead of
"<hostname>\guest".  The same LSA error happens when doing a
LookupAccount() while still impersonating under guest.

Or the character set that's being used when passing a credentials
via an AUTHIDENTITY_ANSI structure into AcquireCredentialsHandle() --
some (indistinguishable) variants of the NTLM SSP do a CharToOEM,
some correctly treat it as ANSI, so the only safe bet is to use the
UNICODE version of the structure instead -- unfortunately the UNICODE
variant isn't implemented in early NTLM implementations on Win9x...

More AUTHIDENTIY_ANSI curiosities: although the structure uses explicit
length fields, you will get an error if user,domain&password aren't
additionally zero-terminated.

Really, there are so many bugs and inconsistencies in the various SSPs

> 
> Yes, if your KDC is running ws2k3 native mode and your service is
> running under a user principal, you will end up with user2user, I post
> some explanation on this a while back.  The OID you listed below is
the
> user2user OID and it is documented in the user2user draft.

Changing behaviour under everyones feet is always going to break
interoperability for "sophisticated" users, so every visible change
in behaviour should default to off and callers that are prepared to
handle it should request it explicitly.

> 
> There is a JDP program that helps to eliminate all these compatibility
> issues before a product is shipped or a change is made.  I strongly
urge
> you to sign it up if you continue to build and support GSS-API
wrappers
> that poke into SSPI implementation details.  We do have mercy for
these
> kinds of applications, but we are doing so in a case-by-case basis.
In
> any case, I do not see how this is relevant to this draft or its
> implementation.

Since 1999 I have been using my gsstest and gsskrb5 code to test
interoperability between the Microsoft W2K Kerberos SSP and
MIT Kerberos.  It is available as OpenSource at zero cost and
Mike Swift used it to reproduce&fix two W2K bugs in 1999 --
and he was happy that this code compiles even on a Win95
machine even with a plain old Visual Studio 97 compiler no
platform SDK whatsoever.

I have no explanation why Microsoft is still not using it at all.

> 
> In the feature, if you see any issue, please drop me a piece of email;
I
> will make sure we will address it as soon as possible.

There is an issues which the official Microsoft Support hasn't
been able to resolve so far: 

We have a customer who uses SmartCards for the Windows/Domain-Logon
with his W2K Machines.  However when doing that, SSPI will fail
AcquireCredentialsHandle() when being passed the users official
Kerberos user and realm name (no password) via an AUTH_IDENTITY_ANSI
structure.

-Martin

---

From: "Douglas E. Engert" <[email-masked]>
Date: Thu, 09 Oct 2003 11:25:13 -0500

> Most native SSPI applications do NOT re-assemble the buffers into one

They will if they want to transport them over the network. Or then have to
send each of them seperatly packets, and hope the reciever can put them back 
together to pass the single buffer to DecryptMessage. If the output
if EncryptMessage is three buffers, and the input to DecryptMessage is
one buffer, some part of the application or transport had to put them together.

> might not care the progress that NTLM SSP has made to be consistent with

No, It is go to hear, as it shows that you are moving towards interoperability
with other systems using standrds. 

-- 

 Douglas E. Engert  <[email-masked]>
 Argonne National Laboratory
 9700 South Cass Avenue
 Argonne, Illinois  60439 
 (630) 252-5444