You have two ways of creating certificates in the past. Either faking the time (1)(2), or defining the time interval when signing the certificate (3).
1) Firstly, about faking the time: to make one program think it is in a different date from the system, have a look at libfaketime
and faketime
To install it in Debian:
sudo apt-get install faketime
You would then use faketime
before the openssl
command.
For examples of use:
$faketime 'last friday 5 pm' /bin/date
Fri Apr 14 17:00:00 WEST 2017
$faketime '2008-12-24 08:15:42' /bin/date
Wed Dec 24 08:15:42 WET 2008
From man faketime
:
The given command will be tricked into believing that the
current
system time is the one specified in the timestamp. The wall clock will
continue to run from this date and time unless specified otherwise (see
advanced options). Actually, faketime is a simple wrapper for
libfaketime, which uses the LD_PRELOAD mechanism to load a small
library which intercepts system calls to functions such as time(2) and
fstat(2).
So for instance, in your case, you can very well define a date of 2008, and create then a certificate with the validity of 2 years up to 2010.
faketime '2008-12-24 08:15:42' openssl ...
As a side note, this utility can be used in several Unix versions, including MacOS, as an wrapper to any kind of programs (not exclusive to the command line).
As a clarification, only the binaries loaded with this method (and their children) have their time changed, and the fake time does not affect the current time of the rest of the system.
2) As @Wyzard states, you also have the datefudge
package which is very similar in use to faketime
.
As differences, datefudge
does not influence fstat
(i.e. does not change file time creation). It also has it´s own library, datefudge.so, that it loads using LD_PRELOAD.
It also has a -s
static time
where the time referenced is always returned despite how many extra seconds have passed.
$ datefudge --static "2007-04-01 10:23" sh -c "sleep 3; date -R"
Sun, 01 Apr 2007 10:23:00 +0100
3) Besides faking the time, and even more simply, you can also define the starting point and ending point of validity of the certificate when signing the certificate in OpenSSL.
The misconception of the question you link to in your question, is that certificate validity is not defined at request time (at the CSR request), but when signing it.
When using openssl ca
to create the self-signed certificate, add the options -startdate
and -enddate
.
The date format in those two options, according to openssl sources at openssl/crypto/x509/x509_vfy.c
, is ASN1_TIME aka ASN1UTCTime: the format must be either YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ.
Quoting openssl/crypto/x509/x509_vfy.c
:
int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time)
{
static const size_t utctime_length = sizeof("YYMMDDHHMMSSZ") - 1;
static const size_t generalizedtime_length = sizeof("YYYYMMDDHHMMSSZ") - 1;
ASN1_TIME *asn1_cmp_time = NULL;
int i, day, sec, ret = 0;
/*
* Note that ASN.1 allows much more slack in the time format than RFC5280.
* In RFC5280, the representation is fixed:
* UTCTime: YYMMDDHHMMSSZ
* GeneralizedTime: YYYYMMDDHHMMSSZ
*
* We do NOT currently enforce the following RFC 5280 requirement:
* "CAs conforming to this profile MUST always encode certificate
* validity dates through the year 2049 as UTCTime; certificate validity
* dates in 2050 or later MUST be encoded as GeneralizedTime."
*/
And from the CHANGE log (2038 bug?) - This change log is just as an additional footnote, as it only concerns those using directly the API.
Changes between 1.1.0e and 1.1.1 [xx XXX xxxx]
*) Add the ASN.1 types INT32, UINT32, INT64, UINT64 and variants prefixed
with Z. These are meant to replace LONG and ZLONG and to be size safe.
The use of LONG and ZLONG is discouraged and scheduled for deprecation
in OpenSSL 1.2.0.
So, creating a certificate from the 1st of January 2008 to the 1st of January of 2010, can be done as:
openssl ca -config /path/to/myca.conf -in req.csr -out ourdomain.pem \
-startdate 200801010000Z -enddate 201001010000Z
or
openssl ca -config /path/to/myca.conf -in req.csr -out ourdomain.pem \
-startdate 0801010000Z -enddate 1001010000Z
-startdate
and -enddate
do appear in the openssl
sources and CHANGE log; as @guntbert noted, while they do not appear in the main man openssl
page, they also appear in man ca
:
-startdate date
this allows the start date to be explicitly set. The format of the date is
YYMMDDHHMMSSZ (the same as an ASN1 UTCTime structure).
-enddate date
this allows the expiry date to be explicitly set. The format of the date is
YYMMDDHHMMSSZ (the same as an ASN1 UTCTime structure).
Quoting openssl/CHANGE
:
Changes between 0.9.3a and 0.9.4 [09 Aug 1999]
*) Fix -startdate and -enddate (which was missing) arguments to 'ca'
program.
P.S. As for the chosen answer of the question you reference from StackExchange: it is generally a bad idea to change the system time, especially in production systems; and with the methods in this answer you do not need root privileges when using them.