Subject: Packet length: header vs. context

From: Levi Broderick <[email-masked]>
Date: Fri, 05 Jan 2007 16:05:57 -0600

(resending, as the original message seems to be MIA)

Consider the following scenario:

An implementation is parsing a public-key packet.  The packet header
gives a body length of 600 bytes; this is then buffered into memory.
The software successfully parses all the data in the packet body -
everything from the packet version number to the final MPI that it was
expecting - and realizes that it has only read 400 bytes.

Even if the public key data was successfully parsed, should the
implementation consider the packet to be malformed and reject the key?
Or should the leftover data be considered optional and be ignored?  I
think it makes more sense to error out, but the RFC draft and mailing
list archives seem to be silent on this issue.

On a somewhat related note, are V3 partial-length headers limited to the
same context as V4 partial-length headers?  That is - are they allowed
only on data packets?

Thanks for your help!
~ Levi

---

From: Ian G <[email-masked]>
Date: Sat, 06 Jan 2007 15:09:44 +0100

> list archives seem to be silent on this issue.

This sounds like one of those philosophical questions about 
coding, and it may be that the draft would be better off 
remaining silent on that question.

The GNU world characterised this as "be precise in what you 
send, be liberal in what you read."  That is, be 
accomodating when finding input.  In this context the answer 
to the above question is "accept the key."

I think it was Dan Bernstein (?) who said something 
different.  He said, "in security work, be precise in what 
you send, and precise in what you read."  So his answer 
would be "reject the key."

I like the second answer for security work, but OpenPGP is 
somewhat in between these worlds;  there are several 
implementations and they all have foibles, and the coding 
history goes back a long time.  It is a fact of life that 
there have been "disagreements" on how to interpret certain 
things, and differing implementations have had to deal with 
it;  we can't just "start again" with all the implementations.

How to deal with that world?  I would say that (a) your 
market will tell you, and (b) you might want a third mode of 
"accept but warn" alongside "reject" and "accept."

Finally, the ID has passed the point of minor tweaks.  We've 
been at this for a decade now.  No more changes please, seal 
the document and let's move on.  I vote NO to any changes, 
even without knowing what they are ;)

iang

---

From: Jon Callas <[email-masked]>
Date: Sun, 7 Jan 2007 15:00:44 -0800

On Jan 6, 2007, at 6:09 AM, Ian G wrote:

>
> The GNU world characterised this as "be precise in what you send,  
> be liberal in what you read."  That is, be accomodating when  
> finding input.  In this context the answer to the above question is  
> "accept the key."
>

Postel said that, actually, long before there was any GNU except  
those one might find in a zoo.

	Jon

---

From: Levi Broderick <[email-masked]>
Date: Sun, 07 Jan 2007 17:19:58 -0600

Ian G wrote:

> Finally, the ID has passed the point of minor tweaks.  We've been at
> this for a decade now.  No more changes please, seal the document and
> let's move on.  I vote NO to any changes, even without knowing what they
> are ;)

Of course!

The reason for my original question was that I was unsure if such a
packet could be used to undermine the security of any protocols in the
system.  Now that I think about it, though, I don't see how it could be
done.  It's unlike other attacks that use the software as an oracle
since public key information is - well - public. :)

~ Levi

---

From: Jon Callas <[email-masked]>
Date: Sun, 7 Jan 2007 15:56:08 -0800

Ian touched on many of the salient points of this dilemma. The most  
correct answer to the problem you pose is "mu."

This is something that you have to make a personal decision on.

Let's suppose that the standard said something definitive on this.  
Many people have gotten into a lot of trouble by over-implementing  
standards. Let's suppose, for example, that you reject the key. Let's  
then suppose that someone finds that they can't import in keys that  
were created with software X on OS Y with a key size of a prime  
number of bits.

Well -- what do you do? There are people who want to use your code  
and can't, and it's not your fault. Screw 'em, they're the ones who  
got the standard wrong.

But when it turns out that the problem is that your software doesn't  
work with the new OpenPGP in Linux that runs underneath Windows  
Mobile Horizon that ships in the new Apple iTunesFone (when it  
creates keys 1987 bits long (selected because it's a prime number  
*and* the year programmer's GF was born -- cool, huh?)) and because  
of it, people can't download music from WalMart's GNU Music Share --  
well, the story on Slashdot is going to have *your* software's name  
on the headline, not theirs. You'll be changing your code to ignore  
that one extra byte because otherwise every phone in Korea has to be  
re-flashed, and it's faster for you to change than them. (Something  
similar to this happened to PGP once, but I changed the name of the  
country in my explanation.)

An alternative to just accepting that packet would be to lop off the  
extra data (which will be ignored), and make the length correct.

When you implement a protocol, there are often more choices than  
being anal or passing idiocy through. In the one you've given, it's  
almost certainly true that you can tweak the packet to the right size  
and not affect anything else. So why not do so?

It might also be a good thing to tell the people who are doing  
something dumb that they're doing something dumb, but don't expect  
them to fix it tomorrow, especially since there's a workaround. When  
it's been a couple of years and no fix has arrived, you have earned  
the right to be snarky, but by then you probably forgot the  
workaround you put in your code, too.

As for your second question -- where partial lengths can be used --  
what's your real question? Do you want to use them in places other  
than data packets? Is someone subjecting you to them and it's a pain  
in the neck to parse them?

It's Sunday afternoon and I need to run some errands, so I don't want  
to go crawl through the spec. I *believe* that they can be used  
anywhere. But I also believe they shouldn't be used everywhere. In  
the case of a 400-byte packet header, whatever would possess someone  
to do that? Yeah, I'm sure it's legal, but don't do it. If it's the  
software I'm responsible for that's doing something cringe-worthy,  
I'm sorry.

Partial lengths exist so that you can process arbitrarily large  
chunks of data that don't fit in memory and might even be  
inconvenient for you to know the size of a priori. That really means  
data packets. However, as a software engineer, I think that even if  
some idiot chopped up a 400-byte key packet into 2-byte partials,  
your software ought to work. If it doesn't, you have to consider who  
the idiot is. That brings us back to the original consideration.  
Welcome to being a software engineer. Sometimes the things we have to  
do because other people are idiots suck. A sense of humor helps deal  
with it, but doesn't prevent it from sucking.

	Jon

---

From: Jon Callas <[email-masked]>
Date: Sun, 7 Jan 2007 16:07:39 -0800

> since public key information is - well - public. :)

In the pre-OpenPGP protocols, there were "comment" packets. We  
removed them because people worried about them being a "covert"  
channel. I put "covert" in quotes because the specific case Jeff  
Schiller (then Security AD) gave was of an implementation that  
lowered the security to 40 bits by putting N-40 in a comment. This is  
also why the marker packet is defined the way it is.

I remember talking to Jeff and said that someone could stick anything  
in packet slack space. He said, "That's different. We shouldn't give  
a *defined* place for a covert channel." He was right.

A sufficiently devious person can put covert channels nearly  
anywhere. (This is why steganography isn't an interesting discipline.  
It's very easy to think of mats to leave keys under.) You could, for  
example, leak key bits or even code a secondary message in OpenPGP  
with partials. Imagine that each partial is a bit, denoted by log2 
(size) & 1. Whee.

	Jon

---

From: [email-masked] (Peter Gutmann)
Date: Mon, 08 Jan 2007 17:37:26 +1300

Jon Callas <[email-masked]> writes:
>Postel said that, actually, long before there was any GNU except those one
>might find in a zoo.

And before Jon Postel said that, the MIT hackers said "Look for anything that
says 'Don't to X', then try as many variations of X as possible.  "Postel's
Law" is great for interoperability, terrible for security.

Peter.

---

From: Ian G <[email-masked]>
Date: Mon, 08 Jan 2007 16:23:05 +0100

Levi Broderick wrote:
> done.

Always worth probing, as long as you don't mind the cringing 
of those fearful of yet more changes to the Doc :)

> It's unlike other attacks that use the software as an oracle

Just a minor quibble:  just because a key is named "public", 
it doesn't mean it is public.  The key marked as "public" is 
to be sent to your counterparty ... and we need to be 
careful to not confuse counterparty with "the whole world."

(I say this because I recently saw a discussion where a CA's 
criteria for audit specified that the public keys had to be 
published in public ... and the CA in question deliberately 
does not publish public keys ... because that might breach 
privacy rules ... )

iang

---

From: Ian G <[email-masked]>
Date: Mon, 08 Jan 2007 17:55:53 +0100

> Law" is great for interoperability, terrible for security.

Thanks guys, I stand corrected!  Perhaps it is better termed 
"Postel's Proposition" because of the rather large exception 
perhaps captured as "Bernstein's Anti-Corollary?"

I for one think that the Postel view is bad for 
interoperability as well because it leads to a loose and 
divergent community, which eventually leads to standards 
wars.  Oh joy...

iang

---

From: Jon Callas <[email-masked]>
Date: Mon, 8 Jan 2007 16:35:02 -0800

> Law" is great for interoperability, terrible for security.

I'll disagree just a bit, Peter, because one of the best ways to get  
security is a lack of interoperability. Rip your network cable out of  
the wall and you have great security.

Yes, if you maximize interoperability, it has effects on security.  
Yes, you can come up with an interoperability hack that is cringe- 
worthy from a security standpoint. Yes, the Internet as we know it is  
riddled with them. But the Internet as we know it out-competed other,  
more secure systems, and succeeded against them because it viewed  
interoperability as the primary virtue (and had an attitude about  
security that included lines like, "polite clients don't *do* that").

"Postel's Law" is a valuble rule of thumb. You *should* (maybe that  
should be SHOULD) be conservative in what you generate and liberal in  
what you accept. It just shouldn't override everything else. The more  
that the rough consensus of implementors succeeds at the former, the  
less it needs to do of the latter. Writing software is an art, not a  
state machine. It needs wisdom.

The example we got here was a good one because there's no obvious  
most right answer. My opinion is that the best answer is to fix up  
the bad data and proceed. That has its own drawbacks. Just accepting  
it is probably worst, but rejecting it isn't that much better.

Interoperability matters. Without it, we don't need security.

	Jon