Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Creating a CA cert with explicit start/end date

2,770 views
Skip to first unread message

Oliver Martin

unread,
Feb 20, 2009, 6:49:01 PM2/20/09
to
--Sig_/NhwoKWPygZ+Gaqrk7x1xrr0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: quoted-printable

Hello,

I'm trying to create a CA cert with explicit notBefore and notAfter
dates. I've tried to follow the advice given in an old mailing list
post [1], but haven't been successful so far.

The commands I'm using are these:

openssl req -nodes -config ca/openssl.cnf -days 1825 -x509 -newkey \
rsa:2048 -out ca/ca-cert-temp.cert -outform PEM

openssl ca -batch -cert ca/ca-cert-temp.cert -ss_cert \
ca/ca-cert-temp.cert -keyfile ca/private/ca-key.key -config \
ca/openssl.cnf -out ca/ca-cert.cert -extensions v3_ca -notext

(I've uploaded my openssl.cnf file here [2])

When I sign other certs with ca-cert.cert, openssl verify fails to
recognize ca-cert.cert as self-signed and instead prints "error 2 at 1
depth lookup:unable to get issuer certificate".

If I sign certs with ca-cert-temp.cert, verify recognizes the CA as
self-signed and prints OK, but obviously I can't set notBefore and
notAfter.

On a somewhat related note, is it possible to use GeneralizedTime
instead of UTCTime for notBefore and notAfter with OpenSSL, as explained
here [3]? My ultimate goal is a certificate that remains valid when
32-bit time_t rolls over in 2038, so I need a notBefore somewhere in
1901.


Regards,
Oliver

[1] http://marc.info/?l=3Dopenssl-users&m=3D99604969427707&w=3D2
[2] http://volatilevoid.net/openssl.cnf
[3] http://marc.info/?l=3Dopenssl-users&m=3D102733541014182&w=3D2

--Sig_/NhwoKWPygZ+Gaqrk7x1xrr0
Content-Type: application/pgp-signature; name=signature.asc
Content-Disposition: attachment; filename=signature.asc

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)

iEYEARECAAYFAkmfN7AACgkQ487DAbO/tL+jewCgmKYnsvW5hplx9WiTgPgd+wt5
AvYAoJgnrOgnerEyj7aDovZ7XG9qovkR
=0f0P
-----END PGP SIGNATURE-----

--Sig_/NhwoKWPygZ+Gaqrk7x1xrr0--
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openss...@openssl.org
Automated List Manager majo...@openssl.org

Oliver Martin

unread,
Feb 21, 2009, 7:25:24 PM2/21/09
to
--Sig_/P=GQjc0TaDXzuTZ3uCvFowv

Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: quoted-printable

Am Sat, 21 Feb 2009 00:07:28 +0100 schrieb Oliver Martin:

> I'm trying to create a CA cert with explicit notBefore and notAfter
> dates. I've tried to follow the advice given in an old mailing list
> post [1], but haven't been successful so far.

I've found a solution for that part:

openssl genrsa 2048 >ca/private/ca-key.key

openssl req -new -nodes -key ca/private/ca-key.key -out ca/ca-cert.csr \
-config ca/openssl.cnf

openssl ca -batch -selfsign -in ca/ca-cert.csr -config ca/openssl.cnf \
-keyfile ca/private/ca-key.key -out ca/ca-cert.cert -extensions v3_ca

This results in a proper self-signed cert with startdate and enddate
from openssl.cnf or from the command line.

> On a somewhat related note, is it possible to use GeneralizedTime
> instead of UTCTime for notBefore and notAfter with OpenSSL, as
> explained here [3]? My ultimate goal is a certificate that remains
> valid when 32-bit time_t rolls over in 2038, so I need a notBefore
> somewhere in 1901.

For this part, however, I've only found a horribly hackish workaround:
1) set system time to one second before wraparound
2) sleep 1
3) sign a pre-existing CSR with no explicit startdate

Is there any easier way to use GeneralizedTime other than writing my
own program using the OpenSSL API to do it?


Cheers,
Oliver

--Sig_/P=GQjc0TaDXzuTZ3uCvFowv


Content-Type: application/pgp-signature; name=signature.asc
Content-Disposition: attachment; filename=signature.asc

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)

iEYEARECAAYFAkmgm1kACgkQ487DAbO/tL/InQCgkjcoxY/o8+OUGrxrlIDpUG/O
ioUAoNDiQxlJf9T9dfmEN2cxoh213XAV
=xUhW
-----END PGP SIGNATURE-----

--Sig_/P=GQjc0TaDXzuTZ3uCvFowv--

Dr. Stephen Henson

unread,
Feb 22, 2009, 8:07:36 AM2/22/09
to
On Sun, Feb 22, 2009, Oliver Martin wrote:

> Am Sat, 21 Feb 2009 00:07:28 +0100 schrieb Oliver Martin:
>
> > On a somewhat related note, is it possible to use GeneralizedTime
> > instead of UTCTime for notBefore and notAfter with OpenSSL, as
> > explained here [3]? My ultimate goal is a certificate that remains
> > valid when 32-bit time_t rolls over in 2038, so I need a notBefore
> > somewhere in 1901.
>
> For this part, however, I've only found a horribly hackish workaround:
> 1) set system time to one second before wraparound
> 2) sleep 1
> 3) sign a pre-existing CSR with no explicit startdate
>
> Is there any easier way to use GeneralizedTime other than writing my
> own program using the OpenSSL API to do it?
>

OpenSSL will only use GenerlizedTime in accordance with the standards: i.e.
for years after 2049. However if you set -days to a large enough value you are
at the mercy of the system time routines in versions of OpenSSL before
0.9.9-dev if they wrap around you'll get an invalid date. Using a system with
a 64 bit time_t will avoid that.

OpenSSL 0.9.9 performs some of its own date calculations and so is immune to
such problems, you can set a -days value which wil set years right up to the
GeneralizedTime year limit of 9999.

Steve.
--
Dr Stephen N. Henson. Email, S/MIME and PGP keys: see homepage
OpenSSL project core developer and freelance consultant.
Homepage: http://www.drh-consultancy.demon.co.uk

Oliver Martin

unread,
Feb 22, 2009, 12:13:00 PM2/22/09
to
--Sig_/3lS/khid4kYqw7h43iQrFDP
Content-Type: multipart/mixed; boundary="MP_/Em9PfYlNEoFmxX3/KA.ylIf"

--MP_/Em9PfYlNEoFmxX3/KA.ylIf


Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: quoted-printable

Content-Disposition: inline

Am Sun, 22 Feb 2009 13:12:21 +0100 schrieb Dr. Stephen Henson:

> OpenSSL will only use GenerlizedTime in accordance with the
> standards: i.e. for years after 2049. However if you set -days to a

Nitpick: RFC 5280 doesn't explicitly mention years before 1950, but
OpenSSL already handles these in the only sensible way by using
GeneralizedTime, as I've found out with my experiment. I consider that
a feature, not a bug. :-)

Anyway, what I really wanted was to be able to use -startdate and
-enddate with GeneralizedTime (with years before 1950 and after 2049,
conforming to the standard). Turns out it is actually a rather simple
change to the ca utility, see the attached patch.

It doesn't yet verify that the year is actually outside the range of
UTCTime, so it can be used to violate the standard. Also, I haven't
updated the manpage. And while I'm by no means an expert on X.509 and
therefore don't know if I have broken anything, it does seem to work.


Cheers,
Oliver

--MP_/Em9PfYlNEoFmxX3/KA.ylIf
Content-Type: text/x-patch; name=openssl_ca_generalizedtime.patch
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment; filename=openssl_ca_generalizedtime.patch

--- openssl-0.9.8j/apps/ca.c.orig 2009-02-22 17:16:41.000000000 +0100
+++ openssl-0.9.8j/apps/ca.c 2009-02-22 18:09:25.000000000 +0100
@@ -1095,9 +1095,11 @@
if (startdate =3D=3D NULL)
ERR_clear_error();
}
- if (startdate && !ASN1_UTCTIME_set_string(NULL,startdate))
+ if (startdate && !ASN1_UTCTIME_set_string(NULL,startdate)
+ && !ASN1_GENERALIZEDTIME_set_string(NULL, startdate))
{
- BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ\n=
");
+ BIO_printf(bio_err,"start date is invalid, it should be YYMMDDHHMMSSZ"
+ " or YYYYMMDDHHMMSSZ\n");
goto err;
}
if (startdate =3D=3D NULL) startdate=3D"today";
@@ -1109,9 +1111,11 @@
if (enddate =3D=3D NULL)
ERR_clear_error();
}
- if (enddate && !ASN1_UTCTIME_set_string(NULL,enddate))
+ if (enddate && !ASN1_UTCTIME_set_string(NULL,enddate)
+ && !ASN1_GENERALIZEDTIME_set_string(NULL, startdate))
{
- BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ\n");
+ BIO_printf(bio_err,"end date is invalid, it should be YYMMDDHHMMSSZ"
+ " or YYYYMMDDHHMMSSZ\n");
goto err;
}
=20
@@ -1991,11 +1995,19 @@
=20
if (strcmp(startdate,"today") =3D=3D 0)
X509_gmtime_adj(X509_get_notBefore(ret),0);
- else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate);
+ else
+ {
+ if (!ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate))
+ ASN1_GENERALIZEDTIME_set_string(X509_get_notBefore(ret),startdate);
+ }
=20
if (enddate =3D=3D NULL)
X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days);
- else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate);
+ else
+ {
+ if (!ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate))
+ ASN1_GENERALIZEDTIME_set_string(X509_get_notAfter(ret),enddate);
+ }
=20
if (!X509_set_subject_name(ret,subject)) goto err;
=20
@@ -2396,11 +2408,15 @@
static int check_time_format(char *str)
{
ASN1_UTCTIME tm;
+ ASN1_GENERALIZEDTIME gtm;
=20
tm.data=3D(unsigned char *)str;
tm.length=3Dstrlen(str);
tm.type=3DV_ASN1_UTCTIME;
- return(ASN1_UTCTIME_check(&tm));
+ gtm.data=3D(unsigned char *)str;
+ gtm.length=3Dstrlen(str);
+ gtm.type=3DV_ASN1_GENERALIZEDTIME;
+ return(ASN1_UTCTIME_check(&tm) || ASN1_GENERALIZEDTIME_check(&gtm));
}
=20
static int do_revoke(X509 *x509, CA_DB *db, int type, char *value)

--MP_/Em9PfYlNEoFmxX3/KA.ylIf--

--Sig_/3lS/khid4kYqw7h43iQrFDP


Content-Type: application/pgp-signature; name=signature.asc
Content-Disposition: attachment; filename=signature.asc

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)

iEYEARECAAYFAkmhh4QACgkQ487DAbO/tL9MTACcCj90+NWUgJxFFKEJUK19Oybe
m2QAniWxGaMhbZxg/d6MzlTwqSY9F10K
=n255
-----END PGP SIGNATURE-----

--Sig_/3lS/khid4kYqw7h43iQrFDP--

0 new messages