Subject: DER encoding of KeyUsage BIT STRING

From: John Thielens <[email-masked]>
Date: Tue, 06 Mar 2001 14:23:54 -0500

I am encountering a problem with a CA that chooses to always encode the KeyUsage BIT STRING as a bit string of length 9, even if this length includes trailing 0's.  Every other CA I have encountered encodes KeyUsage as a minimum-length BIT STRING, stripping off any trailing 0's.

From 2459:

KeyUsage ::= BIT STRING {
           digitalSignature        (0),
           nonRepudiation          (1),
           keyEncipherment         (2),
           dataEncipherment        (3),
           keyAgreement            (4),
           keyCertSign             (5),
           cRLSign                 (6),
           encipherOnly            (7),
           decipherOnly            (8) }

For example, a CA certificate with digitalSignature (0), nonRepudiation (1), keyCertSign (5), and cRLSign (6), mapped out as:
   BITS = 1100 0110 0
which would appear "normally" as:
  03 (BIT STRING) 02 (of length 2) 01 (with 1 pad bit) C6 (BITS as above)
in this "unusual" case appears as:
  03 (BIT STRING) 03 (of length 3) 07 (with 7 pad bits) C6 00 (BITS as above)

Ordinarily, I wouldn't even notice.  But in this case, the certificate goes through a toolkit that parses the certificate into an internal canonical form and then regenerates its own DER encoded certificate, thereby changing the second encoding into the first.  You can imagine the consequences when I calculate the hash on the tbsCertificate that results.

So which statement is true?

1) the "unusual" CA is at fault for generating an improper DER encoding with trailing 0's explicit in a BIT STRING.

2) the toolkit is at fault for not preserving the explicit trailing 0's in an alternate DER encoding of the KeyUsage BIT STRING with a semantic subtlety.

3) the "unusual" CA is using the technically most correct encoding, and the rest of the world shares a flaw where trailing 0's are truncated improperly.

Thanks for any insight from the DER experts!

John Thielens
ValiCert

---

From: Peter Gutmann <[email-masked]>
Date: Tue, 6 Mar 2001 14:51:57 -0500 (EST)

John Thielens <[email-masked]> writes:

>Ordinarily, I wouldn't even notice.  But in this case, the certificate goes
>through a toolkit that parses the certificate into an internal canonical form
>and then regenerates its own DER encoded certificate, thereby changing the
>second encoding into the first.

Is there really a toolkit out there which does that?  Wouldn't that break about
90% of the certificates in existence?

(I'm not just being facetious with that question, I can't imagine how anyone
 could field a toolkit which recodes certs into correct DER without finding
 that almost everything they try fails to work after the recoding.  Which
 toolkit is this?  I should probably put a warning about this in the style
 guide).

>trailing 0's explicit in a BIT STRING.

Yes, look up the rules for named bit strings in X.680/690 (I don't have a copy
handy at the moment so I can't quote chapter and verse).  OTOH the CA isn't
that unusual, a lot of CAs and implementations do this (thus my surprise that
the toolkit managed to get past any field testing with that behaviour).

Peter.

---

From: Ambarish Malpani <[email-masked]>
Date: Tue, 06 Mar 2001 15:25:46 -0800

Hi Steve,
    What I was referring to, was the fact that SSLeay/OpenSSL
does break up a structure into its component pieces and then
re-encode them to, for example verify signatures, etc.

    I know I had encountered this behavior when somebody was 
BER encoding their data for transmission (even thought they
had signed the original DER encoding of the data).

Regards,
Ambarish

---------------------------------------------------------------------
Ambarish Malpani
Architect                                                650.567.5457
ValiCert, Inc.                                  [email-masked]
339 N. Bernardo Ave.                          http://www.valicert.com
Mountain View, CA 94043

> -----Original Message-----
> From: Dr S N Henson [mailto:[email-masked]]
> Sent: Tuesday, March 06, 2001 3:11 PM
> To: [email-masked]
> Subject: Re: DER encoding of KeyUsage BIT STRING
> 
> 
> Ambarish Malpani wrote:
> > 
> > SSLeay/OpenSSL does that. Seems to work pretty well with most
> > things.
> > 
> 
> The way OpenSSL handles BIT STRINGs goes something like this...
> 
> If the BIT STRING comes from an decoding a BIT STRING then the encoded
> structure will precisely match the decoded one. This is primarily to
> avoid breaking signatures.
> 
> If the BIT STRING is created internally then the number of unused bits
> is set appropriately according to the number of trailing zeroes.
> 
> If the BIT STRING has certain flags set (which effectively mark it as
> unnamed) then the number of bits is set to zero.
> 
> None of this however applies to certificate extensions because the
> actual encoding is wrapped in an OCTET STRING. The actual extension
> could contain completely unstructured garbage and it would still
> reencode properly. 
> 
> Steve.
> -- 
> Dr Stephen N. Henson.   http://www.drh-consultancy.demon.co.uk/
> Personal Email: [email-masked] 
> Senior crypto engineer, Celo Communications: http://www.celocom.com/
> Core developer of the   OpenSSL project: http://www.openssl.org/
> Business Email: [email-masked] PGP key: via homepage.
>