Although this is an unusual thing to do, OpenSSL commandline, which includes a lot of features aimed mainly at debugging problems, can do it. Use
openssl x509 (without
-CA certfile -CAkey keyfile or just
-CA file if you have both cert and privatekey in one file (which PEM can do). Add
-sha256 if other than the default (SHA1).
You can specify the new serial explicitly with
-set_serial, or use almost the same serial-file scheme as
openssl ca either by default or explicitly; see
man [1ssl?] x509 on your system (unless Windows) or on the web at the heading 'Signing Options' about 1/3 of the way down. (The difference is that
ca uses the hex value from the file after incrementing, but
x509 [-req] -CA* uses it before. The serial/cert mapping is NOT recorded in a 'database' file, as
ca does.) You can specify the length of the validity period, but cannot specify arbitrary start and end times as
This replaces the issuer name, serial, validity period, and signature, in the new (output) cert, but it does not change any of the extensions, which for your case looks right. If the input cert contains AuthorityKeyIdentifier (AKI) extension to identify its parent/'signing' cert, that extension in the output cert will not correctly identify its parent which may cause trouble in using the cert. You can replace extensions by adding
-clrext -extfile filename -extensions section -- but you have to do all of them, which may be inconvenient.
If you use the two-step process of
x509 -x509toreq to create a CSR and then either
x509 -req -CA* or
ca to issue a cert from that CSR, this discards all extensions from the input cert. If you want any extensions you must add them back: for
x509 -req -CA* this must be explicit on the command line; for
ca it can be configured in the config file or overridden on command line.
ObRant: issuing a cert is often described as 'signing the CSR/request'. It is not. The cert body, aka certTBS (TBS = to-be-signed), is normally based partly on part of the CSR, but most of the cert body is different from the CSR.