/*
- * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
#ifndef W_OK
# ifdef OPENSSL_SYS_VMS
-# if defined(__DECC)
-# include <unistd.h>
-# else
-# include <unixlib.h>
-# endif
+# include <unistd.h>
# elif !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_WINDOWS)
# include <sys/file.h>
# endif
#ifndef W_OK
# define F_OK 0
-# define X_OK 1
# define W_OK 2
# define R_OK 4
#endif
#define ENV_NEW_CERTS_DIR "new_certs_dir"
#define ENV_CERTIFICATE "certificate"
#define ENV_SERIAL "serial"
+#define ENV_RAND_SERIAL "rand_serial"
#define ENV_CRLNUMBER "crlnumber"
#define ENV_PRIVATE_KEY "private_key"
#define ENV_DEFAULT_DAYS "default_days"
OPT_GENCRL, OPT_MSIE_HACK, OPT_CRLDAYS, OPT_CRLHOURS, OPT_CRLSEC,
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_R_ENUM,
/* Do not change the order here; see related case statements below */
OPT_CRL_REASON, OPT_CRL_HOLD, OPT_CRL_COMPROMISE, OPT_CRL_CA_COMPROMISE
} OPTION_CHOICE;
{"utf8", OPT_UTF8, '-', "Input characters are UTF8 (default ASCII)"},
{"create_serial", OPT_CREATE_SERIAL, '-',
"If reading serial fails, create a new random serial"},
+ {"rand_serial", OPT_RAND_SERIAL, '-',
+ "Always create a random serial; do not store it"},
{"multivalue-rdn", OPT_MULTIVALUE_RDN, '-',
"Enable support for multivalued RDNs"},
{"startdate", OPT_STARTDATE, 's', "Cert notBefore, YYMMDDHHMMSSZ"},
"sets compromise time to val and the revocation reason to keyCompromise"},
{"crl_CA_compromise", OPT_CRL_CA_COMPROMISE, 's',
"sets compromise time to val and the revocation reason to CACompromise"},
+ OPT_R_OPTIONS,
#ifndef OPENSSL_NO_ENGINE
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
#endif
char *outdir = NULL, *outfile = NULL, *rev_arg = NULL, *ser_status = NULL;
const char *serialfile = NULL, *subj = NULL;
char *prog, *startdate = NULL, *enddate = NULL;
- char *dbfile = NULL, *f, *randfile = NULL;
+ char *dbfile = NULL, *f;
char new_cert[CERT_MAX + 1];
char tmp[10 + 1] = "\0";
char *const *pp;
int batch = 0, default_op = 1, doupdatedb = 0, ext_copy = EXT_COPY_NONE;
int keyformat = FORMAT_PEM, multirdn = 0, notext = 0, output_der = 0;
int ret = 1, email_dn = 1, req = 0, verbose = 0, gencrl = 0, dorevoke = 0;
- int i, j, selfsign = 0;
+ int rand_ser = 0, i, j, selfsign = 0;
long crldays = 0, crlhours = 0, crlsec = 0, days = 0;
- unsigned long chtype = MBSTRING_ASC, nameopt = 0, certopt = 0;
+ unsigned long chtype = MBSTRING_ASC, certopt = 0;
X509 *x509 = NULL, *x509p = NULL, *x = NULL;
REVINFO_TYPE rev_type = REV_NONE;
X509_REVOKED *r = NULL;
case OPT_UTF8:
chtype = MBSTRING_UTF8;
break;
+ case OPT_RAND_SERIAL:
+ rand_ser = 1;
+ break;
case OPT_CREATE_SERIAL:
create_ser = 1;
break;
case OPT_PASSIN:
passinarg = opt_arg();
break;
+ case OPT_R_CASES:
+ if (!opt_rand(o))
+ goto end;
+ break;
case OPT_KEY:
key = opt_arg();
break;
}
}
- randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE");
- if (randfile == NULL)
- ERR_clear_error();
- app_RAND_load_file(randfile, 0);
+ app_RAND_load_conf(conf, BASE_SECTION);
f = NCONF_get_string(conf, section, STRING_MASK);
- if (!f)
+ if (f == NULL)
ERR_clear_error();
- if (f && !ASN1_STRING_set_default_mask_asc(f)) {
+ if (f != NULL && !ASN1_STRING_set_default_mask_asc(f)) {
BIO_printf(bio_err, "Invalid global string mask setting %s\n", f);
goto end;
}
if (chtype != MBSTRING_UTF8) {
f = NCONF_get_string(conf, section, UTF8_IN);
- if (!f)
+ if (f == NULL)
ERR_clear_error();
else if (strcmp(f, "yes") == 0)
chtype = MBSTRING_UTF8;
db_attr.unique_subject = 1;
p = NCONF_get_string(conf, section, ENV_UNIQUE_SUBJECT);
- if (p) {
+ if (p != NULL)
db_attr.unique_subject = parse_yesno(p, 1);
- } else
+ else
ERR_clear_error();
/*****************************************************************/
&& (keyfile = lookup_conf(conf, section, ENV_PRIVATE_KEY)) == NULL)
goto end;
- if (!key) {
+ if (key == NULL) {
free_key = 1;
if (!app_passwd(passinarg, NULL, &key, NULL)) {
BIO_printf(bio_err, "Error getting password\n");
}
}
pkey = load_key(keyfile, keyformat, 0, key, e, "CA private key");
- if (key)
+ if (key != NULL)
OPENSSL_cleanse(key, strlen(key));
- if (pkey == NULL) {
+ if (pkey == NULL)
/* load_key() has already printed an appropriate message */
goto end;
- }
/*****************************************************************/
/* we need a certificate */
f = NCONF_get_string(conf, section, ENV_NAMEOPT);
- if (f) {
- if (!set_name_ex(&nameopt, f)) {
+ if (f != NULL) {
+ if (!set_nameopt(f)) {
BIO_printf(bio_err, "Invalid name options: \"%s\"\n", f);
goto end;
}
default_op = 0;
- } else {
- nameopt = XN_FLAG_ONELINE;
- ERR_clear_error();
}
f = NCONF_get_string(conf, section, ENV_CERTOPT);
- if (f) {
+ if (f != NULL) {
if (!set_cert_ex(&certopt, f)) {
BIO_printf(bio_err, "Invalid certificate options: \"%s\"\n", f);
goto end;
}
default_op = 0;
- } else
+ } else {
ERR_clear_error();
+ }
f = NCONF_get_string(conf, section, ENV_EXTCOPY);
- if (f) {
+ if (f != NULL) {
if (!set_ext_copy(&ext_copy, f)) {
BIO_printf(bio_err, "Invalid extension copy option: \"%s\"\n", f);
goto end;
}
- } else
+ } else {
ERR_clear_error();
+ }
/*****************************************************************/
/* lookup where to write new certificates */
if (verbose)
BIO_printf(bio_err, "policy is %s\n", policy);
- serialfile = lookup_conf(conf, section, ENV_SERIAL);
- if (serialfile == NULL)
- goto end;
+ if (NCONF_get_string(conf, section, ENV_RAND_SERIAL) != NULL) {
+ rand_ser = 1;
+ } else {
+ serialfile = lookup_conf(conf, section, ENV_SERIAL);
+ if (serialfile == NULL)
+ goto end;
+ }
- if (!extconf) {
+ if (extconf == NULL) {
/*
* no '-extfile' option, so we look for extensions in the main
* configuration file
*/
- if (!extensions) {
+ if (extensions == NULL) {
extensions = NCONF_get_string(conf, section, ENV_EXTENSIONS);
- if (!extensions)
+ if (extensions == NULL)
ERR_clear_error();
}
- if (extensions) {
+ if (extensions != NULL) {
/* Check syntax of file */
X509V3_CTX ctx;
X509V3_set_ctx_test(&ctx);
if (startdate == NULL)
ERR_clear_error();
}
- if (startdate && !ASN1_TIME_set_string(NULL, 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 (enddate == NULL)
ERR_clear_error();
}
- if (enddate && !ASN1_TIME_set_string(NULL, 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 (!NCONF_get_number(conf, section, ENV_DEFAULT_DAYS, &days))
days = 0;
}
- if (!enddate && (days == 0)) {
+ if (enddate == NULL && (days == 0)) {
BIO_printf(bio_err,
"cannot lookup how many days to certify for\n");
goto end;
}
- if ((serial = load_serial(serialfile, create_ser, NULL)) == NULL) {
- BIO_printf(bio_err, "error while loading serial number\n");
- goto end;
- }
- if (verbose) {
- if (BN_is_zero(serial))
- BIO_printf(bio_err, "next serial number is 00\n");
- else {
- if ((f = BN_bn2hex(serial)) == NULL)
- goto end;
- BIO_printf(bio_err, "next serial number is %s\n", f);
- OPENSSL_free(f);
+ if (rand_ser) {
+ if ((serial = BN_new()) == NULL || !rand_serial(serial, NULL)) {
+ BIO_printf(bio_err, "error generating serial number\n");
+ goto end;
+ }
+ } else {
+ if ((serial = load_serial(serialfile, create_ser, NULL)) == NULL) {
+ BIO_printf(bio_err, "error while loading serial number\n");
+ goto end;
+ }
+ if (verbose) {
+ if (BN_is_zero(serial)) {
+ BIO_printf(bio_err, "next serial number is 00\n");
+ } else {
+ if ((f = BN_bn2hex(serial)) == NULL)
+ goto end;
+ BIO_printf(bio_err, "next serial number is %s\n", f);
+ OPENSSL_free(f);
+ }
}
}
j = certify_spkac(&x, spkac_file, pkey, x509, dgst, sigopts,
attribs, db, serial, subj, chtype, multirdn,
email_dn, startdate, enddate, days, extensions,
- conf, verbose, certopt, nameopt, default_op,
+ conf, verbose, certopt, get_nameopt(), default_op,
ext_copy);
if (j < 0)
goto end;
attribs,
db, serial, subj, chtype, multirdn, email_dn,
startdate, enddate, days, batch, extensions,
- conf, verbose, certopt, nameopt, default_op,
+ conf, verbose, certopt, get_nameopt(), default_op,
ext_copy);
if (j < 0)
goto end;
j = certify(&x, infile, pkey, x509p, dgst, sigopts, attribs, db,
serial, subj, chtype, multirdn, email_dn, startdate,
enddate, days, batch, extensions, conf, verbose,
- certopt, nameopt, default_op, ext_copy, selfsign);
+ certopt, get_nameopt(), default_op, ext_copy, selfsign);
if (j < 0)
goto end;
if (j > 0) {
j = certify(&x, argv[i], pkey, x509p, dgst, sigopts, attribs, db,
serial, subj, chtype, multirdn, email_dn, startdate,
enddate, days, batch, extensions, conf, verbose,
- certopt, nameopt, default_op, ext_copy, selfsign);
+ certopt, get_nameopt(), default_op, ext_copy, selfsign);
if (j < 0)
goto end;
if (j > 0) {
BIO_printf(bio_err, "Write out database with %d new entries\n",
sk_X509_num(cert_sk));
- if (!save_serial(serialfile, "new", serial, NULL))
+ if (!rand_ser
+ && !save_serial(serialfile, "new", serial, NULL))
goto end;
if (!save_index(dbfile, "new", db))
/*****************************************************************/
if (gencrl) {
int crl_v2 = 0;
- if (!crl_ext) {
+ if (crl_ext == NULL) {
crl_ext = NCONF_get_string(conf, section, ENV_CRLEXT);
- if (!crl_ext)
+ if (crl_ext == NULL)
ERR_clear_error();
}
- if (crl_ext) {
+ if (crl_ext != NULL) {
/* Check syntax of file */
X509V3_CTX ctx;
X509V3_set_ctx_test(&ctx);
/* Add any extensions asked for */
- if (crl_ext || crlnumberfile != NULL) {
+ if (crl_ext != NULL || crlnumberfile != NULL) {
X509V3_CTX crlctx;
X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
X509V3_set_nconf(&crlctx, conf);
- if (crl_ext)
+ if (crl_ext != NULL)
if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx, crl_ext, crl))
goto end;
if (crlnumberfile != NULL) {
goto end;
}
}
- if (crl_ext || crl_v2) {
+ if (crl_ext != NULL || crl_v2) {
if (!X509_CRL_set_version(crl, 1))
goto end; /* version 2 CRL */
}
/* we have a CRL number that need updating */
if (crlnumberfile != NULL)
- if (!save_serial(crlnumberfile, "new", crlnumber, NULL))
+ if (!rand_ser
+ && !save_serial(crlnumberfile, "new", crlnumber, NULL))
goto end;
BN_free(crlnumber);
BIO_printf(bio_err, "Data Base Updated\n");
}
}
- /*****************************************************************/
ret = 0;
+
end:
+ if (ret)
+ ERR_print_errors(bio_err);
BIO_free_all(Sout);
BIO_free_all(out);
BIO_free_all(in);
sk_X509_pop_free(cert_sk, X509_free);
- if (ret)
- ERR_print_errors(bio_err);
- app_RAND_write_file(randfile);
if (free_key)
OPENSSL_free(key);
BN_free(serial);
goto end;
}
if (verbose)
- X509_REQ_print(bio_err, req);
+ X509_REQ_print_ex(bio_err, req, nameopt, X509_FLAG_COMPAT);
BIO_printf(bio_err, "Check that the request matches the signature\n");
"Signature did not match the certificate request\n");
ERR_print_errors(bio_err);
goto end;
- } else
+ } else {
BIO_printf(bio_err, "Signature ok\n");
+ }
ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial, subj,
chtype, multirdn, email_dn, startdate, enddate, days, batch,
ok = 0;
BIO_printf(bio_err, "Signature did not match the certificate\n");
goto end;
- } else
+ } else {
BIO_printf(bio_err, "Signature ok\n");
+ }
if ((rreq = X509_to_X509_REQ(req, NULL, NULL)) == NULL)
goto end;
"The %s field needed to be supplied and was missing\n",
cv->name);
goto end;
- } else
+ } else {
push = tne;
+ }
} else if (strcmp(cv->value, "match") == 0) {
int last2;
BIO_printf(bio_err,
"The subject name appears to be ok, checking data base for clashes\n");
- /*
+ /*
* Build the correct Subject if no e-mail is wanted in the subject.
* And add it later on because of the method extensions are added (altName)
*/
- if (email_dn)
+ if (email_dn) {
dn_subject = subject;
- else {
+ } else {
X509_NAME_ENTRY *tmpne;
/*
* Its best to dup the subject DN and then delete any email addresses
else
X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
- if (extconf) {
+ if (extconf != NULL) {
if (verbose)
BIO_printf(bio_err, "Extra configuration file found\n");
}
irow = app_malloc(sizeof(*irow) * (DB_NUMBER + 1), "row space");
- for (i = 0; i < DB_NUMBER; i++) {
+ for (i = 0; i < DB_NUMBER; i++)
irow[i] = row[i];
- row[i] = NULL;
- }
irow[DB_NUMBER] = NULL;
if (!TXT_DB_insert(db->db, irow)) {
BIO_printf(bio_err, "TXT_DB error number %ld\n", db->db->error);
goto end;
}
+ irow = NULL;
ok = 1;
end:
- for (i = 0; i < DB_NUMBER; i++)
- OPENSSL_free(row[i]);
+ if (irow != NULL) {
+ for (i = 0; i < DB_NUMBER; i++)
+ OPENSSL_free(row[i]);
+ OPENSSL_free(irow);
+ }
X509_NAME_free(CAname);
X509_NAME_free(subject);
row[DB_rev_date] = NULL;
row[DB_file] = OPENSSL_strdup("unknown");
+ if (row[DB_type] == NULL || row[DB_file] == NULL) {
+ BIO_printf(bio_err, "Memory allocation failure\n");
+ goto end;
+ }
+
irow = app_malloc(sizeof(*irow) * (DB_NUMBER + 1), "row ptr");
- for (i = 0; i < DB_NUMBER; i++) {
+ for (i = 0; i < DB_NUMBER; i++)
irow[i] = row[i];
- row[i] = NULL;
- }
irow[DB_NUMBER] = NULL;
if (!TXT_DB_insert(db->db, irow)) {
BIO_printf(bio_err, "failed to update database\n");
BIO_printf(bio_err, "TXT_DB error number %ld\n", db->db->error);
+ OPENSSL_free(irow);
goto end;
}
+ for (i = 0; i < DB_NUMBER; i++)
+ row[i] = NULL;
+
/* Revoke Certificate */
if (rev_type == REV_VALID)
ok = 1;
}
ok = 1;
end:
- for (i = 0; i < DB_NUMBER; i++) {
+ for (i = 0; i < DB_NUMBER; i++)
OPENSSL_free(row[i]);
- }
return (ok);
}
if (serial_len % 2) {
/*
* Set the first char to 0
- */ ;
+ */
row[DB_serial][0] = '0';
/* Copy String from serial to row[DB_serial] */
}
/* Make it Upper Case */
- for (i = 0; row[DB_serial][i] != '\0'; i++)
- row[DB_serial][i] = toupper((unsigned char)row[DB_serial][i]);
+ make_uppercase(row[DB_serial]);
ok = 1;
goto end;
}
- if (reason_code == 7)
+ if (reason_code == 7) {
reason_code = OCSP_REVOKED_STATUS_REMOVEFROMCRL;
- else if (reason_code == 8) { /* Hold instruction */
+ } else if (reason_code == 8) { /* Hold instruction */
if (!arg_str) {
BIO_printf(bio_err, "missing hold instruction\n");
goto end;