From 4a60bb1898ca8271a6ae46e2e2e805879eb38931 Mon Sep 17 00:00:00 2001 From: Todd Short Date: Fri, 20 Feb 2015 15:00:28 -0500 Subject: [PATCH] Fix #946 Add -preserve_dates to x509 app Add the -preserve_dates dates option to preserve dates when signing a certificate. Prevent -days and -preserve_dates being used simultaneously Fixes #946 Reviewed-by: Rich Salz Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/946) --- apps/x509.c | 30 +++++++++++++++++++++--------- doc/man1/x509.pod | 8 +++++++- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/apps/x509.c b/apps/x509.c index 840e12778b..6a24da2a61 100644 --- a/apps/x509.c +++ b/apps/x509.c @@ -33,12 +33,14 @@ static int callb(int ok, X509_STORE_CTX *ctx); static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, - const EVP_MD *digest, CONF *conf, const char *section); + const EVP_MD *digest, CONF *conf, const char *section, + int preserve_dates); static int x509_certify(X509_STORE *ctx, const char *CAfile, const EVP_MD *digest, X509 *x, X509 *xca, EVP_PKEY *pkey, STACK_OF(OPENSSL_STRING) *sigopts, const char *serialfile, int create, int days, int clrext, CONF *conf, - const char *section, ASN1_INTEGER *sno, int reqfile); + const char *section, ASN1_INTEGER *sno, int reqfile, + int preserve_dates); static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt); typedef enum OPTION_choice { @@ -56,7 +58,7 @@ typedef enum OPTION_choice { OPT_CLRREJECT, OPT_ALIAS, OPT_CACREATESERIAL, OPT_CLREXT, OPT_OCSPID, OPT_SUBJECT_HASH_OLD, OPT_ISSUER_HASH_OLD, - OPT_BADSIG, OPT_MD, OPT_ENGINE, OPT_NOCERT + OPT_BADSIG, OPT_MD, OPT_ENGINE, OPT_NOCERT, OPT_PRESERVE_DATES } OPTION_CHOICE; const OPTIONS x509_options[] = { @@ -140,6 +142,7 @@ const OPTIONS x509_options[] = { #ifndef OPENSSL_NO_ENGINE {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"}, #endif + {"preserve_dates", OPT_PRESERVE_DATES, '-', "preserve existing dates when signing"}, {NULL} }; @@ -173,6 +176,7 @@ int x509_main(int argc, char **argv) int enddate = 0; time_t checkoffset = 0; unsigned long certflag = 0; + int preserve_dates = 0; OPTION_CHOICE o; ENGINE *e = NULL; #ifndef OPENSSL_NO_MD5 @@ -233,6 +237,8 @@ int x509_main(int argc, char **argv) goto opthelp; break; case OPT_DAYS: + if (preserve_dates) + goto opthelp; days = atoi(opt_arg()); break; case OPT_PASSIN: @@ -433,6 +439,11 @@ int x509_main(int argc, char **argv) case OPT_CHECKIP: checkip = opt_arg(); break; + case OPT_PRESERVE_DATES: + if (days != DEF_DAYS) + goto opthelp; + preserve_dates = 1; + break; case OPT_MD: if (!opt_md(opt_unknown(), &digest)) goto opthelp; @@ -783,7 +794,7 @@ int x509_main(int argc, char **argv) } assert(need_rand); - if (!sign(x, Upkey, days, clrext, digest, extconf, extsect)) + if (!sign(x, Upkey, days, clrext, digest, extconf, extsect, preserve_dates)) goto end; } else if (CA_flag == i) { BIO_printf(bio_err, "Getting CA Private Key\n"); @@ -798,7 +809,7 @@ int x509_main(int argc, char **argv) if (!x509_certify(ctx, CAfile, digest, x, xca, CApkey, sigopts, CAserial, CA_createserial, days, clrext, - extconf, extsect, sno, reqfile)) + extconf, extsect, sno, reqfile, preserve_dates)) goto end; } else if (x509req == i) { EVP_PKEY *pk; @@ -933,7 +944,7 @@ static int x509_certify(X509_STORE *ctx, const char *CAfile, const EVP_MD *diges STACK_OF(OPENSSL_STRING) *sigopts, const char *serialfile, int create, int days, int clrext, CONF *conf, const char *section, - ASN1_INTEGER *sno, int reqfile) + ASN1_INTEGER *sno, int reqfile, int preserve_dates) { int ret = 0; ASN1_INTEGER *bs = NULL; @@ -977,7 +988,7 @@ static int x509_certify(X509_STORE *ctx, const char *CAfile, const EVP_MD *diges if (!X509_set_serialNumber(x, bs)) goto end; - if (!set_cert_times(x, NULL, NULL, days)) + if (!preserve_dates && !set_cert_times(x, NULL, NULL, days)) goto end; if (clrext) { @@ -1041,12 +1052,13 @@ static int callb(int ok, X509_STORE_CTX *ctx) /* self sign */ static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, - const EVP_MD *digest, CONF *conf, const char *section) + const EVP_MD *digest, CONF *conf, const char *section, + int preserve_dates) { if (!X509_set_issuer_name(x, X509_get_subject_name(x))) goto err; - if (!set_cert_times(x, NULL, NULL, days)) + if (!preserve_dates && !set_cert_times(x, NULL, NULL, days)) goto err; if (!X509_set_pubkey(x, pkey)) goto err; diff --git a/doc/man1/x509.pod b/doc/man1/x509.pod index fccfd6c21a..b769829b77 100644 --- a/doc/man1/x509.pod +++ b/doc/man1/x509.pod @@ -60,6 +60,7 @@ B B [B<-extfile filename>] [B<-extensions section>] [B<-engine id>] +[B<-preserve_dates>] =head1 DESCRIPTION @@ -121,6 +122,11 @@ to attempt to obtain a functional reference to the specified engine, thus initialising it if needed. The engine will then be set as the default for all available algorithms. +=item B<-preserve_dates> + +When signing a certificate, preserve the "notBefore" and "notAfter" dates instead +of adjusting them to current time and duration. Cannot be used with the B<-days> option. + =back =head2 Display Options @@ -355,7 +361,7 @@ B<-signkey> option. =item B<-days arg> Specifies the number of days to make a certificate valid for. The default -is 30 days. +is 30 days. Cannot be used with the B<-preserve_dates> option. =item B<-x509toreq> -- 2.34.1