Subject: Re: ASN.1 header proposal

From: Martin Rex <[email-masked]>
Date: Tue, 14 Oct 2003 16:48:11 +0200 (MET DST)

Liqiang\ wrote:
> 
> How about making the ASN.1 header optional, the sender can send the
> message with or without it, but the receiver must be able to accept
> both. AS of MS, we are looking into turning on the header encoding via
> out of band mechanisms, say group policy, for debugging purposes only.
> Martin, are you willing to accept that?

Sounds like a good idea.

I would suggest to define a gssapi context level flag (a generic one
that should be added to rfc2743bis whenever that is updated),
something like "GSS_C_FLAG_MINIMAL_MP_FRAMING" for Minimal message
protection framing which an application can explicitly request.

But I would strongly recommend that you then reserve the 0x60 0xYY
token values and add descriptive how to parse the incoming tokens
(as I've suggested before) and all the constraints when building
outgoing token regarding interoperability with the installed base
of rfc-1964.

> 
> As it turns out, in Microsoft TS scenarios, the messages are mostly
> tiny, and such extra 15 bytes can count to up to 20% of the total
> traffic.

Personally, I wouldn't bet on any such numbers if I were you.
On the network you usually face a minimum PDU size (Ethernet 64 octets)
and for memory management (heap allocators) memory in small sizes
are usually allocated in steps of ^2 sizes (16,32,64,128) octets
for more efficient management.

Regular rfc1964 Kerberos uses SIGN tokens of about 37 octets
and WRAP tokens that are 46-48(50) octets larger than the
contained application data.

And the processing of the generic framing is should really be
NIL compared to the crypto operations that are required for
SIGN and WRAP tokens.

The Simple Public Key mechanism (rfc2025) has only one mandatory
to implement MIC algorithm, and that is an RSA digital signature.
Besides being a real performance killer a digitial signature also
requires quite a bit of space, especially when using long keys.

Several vendors of gssapi mechanisms that showed up for interoperability
certification with our software had to optimize their code to meet
our performance constraints and the message size growth limit
of 128 octets that we require (the architectural constraint for
this size limit has been overcome several years ago, but I never
dropped the constraint in the interoperability certification).

When I first tested with MIT Kerberos5 in 1995/6 on relatively
small CPUs (486/66, Pentium-60, PA-Risc 7100-40Mhz) and defined
performance constraints for interoperability based on those
CPUs, with limits at 3-10x slower than what MIT Kerberos5 delivered
on those platforms.

Although CPU horsepower has increased at least 10x since then, I
have to convince almost every new vendor that shows up that some aspect
of his implementation is not particularly efficient because it barely
succeeds our ancient performance constraints (measured in milliseconds
per API-call) on today's hardware.

We had extremes up to 500x slower than our constraints on certain
calls.  So far each vendor was able to improve his implementation
to meet our performance constraints, often a larger than 10x
improvement...

-Martin

---

From: Nicolas Williams <[email-masked]>
Date: Tue, 21 Oct 2003 08:23:22 -0700

[I never got the e-mail from Larry that Martin quotes.]

> > Martin, are you willing to accept that?

I think it's horrible.  It adds complexity for no good reason.

If negotiated, what initiators would ever choose to use the ASN.1
wrapper, how (what API) and why?

If not negotiated, we must be extra careful to make sure that it's
always possible to tell the difference between a wrapped token and an
unwrapped token.  But the same question as above applies: what acceptor
would ever choose to use the ASN.1 wrapper, how and why?

Cheers,

Nico
--

---

From: Martin Rex <[email-masked]>
Date: Tue, 21 Oct 2003 18:49:44 +0200 (MET DST)

> [I never got the e-mail from Larry that Martin quotes.]

Because Larry apparently forgot to Cc it to the list--which is why
I didn't realize my Reply didn't go to the list either.

> I think it's horrible.  It adds complexity for no good reason.

Not at all.  The complexity comes from having the header removed.

> wrapper, how (what API) and why?

ALL portable app initiators that don't specifically request the header
to be left off would get it just as with rfc-1964.
 
> would ever choose to use the ASN.1 wrapper, how and why?

You always have to get that right, I specifically pointed that out long
ago.  Seems like you've missed most of the discussion.

-Martin

---

From: Nicolas Williams <[email-masked]>
Date: Tue, 21 Oct 2003 09:51:15 -0700

> Not at all.  The complexity comes from having the header removed.

Having this option is worse than not having it.

> to be left off would get it just as with rfc-1964.

And just how would one request that the wrappers be left off?

> ago.  Seems like you've missed most of the discussion.

I skimmed most of the discussion.  It's clear from the context whether
one should expect a context token with or without the wrapper, so I
don't agree that dropping the wrapper creates any problems.  It's not
true for packet sniffers, but hey, we can make sure that they can figure
it out from the first octet of the token.

Nico
--

---

From: Martin Rex <[email-masked]>
Date: Tue, 21 Oct 2003 19:15:04 +0200 (MET DST)

> And just how would one request that the wrappers be left off?

I can't believe that you missed it...

:
: I would suggest to define a gssapi context level flag (a generic one
: that should be added to rfc2743bis whenever that is updated),
: something like "GSS_C_FLAG_MINIMAL_MP_FRAMING" for Minimal message
: protection framing which an application can explicitly request.

> it out from the first octet of the token.

It may be "clear from the context", but it may not be obvious to
implementors that this may change during communication on a security
context -- with PROT_READY the negotiation may complete after several
protected messages have already been protected (and maybe sent)
by the initiator.  And what do you do about unidirectional authentication
where there is no negotiation (i.e. the initiator never gets an
AP_REP, so no confirmation of a negotiation result and neither
an acceptor-asserted subkey.

My original comment on this from Oct, 8th:
: Add the following:
:   all Token IDs 0x60 0x00 through 0x60 0xff are reserved and
:   must never be assigned by this or a future rfc1964 successor.
: 
: Describe exactly how an implementation should decide how to process
: a message token in gss_unwrap() or gss_verify_mic().  Example:
:   look at the first byte, if it is 0x60 then the token must carry
:   the generic gssapi framing.  if the first byte is not 0x60,
:   then the parser should try to interpret it as an inner token.
: 
: Describe exactly how an implementation should decide in gss_wrap()
: and gss_get_mic() whether to add or to leave off the generic framing.
: Make sure the description *fully* covers Kerberos implementations
: that provide PROT_READY today and may want to continue providing
: that feature.  -- this part is harder.  Whoever wants the change
: should help coming up with a sufficiently clear spec.

-Martin

---

From: Nicolas Williams <[email-masked]>
Date: Tue, 21 Oct 2003 10:20:57 -0700

> I can't believe that you missed it...

Well I must have then.

> an acceptor-asserted subkey.

With PROT_READY there's no way to process per-msg tokens before
processing the initiator's context token - not with this mechanism.

In all applications I'm aware of it is possible to determine from the
context whether a given token is a context token or a per-msg token, and
even if it weren't, with this mech an acceptor that has not yet
processed an initiator's context token cannot do anything with per-msg
tokens.

As for non-mutual authentication, the negotiation happens, as in the
mutual authentication case, in the KDC exchange.  If the session key in
the ticket is of a "newer" enctype, then the acceptor MUST support the
new mechanism[*].

[*]  A more correct way of putting this is that KDCs MUST NOT issue
     tickets with session keys of "newer" enctypes if the target
     principal does not support such newer enctypes, etierh in raw AP
     exchanges or in the Kerberos V GSS-API mechanism.

Cheers,

Nico
--

---

From: Ken Raeburn <[email-masked]>
Date: Thu, 23 Oct 2003 15:42:37 -0400

> Having this option is worse than not having it.

I agree with Nico.  While at the moment I'm only weakly in favor of
keeping the wrapper, I think having it be optional for cfx (and
required for RFC 1964 tokens) sounds like the worst of the options.

Ken

---

From: Martin Rex <[email-masked]>
Date: Thu, 23 Oct 2003 22:38:46 +0200 (MET DST)

> required for RFC 1964 tokens) sounds like the worst of the options.

Not at all.

I remember that Ted Ts'o talked about the overhead of the generic
gssapi framing for protocols like telnet, and he proposed that a
context-level flag could be used to indicate to the gssapi mechanism
that it should not put the generic gssapi framing in front of
message protection tokens.

I still think that is the best approach today.
Leave it as it is per default and fix error reporting of current
Kerberos implementations (they're lousy in checking the PDU length
field and reporting reasonable errors today).  That will help
app developers to determine when their apps are buggy and it
will not noticably affect 98% of the applications anyway.

Those apps that do care can request the context level flag
and run without the generic token framing.

-Martin

---

From: Nicolas Williams <[email-masked]>
Date: Thu, 23 Oct 2003 14:01:52 -0700

> message protection tokens.

This assumes that mechs do that.  No mech should do that though and the
GSS-API never required it.

> I still think that is the best approach today.

So, what should be the default?  Who would decided when to use it and
when not to?  Based on what?  Why is this option something that
developers should know or care about?  Why should we have a "be
more/less efficient" option when there is no positive result from being
less efficient (there's no trade-off)?

How is not using the wrapper, given the negotiation we've proposed
(i.e., in the KDC exchanges) an incompatible change that warrants this
option?

> will not noticably affect 98% of the applications anyway.

I don't get the relation between the one thing [to use or not to use the
wrapper] and the other [application bugs].

You continue to imply that applications write GSS-API tokens on the wire
with zero encapsulation at the application layer.  Which apps?  (Maybe
GSI's SSL-based mechanism where, if you write the tokens and nothing
else the result is SSL on the wire - but that's a very special case.)

How can such apps (leaving GSI SSL apps aside) work unless they use
transports that preserve message boundaries or are datagram based?

(After all there's no GSS-API function that given a buffer tells you how
long that buffer should be given its mech-specific header.)

And anyways, the new mech's tokens' lengths can be determined from
inspection - so what does the DER wrapper add then?  Nothing, methinks.

Where's the evidence that not including the DER wrapper will cause
problems?  (Again, we already know how to negotiate the use of the new
mech, so there is no danger of confusion.)

> and run without the generic token framing.

Which would those be?

Cheers,

Nico
--

---

From: "Joel N. Weber II" <[email-masked]>
Date: Thu, 23 Oct 2003 18:23:33 -0400

> message protection tokens.

So, why is the telnet ``problem'' worth solving?

It looks like these days, people who want to use that sort of protocol
in conjunction with gssapi tend to use ssh, and the way that ssh is
intergrated with gssapi is such that you only use gssapi at the
beginning of the connection setup.  I'm a little unclear on what
telnet like protocols people intend to use with gssapi encrypting each
character.

Second, as someone who tends to make fairly extensive use of telnet
like protocols over a wide variety of types of links (I've used a 14.4
modem, nowadays I normally use 56kb/112kb ISDN, occasionally I end up
using something faster), I've never felt like an extra 10 bytes (or
whatever) of overhead for every character I type would make any
significant difference in the congestion, throughput, or latency of
any link I've been using.  Maybe it would matter if I were at a large
site with a large number of users, all of whom used telnet like
protocols, and none of whom surfed the web, but I kind of doubt that's
an especially common configuration in general.

---

From: "Theodore Ts'o" <[email-masked]>
Date: Thu, 23 Oct 2003 18:44:38 -0400

> GSS-API never required it.

No mechanism does this today, but the GSS-API does not forbid it; the
framing is only required for the context establishment tokens.

So this would something that would have to be added to future
mechanisms, if this approach were to be taken.

						- Ted

---

From: Nicolas Williams <[email-masked]>
Date: Thu, 23 Oct 2003 16:01:09 -0700

> framing is only required for the context establishment tokens.

The Kerberos V mechanism does this today.  The DER wrapper is required
ONLY for initial context tokens - the OID from the wrapper is redundant
for any other tokens.

> mechanisms, if this approach were to be taken.

We're talking about the new Kerberos V mechanism not using the silly DER
wrapper.

(The new mech will use the same OID as the old mech - its use will be
 negotiated in the KDC exchanges).

Cheers,

Nico
--

---

From: Martin Rex <[email-masked]>
Date: Fri, 24 Oct 2003 19:28:29 +0200 (MET DST)

> less efficient (there's no trade-off)?

Come on, the "efficiency" is really a moot point and has been discussed
to death.  On my initial complaint Sam explicitly pointed out that
the additional size wasn't the motivation for proposing that change.

The default should be the generic framing present, just as in rfc-1964.

Look at the inner token again, it doesn't contain a PDU length field.
That's a seriously bad tradeoff.  I would feel much better if the
Token with no leading mechanism OID had at least a PDU length field,
but that would make implementations even more complex.

> (i.e., in the KDC exchanges) an incompatible change that warrants this

I *NEVER*  disputed that it would be incompatible if correctly constraint
to new enctypes, I just said that it will increase implementation
complexity, is error-prone for implementors to get the conditionals
right and that the current document is UNDERSPECIFIED, screaming
for interoperability problems. 

Also keep in mind that the currently proposed change is NOT a negotiation,
but a result of the selection of an specific enc-type before the initiator
sends the first context level token.

> wrapper] and the other [application bugs].

The only PDU length field in protected messages in rfc-1964 is in the
generic framing.  And that length field should be used and checked
by the gssapi mechanism to distinct probable errors at the application
layer from crypto-related failures or possible attacks,
e.g.
   - token doesn't look like a protected message token at all
     when it doesn't have the generic framing with the rfc-1964
     mechanism OID at the beginning
   - token trucated (the length field in the generic framing
     indicates that the token should be longer than the buffer
     that the application passed in.
   - trailing garbage (the length field in the generic framing
     indicates that the token is actually shorter than the
     buffer that the application passed in.

It is extremely valuable if a mechanism determines and distinguishes
these kinds of errors from failures at the cryptographic level.
I know that many existing Kerberos implementations are very poor
at reporting errors, but that are simple bugs that can be fixed
and not deficiencies of the protocol.

By removing the length field from the protected message PDU it
would become impossible for the gssapi mechanisms to distinguish
these errors and that would definitely constitute a serious
protocol deficiency.

>  with zero encapsulation at the application layer.  Which apps?

I *NEVER* did that.

> (Maybe GSI's SSL-based mechanism where, if you write the tokens and nothing

Well, every application that uses a datagram-style communication wouldn't
need any application level framing.  I know that Denis Pinks and
Carlisle Adams were proponents of zero-overhead application framing
during discussions in the CAT IETF working group.

With your reasoning one should revision almost every protocol layer removing
PDU length fields because there's already one in the next layer.
You would probably rip the length field out of IP datagrams when running
over Ethernet.

> inspection - so what does the DER wrapper add then?  Nothing, methinks.

Huh? How -- please explain, I seem to have missed something important!

> mech, so there is no danger of confusion.)

You probably are not in the software business or you would know better.
Bugs in software are very common, and that is not likely to change.

Although I'm a developer and really love to write code, I have to spend
at least half of my time chasing bugs in software of other people.
All my code tries its best to produce helpful error message that
describe the situation where the error happened, and if there is
a little redundancy it is much easier (=faster) to find the source/cause
of the problem.  And most of the time I don't have access to the
machines where the error happens, often there isn't even a debugger
available, and also no one at the customer site who could operate
it if it were.

The bugs that one will face are manyfold: bugs in upper application layers,
bugs in application middleware, bugs in lower application levels, bugs
in gssapi mechanisms, interoperability problems among independent
implementations of a gssapi mechanism.

And for all of that, the presence of the generic gssapi framing will
provide significant help in determining where the bug(s) are.

> > and run without the generic token framing.

THOSE that really need it and care about it, like the tons of
tiny messages for the Transaction Server that Larry mentioned.

Apps which don't supply the context level flag will not have
a problem with the few extra bytes but, and that will be the large
majority of apps.

-Martin

---

From: Martin Rex <[email-masked]>
Date: Fri, 24 Oct 2003 19:41:20 +0200 (MET DST)

> an especially common configuration in general.

It apparently wasn't worth "solving", that's why noone did it.
But it was only an example, there are low-overhead communications
protocols where several additional octets do matter, although
they're extremely rare, particular in this millenium.

I started using the internet in 1992 with a 14400 modem my home PC
running Linux to an SGI Indigo workstation at the university.
At that time I did a 5 MByte compressed news tarball download daily.

Have you ever heard of "term", a program to proxy TCP/IP protocol
over a modem line with a packetizing protocol and an extremely low
overhead and using priorities on top of that?  I could work
with telnet-style connections and read my Email while the download
happened in the background at low priority, almost unnoticed.
If you did an FTP download via a 14400 SLIP or PPP dialup, it was
barely possible to use a parallel telnet session while the FTP
was in progress.

-Martin

PS: but what did you actually intend to express?
    do you agree that a few octets in saved size isn't worth additional
    complexity and the loss of valuable protocol information?

---

From: Nicolas Williams <[email-masked]>
Date: Fri, 24 Oct 2003 11:04:02 -0700

> The default should be the generic framing present, just as in rfc-1964.

Give us some good reasons please.

> Look at the inner token again, it doesn't contain a PDU length field.

Do applications look inside tokens?  Applications MUST provide the token
data _and_ length to the GSS-API, which means that applications MUST
independently know the tokens' lengths, which they cannot determine from
token inspection (since there's no API to do so), which means that
applications MUST encapsulate tokens themselves.

> That's a seriously bad tradeoff.  I would feel much better if the

How so?  To answer this you must answer the question above.  And see
below.

> but that would make implementations even more complex.

The mechanism can verify that the token length given by the application
is correct.  Why is more needed?

> I *NEVER*  disputed that it would be incompatible if correctly constraint

I thought you might argue that, if you hadn't, so I wanted to cover that
base.  I did not mean to imply that you had.

> for interoperability problems. 

Several implementors have already decided to have separate code paths
for rfc1964 and CFX.  We believe the resulting code will be a lot
cleaner.  Just look at existing MIT rfc1964 code and you'll understand
why (this is not a dig at MIT - I'm pointing out that a single code path
for rfc1964 for all the enctypes available for rfc1964 results in hairy
code).

> sends the first context level token.

That is a form of negotiation, by proxy.  The client will not ask for
new enctypes if it's an rfc1964-only initiator, and a KDC won't issue
tickets with session keys of the new enctypes for principals that are
rfc1964-only acceptors.

>      mechanism OID at the beginning

This particular check adds no value.

>      that the application passed in.

The length in the DER wrapper is not integrity protected in rfc1964, so
it cannot be used to make this check.

>      buffer that the application passed in.

The length in the DER wrapper is not integrity protected in rfc1964, so
it cannot be used to make this check.

I.e., these three checks that you propose add no security to the system.
Therefore the DER wrapper is redundant and useless.

> these kinds of errors from failures at the cryptographic level.

We're only interested in: securely validating the token length passed in
by the application *and* securely verifying the MIC / unwrapping the
wrap tokens.  The proposed mechanism (modulo the changes that Larry will
make in response to Ken's issues about MIC/wrap aliasing) does this.

> these errors and that would definitely constitute a serious

But we don't care to distinguish such errors - either the token is
valid, or it isn't, and if it isn't we don't care why it isn't - it just
isn't.

"This HMAC doesn't check out," "why?" "well, the data must have been
changed - dunno how as there are no error correction codes," "ah, ok."

> >  with zero encapsulation at the application layer.  Which apps?

Your argument for the DER wrapper made me think you did imply that,
since I saw, and still see, no use for the length in the DER wrapper.

Note I said "imply," which you can take to mean that that was the
meaning I derived from your objection.

> PDU length fields because there's already one in the next layer.

No, we're just getting rid of the DER wrapper in the new mechanism.
We're doing so because the DER wrapper was never integrity protected, so
it added no security value.

> You would probably rip the length field out of IP datagrams when running

I do seem to remember something about compressing IP in various tunnels.

> Huh? How -- please explain, I seem to have missed something important!

Sorry, I was wrong - I got ahead of myself.  The application must
provide the token length and the mechanism has a way to validate that
length.

> Bugs in software are very common, and that is not likely to change.

I'm in the security business.  The DER wrapper is not integrity
protected and is redundant.  From my point of view it adds nothing to
the security of the mechanism, therefore I don't want it.

> available, and also no one at the customer site who could operate

Arguably the redundancy of BER/DER/CER and ASN.1 tagging has been the
source of many security bugs.

> provide significant help in determining where the bug(s) are.

Are you planning to implement the new mechanism?

Cheers,

Nico
--

---

From: Nicolas Williams <[email-masked]>
Date: Sat, 25 Oct 2003 10:25:35 -0500

I take back one thing: the DER wrapper is implicitly integrity
protected.

But it's still redundant.  And I can very well see a programmer
forgetting to verify the OID and/or token length in the DER wrapper - at
worst this might cause the mech to read past the end of a token buffer,
at best it would create a covert channel.

I think redundancy, in this case, is bad.

Cheers,

Nico
--

---

From: Martin Rex <[email-masked]>
Date: Mon, 27 Oct 2003 19:32:36 +0100 (MET)

> I take back one thing: the DER wrapper is implicitly integrity

Not really. You should be able to get away with non-canonical encoding
of the token length field if you wanted to achieve a fixed header length
as I explained a while ago upon Larry's request for a fixed length header.

And you would get away with an entirely different OID in front of the
message token as well if the gssapi mechanism didn't care to verify it
explicitly.

Of course, I would expect that a trucated token or token with
trailing garbage and a doctored length would fail the cryptographic
processing later on.

> I think redundancy, in this case, is bad.

It may not be necessary for the basic operation of the protocol,
and the OID may be implicit for the (security) context, but the
length field is definitely not redundant and extremely valuable
in producing good error messages.

The reason why the inner token doesn't have a seperate length
field is because that would have been redundant.  But by chopping
away the generic framing you would also loose the PDU length field,
and THAT really is a BAD IDEA.

-Martin

---

From: Nicolas Williams <[email-masked]>
Date: Mon, 27 Oct 2003 11:06:51 -0800

On Mon, Oct 27, 2003 at 07:32:36PM +0100, Martin Rex wrote:
> Not really.

The DER wrapper is implicitly protected as follows:

 - the mechanism knows what OID should be listed in the wrapper, which
   can only be one OID as per the established context

 - the mechanism knows that the token length MUST match the length
   provided by the application (adjusted by the length of the DER
   wrapper)

 - the Kerberos cryptosystem and the CFX tokens provide integrity
   protection for the length of the token implicitly by protecting
   against token truncation/extension attacks (which protection depends
   on the enctype being used)

>             You should be able to get away with non-canonical encoding

What does this have to do with the DER wrapper being integrity protected
or not?

> message token as well if the gssapi mechanism didn't care to verify it

Which would make a covert channel.

> trailing garbage and a doctored length would fail the cryptographic

Correct - this is the source of the implicit integrity protection of the
DER wrapper that I claimed.

> in producing good error messages.

It is redundant.  The application MUST provide the correct token length
else nothing works.  Given this the length in the DER wrapper is 100%
redundant.

> away the generic framing you would also loose the PDU length field,

Q.  So?  What harm comes from not having the length in the token itself?
A.  As long as the cryptosystem protects against token
    truncation/extension attacks: none.

> and THAT really is a BAD IDEA.

Show us how that is a bad idea; show us some security problems that
arise from not having the token length in the header (again, assume that
the cryptosystem protects against ...); show us how not having that
token length in the header makes some attack possible.

If you cannot, I think the redundancy-in-encoding-is-bad viewpoint wins.
I've seen the kind of implementation bug I think the DER wrapper makes
possible, so I think we have a good reason to remove it (not merely
aesthetic considerations).

Cheers,

Nico
--