test script signs different certs with the same serial number



10 years ago
10 years ago


(Reporter: slavomir.katuscak+mozilla, Assigned: slavomir.katuscak+mozilla)



Firefox Tracking Flags

(Not tracked)



(2 attachments, 2 obsolete attachments)



10 years ago
Sometimes when 2 certificate requests are signed in very short time, they can have the same serial number:

Scenario from Tinderbox: 

1. Create Root CA:
certutil -N -d RootCADB -f RootCADB/dbpasswd
certutil -s "CN=RootCA ROOT CA, O=RootCA, C=US" -S -n RootCA -t CTu,CTu,CTu -v 600 -x -d RootCADB -1 -2 -5 -f RootCADB/dbpasswd -z tests_noise.12222
certutil -L -d RootCADB -r -n RootCA -o RootCA.der

2. Create CA1 signed by Root CA:
certutil -N -d CA1DB -f CA1DB/dbpasswd
certutil -s "CN=CA1 Intermediate, O=CA1, C=US" -R -2 -d CA1DB -f CA1DB/dbpasswd -z tests_noise.12222 -o CA1Req.der
certutil -C -c RootCA -v 60 -d RootCADB -i CA1Req.der -o CA1RootCA.der -f RootCADB/dbpasswd   --extCP
certutil -A -n CA1 -t u,u,u -d CA1DB -f CA1DB/dbpasswd -i CA1RootCA.der

3. Create CA2 signed by CA1:
certutil -N -d CA2DB -f CA2DB/dbpasswd
certutil -s "CN=CA2 Intermediate, O=CA2, C=US" -R -2 -d CA2DB -f CA2DB/dbpasswd -z tests_noise.12222 -o CA2Req.der
certutil -C -c CA1 -v 60 -d CA1DB -i CA2Req.der -o CA2CA1.der -f CA1DB/dbpasswd   --extCP --extIA
certutil -A -n CA2 -t u,u,u -d CA2DB -f CA2DB/dbpasswd -i CA2CA1.der

4. Create CA3 signed by CA1:
certutil -N -d CA3DB -f CA3DB/dbpasswd
certutil -s "CN=CA3 Intermediate, O=CA3, C=US" -R -2 -d CA3DB -f CA3DB/dbpasswd -z tests_noise.12222 -o CA3Req.der
certutil -C -c CA1 -v 60 -d CA1DB -i CA3Req.der -o CA3CA1.der -f CA1DB/dbpasswd   --extCP
certutil -A -n CA3 -t u,u,u -d CA3DB -f CA3DB/dbpasswd -i CA3CA1.der

Create new DB and try to import certs of all of those CAs:
certutil -N -d AllDB -f AllDB/dbpasswd
certutil -A -n RootCA  -t "" -d AllDB -f AllDB/dbpasswd -i RootCA.der
certutil -A -n CA1  -t "" -d AllDB -f AllDB/dbpasswd -i CA1RootCA.der
certutil -A -n CA2  -t "" -d AllDB -f AllDB/dbpasswd -i CA2CA1.der
certutil -A -n CA3  -t "" -d AllDB -f AllDB/dbpasswd -i CA3CA1.der
certutil: could not obtain certificate from file: You are attempting to import a cert with the same issuer/serial as an existing cert, but that is not the same cert.

After analysis I found that certificates CA2CA1.der and CA3CA1.der has the same serial number 00:8b:5c:2e:54.

This causes problem when importing those certs to one DB (as in example).

Comment 1

10 years ago
Created attachment 346313 [details]
Certs + DBs to analyze.

Comment 2

10 years ago
This bug can be platform specific, was seen on Linux and Solaris Tinderboxes, but I haven't seen it on my Mac laptop which I use for development/testing. But this can be also affected be CPU speed.
The behavior is by design.  If a script is unintentionally producing certs with
duplicate issuer/serials, that's a script fault.

If a script wants to prevent it, the script must provide serial numbers that 
do not have the problem.  I suggest that the script get the current time 
(unix time_t), and then add 1 to it for each cert subsequently generated for 
the remainder of the lifetime of that script.
Last Resolved: 10 years ago
Resolution: --- → INVALID

Comment 4

10 years ago
Hi Nelson,

I'm not sure this is correct.

Simple customer scenario:
1. Generate CA
2. Sign more certs with this CA
3. Import signed certs to one DB

If you don't explicitly set serial numbers when signing, they can have the same serial numbers (which are probably derived form time). Certutil should prevent this and not set the same serial number to different certs unless user set it manually.

But I just prepared patch for to manually increase serial numbers, so it would be workarounded at least in our testing.

Comment 5

10 years ago
Created attachment 346466 [details] [diff] [review]

This workaround sets serial number manually (increasing to prevent have the same more times).
Attachment #346466 - Flags: review?


10 years ago
Resolution: INVALID → ---
Comment on attachment 346466 [details] [diff] [review]

>+    CERT_SN=1000

fixed starting serial numbers are not acceptable.  They will ENSURE that 
the same serial numbers are used over and over, which is bad.

Other than that, this patch looks OK.
Attachment #346466 - Flags: review? → review-
Customers should not be using certutil as a CA. 
If they choose to do so, they must solve the same problems that is now having.
Assignee: alexei.volkov.bugs → nobody
Component: Tools → Test
QA Contact: tools → test
Summary: Certutil signs different certs with the same serial number. → test script signs different certs with the same serial number
Assignee: nobody → slavomir.katuscak

Comment 8

10 years ago
Created attachment 346681 [details] [diff] [review]
Patch v2.

Added random starting serial number (using $RANDOM variable). Command date (in comment #3 was suggestion to use system time) differs on various platforms (some parameters are not accepted), so I rather don't want to rely on it.
Attachment #346466 - Attachment is obsolete: true
Attachment #346681 - Flags: review?(nelson)
$RANDOM is only a 16-bit random number.  
you might try  $(expr $RANDOM \* 65536 + $RANDOM)
Attachment #346681 - Flags: review?(nelson) → review-
Comment on attachment 346681 [details] [diff] [review]
Patch v2.

Slavo, please try this experiment on the different platforms

run this command 10 times

(echo $RANDOM);(echo $RANDOM);(echo $RANDOM);(echo $RANDOM);(echo $RANDOM)

Tell me if you get 50 different numbers or 50 copies of the same number,
or 10 copies of the same 5 numbers, or any other detectable patterns.
Also, please report here the largest number returned by any of those 
tests on each platform.  Please report if you get any negative results.

If you get multiple copies of the same number on ANY platform, then 
$RANDOM will not be a suitable basis for our purposes. 

If you do not get any duplicates, and if the largest value returned 
is less than 65536 (as I expect it will be) then the expression
   $(expr $RANDOM \* 32768 + $RANDOM)
or  `expr $RANDOM \* 32768 + $RANDOM` on Solaris
will be a suitable initial value. 

However, I expect you will get a repeating pattern from your tests on 
at least one platform.

I know you've already played with the date command, but does this command
work on all relevant platforms?

date '+%H%M%S%m%d'

Comment 11

10 years ago
OK, I did some experiments.

Numbers were always random (different), largest number was on all platforms above 32000, no negative results, no repeating patterns.

I tried also date '+%H%M%S%m%d', this works on all platforms. But date command called there is usually independent on shell, and it can differ (I had already problem with this - on some platforms date doesn't print epoch time). But '+%H%M%S%m%d' seems to be usable.

Comment 12

10 years ago
Created attachment 346871 [details] [diff] [review]
Patch v3.

Using date command to get random initial value.
Attachment #346681 - Attachment is obsolete: true
Attachment #346871 - Flags: review?(nelson)


10 years ago
Attachment #346871 - Flags: review+
Attachment #346871 - Flags: review?(nelson) → review+
Comment on attachment 346871 [details] [diff] [review]
Patch v3.

> largest number was on all platforms above 32000,

Was it above 32768?
Was it above 65536?

Alas, '+%H%M%S%m%d' will output numbers that may be too large to
be value positive 32-bit numbers.  If it runs just before midnight,
you may well have problems.  But if that string worked, then so 
will '+%m%d%H%M%S' and that will output values that are never too 
large.  So, you can use that.

r+ here, when you change '+%H%M%S%m%d' to '+%m%d%H%M%S'

Comment 14

10 years ago
Patch was integrated.
Last Resolved: 10 years ago10 years ago
Resolution: --- → FIXED

Comment 15

10 years ago
(In reply to comment #13)
> (From update of attachment 346871 [details] [diff] [review])
> > largest number was on all platforms above 32000,
> Was it above 32768?
> Was it above 65536?

Not above 32768, in bash man page it's documnted as:

RANDOM Each time this parameter is referenced, a random integer between
       0 and 32767 is generated.  The sequence of random numbers may be
       initialized by assigning a value to RANDOM.  If RANDOM is unset,
       it  loses  its  special  properties,  even if it is subsequently

I hope this is the same on all platforms we use (at least from my experiments it looks that it is).
You need to log in before you can comment on or make changes to this bug.