I didn't post this as part of yesterday's message because I didn't want to
muddy the waters even further, but let's look at the exact wording of BR 7.1:

  CAs SHALL generate non-sequential Certificate serial numbers greater than
  zero (0) containing at least 64 bits of output from a CSPRNG

Note the comment I made yesterday:

  That's the problem with rules-lawyering, if you're going to insist on your
  own very specific interpretation of a loosely-worded requirement then it's
  open season for anyone else to find dozens of other fully compatible but
  very different interpretations.

So lets look at the most pathologically silly but still fully compliant with
BR 7.1 serial number you can come up with.  Most importantly, 7.1 it never
says what form those bits should be in, merely that it needs to contain "at
least 64 bits of output from a CSPRNG".  In particular, it doesn't specify
which order those bits should be in, or which bits should be used, as long as
there's at least 64.

So the immediate application of this observation is to make any 64-bit value
comply with the ASN.1 encoding rules: If the first bit is 1 (so the sign bit
is set), swap it with any convenient zero bit elsewhere in the value.
Similarly, if the first 9 bits are zero, swap one of them with a one bit from
somewhere else.  Fully compliant with BR 7.1, and now also fully compliant
with ASN.1 DER.

Let's take it further.  Note that there's no requirement for the order to be
preserved.  So let's define the serial number as:

  serialNumber = sortbits( CSPRNG64() );

On average you're going to get a 50:50 mix of ones and zeroes, so your serial
numbers are all going to be:

  0x00000000FFFFFFFF

plus/minus a few bits around the middle.  When encoded, this will actually be
0x00FFFFFFFF, with the remaining zero bits implicit - feel free to debate
whether the presence of implict zero bits is compliant with BR 7.1 or not.

Anyway, continuing, you can also choose to alternate the bits so you still get
a fixed-length value:

  0x5555555555555555

(plus/minus a bit or two at the LSB, as before).

Or you could sort the bits into patterns, for example to display as rude
messages in ASCII:

  "BR7SILLY"

Or, given that you've got eight virtual pixels to play with, create ASCII art
in a series of certificates, e.g. encode one line of an emoji in each serial
number.

Getting back to the claim that "BR 7.1 allows any serial number except 0",
here's how you get this:

At one end of the range, your bit-selection rule is "discard every one bit
except the 64th one", so your serial number is:

  0x0000000000000001

or, when DER encoded:

  0x01

At the other end of the scale, "discard every zero bit except the first one":

  0x7FFFFFFFFFFFFFFF

or INT_MAX.

All fully compliant with the requirement that:

  CAs SHALL generate non-sequential Certificate serial numbers greater than
  zero (0) containing at least 64 bits of output from a CSPRNG

I should note in passing that this also allows all the certificates you issue
to have the same serial number, 1, since they're non-sequential and greater
than zero.

Peter.
_______________________________________________
dev-security-policy mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-security-policy

Reply via email to