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).
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 all.sh script.
Status: NEW → RESOLVED
Last Resolved: 10 years ago
Resolution: --- → INVALID
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 chains.sh to manually increase serial numbers, so it would be workarounded at least in our testing.
Created attachment 346466 [details] [diff] [review] Workaround. This workaround sets serial number manually (increasing to prevent have the same more times).
Attachment #346466 - Flags: review?
Status: RESOLVED → REOPENED
Resolution: INVALID → ---
Comment on attachment 346466 [details] [diff] [review] Workaround. >+ 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 cert.sh 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. → chains.sh test script signs different certs with the same serial number
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.
$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'
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.
Created attachment 346871 [details] [diff] [review] Patch v3. Using date command to get random initial value.
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'
Patch was integrated.
Status: REOPENED → RESOLVED
Last Resolved: 10 years ago → 10 years ago
Resolution: --- → FIXED
(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 reset. 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.