Why Does Signing a Certificate Require `-Cacreateserial` Argument?
For Example, Openssl X509 \ -Req -Sha256 \ -Days "365" \ -Cacreateserial \ -Ca "Ca. Crt" -Cakey "Ca. Key" -Passin "Pass: Abcd" \ -in "Csr. Csr" -Extfile "Ext...
For example,
openssl x509 \
-req -sha256 \
-days "365" \
-CAcreateserial \
-CA "ca.crt" -CAkey "ca.key" -passin "pass:abcd" \
-in "csr.csr" -extfile "ext.ext" \
-out "c.crt"`
It also creates a file ca.srl which contains signed certificate's serial.
The above won't work if -CAcreateserial argument is absent and outputs an error:
/test/ca.srl: No such file or directory
140413509251520:error:06067099:digital envelope routines:EVP_PKEY_copy_parameters:different parameters:../crypto/evp/p_lib.c:93:
140413509251520:error:02001002:system library:fopen:No such file or directory:../crypto/bio/bss_file.c:72:fopen('/test/ca.srl','r')
140413509251520:error:2006D080:BIO routines:BIO_new_file:no such file:../crypto/bio/bss_file.c:79:
Isn't that argument used to output a file with a serial which is possible to get via a command below anyways?
openssl x509 \
-in "c.crt" \
-noout \
-serial
What's the point then? Why is it not creating the file internally if required, but saving it on a storage?
2 Answers
The -serial option of your second command just outputs the serial number of an existing certificate. But when you're signing a certificate the CA needs to generate a unique serial number for each certificate, and until it does that, there's no serial number for -serial to output yet.
Since the serial number for each certificate needs to be unique for each issuer, an issuer needs to keep track of which serial numbers it has used before, to make sure it doesn't reuse any. OpenSSL gives you a simple way to keep track of this using a serial number file. When you specify -CAcreateserial, it'll assign the serial number 01 to the signed certificate, and then create this serial number file with the next serial number (02) in it. On future signing operations, you should be using -CAserial with the name of that file, and not -CAcreateserial, and OpenSSL will increment the value in that file for each certificate signed. In this way, you can sign a bunch of certificates with one issuer certificate, and all their serial numbers will be unique.
If you're using multiple issuer certificates, then you can use a separate serial number file for each one.
Note that while this approach works, it's unsuitable for production use, as there are some problems with using strictly sequentially increasing certificate serial numbers.
Thanks to the @Crowman's answer, I created some script which might demonstrate the issue.
A possible script's result:
--------------------------------------------------------------------------------
| A new {serial #1} generated | 310BD94F916BDF47913249966B85A9F7771D746A |
| A new {serial #2} generated | 0AC91627E4E99612D3CC7D99BB9793445CEDB36B |
| Used the same {serial #2} 5 times | 0AC91627E4E99612D3CC7D99BB9793445CEDB370 |
| Used the same {serial #2} 256 times | 0AC91627E4E99612D3CC7D99BB9793445CEDB470 |
--------------------------------------------------------------------------------