Search code examples
sslopensslssl-certificatecommand-line-interfaceiso8601

openssl using -dateopt causes "Invalid date format: iso_8601" error


How to set the option -dateopt for the openssl properly?

An example of a self signed certificate generation:

openssl req \
-x509 \
-days 10 \
-nodes \
-newkey rsa:2048 \
-keyout "$PWD/self.key" \
-out "$PWD/self.crt" \
-subj "/C=US/ST=STATE/L=CITY/O=ORG_NAME/OU=OU_NAME/CN=CN_OR_FQDN_OR_SERVER_NAME"

gives me two files in the current directory:

self.key
self.crt

To check the end date of the self.crt i run:

openssl x509 -enddate -noout -in "$PWD/self.crt"

that returns the proper result:

notAfter=Oct 4 16:05:59 2022 GMT

but if I use the -dateopt switch documentation:

-dateopt. Specify the date output format. Values are: rfc_822 and iso_8601. Defaults to rfc_822.

this way:

openssl x509 -enddate -dateopt iso_8601 -noout -in "$PWD/self.crt"

I get the error (ec=1):

Invalid date format: iso_8601

Perhaps the reason is somewhere around these lines here:

case OPT_DATEOPT:
   if (!set_dateopt(&dateopt, opt_arg())) {
       BIO_printf(bio_err,
       "Invalid date format: %s\n", opt_arg());

       goto err;
   }
   break;

or here:

int set_dateopt(unsigned long *dateopt, const char *arg)
{
    if (strcasecmp(arg, "rfc_822") == 0)
        *dateopt = ASN1_DTFLGS_RFC822;
    else if (strcasecmp(arg, "iso_8601") == 0)
        *dateopt = ASN1_DTFLGS_ISO8601;
    return 0;
}

or maybe it is related to the issue: -dateopt option only affects x509 -dates option output

I would like to ask how to set the -dateopt properly in order to get the -enddate in the ISO 8601 date format?

I tried: iso_8601, ISO_8601, "iso 8601", ISO 8601, iso8601, ISO8601, iso8601 but none of them worked.

My:

openssl version

is: OpenSSL 3.0.2 15 Mar 2022 (Library: OpenSSL 3.0.2 15 Mar 2022)


Solution

  • OpenSSL 3.0.2 15 Mar 2022 (Library: OpenSSL 3.0.2 15 Mar 2022)

    The relevant function was broken in openssl 3.0.3 and lower since the function set_dateopt (which you quote) always returned 0:

    int set_dateopt(unsigned long *dateopt, const char *arg)
    {
        if (OPENSSL_strcasecmp(arg, "rfc_822") == 0)
            *dateopt = ASN1_DTFLGS_RFC822;
        else if (OPENSSL_strcasecmp(arg, "iso_8601") == 0)
            *dateopt = ASN1_DTFLGS_ISO8601;
        return 0;
    }
    

    This seems to be fixed in openssl 3.0.4. See issue #18553 for bug report and issue #18554 for fix.