mirror of
https://github.com/openssl/openssl.git
synced 2024-11-27 05:21:51 +08:00
apps: ca,req,x509: Add explicit start and end dates options
- Added options `-not_before` (start date) and `-not-after` (end date) for explicit setting of the validity period of a certificate in the apps `ca`, `req` and `x509` - The new options accept time strings or "today" - In app `ca`, use the new options as aliases of the already existing options `-startdate` and `-enddate` - When used in apps `req` and `x509`, the end date must be >= the start date, in app `ca` end date < start date is also accepted - In any case, `-not-after` overrides the `-days` option - Added helper function `check_cert_time_string` to validate given certificate time strings - Use the new helper function in apps `ca`, `req` and `x509` - Moved redundant code for time string checking into `set_cert_times` helper function. - Added tests for explicit start and end dates in apps `req` and `x509` - test: Added auxiliary functions for parsing fields from `-text` formatted output to `tconversion.pl` - CHANGES: Added to new section 3.4 Signed-off-by: Stephan Wurm <atomisirsi@gsklan.de> Reviewed-by: David von Oheimb <david.von.oheimb@siemens.com> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/21716)
This commit is contained in:
parent
4514e02cdf
commit
8120223773
@ -12,6 +12,7 @@ appropriate release branch.
|
||||
OpenSSL Releases
|
||||
----------------
|
||||
|
||||
- [OpenSSL 3.4](#openssl-34)
|
||||
- [OpenSSL 3.3](#openssl-33)
|
||||
- [OpenSSL 3.2](#openssl-32)
|
||||
- [OpenSSL 3.1](#openssl-31)
|
||||
@ -28,7 +29,12 @@ OpenSSL 3.4
|
||||
|
||||
### Changes between 3.3 and 3.4 [xx XXX xxxx]
|
||||
|
||||
* None yet
|
||||
* Added options `-not_before` and `-not_after` for explicit setting
|
||||
start and end dates of certificates created with the `req` and `x509`
|
||||
apps. Added the same options also to `ca` app as alias for
|
||||
`-startdate` and `-enddate` options.
|
||||
|
||||
*Stephan Wurm*
|
||||
|
||||
OpenSSL 3.3
|
||||
-----------
|
||||
|
32
apps/ca.c
32
apps/ca.c
@ -150,7 +150,7 @@ typedef enum OPTION_choice {
|
||||
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,
|
||||
OPT_CRLDAYS, OPT_CRLHOURS, OPT_CRLSEC, OPT_NOT_BEFORE, OPT_NOT_AFTER,
|
||||
OPT_INFILES, OPT_SS_CERT, OPT_SPKAC, OPT_REVOKE, OPT_VALID,
|
||||
OPT_EXTENSIONS, OPT_EXTFILE, OPT_STATUS, OPT_UPDATEDB, OPT_CRLEXTS,
|
||||
OPT_RAND_SERIAL, OPT_QUIET,
|
||||
@ -199,10 +199,13 @@ const OPTIONS ca_options[] = {
|
||||
"Always create a random serial; do not store it"},
|
||||
{"multivalue-rdn", OPT_MULTIVALUE_RDN, '-',
|
||||
"Deprecated; multi-valued RDNs support is always on."},
|
||||
{"startdate", OPT_STARTDATE, 's', "Cert notBefore, YYMMDDHHMMSSZ"},
|
||||
{"startdate", OPT_STARTDATE, 's',
|
||||
"[CC]YYMMDDHHMMSSZ value for notBefore certificate field"},
|
||||
{"not_before", OPT_NOT_BEFORE, 's', "An alias for -startdate"},
|
||||
{"enddate", OPT_ENDDATE, 's',
|
||||
"YYMMDDHHMMSSZ cert notAfter (overrides -days)"},
|
||||
{"days", OPT_DAYS, 'p', "Number of days to certify the cert for"},
|
||||
"[CC]YYMMDDHHMMSSZ value for notAfter certificate field, overrides -days"},
|
||||
{"not_after", OPT_NOT_AFTER, 's', "An alias for -enddate"},
|
||||
{"days", OPT_DAYS, 'p', "Number of days from today to certify the cert for"},
|
||||
{"extensions", OPT_EXTENSIONS, 's',
|
||||
"Extension section (override value in config file)"},
|
||||
{"extfile", OPT_EXTFILE, '<',
|
||||
@ -359,9 +362,11 @@ opthelp:
|
||||
/* obsolete */
|
||||
break;
|
||||
case OPT_STARTDATE:
|
||||
case OPT_NOT_BEFORE:
|
||||
startdate = opt_arg();
|
||||
break;
|
||||
case OPT_ENDDATE:
|
||||
case OPT_NOT_AFTER:
|
||||
enddate = opt_arg();
|
||||
break;
|
||||
case OPT_DAYS:
|
||||
@ -874,22 +879,8 @@ end_of_options:
|
||||
if (startdate == NULL)
|
||||
startdate =
|
||||
app_conf_try_string(conf, section, ENV_DEFAULT_STARTDATE);
|
||||
if (startdate != NULL && !ASN1_TIME_set_string_X509(NULL, startdate)) {
|
||||
BIO_printf(bio_err,
|
||||
"start date is invalid, it should be YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ\n");
|
||||
goto end;
|
||||
}
|
||||
if (startdate == NULL)
|
||||
startdate = "today";
|
||||
|
||||
if (enddate == NULL)
|
||||
enddate = app_conf_try_string(conf, section, ENV_DEFAULT_ENDDATE);
|
||||
if (enddate != NULL && !ASN1_TIME_set_string_X509(NULL, enddate)) {
|
||||
BIO_printf(bio_err,
|
||||
"end date is invalid, it should be YYMMDDHHMMSSZ or YYYYMMDDHHMMSSZ\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (days == 0) {
|
||||
if (!app_conf_try_number(conf, section, ENV_DEFAULT_DAYS, &days))
|
||||
days = 0;
|
||||
@ -898,6 +889,9 @@ end_of_options:
|
||||
BIO_printf(bio_err, "cannot lookup how many days to certify for\n");
|
||||
goto end;
|
||||
}
|
||||
if (days != 0 && enddate != NULL)
|
||||
BIO_printf(bio_err,
|
||||
"Warning: -enddate or -not_after option overriding -days option\n");
|
||||
|
||||
if (rand_ser) {
|
||||
if ((serial = BN_new()) == NULL || !rand_serial(serial, NULL)) {
|
||||
@ -1671,7 +1665,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!set_cert_times(ret, startdate, enddate, days))
|
||||
if (!set_cert_times(ret, startdate, enddate, days, 0))
|
||||
goto end;
|
||||
|
||||
if (enddate != NULL) {
|
||||
|
@ -82,8 +82,12 @@ int has_stdin_waiting(void);
|
||||
# endif
|
||||
|
||||
void corrupt_signature(const ASN1_STRING *signature);
|
||||
|
||||
/* Helpers for setting X509v3 certificate fields notBefore and notAfter */
|
||||
int check_cert_time_string(const char *time, const char *desc);
|
||||
int set_cert_times(X509 *x, const char *startdate, const char *enddate,
|
||||
int days);
|
||||
int days, int strict_compare_times);
|
||||
|
||||
int set_crl_lastupdate(X509_CRL *crl, const char *lastupdate);
|
||||
int set_crl_nextupdate(X509_CRL *crl, const char *nextupdate,
|
||||
long days, long hours, long secs);
|
||||
|
@ -3275,23 +3275,54 @@ void corrupt_signature(const ASN1_STRING *signature)
|
||||
s[signature->length - 1] ^= 0x1;
|
||||
}
|
||||
|
||||
int set_cert_times(X509 *x, const char *startdate, const char *enddate,
|
||||
int days)
|
||||
int check_cert_time_string(const char *time, const char *desc)
|
||||
{
|
||||
if (time == NULL || strcmp(time, "today") == 0
|
||||
|| ASN1_TIME_set_string_X509(NULL, time))
|
||||
return 1;
|
||||
BIO_printf(bio_err,
|
||||
"%s is invalid, it should be \"today\" or have format [CC]YYMMDDHHMMSSZ\n",
|
||||
desc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int set_cert_times(X509 *x, const char *startdate, const char *enddate,
|
||||
int days, int strict_compare_times)
|
||||
{
|
||||
if (!check_cert_time_string(startdate, "start date"))
|
||||
return 0;
|
||||
if (!check_cert_time_string(enddate, "end date"))
|
||||
return 0;
|
||||
if (startdate == NULL || strcmp(startdate, "today") == 0) {
|
||||
if (X509_gmtime_adj(X509_getm_notBefore(x), 0) == NULL)
|
||||
if (X509_gmtime_adj(X509_getm_notBefore(x), 0) == NULL) {
|
||||
BIO_printf(bio_err, "Error setting notBefore certificate field\n");
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (!ASN1_TIME_set_string_X509(X509_getm_notBefore(x), startdate))
|
||||
if (!ASN1_TIME_set_string_X509(X509_getm_notBefore(x), startdate)) {
|
||||
BIO_printf(bio_err, "Error setting notBefore certificate field\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (enddate != NULL && strcmp(enddate, "today") == 0) {
|
||||
enddate = NULL;
|
||||
days = 0;
|
||||
}
|
||||
if (enddate == NULL) {
|
||||
if (X509_time_adj_ex(X509_getm_notAfter(x), days, 0, NULL)
|
||||
== NULL)
|
||||
if (X509_time_adj_ex(X509_getm_notAfter(x), days, 0, NULL) == NULL) {
|
||||
BIO_printf(bio_err, "Error setting notAfter certificate field\n");
|
||||
return 0;
|
||||
}
|
||||
} else if (!ASN1_TIME_set_string_X509(X509_getm_notAfter(x), enddate)) {
|
||||
BIO_printf(bio_err, "Error setting notAfter certificate field\n");
|
||||
return 0;
|
||||
}
|
||||
if (ASN1_TIME_compare(X509_get0_notAfter(x), X509_get0_notBefore(x)) < 0) {
|
||||
BIO_printf(bio_err, "%s: end date before start date\n",
|
||||
strict_compare_times ? "Error" : "Warning");
|
||||
if (strict_compare_times)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
34
apps/req.c
34
apps/req.c
@ -43,7 +43,7 @@
|
||||
|
||||
#define DEFAULT_KEY_LENGTH 2048
|
||||
#define MIN_KEY_LENGTH 512
|
||||
#define DEFAULT_DAYS 30 /* default cert validity period in days */
|
||||
#define DEFAULT_DAYS 30 /* default certificate validity period in days */
|
||||
#define UNSET_DAYS -2 /* -1 may be used for testing expiration checks */
|
||||
#define EXT_COPY_UNSET -1
|
||||
|
||||
@ -87,7 +87,7 @@ typedef enum OPTION_choice {
|
||||
OPT_VERIFY, OPT_NOENC, OPT_NODES, OPT_NOOUT, OPT_VERBOSE, OPT_UTF8,
|
||||
OPT_NAMEOPT, OPT_REQOPT, OPT_SUBJ, OPT_SUBJECT, OPT_TEXT,
|
||||
OPT_X509, OPT_X509V1, OPT_CA, OPT_CAKEY,
|
||||
OPT_MULTIVALUE_RDN, OPT_DAYS, OPT_SET_SERIAL,
|
||||
OPT_MULTIVALUE_RDN, OPT_NOT_BEFORE, OPT_NOT_AFTER, OPT_DAYS, OPT_SET_SERIAL,
|
||||
OPT_COPY_EXTENSIONS, OPT_EXTENSIONS, OPT_REQEXTS, OPT_ADDEXT,
|
||||
OPT_PRECERT, OPT_MD,
|
||||
OPT_SECTION, OPT_QUIET,
|
||||
@ -127,7 +127,11 @@ const OPTIONS req_options[] = {
|
||||
"Print the subject of the output request or cert"},
|
||||
{"multivalue-rdn", OPT_MULTIVALUE_RDN, '-',
|
||||
"Deprecated; multi-valued RDNs support is always on."},
|
||||
{"days", OPT_DAYS, 'p', "Number of days cert is valid for"},
|
||||
{"not_before", OPT_NOT_BEFORE, 's',
|
||||
"[CC]YYMMDDHHMMSSZ value for notBefore certificate field"},
|
||||
{"not_after", OPT_NOT_AFTER, 's',
|
||||
"[CC]YYMMDDHHMMSSZ value for notAfter certificate field, overrides -days"},
|
||||
{"days", OPT_DAYS, 'p', "Number of days certificate is valid for"},
|
||||
{"set_serial", OPT_SET_SERIAL, 's', "Serial number to use"},
|
||||
{"copy_extensions", OPT_COPY_EXTENSIONS, 's',
|
||||
"copy extensions from request when using -x509"},
|
||||
@ -259,6 +263,7 @@ int req_main(int argc, char **argv)
|
||||
char *template = default_config_file, *keyout = NULL;
|
||||
const char *keyalg = NULL;
|
||||
OPTION_CHOICE o;
|
||||
char *not_before = NULL, *not_after = NULL;
|
||||
int days = UNSET_DAYS;
|
||||
int ret = 1, gen_x509 = 0, i = 0, newreq = 0, verbose = 0, progress = 1;
|
||||
int informat = FORMAT_UNDEF, outformat = FORMAT_PEM, keyform = FORMAT_UNDEF;
|
||||
@ -423,9 +428,15 @@ int req_main(int argc, char **argv)
|
||||
case OPT_CAKEY:
|
||||
CAkeyfile = opt_arg();
|
||||
break;
|
||||
case OPT_NOT_BEFORE:
|
||||
not_before = opt_arg();
|
||||
break;
|
||||
case OPT_NOT_AFTER:
|
||||
not_after = opt_arg();
|
||||
break;
|
||||
case OPT_DAYS:
|
||||
days = atoi(opt_arg());
|
||||
if (days < -1) {
|
||||
if (days <= UNSET_DAYS) {
|
||||
BIO_printf(bio_err, "%s: -days parameter arg must be >= -1\n",
|
||||
prog);
|
||||
goto end;
|
||||
@ -494,9 +505,13 @@ int req_main(int argc, char **argv)
|
||||
|
||||
if (!gen_x509) {
|
||||
if (days != UNSET_DAYS)
|
||||
BIO_printf(bio_err, "Ignoring -days without -x509; not generating a certificate\n");
|
||||
BIO_printf(bio_err, "Warning: Ignoring -days without -x509; not generating a certificate\n");
|
||||
if (not_before != NULL)
|
||||
BIO_printf(bio_err, "Warning: Ignoring -not_before without -x509; not generating a certificate\n");
|
||||
if (not_after != NULL)
|
||||
BIO_printf(bio_err, "Warning: Ignoring -not_after without -x509; not generating a certificate\n");
|
||||
if (ext_copy == EXT_COPY_NONE)
|
||||
BIO_printf(bio_err, "Ignoring -copy_extensions 'none' when -x509 is not given\n");
|
||||
BIO_printf(bio_err, "Warning: Ignoring -copy_extensions 'none' when -x509 is not given\n");
|
||||
}
|
||||
if (infile == NULL) {
|
||||
if (gen_x509)
|
||||
@ -802,10 +817,11 @@ int req_main(int argc, char **argv)
|
||||
|
||||
if (!X509_set_issuer_name(new_x509, issuer))
|
||||
goto end;
|
||||
if (days == UNSET_DAYS) {
|
||||
if (days == UNSET_DAYS)
|
||||
days = DEFAULT_DAYS;
|
||||
}
|
||||
if (!set_cert_times(new_x509, NULL, NULL, days))
|
||||
else if (not_after != NULL)
|
||||
BIO_printf(bio_err,"Warning: -not_after option overriding -days option\n");
|
||||
if (!set_cert_times(new_x509, not_before, not_after, days, 1))
|
||||
goto end;
|
||||
if (!X509_set_subject_name(new_x509, n_subj))
|
||||
goto end;
|
||||
|
31
apps/x509.c
31
apps/x509.c
@ -29,8 +29,8 @@
|
||||
|
||||
#undef POSTFIX
|
||||
#define POSTFIX ".srl"
|
||||
#define DEFAULT_DAYS 30 /* default cert validity period in days */
|
||||
#define UNSET_DAYS -2 /* -1 is used for testing expiration checks */
|
||||
#define DEFAULT_DAYS 30 /* default certificate validity period in days */
|
||||
#define UNSET_DAYS -2 /* -1 may be used for testing expiration checks */
|
||||
#define EXT_COPY_UNSET -1
|
||||
|
||||
static int callb(int ok, X509_STORE_CTX *ctx);
|
||||
@ -54,6 +54,7 @@ typedef enum OPTION_choice {
|
||||
OPT_CLRREJECT, OPT_ALIAS, OPT_CACREATESERIAL, OPT_CLREXT, OPT_OCSPID,
|
||||
OPT_SUBJECT_HASH_OLD, OPT_ISSUER_HASH_OLD, OPT_COPY_EXTENSIONS,
|
||||
OPT_BADSIG, OPT_MD, OPT_ENGINE, OPT_NOCERT, OPT_PRESERVE_DATES,
|
||||
OPT_NOT_BEFORE, OPT_NOT_AFTER,
|
||||
OPT_R_ENUM, OPT_PROV_ENUM, OPT_EXT
|
||||
} OPTION_CHOICE;
|
||||
|
||||
@ -135,6 +136,10 @@ const OPTIONS x509_options[] = {
|
||||
"Serial number to use, overrides -CAserial"},
|
||||
{"next_serial", OPT_NEXT_SERIAL, '-',
|
||||
"Increment current certificate serial number"},
|
||||
{"not_before", OPT_NOT_BEFORE, 's',
|
||||
"[CC]YYMMDDHHMMSSZ value for notBefore certificate field"},
|
||||
{"not_after", OPT_NOT_AFTER, 's',
|
||||
"[CC]YYMMDDHHMMSSZ value for notAfter certificate field, overrides -days"},
|
||||
{"days", OPT_DAYS, 'n',
|
||||
"Number of days until newly generated certificate expires - default 30"},
|
||||
{"preserve_dates", OPT_PRESERVE_DATES, '-',
|
||||
@ -279,7 +284,7 @@ int x509_main(int argc, char **argv)
|
||||
char *ext_names = NULL;
|
||||
char *extsect = NULL, *extfile = NULL, *passin = NULL, *passinarg = NULL;
|
||||
char *infile = NULL, *outfile = NULL, *privkeyfile = NULL, *CAfile = NULL;
|
||||
char *prog;
|
||||
char *prog, *not_before = NULL, *not_after = NULL;
|
||||
int days = UNSET_DAYS; /* not explicitly set */
|
||||
int x509toreq = 0, modulus = 0, print_pubkey = 0, pprint = 0;
|
||||
int CAformat = FORMAT_UNDEF, CAkeyformat = FORMAT_UNDEF;
|
||||
@ -376,9 +381,15 @@ int x509_main(int argc, char **argv)
|
||||
if (!vfyopts || !sk_OPENSSL_STRING_push(vfyopts, opt_arg()))
|
||||
goto opthelp;
|
||||
break;
|
||||
case OPT_NOT_BEFORE:
|
||||
not_before = opt_arg();
|
||||
break;
|
||||
case OPT_NOT_AFTER:
|
||||
not_after = opt_arg();
|
||||
break;
|
||||
case OPT_DAYS:
|
||||
days = atoi(opt_arg());
|
||||
if (days < -1) {
|
||||
if (days <= UNSET_DAYS) {
|
||||
BIO_printf(bio_err, "%s: -days parameter arg must be >= -1\n",
|
||||
prog);
|
||||
goto err;
|
||||
@ -610,12 +621,22 @@ int x509_main(int argc, char **argv)
|
||||
if (!opt_check_md(digest))
|
||||
goto opthelp;
|
||||
|
||||
if (preserve_dates && not_before != NULL) {
|
||||
BIO_printf(bio_err, "Cannot use -preserve_dates with -not_before option\n");
|
||||
goto err;
|
||||
}
|
||||
if (preserve_dates && not_after != NULL) {
|
||||
BIO_printf(bio_err, "Cannot use -preserve_dates with -not_after option\n");
|
||||
goto err;
|
||||
}
|
||||
if (preserve_dates && days != UNSET_DAYS) {
|
||||
BIO_printf(bio_err, "Cannot use -preserve_dates with -days option\n");
|
||||
goto err;
|
||||
}
|
||||
if (days == UNSET_DAYS)
|
||||
days = DEFAULT_DAYS;
|
||||
else if (not_after != NULL)
|
||||
BIO_printf(bio_err, "Warning: -not_after option overriding -days option\n");
|
||||
|
||||
if (!app_passwd(passinarg, NULL, &passin, NULL)) {
|
||||
BIO_printf(bio_err, "Error getting password\n");
|
||||
@ -837,7 +858,7 @@ int x509_main(int argc, char **argv)
|
||||
goto end;
|
||||
|
||||
if (reqfile || newcert || privkey != NULL || CAfile != NULL) {
|
||||
if (!preserve_dates && !set_cert_times(x, NULL, NULL, days))
|
||||
if (!preserve_dates && !set_cert_times(x, not_before, not_after, days, 1))
|
||||
goto end;
|
||||
if (fissu != NULL) {
|
||||
if (!X509_set_issuer_name(x, fissu))
|
||||
|
@ -30,7 +30,9 @@ B<openssl> B<ca>
|
||||
[B<-crlsec> I<seconds>]
|
||||
[B<-crlexts> I<section>]
|
||||
[B<-startdate> I<date>]
|
||||
[B<-not_before> I<date>]
|
||||
[B<-enddate> I<date>]
|
||||
[B<-not_after> I<date>]
|
||||
[B<-days> I<arg>]
|
||||
[B<-md> I<arg>]
|
||||
[B<-policy> I<arg>]
|
||||
@ -226,23 +228,32 @@ Don't output the text form of a certificate to the output file.
|
||||
Specify the date output format. Values are: rfc_822 and iso_8601.
|
||||
Defaults to rfc_822.
|
||||
|
||||
=item B<-startdate> I<date>
|
||||
=item B<-startdate> I<date>, B<-not_before> I<date>
|
||||
|
||||
This allows the start date to be explicitly set. The format of the
|
||||
date is YYMMDDHHMMSSZ (the same as an ASN1 UTCTime structure), or
|
||||
YYYYMMDDHHMMSSZ (the same as an ASN1 GeneralizedTime structure). In
|
||||
both formats, seconds SS and timezone Z must be present.
|
||||
Alternatively, you can also use "today".
|
||||
|
||||
=item B<-enddate> I<date>
|
||||
=item B<-enddate> I<date>, B<-not_after> I<date>
|
||||
|
||||
This allows the expiry date to be explicitly set. The format of the
|
||||
date is YYMMDDHHMMSSZ (the same as an ASN1 UTCTime structure), or
|
||||
YYYYMMDDHHMMSSZ (the same as an ASN1 GeneralizedTime structure). In
|
||||
both formats, seconds SS and timezone Z must be present.
|
||||
Alternatively, you can also use "today".
|
||||
|
||||
This overrides the B<-days> option.
|
||||
|
||||
=item B<-days> I<arg>
|
||||
|
||||
The number of days to certify the certificate for.
|
||||
The number of days from today to certify the certificate for.
|
||||
|
||||
Regardless of the option B<-not_before>, the days are always counted from
|
||||
today.
|
||||
When used together with the option B<-not_after>/B<-startdate>, the explicit
|
||||
expiry date takes precedence.
|
||||
|
||||
=item B<-md> I<alg>
|
||||
|
||||
@ -502,7 +513,7 @@ not necessary anymore, see the L</HISTORY> section.
|
||||
|
||||
=item B<default_days>
|
||||
|
||||
The same as the B<-days> option. The number of days to certify
|
||||
The same as the B<-days> option. The number of days from today to certify
|
||||
a certificate for.
|
||||
|
||||
=item B<default_startdate>
|
||||
|
@ -36,6 +36,8 @@ B<openssl> B<req>
|
||||
[B<-x509v1>]
|
||||
[B<-CA> I<filename>|I<uri>]
|
||||
[B<-CAkey> I<filename>|I<uri>]
|
||||
[B<-not_before> I<date>]
|
||||
[B<-not_after> I<date>]
|
||||
[B<-days> I<n>]
|
||||
[B<-set_serial> I<n>]
|
||||
[B<-newhdr>]
|
||||
@ -327,12 +329,37 @@ Sets the "CA" private key to sign a certificate with.
|
||||
The private key must match the public key of the certificate given with B<-CA>.
|
||||
If this option is not provided then the key must be present in the B<-CA> input.
|
||||
|
||||
=item B<-not_before> I<date>
|
||||
|
||||
When B<-x509> is in use this allows the start date to be explicitly set,
|
||||
otherwise it is ignored. The format of I<date> is YYMMDDHHMMSSZ (the
|
||||
same as an ASN1 UTCTime structure), or YYYYMMDDHHMMSSZ (the same as an
|
||||
ASN1 GeneralizedTime structure). In both formats, seconds SS and
|
||||
timezone Z must be present.
|
||||
Alternatively, you can also use "today".
|
||||
|
||||
=item B<-not_after> I<date>
|
||||
|
||||
When B<-x509> is in use this allows the expiry date to be explicitly
|
||||
set, otherwise it is ignored. The format of I<date> is YYMMDDHHMMSSZ
|
||||
(the same as an ASN1 UTCTime structure), or YYYYMMDDHHMMSSZ (the same as
|
||||
an ASN1 GeneralizedTime structure). In both formats, seconds SS and
|
||||
timezone Z must be present.
|
||||
Alternatively, you can also use "today".
|
||||
|
||||
This overrides the B<-days> option.
|
||||
|
||||
=item B<-days> I<n>
|
||||
|
||||
When B<-x509> is in use this specifies the number of
|
||||
days to certify the certificate for, otherwise it is ignored. I<n> should
|
||||
When B<-x509> is in use this specifies the number of days from today to
|
||||
certify the certificate for, otherwise it is ignored. I<n> should
|
||||
be a positive integer. The default is 30 days.
|
||||
|
||||
Regardless of the option B<-not_before>, the days are always counted from
|
||||
today.
|
||||
When used together with the option B<-not_after>, the explicit expiry
|
||||
date takes precedence.
|
||||
|
||||
=item B<-set_serial> I<n>
|
||||
|
||||
Serial number to use when outputting a self-signed certificate.
|
||||
|
@ -54,6 +54,8 @@ B<openssl> B<x509>
|
||||
[B<-checkip> I<ipaddr>]
|
||||
[B<-set_serial> I<n>]
|
||||
[B<-next_serial>]
|
||||
[B<-not_before> I<date>]
|
||||
[B<-not_after> I<date>]
|
||||
[B<-days> I<arg>]
|
||||
[B<-preserve_dates>]
|
||||
[B<-set_issuer> I<arg>]
|
||||
@ -183,6 +185,8 @@ It sets the issuer name to the subject name (i.e., makes it self-issued).
|
||||
Unless the B<-preserve_dates> option is supplied,
|
||||
it sets the validity start date to the current time
|
||||
and the end date to a value determined by the B<-days> option.
|
||||
Start date and end date can also be explicitly supplied with options
|
||||
B<-not_before> and B<-not_after>.
|
||||
|
||||
=item B<-signkey> I<filename>|I<uri>
|
||||
|
||||
@ -376,17 +380,40 @@ The serial number can be decimal or hex (if preceded by C<0x>).
|
||||
|
||||
Set the serial to be one more than the number in the certificate.
|
||||
|
||||
=item B<-not_before> I<date>
|
||||
|
||||
This allows the start date to be explicitly set. The format of the
|
||||
date is YYMMDDHHMMSSZ (the same as an ASN1 UTCTime structure), or
|
||||
YYYYMMDDHHMMSSZ (the same as an ASN1 GeneralizedTime structure). In
|
||||
both formats, seconds SS and timezone Z must be present.
|
||||
Alternatively, you can also use "today".
|
||||
|
||||
Cannot be used together with the B<-preserve_dates> option.
|
||||
|
||||
=item B<-not_after> I<date>
|
||||
|
||||
This allows the expiry date to be explicitly set. The format of the
|
||||
date is YYMMDDHHMMSSZ (the same as an ASN1 UTCTime structure), or
|
||||
YYYYMMDDHHMMSSZ (the same as an ASN1 GeneralizedTime structure). In
|
||||
both formats, seconds SS and timezone Z must be present.
|
||||
Alternatively, you can also use "today".
|
||||
|
||||
Cannot be used together with the B<-preserve_dates> option.
|
||||
This overrides the option B<-days>.
|
||||
|
||||
=item B<-days> I<arg>
|
||||
|
||||
Specifies the number of days until a newly generated certificate expires.
|
||||
Specifies the number of days from today until a newly generated certificate expires.
|
||||
The default is 30.
|
||||
Cannot be used together with the B<-preserve_dates> option.
|
||||
|
||||
Cannot be used together with the option B<-preserve_dates>.
|
||||
If option B<-not_after> is set, the explicit expiry date takes precedence.
|
||||
|
||||
=item B<-preserve_dates>
|
||||
|
||||
When signing a certificate, preserve "notBefore" and "notAfter" dates of any
|
||||
input certificate instead of adjusting them to current time and duration.
|
||||
Cannot be used together with the B<-days> option.
|
||||
Cannot be used together with the options B<-days>, B<-not_before> and B<-not_after>.
|
||||
|
||||
=item B<-set_issuer> I<arg>
|
||||
|
||||
|
@ -15,7 +15,7 @@ use OpenSSL::Test qw/:DEFAULT srctop_file/;
|
||||
|
||||
setup("test_req");
|
||||
|
||||
plan tests => 108;
|
||||
plan tests => 109;
|
||||
|
||||
require_ok(srctop_file('test', 'recipes', 'tconversion.pl'));
|
||||
|
||||
@ -607,3 +607,15 @@ ok(run(app(["openssl", "req", "-x509", "-new", "-days", "365",
|
||||
# Verify cert
|
||||
ok(run(app(["openssl", "x509", "-in", "testreq-cert.pem",
|
||||
"-noout", "-text"])), "cert verification");
|
||||
|
||||
# Generate cert with explicit start and end dates
|
||||
my $today = strftime("%Y-%m-%d", localtime);
|
||||
my $cert = "self-signed_explicit_date.pem";
|
||||
ok(run(app(["openssl", "req", "-x509", "-new", "-text",
|
||||
"-config", srctop_file('test', 'test.cnf'),
|
||||
"-key", srctop_file("test", "testrsa.pem"),
|
||||
"-not_before", "today",
|
||||
"-not_after", "today",
|
||||
"-out", $cert]))
|
||||
&& get_not_before_date($cert) eq $today
|
||||
&& get_not_after_date($cert) eq $today, "explicit start and end dates");
|
||||
|
@ -16,7 +16,7 @@ use OpenSSL::Test qw/:DEFAULT srctop_file/;
|
||||
|
||||
setup("test_x509");
|
||||
|
||||
plan tests => 46;
|
||||
plan tests => 51;
|
||||
|
||||
# Prevent MSys2 filename munging for arguments that look like file paths but
|
||||
# aren't
|
||||
@ -187,20 +187,6 @@ ok(!run(app(["openssl", "x509", "-noout", "-dates", "-dateopt", "invalid_format"
|
||||
"-in", srctop_file("test/certs", "ca-cert.pem")])),
|
||||
"Run with invalid -dateopt format");
|
||||
|
||||
# extracts issuer from a -text formatted-output
|
||||
sub get_issuer {
|
||||
my $f = shift(@_);
|
||||
my $issuer = "";
|
||||
open my $fh, $f or die;
|
||||
while (my $line = <$fh>) {
|
||||
if ($line =~ /Issuer:/) {
|
||||
$issuer = $line;
|
||||
}
|
||||
}
|
||||
close $fh;
|
||||
return $issuer;
|
||||
}
|
||||
|
||||
# Tests for signing certs (broken in 1.1.1o)
|
||||
my $a_key = "a-key.pem";
|
||||
my $a_cert = "a-cert.pem";
|
||||
@ -224,7 +210,7 @@ ok(run(app(["openssl", "x509", "-in", $a_cert, "-CA", $ca_cert,
|
||||
"-CAkey", $ca_key, "-set_serial", "1234567890",
|
||||
"-preserve_dates", "-sha256", "-text", "-out", $a2_cert])));
|
||||
# verify issuer is CA
|
||||
ok (get_issuer($a2_cert) =~ /CN=ca.example.com/);
|
||||
ok(get_issuer($a2_cert) =~ /CN=ca.example.com/);
|
||||
|
||||
my $in_csr = srctop_file('test', 'certs', 'x509-check.csr');
|
||||
my $in_key = srctop_file('test', 'certs', 'x509-check-key.pem');
|
||||
@ -268,6 +254,51 @@ ok(run(app(["openssl", "x509", "-req", "-text", "-CAcreateserial",
|
||||
"-in", $b_csr])));
|
||||
ok(-e $ca_serial_dot_in_dir);
|
||||
|
||||
# Tests for explict start and end dates of certificates
|
||||
my $today;
|
||||
my $enddate;
|
||||
$today = strftime("%Y-%m-%d", localtime);
|
||||
ok(run(app(["openssl", "x509", "-req", "-text",
|
||||
"-key", $b_key,
|
||||
"-not_before", "20231031000000Z",
|
||||
"-not_after", "today",
|
||||
"-in", $b_csr, "-out", $b_cert]))
|
||||
&& get_not_before($b_cert) =~ /Oct 31 00:00:00 2023 GMT/
|
||||
&& get_not_after_date($b_cert) eq $today);
|
||||
# explicit start and end dates
|
||||
ok(run(app(["openssl", "x509", "-req", "-text",
|
||||
"-key", $b_key,
|
||||
"-not_before", "20231031000000Z",
|
||||
"-not_after", "20231231000000Z",
|
||||
"-days", "99",
|
||||
"-in", $b_csr, "-out", $b_cert]))
|
||||
&& get_not_before($b_cert) =~ /Oct 31 00:00:00 2023 GMT/
|
||||
&& get_not_after($b_cert) =~ /Dec 31 00:00:00 2023 GMT/);
|
||||
# start date today and days
|
||||
$today = strftime("%Y-%m-%d", localtime);
|
||||
$enddate = strftime("%Y-%m-%d", localtime(time + 99 * 24 * 60 * 60));
|
||||
ok(run(app(["openssl", "x509", "-req", "-text",
|
||||
"-key", $b_key,
|
||||
"-not_before", "today",
|
||||
"-days", "99",
|
||||
"-in", $b_csr, "-out", $b_cert]))
|
||||
&& get_not_before_date($b_cert) eq $today
|
||||
&& get_not_after_date($b_cert) eq $enddate);
|
||||
# end date before start date
|
||||
ok(!run(app(["openssl", "x509", "-req", "-text",
|
||||
"-key", $b_key,
|
||||
"-not_before", "today",
|
||||
"-not_after", "20231031000000Z",
|
||||
"-in", $b_csr, "-out", $b_cert])));
|
||||
# default days option
|
||||
$today = strftime("%Y-%m-%d", localtime);
|
||||
$enddate = strftime("%Y-%m-%d", localtime(time + 30 * 24 * 60 * 60));
|
||||
ok(run(app(["openssl", "x509", "-req", "-text",
|
||||
"-key", $b_key,
|
||||
"-in", $b_csr, "-out", $b_cert]))
|
||||
&& get_not_before_date($b_cert) eq $today
|
||||
&& get_not_after_date($b_cert) eq $enddate);
|
||||
|
||||
SKIP: {
|
||||
skip "EC is not supported by this OpenSSL build", 1
|
||||
if disabled("ec");
|
||||
|
@ -13,6 +13,8 @@ use warnings;
|
||||
use File::Compare qw/compare_text/;
|
||||
use File::Copy;
|
||||
use OpenSSL::Test qw/:DEFAULT/;
|
||||
use Time::Piece;
|
||||
use POSIX qw(strftime);
|
||||
|
||||
my %conversionforms = (
|
||||
# Default conversion forms. Other series may be added with
|
||||
@ -176,4 +178,44 @@ sub cert_ext_has_n_different_lines {
|
||||
# not unlinking $out
|
||||
}
|
||||
|
||||
# extracts string value of certificate field from a -text formatted-output
|
||||
sub get_field {
|
||||
my ($f, $field) = @_;
|
||||
my $string = "";
|
||||
open my $fh, $f or die;
|
||||
while (my $line = <$fh>) {
|
||||
if ($line =~ /$field:\s+(.*)/) {
|
||||
$string = $1;
|
||||
}
|
||||
}
|
||||
close $fh;
|
||||
return $string;
|
||||
}
|
||||
|
||||
sub get_issuer {
|
||||
return get_field(@_, "Issuer");
|
||||
}
|
||||
|
||||
sub get_not_before {
|
||||
return get_field(@_, "Not Before");
|
||||
}
|
||||
|
||||
# Date as yyyy-mm-dd
|
||||
sub get_not_before_date {
|
||||
return Time::Piece->strptime(
|
||||
get_not_before(@_),
|
||||
"%b %d %T %Y %Z")->date;
|
||||
}
|
||||
|
||||
sub get_not_after {
|
||||
return get_field(@_, "Not After ");
|
||||
}
|
||||
|
||||
# Date as yyyy-mm-dd
|
||||
sub get_not_after_date {
|
||||
return Time::Piece->strptime(
|
||||
get_not_after(@_),
|
||||
"%b %d %T %Y %Z")->date;
|
||||
}
|
||||
|
||||
1;
|
||||
|
Loading…
Reference in New Issue
Block a user