diff options
author | William Edmisten <wcedmisten@gmail.com> | 2021-03-01 18:33:29 -0500 |
---|---|---|
committer | Tomas Mraz <tomas@openssl.org> | 2021-06-11 12:39:46 +0200 |
commit | 8c5bff2220c4f39b48660afda40005871f53250d (patch) | |
tree | bc1d608ac356c10b1e460a296f4200dd310505e3 /apps | |
parent | 3eb4b5bfe66ba0911fffa05ff1e3a00f4c54d641 (diff) |
Add support for ISO 8601 datetime format
Fixes #5430
Added the configuration file option "date_opt" to the openssl applications ca,
crl and x509.
Added ASN1_TIME_print_ex which supports the new datetime format using the
flag ASN1_DTFLGS_ISO8601
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14384)
Diffstat (limited to 'apps')
-rwxr-xr-x | apps/ca.c | 40 | ||||
-rw-r--r-- | apps/crl.c | 12 | ||||
-rw-r--r-- | apps/include/apps.h | 1 | ||||
-rw-r--r-- | apps/lib/apps.c | 9 | ||||
-rw-r--r-- | apps/x509.c | 16 |
5 files changed, 55 insertions, 23 deletions
@@ -99,7 +99,7 @@ static int certify(X509 **xret, const char *infile, int informat, const char *enddate, long days, int batch, const char *ext_sect, CONF *conf, int verbose, unsigned long certopt, unsigned long nameopt, - int default_op, int ext_copy, int selfsign); + int default_op, int ext_copy, int selfsign, unsigned long dateopt); static int certify_cert(X509 **xret, const char *infile, int certformat, const char *passin, EVP_PKEY *pkey, X509 *x509, const char *dgst, @@ -110,7 +110,7 @@ static int certify_cert(X509 **xret, const char *infile, int certformat, int multirdn, int email_dn, const char *startdate, const char *enddate, long days, int batch, const char *ext_sect, CONF *conf, int verbose, unsigned long certopt, - unsigned long nameopt, int default_op, int ext_copy); + unsigned long nameopt, int default_op, int ext_copy, unsigned long dateopt); static int certify_spkac(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509, const char *dgst, STACK_OF(OPENSSL_STRING) *sigopts, @@ -119,7 +119,7 @@ static int certify_spkac(X509 **xret, const char *infile, EVP_PKEY *pkey, int multirdn, int email_dn, const char *startdate, const char *enddate, long days, const char *ext_sect, CONF *conf, int verbose, unsigned long certopt, - unsigned long nameopt, int default_op, int ext_copy); + unsigned long nameopt, int default_op, int ext_copy, unsigned long dateopt); static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const char *dgst, STACK_OF(OPENSSL_STRING) *sigopts, STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, @@ -127,7 +127,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, int email_dn, const char *startdate, const char *enddate, long days, int batch, int verbose, X509_REQ *req, const char *ext_sect, CONF *conf, unsigned long certopt, unsigned long nameopt, - int default_op, int ext_copy, int selfsign); + int default_op, int ext_copy, int selfsign, unsigned long dateopt); 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); @@ -148,7 +148,7 @@ typedef enum OPTION_choice { OPT_CREATE_SERIAL, OPT_MULTIVALUE_RDN, OPT_STARTDATE, OPT_ENDDATE, OPT_DAYS, OPT_MD, OPT_POLICY, OPT_KEYFILE, OPT_KEYFORM, OPT_PASSIN, OPT_KEY, OPT_CERT, OPT_CERTFORM, OPT_SELFSIGN, - OPT_IN, OPT_INFORM, OPT_OUT, OPT_OUTDIR, OPT_VFYOPT, + OPT_IN, OPT_INFORM, OPT_OUT, OPT_DATEOPT, OPT_OUTDIR, OPT_VFYOPT, OPT_SIGOPT, OPT_NOTEXT, OPT_BATCH, OPT_PRESERVEDN, OPT_NOEMAILDN, OPT_GENCRL, OPT_MSIE_HACK, OPT_CRL_LASTUPDATE, OPT_CRL_NEXTUPDATE, OPT_CRLDAYS, OPT_CRLHOURS, OPT_CRLSEC, @@ -171,6 +171,7 @@ const OPTIONS ca_options[] = { {"inform", OPT_INFORM, 'F', "CSR input format (DER or PEM); default PEM"}, {"infiles", OPT_INFILES, '-', "The last argument, requests to process"}, {"out", OPT_OUT, '>', "Where to put the output file(s)"}, + {"dateopt", OPT_DATEOPT, 's', "Datetime format used for printing. (rfc_822/iso_8601). Default is rfc_822."}, {"notext", OPT_NOTEXT, '-', "Do not print the generated certificate"}, {"batch", OPT_BATCH, '-', "Don't ask questions"}, {"msie_hack", OPT_MSIE_HACK, '-', @@ -275,6 +276,7 @@ int ca_main(int argc, char **argv) char *dgst = NULL, *policy = NULL, *keyfile = NULL; char *certfile = NULL, *crl_ext = NULL, *crlnumberfile = NULL; int certformat = FORMAT_UNDEF, informat = FORMAT_UNDEF; + unsigned long dateopt = ASN1_DTFLGS_RFC822; const char *infile = NULL, *spkac_file = NULL, *ss_cert_file = NULL; const char *extensions = NULL, *extfile = NULL, *passinarg = NULL; char *passin = NULL; @@ -323,6 +325,10 @@ opthelp: case OPT_OUT: outfile = opt_arg(); break; + case OPT_DATEOPT: + if (!set_dateopt(&dateopt, opt_arg())) + goto opthelp; + break; case OPT_VERBOSE: verbose = 1; break; @@ -947,7 +953,7 @@ end_of_options: attribs, db, serial, subj, chtype, multirdn, email_dn, startdate, enddate, days, extensions, conf, verbose, certopt, get_nameopt(), default_op, - ext_copy); + ext_copy, dateopt); if (j < 0) goto end; if (j > 0) { @@ -968,7 +974,7 @@ end_of_options: db, serial, subj, chtype, multirdn, email_dn, startdate, enddate, days, batch, extensions, conf, verbose, certopt, get_nameopt(), default_op, - ext_copy); + ext_copy, dateopt); if (j < 0) goto end; if (j > 0) { @@ -988,7 +994,7 @@ end_of_options: sigopts, vfyopts, attribs, db, serial, subj, chtype, multirdn, email_dn, startdate, enddate, days, batch, extensions, conf, verbose, - certopt, get_nameopt(), default_op, ext_copy, selfsign); + certopt, get_nameopt(), default_op, ext_copy, selfsign, dateopt); if (j < 0) goto end; if (j > 0) { @@ -1009,7 +1015,7 @@ end_of_options: attribs, db, serial, subj, chtype, multirdn, email_dn, startdate, enddate, days, batch, extensions, conf, verbose, - certopt, get_nameopt(), default_op, ext_copy, selfsign); + certopt, get_nameopt(), default_op, ext_copy, selfsign, dateopt); if (j < 0) goto end; if (j > 0) { @@ -1357,7 +1363,7 @@ static int certify(X509 **xret, const char *infile, int informat, const char *enddate, long days, int batch, const char *ext_sect, CONF *lconf, int verbose, unsigned long certopt, unsigned long nameopt, - int default_op, int ext_copy, int selfsign) + int default_op, int ext_copy, int selfsign, unsigned long dateopt) { X509_REQ *req = NULL; EVP_PKEY *pktmp = NULL; @@ -1396,7 +1402,7 @@ static int certify(X509 **xret, const char *infile, int informat, ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial, subj, chtype, multirdn, email_dn, startdate, enddate, days, batch, verbose, req, ext_sect, lconf, certopt, nameopt, default_op, - ext_copy, selfsign); + ext_copy, selfsign, dateopt); end: ERR_print_errors(bio_err); @@ -1414,7 +1420,7 @@ static int certify_cert(X509 **xret, const char *infile, int certformat, int multirdn, int email_dn, const char *startdate, const char *enddate, long days, int batch, const char *ext_sect, CONF *lconf, int verbose, unsigned long certopt, - unsigned long nameopt, int default_op, int ext_copy) + unsigned long nameopt, int default_op, int ext_copy, unsigned long dateopt) { X509 *template_cert = NULL; X509_REQ *rreq = NULL; @@ -1453,7 +1459,7 @@ static int certify_cert(X509 **xret, const char *infile, int certformat, ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial, subj, chtype, multirdn, email_dn, startdate, enddate, days, batch, verbose, rreq, ext_sect, lconf, certopt, nameopt, default_op, - ext_copy, 0); + ext_copy, 0, dateopt); end: X509_REQ_free(rreq); @@ -1468,7 +1474,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, int email_dn, const char *startdate, const char *enddate, long days, int batch, int verbose, X509_REQ *req, const char *ext_sect, CONF *lconf, unsigned long certopt, unsigned long nameopt, - int default_op, int ext_copy, int selfsign) + int default_op, int ext_copy, int selfsign, unsigned long dateopt) { const X509_NAME *name = NULL; X509_NAME *CAname = NULL, *subject = NULL; @@ -1877,7 +1883,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, } BIO_printf(bio_err, "Certificate is to be certified until "); - ASN1_TIME_print(bio_err, X509_get0_notAfter(ret)); + ASN1_TIME_print_ex(bio_err, X509_get0_notAfter(ret), dateopt); if (days) BIO_printf(bio_err, " (%ld days)", days); BIO_printf(bio_err, "\n"); @@ -1970,7 +1976,7 @@ static int certify_spkac(X509 **xret, const char *infile, EVP_PKEY *pkey, int multirdn, int email_dn, const char *startdate, const char *enddate, long days, const char *ext_sect, CONF *lconf, int verbose, unsigned long certopt, - unsigned long nameopt, int default_op, int ext_copy) + unsigned long nameopt, int default_op, int ext_copy, unsigned long dateopt) { STACK_OF(CONF_VALUE) *sk = NULL; LHASH_OF(CONF_VALUE) *parms = NULL; @@ -2083,7 +2089,7 @@ static int certify_spkac(X509 **xret, const char *infile, EVP_PKEY *pkey, ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial, subj, chtype, multirdn, email_dn, startdate, enddate, days, 1, verbose, req, ext_sect, lconf, certopt, nameopt, default_op, - ext_copy, 0); + ext_copy, 0, dateopt); end: X509_REQ_free(req); CONF_free(parms); diff --git a/apps/crl.c b/apps/crl.c index ff7c314717..2158a107e5 100644 --- a/apps/crl.c +++ b/apps/crl.c @@ -23,7 +23,7 @@ typedef enum OPTION_choice { OPT_INFORM, OPT_IN, OPT_OUTFORM, OPT_OUT, OPT_KEYFORM, OPT_KEY, OPT_ISSUER, OPT_LASTUPDATE, OPT_NEXTUPDATE, OPT_FINGERPRINT, OPT_CRLNUMBER, OPT_BADSIG, OPT_GENDELTA, OPT_CAPATH, OPT_CAFILE, OPT_CASTORE, - OPT_NOCAPATH, OPT_NOCAFILE, OPT_NOCASTORE, OPT_VERIFY, OPT_TEXT, OPT_HASH, + OPT_NOCAPATH, OPT_NOCAFILE, OPT_NOCASTORE, OPT_VERIFY, OPT_DATEOPT, OPT_TEXT, OPT_HASH, OPT_HASH_OLD, OPT_NOOUT, OPT_NAMEOPT, OPT_MD, OPT_PROV_ENUM } OPTION_CHOICE; @@ -41,6 +41,7 @@ const OPTIONS crl_options[] = { OPT_SECTION("Output"), {"out", OPT_OUT, '>', "output file - default stdout"}, {"outform", OPT_OUTFORM, 'F', "Output format - default PEM"}, + {"dateopt", OPT_DATEOPT, 's', "Datetime format used for printing. (rfc_822/iso_8601). Default is rfc_822."}, {"text", OPT_TEXT, '-', "Print out a text format version"}, {"hash", OPT_HASH, '-', "Print hash value"}, #ifndef OPENSSL_NO_MD5 @@ -91,6 +92,7 @@ int crl_main(int argc, char **argv) int informat = FORMAT_UNDEF, outformat = FORMAT_PEM, keyformat = FORMAT_UNDEF; int ret = 1, num = 0, badsig = 0, fingerprint = 0, crlnumber = 0; int text = 0, do_ver = 0, noCAfile = 0, noCApath = 0, noCAstore = 0; + unsigned long dateopt = ASN1_DTFLGS_RFC822; int i; #ifndef OPENSSL_NO_MD5 int hash_old = 0; @@ -161,6 +163,10 @@ int crl_main(int argc, char **argv) case OPT_VERIFY: do_ver = 1; break; + case OPT_DATEOPT: + if (!set_dateopt(&dateopt, opt_arg())) + goto opthelp; + break; case OPT_TEXT: text = 1; break; @@ -327,13 +333,13 @@ int crl_main(int argc, char **argv) #endif if (lastupdate == i) { BIO_printf(bio_out, "lastUpdate="); - ASN1_TIME_print(bio_out, X509_CRL_get0_lastUpdate(x)); + ASN1_TIME_print_ex(bio_out, X509_CRL_get0_lastUpdate(x), dateopt); BIO_printf(bio_out, "\n"); } if (nextupdate == i) { BIO_printf(bio_out, "nextUpdate="); if (X509_CRL_get0_nextUpdate(x)) - ASN1_TIME_print(bio_out, X509_CRL_get0_nextUpdate(x)); + ASN1_TIME_print_ex(bio_out, X509_CRL_get0_nextUpdate(x), dateopt); else BIO_printf(bio_out, "NONE"); BIO_printf(bio_out, "\n"); diff --git a/apps/include/apps.h b/apps/include/apps.h index c9f77f6067..4b5c34f2e2 100644 --- a/apps/include/apps.h +++ b/apps/include/apps.h @@ -100,6 +100,7 @@ void print_bignum_var(BIO *, const BIGNUM *, const char*, void print_array(BIO *, const char *, int, const unsigned char *); int set_nameopt(const char *arg); unsigned long get_nameopt(void); +int set_dateopt(unsigned long *dateopt, const char *arg); int set_cert_ex(unsigned long *flags, const char *arg); int set_name_ex(unsigned long *flags, const char *arg); int set_ext_copy(int *copy_type, const char *arg); diff --git a/apps/lib/apps.c b/apps/lib/apps.c index 9aae725fc6..79fe4f8409 100644 --- a/apps/lib/apps.c +++ b/apps/lib/apps.c @@ -1214,6 +1214,15 @@ int set_name_ex(unsigned long *flags, const char *arg) return 1; } +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; +} + int set_ext_copy(int *copy_type, const char *arg) { if (strcasecmp(arg, "none") == 0) diff --git a/apps/x509.c b/apps/x509.c index 8ec6ba2db5..25c75e8574 100644 --- a/apps/x509.c +++ b/apps/x509.c @@ -44,7 +44,7 @@ typedef enum OPTION_choice { OPT_CAKEYFORM, OPT_VFYOPT, OPT_SIGOPT, OPT_DAYS, OPT_PASSIN, OPT_EXTFILE, OPT_EXTENSIONS, OPT_IN, OPT_OUT, OPT_KEY, OPT_SIGNKEY, OPT_CA, OPT_CAKEY, OPT_CASERIAL, OPT_SET_SERIAL, OPT_NEW, OPT_FORCE_PUBKEY, OPT_SUBJ, - OPT_ADDTRUST, OPT_ADDREJECT, OPT_SETALIAS, OPT_CERTOPT, OPT_NAMEOPT, + OPT_ADDTRUST, OPT_ADDREJECT, OPT_SETALIAS, OPT_CERTOPT, OPT_DATEOPT, OPT_NAMEOPT, OPT_EMAIL, OPT_OCSP_URI, OPT_SERIAL, OPT_NEXT_SERIAL, OPT_MODULUS, OPT_PUBKEY, OPT_X509TOREQ, OPT_TEXT, OPT_HASH, OPT_ISSUER_HASH, OPT_SUBJECT, OPT_ISSUER, OPT_FINGERPRINT, OPT_DATES, @@ -87,6 +87,7 @@ const OPTIONS x509_options[] = { OPT_SECTION("Certificate printing"), {"text", OPT_TEXT, '-', "Print the certificate in text form"}, + {"dateopt", OPT_DATEOPT, 's', "Datetime format used for printing. (rfc_822/iso_8601). Default is rfc_822."}, {"certopt", OPT_CERTOPT, 's', "Various certificate text printing options"}, {"fingerprint", OPT_FINGERPRINT, '-', "Print the certificate fingerprint"}, {"alias", OPT_ALIAS, '-', "Print certificate alias"}, @@ -267,6 +268,7 @@ int x509_main(int argc, char **argv) int days = UNSET_DAYS; /* not explicitly set */ int x509toreq = 0, modulus = 0, print_pubkey = 0, pprint = 0; int CAformat = FORMAT_UNDEF, CAkeyformat = FORMAT_UNDEF; + unsigned long dateopt = ASN1_DTFLGS_RFC822; int fingerprint = 0, reqfile = 0, checkend = 0; int informat = FORMAT_UNDEF, outformat = FORMAT_PEM, keyformat = FORMAT_UNDEF; int next_serial = 0, subject_hash = 0, issuer_hash = 0, ocspid = 0; @@ -330,6 +332,14 @@ int x509_main(int argc, char **argv) case OPT_REQ: reqfile = 1; break; + + case OPT_DATEOPT: + if (!set_dateopt(&dateopt, opt_arg())) { + BIO_printf(bio_err, + "Invalid date format: %s\n", opt_arg()); + goto end; + } + break; case OPT_COPY_EXTENSIONS: if (!set_ext_copy(&ext_copy, opt_arg())) { BIO_printf(bio_err, @@ -956,11 +966,11 @@ int x509_main(int argc, char **argv) X509_print_ex(out, x, get_nameopt(), certflag); } else if (i == startdate) { BIO_puts(out, "notBefore="); - ASN1_TIME_print(out, X509_get0_notBefore(x)); + ASN1_TIME_print_ex(out, X509_get0_notBefore(x), dateopt); BIO_puts(out, "\n"); } else if (i == enddate) { BIO_puts(out, "notAfter="); - ASN1_TIME_print(out, X509_get0_notAfter(x)); + ASN1_TIME_print_ex(out, X509_get0_notAfter(x), dateopt); BIO_puts(out, "\n"); } else if (i == fingerprint) { unsigned int n; |