Please send this patch as an attachment to [email protected]. This will track it as a ticket.
-Kyle H On Tue, Mar 3, 2009 at 2:37 PM, Oliver Martin <[email protected]> wrote: > Hello, > > this patch adds support for GeneralizedTime for startdate/enddate in > openssl ca. I submitted an earlier version to openssl-users a bit more > than a week ago [1] but got no reaction there, so I'll try again here. > Any chance of getting something like this accepted? I guess not too > many people need certificates beyond 2049 (or before 1950) right now, > but having the capability surely can't hurt. > > Also, previously it accepted non-GMT times and values without seconds, > both of which are not allowed by RFC 5280 (and previous ones). This is > fixed too. > > Regards, > Oliver > > [1] http://marc.info/?l=openssl-users&m=123532280026134&w=2 > > > --- openssl-SNAP-20090303.orig/apps/ca.c 2009-03-03 19:04:00.000000000 > +0100 > +++ openssl-SNAP-20090303/apps/ca.c 2009-03-03 23:04:24.000000000 +0100 > @@ -227,6 +227,9 @@ > static int get_certificate_status(const char *ser_status, CA_DB *db); > static int do_updatedb(CA_DB *db); > static int check_time_format(const char *str); > +static int check_time_valid_rfc(const char *str, int numcnt); > +static int check_utctime(const char *str); > +static int check_generalizedtime(const char *str); > char *make_revocation_str(int rev_type, char *rev_arg); > int make_revoked(X509_REVOKED *rev, const char *str); > int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str); > @@ -1109,9 +1112,10 @@ > if (startdate == NULL) > ERR_clear_error(); > } > - if (startdate && !ASN1_UTCTIME_set_string(NULL,startdate)) > + if (startdate && !((ASN1_UTCTIME_set_string(NULL, startdate) > && check_utctime(startdate)) > + || (ASN1_GENERALIZEDTIME_set_string(NULL, > startdate) && check_generalizedtime(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 == NULL) startdate="today"; > @@ -1123,9 +1127,10 @@ > if (enddate == NULL) > ERR_clear_error(); > } > - if (enddate && !ASN1_UTCTIME_set_string(NULL,enddate)) > + if (enddate && !((ASN1_UTCTIME_set_string(NULL, enddate) && > check_utctime(enddate)) > + || (ASN1_GENERALIZEDTIME_set_string(NULL, > startdate) && check_generalizedtime(enddate)))) > { > - 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; > } > > @@ -1689,6 +1694,7 @@ > STRING *irow=NULL; > STRING *rrow=NULL; > char buf[25]; > + int year; > > tmptm=ASN1_UTCTIME_new(); > if (tmptm == NULL) > @@ -2007,11 +2013,39 @@ > > if (strcmp(startdate,"today") == 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)) > + { > + if (sscanf(startdate, "%4u", &year) != 1) > + goto err; > + if (year >= 1950 && year <= 2049) > + { > + memmove(startdate, startdate + 2, > strlen(startdate) - 1); > + > ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate); > + } > + else > + > ASN1_GENERALIZEDTIME_set_string(X509_get_notBefore(ret),startdate); > + } > + } > > if (enddate == NULL) > X509_time_adj_ex(X509_get_notAfter(ret),days, 0, NULL); > - else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate); > + else > + { > + if (!ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate)) > + { > + if (sscanf(enddate, "%4u", &year) != 1) > + goto err; > + if (year >= 1950 && year <= 2049) > + { > + memmove(enddate, enddate + 2, strlen(enddate) > - 1); > + > ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate); > + } > + else > + > ASN1_GENERALIZEDTIME_set_string(X509_get_notAfter(ret),enddate); > + } > + } > > if (!X509_set_subject_name(ret,subject)) goto err; > > @@ -2107,7 +2141,7 @@ > } > > BIO_printf(bio_err,"Certificate is to be certified until "); > - ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret)); > + ASN1_TIME_print(bio_err,X509_get_notAfter(ret)); > if (days) BIO_printf(bio_err," (%ld days)",days); > BIO_printf(bio_err, "\n"); > > @@ -2398,11 +2432,15 @@ > static int check_time_format(const char *str) > { > ASN1_UTCTIME tm; > + ASN1_GENERALIZEDTIME gtm; > > tm.data=(unsigned char *)str; > tm.length=strlen(str); > tm.type=V_ASN1_UTCTIME; > - return(ASN1_UTCTIME_check(&tm)); > + gtm.data=(unsigned char *)str; > + gtm.length=strlen(str); > + gtm.type=V_ASN1_GENERALIZEDTIME; > + return(ASN1_UTCTIME_check(&tm) || ASN1_GENERALIZEDTIME_check(>m)); > } > > static int do_revoke(X509 *x509, CA_DB *db, int type, char *value) > @@ -3005,3 +3043,32 @@ > > return ret; > } > + > +/* As per RFC 5280, both UTCTime and GeneralizedTime must include seconds > and be > + * specified in GMT; additionally, the latter must not include fractional > seconds. > + */ > +static int check_time_valid_rfc(const char *str, int numcnt) > + { > + int i; > + > + if (strlen(str) != numcnt + 1) > + return 0; > + if (str[numcnt] != 'Z') > + return 0; > + for (i = 0; i < numcnt; i++) > + { > + if (str[i] < '0' || str[i] > '9') > + return 0; > + } > + return 1; > + } > + > +static int check_utctime(const char *str) > + { > + return check_time_valid_rfc(str, 12); > + } > + > +static int check_generalizedtime(const char *str) > + { > + return check_time_valid_rfc(str, 14); > + } >
