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 {
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,
+ OPT_R_ENUM
} OPTION_CHOICE;
const OPTIONS x509_options[] = {
{"text", OPT_TEXT, '-', "Print the certificate in text form"},
{"C", OPT_C, '-', "Print out C code forms"},
{"extfile", OPT_EXTFILE, '<', "File with X509V3 extensions to add"},
+ OPT_R_OPTIONS,
{"extensions", OPT_EXTENSIONS, 's', "Section from config file to use"},
{"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"},
{"certopt", OPT_CERTOPT, 's', "Various certificate text 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}
};
char *prog;
int x509req = 0, days = DEF_DAYS, modulus = 0, pubkey = 0, pprint = 0;
int C = 0, CAformat = FORMAT_PEM, CAkeyformat = FORMAT_PEM;
- int fingerprint = 0, reqfile = 0, need_rand = 0, checkend = 0;
+ int fingerprint = 0, reqfile = 0, checkend = 0;
int informat = FORMAT_PEM, outformat = FORMAT_PEM, keyformat = FORMAT_PEM;
int next_serial = 0, subject_hash = 0, issuer_hash = 0, ocspid = 0;
int noout = 0, sign_flag = 0, CA_flag = 0, CA_createserial = 0, email = 0;
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
outfile = opt_arg();
break;
case OPT_REQ:
- reqfile = need_rand = 1;
+ reqfile = 1;
break;
case OPT_SIGOPT:
goto opthelp;
break;
case OPT_DAYS:
+ if (preserve_dates)
+ goto opthelp;
days = atoi(opt_arg());
break;
case OPT_PASSIN:
case OPT_EXTFILE:
extfile = opt_arg();
break;
+ case OPT_R_CASES:
+ if (!opt_rand(o))
+ goto end;
+ break;
case OPT_EXTENSIONS:
extsect = opt_arg();
break;
case OPT_SIGNKEY:
keyfile = opt_arg();
sign_flag = ++num;
- need_rand = 1;
break;
case OPT_CA:
CAfile = opt_arg();
CA_flag = ++num;
- need_rand = 1;
break;
case OPT_CAKEY:
CAkeyfile = opt_arg();
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;
if (out == NULL)
goto end;
- if (need_rand)
- app_RAND_load_file(NULL, 0);
-
if (!app_passwd(passinarg, NULL, &passin, NULL)) {
BIO_printf(bio_err, "Error getting password\n");
goto end;
goto end;
}
- 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");
goto end;
}
- assert(need_rand);
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;
}
ret = 0;
end:
- if (need_rand)
- app_RAND_write_file(NULL);
NCONF_free(extconf);
BIO_free_all(out);
X509_STORE_free(ctx);
ASN1_OBJECT_free(objtmp);
release_engine(e);
OPENSSL_free(passin);
- return (ret);
+ return ret;
}
-static ASN1_INTEGER *x509_load_serial(const char *CAfile, const char *serialfile,
- int create)
+static ASN1_INTEGER *x509_load_serial(const char *CAfile,
+ const char *serialfile, int create)
{
- char *buf = NULL, *p;
+ char *buf = NULL;
ASN1_INTEGER *bs = NULL;
BIGNUM *serial = NULL;
- size_t len;
- len = ((serialfile == NULL)
- ? (strlen(CAfile) + strlen(POSTFIX) + 1)
- : (strlen(serialfile))) + 1;
- buf = app_malloc(len, "serial# buffer");
if (serialfile == NULL) {
- strcpy(buf, CAfile);
- for (p = buf; *p; p++)
- if (*p == '.') {
- *p = '\0';
- break;
- }
- strcat(buf, POSTFIX);
- } else {
- strcpy(buf, serialfile);
+ const char *p = strchr(CAfile, '.');
+ size_t len = p != NULL ? (size_t)(p - CAfile) : strlen(CAfile);
+
+ buf = app_malloc(len + sizeof(POSTFIX), "serial# buffer");
+ memcpy(buf, CAfile, len);
+ memcpy(buf + len, POSTFIX, sizeof(POSTFIX));
+ serialfile = buf;
}
- serial = load_serial(buf, create, NULL);
+ serial = load_serial(serialfile, create, NULL);
if (serial == NULL)
goto end;
goto end;
}
- if (!save_serial(buf, NULL, serial, &bs))
+ if (!save_serial(serialfile, NULL, serial, &bs))
goto end;
end:
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;
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) {
/* 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;