On 2009-07-31 12:38 PDT, Ian G wrote:
> On 31/07/2009 11:29, William L. Hartzell wrote:
>> Nelson B Bolyard wrote:

>>> Some lax CAs will evidently issue certs with just about anything in the
>>> DNS names. I'd pull the plug on them if I could find them, but the
>>> presenters at Black Hat were careful NOT to reveal which CAs made the bad
>>> certs for them. I guess that's why they call it "Black Hat".
> 
> For the record, I spent most of the day helping look at this at CAcert 
> (not at the code, myself, but the people).

You looked at the people?  :)

IMO, it would be dishonest of the Black Hat presenters to say that FF 3.0.x
is vulnerable if this flaw requires that the user trust a root CA that is
not distributed with FF 3.0.x.

>>> All these presenters make the same mistake of blaming SSL for a problem
>>> that is not in the SSL protocol anywhere.

SSL itself is agnostic about certificates and CAs.  SSL is used by an
application.  As far as SSL is concerned, certificates are opaque blobs
of data that it transports from one peer to the other.  The application, and
not SSL, decides if such a blob of data is a cert, and if it is valid or
not, and if it belongs to the desired/intended peer party or not.
If it decides that the cert passes all the tests then it gives the public
key from the cert to SSL, which then uses it because the app told it to
do so.

Applications that do SSL generally have multiple related libraries,
including an SSL library and a certificate library.  NSS offers both,
among others.  The faults discussed at Black Hat are certificate library
faults, not SSL library faults.  No change to SSL code is necessary or
suggested to fix them.

> I don't know for sure, but I'll happily speculate:  this is a 
> side-effect of complication.  Using ASN1 and similar results in very 
> tortuous code, which contributes to all sorts of difficulties in production.

I'll agree that ASN.1 code is often tortuous code, but I wouldn't blame this
vulnerability on that.

Ever since there have been "strings" of characters handled by computers,
there have been two fundamentally different ways of organizing them.

One way, often called "Pascal strings", stores the string length explicitly
in memory, separately from (or perhaps adjacent to) the actual array of
characters in memory.  The end of the string is determined by this separate
length, not by any special value of any character in the array.

The other method, often called "z strings" or "NUL terminated strings"
does not store the length explicitly, but requires that a special character
value (binary zero, typically) be reserved to mean "end of string".  This
special end-of-string (a.k.a. NUL, note: one L) character cannot appear
inside of a z string.

Since Pascal strings have explicit lengths, there is no reserved character
in Pascal strings.  Consequently, any character, including NUL, can
legitimately appear in the middle of a Pascal string.

Most programmers spend the vast majority of their careers working with
just one of those.  Some always use pascal strings, other always use
z strings.  They make mistakes and get into trouble when they are asked
to work with strings of the other type, the type they don't normally use.

Programmers in the c language use z strings almost exclusively.  All the
c language functions that operate on strings expect the strings to be
z strings.  Some functions take an explicit length argument along with a
z string, and as they process the string from left to right, they stop
when they reach the specified length, or when they reach the NUL character,
which ever comes first.

SSL and ASN.1 DER encoding both always use Pascal strings.  They do not
recognize NUL characters as having any special meaning.   But there are
"fields" used in in ASN.1 DER encoded certificates that must be compared,
perhaps in a case-insensitive way (DNS names are case insensitive) or
perhaps using wildcards.  Unfortunately, ALL the c language functions
that do that sort of comparison or wildcard matching assume their inputs
are z strings.

So, to do a comparison of two DNS names, one of which is found in a Pascal
string in a certificate, it is necessary to covert that string into a
z string.  And lots of programmers who attempt that get it wrong, including
lots of programmers who have attempted to create libraries for certificates.

When converting a pascal string of known length into a z string, it is
necessary to ensure that ALL the characters get copied, and that only the
very last character of the resultant zstring in the NUL character, even if
there was a NUL character inside the pascal string.  This is done using a
technique known as "escaping".  There are RFCs that define approved and
expected ways to do that, but if a programmer is unaware of them, or simply
forgets to use the special conversion technique required and instead uses a
quick naive conversion, he may create a potential vulnerability.

The problem isn't purely the fault of z string programmers.  Evidently,
some CAs use software that's all Pascal strings, but they forget to check
that each and every character in each Pascal string is an allowed character
for that type of string.  They should stop and reject a string with a NUL
in the middle, because NUL isn't an allowed character in the middle of DNS
names.  But they forget to check that all the characters are allowed
characters, so they see a string like   www.mybank.com0*.badguy.org
(where that 0 represents a NUL) and they see the asterisk, and figure
they can only check the stuff to the right of that, so they ignore every
thing to the left of it.  It takes two mistakes from two different kinds
of programmers to make this vulnerability exploitable.

> One can say "they should write good code" but that's just hopeful.  To 
> echo Dan, to fix this we should really start again using techniques 
> developed more in more modern times.  But that's equally hopeful :)

Has someone invented another string representation that is neither zstring
nor pascal? Has someone found a way to ensure that programmers don't forget
to check for disallowed characters in strings?

-- 
dev-tech-crypto mailing list
dev-tech-crypto@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-tech-crypto

Reply via email to