提交 ffb46830 编写于 作者: R Rich Salz

Add random serial# support.

Add -rand_serial to CA command and "serial_rand" config option.

Up RAND_BITS to 159, and comment why: now confirms to CABForum
guidelines (Ballot 164) as well as IETF RFC 5280 (PKIX).
Reviewed-by: NRichard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/4185)
上级 932c0df2
...@@ -1503,15 +1503,11 @@ int rand_serial(BIGNUM *b, ASN1_INTEGER *ai) ...@@ -1503,15 +1503,11 @@ int rand_serial(BIGNUM *b, ASN1_INTEGER *ai)
BIGNUM *btmp; BIGNUM *btmp;
int ret = 0; int ret = 0;
if (b) btmp = b == NULL ? BN_new() : b;
btmp = b;
else
btmp = BN_new();
if (btmp == NULL) if (btmp == NULL)
return 0; return 0;
if (!BN_rand(btmp, SERIAL_RAND_BITS, 0, 0)) if (!BN_rand(btmp, SERIAL_RAND_BITS, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY))
goto error; goto error;
if (ai && !BN_to_ASN1_INTEGER(btmp, ai)) if (ai && !BN_to_ASN1_INTEGER(btmp, ai))
goto error; goto error;
......
...@@ -568,7 +568,12 @@ void store_setup_crl_download(X509_STORE *st); ...@@ -568,7 +568,12 @@ void store_setup_crl_download(X509_STORE *st);
# define APP_PASS_LEN 1024 # define APP_PASS_LEN 1024
# define SERIAL_RAND_BITS 64 /*
* IETF RFC 5280 says serial number must be <= 20 bytes. Use 159 bits
* so that the first bit will never be one, so that the DER encoding
* rules won't force a leading octet.
*/
# define SERIAL_RAND_BITS 159
int app_isdir(const char *); int app_isdir(const char *);
int app_access(const char *, int flag); int app_access(const char *, int flag);
......
...@@ -62,6 +62,7 @@ ...@@ -62,6 +62,7 @@
#define ENV_NEW_CERTS_DIR "new_certs_dir" #define ENV_NEW_CERTS_DIR "new_certs_dir"
#define ENV_CERTIFICATE "certificate" #define ENV_CERTIFICATE "certificate"
#define ENV_SERIAL "serial" #define ENV_SERIAL "serial"
#define ENV_RAND_SERIAL "rand_serial"
#define ENV_CRLNUMBER "crlnumber" #define ENV_CRLNUMBER "crlnumber"
#define ENV_PRIVATE_KEY "private_key" #define ENV_PRIVATE_KEY "private_key"
#define ENV_DEFAULT_DAYS "default_days" #define ENV_DEFAULT_DAYS "default_days"
...@@ -153,6 +154,7 @@ typedef enum OPTION_choice { ...@@ -153,6 +154,7 @@ typedef enum OPTION_choice {
OPT_GENCRL, OPT_MSIE_HACK, OPT_CRLDAYS, OPT_CRLHOURS, OPT_CRLSEC, OPT_GENCRL, OPT_MSIE_HACK, OPT_CRLDAYS, OPT_CRLHOURS, OPT_CRLSEC,
OPT_INFILES, OPT_SS_CERT, OPT_SPKAC, OPT_REVOKE, OPT_VALID, OPT_INFILES, OPT_SS_CERT, OPT_SPKAC, OPT_REVOKE, OPT_VALID,
OPT_EXTENSIONS, OPT_EXTFILE, OPT_STATUS, OPT_UPDATEDB, OPT_CRLEXTS, OPT_EXTENSIONS, OPT_EXTFILE, OPT_STATUS, OPT_UPDATEDB, OPT_CRLEXTS,
OPT_RAND_SERIAL,
OPT_R_ENUM, OPT_R_ENUM,
/* Do not change the order here; see related case statements below */ /* Do not change the order here; see related case statements below */
OPT_CRL_REASON, OPT_CRL_HOLD, OPT_CRL_COMPROMISE, OPT_CRL_CA_COMPROMISE OPT_CRL_REASON, OPT_CRL_HOLD, OPT_CRL_COMPROMISE, OPT_CRL_CA_COMPROMISE
...@@ -167,6 +169,8 @@ const OPTIONS ca_options[] = { ...@@ -167,6 +169,8 @@ const OPTIONS ca_options[] = {
{"utf8", OPT_UTF8, '-', "Input characters are UTF8 (default ASCII)"}, {"utf8", OPT_UTF8, '-', "Input characters are UTF8 (default ASCII)"},
{"create_serial", OPT_CREATE_SERIAL, '-', {"create_serial", OPT_CREATE_SERIAL, '-',
"If reading serial fails, create a new random 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, '-', {"multivalue-rdn", OPT_MULTIVALUE_RDN, '-',
"Enable support for multivalued RDNs"}, "Enable support for multivalued RDNs"},
{"startdate", OPT_STARTDATE, 's', "Cert notBefore, YYMMDDHHMMSSZ"}, {"startdate", OPT_STARTDATE, 's', "Cert notBefore, YYMMDDHHMMSSZ"},
...@@ -258,7 +262,7 @@ int ca_main(int argc, char **argv) ...@@ -258,7 +262,7 @@ int ca_main(int argc, char **argv)
int batch = 0, default_op = 1, doupdatedb = 0, ext_copy = EXT_COPY_NONE; 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 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 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; long crldays = 0, crlhours = 0, crlsec = 0, days = 0;
unsigned long chtype = MBSTRING_ASC, certopt = 0; unsigned long chtype = MBSTRING_ASC, certopt = 0;
X509 *x509 = NULL, *x509p = NULL, *x = NULL; X509 *x509 = NULL, *x509p = NULL, *x = NULL;
...@@ -303,6 +307,9 @@ opthelp: ...@@ -303,6 +307,9 @@ opthelp:
case OPT_UTF8: case OPT_UTF8:
chtype = MBSTRING_UTF8; chtype = MBSTRING_UTF8;
break; break;
case OPT_RAND_SERIAL:
rand_ser = 1;
break;
case OPT_CREATE_SERIAL: case OPT_CREATE_SERIAL:
create_ser = 1; create_ser = 1;
break; break;
...@@ -774,9 +781,13 @@ end_of_options: ...@@ -774,9 +781,13 @@ end_of_options:
if (verbose) if (verbose)
BIO_printf(bio_err, "policy is %s\n", policy); BIO_printf(bio_err, "policy is %s\n", policy);
serialfile = lookup_conf(conf, section, ENV_SERIAL); if (NCONF_get_string(conf, section, ENV_RAND_SERIAL) != NULL) {
if (serialfile == NULL) rand_ser = 1;
goto end; } else {
serialfile = lookup_conf(conf, section, ENV_SERIAL);
if (serialfile == NULL)
goto end;
}
if (extconf == NULL) { if (extconf == NULL) {
/* /*
...@@ -838,18 +849,25 @@ end_of_options: ...@@ -838,18 +849,25 @@ end_of_options:
goto end; goto end;
} }
if ((serial = load_serial(serialfile, create_ser, NULL)) == NULL) { if (rand_ser) {
BIO_printf(bio_err, "error while loading serial number\n"); if ((serial = BN_new()) == NULL || !rand_serial(serial, NULL)) {
goto end; BIO_printf(bio_err, "error generating serial number\n");
} goto end;
if (verbose) { }
if (BN_is_zero(serial)) { } else {
BIO_printf(bio_err, "next serial number is 00\n"); if ((serial = load_serial(serialfile, create_ser, NULL)) == NULL) {
} else { BIO_printf(bio_err, "error while loading serial number\n");
if ((f = BN_bn2hex(serial)) == NULL) goto end;
goto end; }
BIO_printf(bio_err, "next serial number is %s\n", f); if (verbose) {
OPENSSL_free(f); 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);
}
} }
} }
...@@ -973,7 +991,8 @@ end_of_options: ...@@ -973,7 +991,8 @@ end_of_options:
BIO_printf(bio_err, "Write out database with %d new entries\n", BIO_printf(bio_err, "Write out database with %d new entries\n",
sk_X509_num(cert_sk)); sk_X509_num(cert_sk));
if (!save_serial(serialfile, "new", serial, NULL)) if (!rand_ser
&& !save_serial(serialfile, "new", serial, NULL))
goto end; goto end;
if (!save_index(dbfile, "new", db)) if (!save_index(dbfile, "new", db))
...@@ -1171,7 +1190,8 @@ end_of_options: ...@@ -1171,7 +1190,8 @@ end_of_options:
/* we have a CRL number that need updating */ /* we have a CRL number that need updating */
if (crlnumberfile != NULL) if (crlnumberfile != NULL)
if (!save_serial(crlnumberfile, "new", crlnumber, NULL)) if (!rand_ser
&& !save_serial(crlnumberfile, "new", crlnumber, NULL))
goto end; goto end;
BN_free(crlnumber); BN_free(crlnumber);
...@@ -1213,16 +1233,16 @@ end_of_options: ...@@ -1213,16 +1233,16 @@ end_of_options:
BIO_printf(bio_err, "Data Base Updated\n"); BIO_printf(bio_err, "Data Base Updated\n");
} }
} }
/*****************************************************************/
ret = 0; ret = 0;
end: end:
if (ret)
ERR_print_errors(bio_err);
BIO_free_all(Sout); BIO_free_all(Sout);
BIO_free_all(out); BIO_free_all(out);
BIO_free_all(in); BIO_free_all(in);
sk_X509_pop_free(cert_sk, X509_free); sk_X509_pop_free(cert_sk, X509_free);
if (ret)
ERR_print_errors(bio_err);
if (free_key) if (free_key)
OPENSSL_free(key); OPENSSL_free(key);
BN_free(serial); BN_free(serial);
......
...@@ -51,6 +51,7 @@ B<openssl> B<ca> ...@@ -51,6 +51,7 @@ B<openssl> B<ca>
[B<-subj arg>] [B<-subj arg>]
[B<-utf8>] [B<-utf8>]
[B<-create_serial>] [B<-create_serial>]
[B<-rand_serial>]
[B<-multivalue-rdn>] [B<-multivalue-rdn>]
[B<-rand file...>] [B<-rand file...>]
[B<-writerand file>] [B<-writerand file>]
...@@ -262,6 +263,13 @@ configuration file, must be valid UTF8 strings. ...@@ -262,6 +263,13 @@ configuration file, must be valid UTF8 strings.
If reading serial from the text file as specified in the configuration If reading serial from the text file as specified in the configuration
fails, specifying this option creates a new random serial to be used as next fails, specifying this option creates a new random serial to be used as next
serial number. serial number.
To get random serial numbers, use the B<-rand_serial> flag instead; this
should only be used for simple error-recovery.
=item B<-rand_serial>
Generate a large random number to use as the serial number.
This overrides any option or configuration to use a serial number file.
=item B<-multivalue-rdn> =item B<-multivalue-rdn>
...@@ -614,6 +622,7 @@ A sample configuration file with the relevant sections for B<ca>: ...@@ -614,6 +622,7 @@ A sample configuration file with the relevant sections for B<ca>:
certificate = $dir/cacert.pem # The CA cert certificate = $dir/cacert.pem # The CA cert
serial = $dir/serial # serial no file serial = $dir/serial # serial no file
#rand_serial = yes # for random serial#'s
private_key = $dir/private/cakey.pem# CA private key private_key = $dir/private/cakey.pem# CA private key
RANDFILE = $dir/private/.rand # random number file RANDFILE = $dir/private/.rand # random number file
......
...@@ -35,7 +35,7 @@ plan tests => 5; ...@@ -35,7 +35,7 @@ plan tests => 5;
if !ok(run(perlapp(["CA.pl","-newreq"])), if !ok(run(perlapp(["CA.pl","-newreq"])),
'creating certificate request'); 'creating certificate request');
$ENV{OPENSSL_CONFIG} = '-config "'.$std_openssl_cnf.'"'; $ENV{OPENSSL_CONFIG} = '-rand_serial -config "'.$std_openssl_cnf.'"';
skip "failed to sign certificate request", 2 skip "failed to sign certificate request", 2
if !is(yes(cmdstr(perlapp(["CA.pl", "-sign"]))), 0, if !is(yes(cmdstr(perlapp(["CA.pl", "-sign"]))), 0,
'signing certificate request'); 'signing certificate request');
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册