OpenSSL 1.1.1-pre2

This commit is contained in:
Hakase
2018-04-07 17:29:40 +09:00
parent 82a44d2483
commit bbac8ca55d
17755 changed files with 221242 additions and 98415 deletions
+39 -21
View File
@@ -46,8 +46,25 @@ my $NEWCERT = "newcert.pem";
my $NEWP12 = "newcert.p12";
my $RET = 0;
my $WHAT = shift @ARGV || "";
my @OPENSSL_CMDS = ("req", "ca", "pkcs12", "x509", "verify");
my %EXTRA = extra_args(\@ARGV, "-extra-");
my $FILE;
sub extra_args {
my ($args_ref, $arg_prefix) = @_;
my %eargs = map {
if ($_ < $#$args_ref) {
my ($arg, $value) = splice(@$args_ref, $_, 2);
$arg =~ s/$arg_prefix//;
($arg, $value);
} else {
();
}
} reverse grep($$args_ref[$_] =~ /$arg_prefix/, 0..$#$args_ref);
my %empty = map { ($_, "") } @OPENSSL_CMDS;
return (%empty, %eargs);
}
# See if reason for a CRL entry is valid; exit if not.
sub crl_reason_ok
{
@@ -96,22 +113,23 @@ sub run
if ( $WHAT =~ /^(-\?|-h|-help)$/ ) {
print STDERR "usage: CA -newcert|-newreq|-newreq-nodes|-newca|-sign|-signcert|-verify\n";
print STDERR " CA -pkcs12 [certname]\n";
print STDERR " CA -crl|-revoke cert-filename [reason]\n";
print STDERR "usage: CA.pl -newcert | -newreq | -newreq-nodes | -xsign | -sign | -signCA | -signcert | -crl | -newca [-extra-cmd extra-params]\n";
print STDERR " CA.pl -pkcs12 [-extra-pkcs12 extra-params] [certname]\n";
print STDERR " CA.pl -verify [-extra-verify extra-params] certfile ...\n";
print STDERR " CA.pl -revoke [-extra-ca extra-params] certfile [reason]\n";
exit 0;
}
if ($WHAT eq '-newcert' ) {
# create a certificate
$RET = run("$REQ -new -x509 -keyout $NEWKEY -out $NEWCERT $DAYS");
$RET = run("$REQ -new -x509 -keyout $NEWKEY -out $NEWCERT $DAYS $EXTRA{req}");
print "Cert is in $NEWCERT, private key is in $NEWKEY\n" if $RET == 0;
} elsif ($WHAT eq '-newreq' ) {
} elsif ($WHAT eq '-precert' ) {
# create a pre-certificate
$RET = run("$REQ -x509 -precert -keyout $NEWKEY -out $NEWCERT $DAYS");
print "Pre-cert is in $NEWCERT, private key is in $NEWKEY\n" if $RET == 0;
} elsif ($WHAT =~ /^\-newreq(\-nodes)?$/ ) {
# create a certificate request
$RET = run("$REQ -new -keyout $NEWKEY -out $NEWREQ $DAYS");
print "Request is in $NEWREQ, private key is in $NEWKEY\n" if $RET == 0;
} elsif ($WHAT eq '-newreq-nodes' ) {
# create a certificate request
$RET = run("$REQ -new -nodes -keyout $NEWKEY -out $NEWREQ $DAYS");
$RET = run("$REQ -new $1 -keyout $NEWKEY -out $NEWREQ $DAYS $EXTRA{req}");
print "Request is in $NEWREQ, private key is in $NEWKEY\n" if $RET == 0;
} elsif ($WHAT eq '-newca' ) {
# create the directory hierarchy
@@ -136,11 +154,11 @@ if ($WHAT eq '-newcert' ) {
print "Making CA certificate ...\n";
$RET = run("$REQ -new -keyout"
. " ${CATOP}/private/$CAKEY"
. " -out ${CATOP}/$CAREQ");
. " -out ${CATOP}/$CAREQ $EXTRA{req}");
$RET = run("$CA -create_serial"
. " -out ${CATOP}/$CACERT $CADAYS -batch"
. " -keyfile ${CATOP}/private/$CAKEY -selfsign"
. " -extensions v3_ca"
. " -extensions v3_ca $EXTRA{ca}"
. " -infiles ${CATOP}/$CAREQ") if $RET == 0;
print "CA certificate is in ${CATOP}/$CACERT\n" if $RET == 0;
}
@@ -150,32 +168,32 @@ if ($WHAT eq '-newcert' ) {
$RET = run("$PKCS12 -in $NEWCERT -inkey $NEWKEY"
. " -certfile ${CATOP}/$CACERT"
. " -out $NEWP12"
. " -export -name \"$cname\"");
. " -export -name \"$cname\" $EXTRA{pkcs12}");
print "PKCS #12 file is in $NEWP12\n" if $RET == 0;
} elsif ($WHAT eq '-xsign' ) {
$RET = run("$CA -policy policy_anything -infiles $NEWREQ");
$RET = run("$CA -policy policy_anything $EXTRA{ca} -infiles $NEWREQ");
} elsif ($WHAT eq '-sign' ) {
$RET = run("$CA -policy policy_anything -out $NEWCERT -infiles $NEWREQ");
$RET = run("$CA -policy policy_anything -out $NEWCERT $EXTRA{ca} -infiles $NEWREQ");
print "Signed certificate is in $NEWCERT\n" if $RET == 0;
} elsif ($WHAT eq '-signCA' ) {
$RET = run("$CA -policy policy_anything -out $NEWCERT"
. " -extensions v3_ca -infiles $NEWREQ");
. " -extensions v3_ca $EXTRA{ca} -infiles $NEWREQ");
print "Signed CA certificate is in $NEWCERT\n" if $RET == 0;
} elsif ($WHAT eq '-signcert' ) {
$RET = run("$X509 -x509toreq -in $NEWREQ -signkey $NEWREQ"
. " -out tmp.pem");
. " -out tmp.pem $EXTRA{x509}");
$RET = run("$CA -policy policy_anything -out $NEWCERT"
. " -infiles tmp.pem") if $RET == 0;
. "$EXTRA{ca} -infiles tmp.pem") if $RET == 0;
print "Signed certificate is in $NEWCERT\n" if $RET == 0;
} elsif ($WHAT eq '-verify' ) {
my @files = @ARGV ? @ARGV : ( $NEWCERT );
my $file;
foreach $file (@files) {
my $status = run("$VERIFY \"-CAfile\" ${CATOP}/$CACERT $file");
my $status = run("$VERIFY \"-CAfile\" ${CATOP}/$CACERT $file $EXTRA{verify}");
$RET = $status if $status != 0;
}
} elsif ($WHAT eq '-crl' ) {
$RET = run("$CA -gencrl -out ${CATOP}/crl/$CACRL");
$RET = run("$CA -gencrl -out ${CATOP}/crl/$CACRL $EXTRA{ca}");
print "Generated CRL is in ${CATOP}/crl/$CACRL\n" if $RET == 0;
} elsif ($WHAT eq '-revoke' ) {
my $cname = $ARGV[0];
@@ -186,7 +204,7 @@ if ($WHAT eq '-newcert' ) {
my $reason = $ARGV[1];
$reason = " -crl_reason $reason"
if defined $reason && crl_reason_ok($reason);
$RET = run("$CA -revoke \"$cname\"" . $reason);
$RET = run("$CA -revoke \"$cname\"" . $reason . $EXTRA{ca});
} else {
print STDERR "Unknown arg \"$WHAT\"\n";
print STDERR "Use -help for help.\n";
+58 -79
View File
@@ -1,5 +1,5 @@
/*
* 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
@@ -9,107 +9,86 @@
#include "apps.h"
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#include <openssl/conf.h>
static int seeded = 0;
static int egdsocket = 0;
static char *save_rand_file;
int app_RAND_load_file(const char *file, int dont_warn)
void app_RAND_load_conf(CONF *c, const char *section)
{
int consider_randfile = (file == NULL);
char buffer[200];
const char *randfile = NCONF_get_string(c, section, "RANDFILE");
if (file == NULL)
file = RAND_file_name(buffer, sizeof(buffer));
#ifndef OPENSSL_NO_EGD
else if (RAND_egd(file) > 0) {
/*
* we try if the given filename is an EGD socket. if it is, we don't
* write anything back to the file.
*/
egdsocket = 1;
return 1;
if (randfile == NULL) {
ERR_clear_error();
return;
}
#endif
if (file == NULL || !RAND_load_file(file, -1)) {
if (RAND_status() == 0) {
if (!dont_warn) {
BIO_printf(bio_err, "unable to load 'random state'\n");
BIO_printf(bio_err,
"This means that the random number generator has not been seeded\n");
BIO_printf(bio_err, "with much random data.\n");
if (consider_randfile) { /* explanation does not apply when a
* file is explicitly named */
BIO_printf(bio_err,
"Consider setting the RANDFILE environment variable to point at a file that\n");
BIO_printf(bio_err,
"'random' data can be kept in (the file will be overwritten).\n");
}
}
return 0;
}
if (RAND_load_file(randfile, -1) < 0) {
BIO_printf(bio_err, "Can't load %s into RNG\n", randfile);
ERR_print_errors(bio_err);
return;
}
seeded = 1;
return 1;
if (save_rand_file == NULL)
save_rand_file = OPENSSL_strdup(randfile);
}
long app_RAND_load_files(char *name)
static int loadfiles(char *name)
{
char *p, *n;
int last;
long tot = 0;
#ifndef OPENSSL_NO_EGD
int egd;
#endif
char *p;
int last, ret = 1;
for (;;) {
for ( ; ; ) {
last = 0;
for (p = name; ((*p != '\0') && (*p != LIST_SEPARATOR_CHAR)); p++) ;
for (p = name; *p != '\0' && *p != LIST_SEPARATOR_CHAR; p++)
continue;
if (*p == '\0')
last = 1;
*p = '\0';
n = name;
name = p + 1;
if (*n == '\0')
break;
#ifndef OPENSSL_NO_EGD
egd = RAND_egd(n);
if (egd > 0)
tot += egd;
else
#endif
tot += RAND_load_file(n, -1);
if (RAND_load_file(name, -1) < 0) {
BIO_printf(bio_err, "Can't load %s into RNG\n", name);
ERR_print_errors(bio_err);
ret = 0;
}
if (last)
break;
name = p + 1;
if (*name == '\0')
break;
}
if (tot > 512)
app_RAND_allow_write_file();
return (tot);
return ret;
}
int app_RAND_write_file(const char *file)
void app_RAND_write(void)
{
char buffer[200];
if (save_rand_file == NULL)
return;
if (RAND_write_file(save_rand_file) == -1) {
BIO_printf(bio_err, "Cannot write random bytes:\n");
ERR_print_errors(bio_err);
}
OPENSSL_free(save_rand_file);
save_rand_file = NULL;
}
if (egdsocket || !seeded)
/*
* If we did not manage to read the seed file, we should not write a
* low-entropy seed file back -- it would suppress a crucial warning
* the next time we want to use it.
*/
return 0;
if (file == NULL)
file = RAND_file_name(buffer, sizeof(buffer));
if (file == NULL || !RAND_write_file(file)) {
BIO_printf(bio_err, "unable to write 'random state'\n");
return 0;
/*
* See comments in opt_verify for explanation of this.
*/
enum r_range { OPT_R_ENUM };
int opt_rand(int opt)
{
switch ((enum r_range)opt) {
case OPT_R__FIRST:
case OPT_R__LAST:
break;
case OPT_R_RAND:
return loadfiles(opt_arg());
break;
case OPT_R_WRITERAND:
OPENSSL_free(save_rand_file);
save_rand_file = OPENSSL_strdup(opt_arg());
break;
}
return 1;
}
void app_RAND_allow_write_file(void)
{
seeded = 1;
}
+202 -136
View File
@@ -1,5 +1,5 @@
/*
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2018 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
@@ -54,9 +54,8 @@ typedef struct {
unsigned long mask;
} NAME_EX_TBL;
#if !defined(OPENSSL_NO_UI) || !defined(OPENSSL_NO_ENGINE)
static UI_METHOD *ui_method = NULL;
#endif
static const UI_METHOD *ui_fallback_method = NULL;
static int set_table_opts(unsigned long *flags, const char *arg,
const NAME_EX_TBL * in_tbl);
@@ -110,13 +109,13 @@ int chopup_args(ARGS *arg, char *buf)
}
}
arg->argv[arg->argc] = NULL;
return (1);
return 1;
}
#ifndef APP_INIT
int app_init(long mesgwin)
{
return (1);
return 1;
}
#endif
@@ -138,41 +137,55 @@ int ctx_set_verify_locations(SSL_CTX *ctx, const char *CAfile,
int ctx_set_ctlog_list_file(SSL_CTX *ctx, const char *path)
{
if (path == NULL) {
if (path == NULL)
return SSL_CTX_set_default_ctlog_list_file(ctx);
}
return SSL_CTX_set_ctlog_list_file(ctx, path);
}
#endif
static unsigned long nmflag = 0;
static char nmflag_set = 0;
int set_nameopt(const char *arg)
{
int ret = set_name_ex(&nmflag, arg);
if (ret)
nmflag_set = 1;
return ret;
}
unsigned long get_nameopt(void)
{
return (nmflag_set) ? nmflag : XN_FLAG_ONELINE;
}
int dump_cert_text(BIO *out, X509 *x)
{
char *p;
p = X509_NAME_oneline(X509_get_subject_name(x), NULL, 0);
BIO_puts(out, "subject=");
BIO_puts(out, p);
OPENSSL_free(p);
p = X509_NAME_oneline(X509_get_issuer_name(x), NULL, 0);
BIO_puts(out, "\nissuer=");
BIO_puts(out, p);
print_name(out, "subject=", X509_get_subject_name(x), get_nameopt());
BIO_puts(out, "\n");
print_name(out, "issuer=", X509_get_issuer_name(x), get_nameopt());
BIO_puts(out, "\n");
OPENSSL_free(p);
return 0;
}
#ifndef OPENSSL_NO_UI
static int ui_open(UI *ui)
{
return UI_method_get_opener(UI_OpenSSL())(ui);
int (*opener)(UI *ui) = UI_method_get_opener(ui_fallback_method);
if (opener)
return opener(ui);
return 1;
}
static int ui_read(UI *ui, UI_STRING *uis)
{
int (*reader)(UI *ui, UI_STRING *uis) = NULL;
if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD
&& UI_get0_user_data(ui)) {
switch (UI_get_string_type(uis)) {
@@ -186,15 +199,25 @@ static int ui_read(UI *ui, UI_STRING *uis)
return 1;
}
}
default:
break;
case UIT_NONE:
case UIT_BOOLEAN:
case UIT_INFO:
case UIT_ERROR:
break;
}
}
return UI_method_get_reader(UI_OpenSSL())(ui, uis);
reader = UI_method_get_reader(ui_fallback_method);
if (reader)
return reader(ui, uis);
return 1;
}
static int ui_write(UI *ui, UI_STRING *uis)
{
int (*writer)(UI *ui, UI_STRING *uis) = NULL;
if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD
&& UI_get0_user_data(ui)) {
switch (UI_get_string_type(uis)) {
@@ -206,20 +229,36 @@ static int ui_write(UI *ui, UI_STRING *uis)
if (password && password[0] != '\0')
return 1;
}
default:
break;
case UIT_NONE:
case UIT_BOOLEAN:
case UIT_INFO:
case UIT_ERROR:
break;
}
}
return UI_method_get_writer(UI_OpenSSL())(ui, uis);
writer = UI_method_get_writer(ui_fallback_method);
if (writer)
return writer(ui, uis);
return 1;
}
static int ui_close(UI *ui)
{
return UI_method_get_closer(UI_OpenSSL())(ui);
int (*closer)(UI *ui) = UI_method_get_closer(ui_fallback_method);
if (closer)
return closer(ui);
return 1;
}
int setup_ui_method(void)
{
ui_fallback_method = UI_null();
#ifndef OPENSSL_NO_UI_CONSOLE
ui_fallback_method = UI_OpenSSL();
#endif
ui_method = UI_create_method("OpenSSL application user interface");
UI_method_set_opener(ui_method, ui_open);
UI_method_set_reader(ui_method, ui_read);
@@ -235,24 +274,18 @@ void destroy_ui_method(void)
ui_method = NULL;
}
}
#endif
const UI_METHOD *get_ui_method(void)
{
return ui_method;
}
int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_tmp)
{
int res = 0;
#ifndef OPENSSL_NO_UI
UI *ui = NULL;
#endif
PW_CB_DATA *cb_data = (PW_CB_DATA *)cb_tmp;
#ifdef OPENSSL_NO_UI
if (cb_data != NULL && cb_data->password != NULL) {
res = strlen(cb_data->password);
if (res > bufsiz)
res = bufsiz;
memcpy(buf, cb_data->password, res);
}
#else
ui = UI_new_method(ui_method);
if (ui) {
int ok = 0;
@@ -276,9 +309,9 @@ int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_tmp)
/* We know that there is no previous user data to return to us */
(void)UI_add_user_data(ui, cb_data);
if (ok >= 0)
ok = UI_add_input_string(ui, prompt, ui_flags, buf,
PW_MIN_LENGTH, bufsiz - 1);
ok = UI_add_input_string(ui, prompt, ui_flags, buf,
PW_MIN_LENGTH, bufsiz - 1);
if (ok >= 0 && verify) {
buff = app_malloc(bufsiz, "password buffer");
ok = UI_add_verify_string(ui, prompt, ui_flags, buff,
@@ -287,8 +320,7 @@ int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_tmp)
if (ok >= 0)
do {
ok = UI_process(ui);
}
while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0));
} while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0));
OPENSSL_clear_free(buff, (unsigned int)bufsiz);
@@ -308,7 +340,6 @@ int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_tmp)
UI_free(ui);
OPENSSL_free(prompt);
}
#endif
return res;
}
@@ -317,22 +348,24 @@ static char *app_get_pass(const char *arg, int keepbio);
int app_passwd(const char *arg1, const char *arg2, char **pass1, char **pass2)
{
int same;
if (!arg2 || !arg1 || strcmp(arg1, arg2))
if (arg2 == NULL || arg1 == NULL || strcmp(arg1, arg2))
same = 0;
else
same = 1;
if (arg1) {
if (arg1 != NULL) {
*pass1 = app_get_pass(arg1, same);
if (!*pass1)
if (*pass1 == NULL)
return 0;
} else if (pass1)
} else if (pass1 != NULL) {
*pass1 = NULL;
if (arg2) {
}
if (arg2 != NULL) {
*pass2 = app_get_pass(arg2, same ? 2 : 0);
if (!*pass2)
if (*pass2 == NULL)
return 0;
} else if (pass2)
} else if (pass2 != NULL) {
*pass2 = NULL;
}
return 1;
}
@@ -346,16 +379,16 @@ static char *app_get_pass(const char *arg, int keepbio)
return OPENSSL_strdup(arg + 5);
if (strncmp(arg, "env:", 4) == 0) {
tmp = getenv(arg + 4);
if (!tmp) {
if (tmp == NULL) {
BIO_printf(bio_err, "Can't read environment variable %s\n", arg + 4);
return NULL;
}
return OPENSSL_strdup(tmp);
}
if (!keepbio || !pwdbio) {
if (!keepbio || pwdbio == NULL) {
if (strncmp(arg, "file:", 5) == 0) {
pwdbio = BIO_new_file(arg + 5, "r");
if (!pwdbio) {
if (pwdbio == NULL) {
BIO_printf(bio_err, "Can't open file %s\n", arg + 5);
return NULL;
}
@@ -404,12 +437,12 @@ static char *app_get_pass(const char *arg, int keepbio)
return NULL;
}
tmp = strchr(tpass, '\n');
if (tmp)
if (tmp != NULL)
*tmp = 0;
return OPENSSL_strdup(tpass);
}
static CONF *app_load_config_(BIO *in, const char *filename)
CONF *app_load_config_bio(BIO *in, const char *filename)
{
long errorline = -1;
CONF *conf;
@@ -420,15 +453,21 @@ static CONF *app_load_config_(BIO *in, const char *filename)
if (i > 0)
return conf;
if (errorline <= 0)
BIO_printf(bio_err, "%s: Can't load config file \"%s\"\n",
opt_getprog(), filename);
if (errorline <= 0) {
BIO_printf(bio_err, "%s: Can't load ", opt_getprog());
} else {
BIO_printf(bio_err, "%s: Error on line %ld of ", opt_getprog(),
errorline);
}
if (filename != NULL)
BIO_printf(bio_err, "config file \"%s\"\n", filename);
else
BIO_printf(bio_err, "%s: Error on line %ld of config file \"%s\"\n",
opt_getprog(), errorline, filename);
BIO_printf(bio_err, "config input");
NCONF_free(conf);
return NULL;
}
CONF *app_load_config(const char *filename)
{
BIO *in;
@@ -438,10 +477,11 @@ CONF *app_load_config(const char *filename)
if (in == NULL)
return NULL;
conf = app_load_config_(in, filename);
conf = app_load_config_bio(in, filename);
BIO_free(in);
return conf;
}
CONF *app_load_config_quiet(const char *filename)
{
BIO *in;
@@ -451,7 +491,7 @@ CONF *app_load_config_quiet(const char *filename)
if (in == NULL)
return NULL;
conf = app_load_config_(in, filename);
conf = app_load_config_bio(in, filename);
BIO_free(in);
return conf;
}
@@ -515,9 +555,9 @@ static int load_pkcs12(BIO *in, const char *desc,
goto die;
}
/* See if an empty password will do */
if (PKCS12_verify_mac(p12, "", 0) || PKCS12_verify_mac(p12, NULL, 0))
if (PKCS12_verify_mac(p12, "", 0) || PKCS12_verify_mac(p12, NULL, 0)) {
pass = "";
else {
} else {
if (!pem_cb)
pem_cb = (pem_password_cb *)password_callback;
len = pem_cb(tpass, PEM_BUFSIZE, 0, cb_data);
@@ -578,8 +618,7 @@ static int load_cert_crl_http(const char *url, X509 **pcert, X509_CRL **pcrl)
OPENSSL_free(host);
OPENSSL_free(path);
OPENSSL_free(port);
if (bio)
BIO_free_all(bio);
BIO_free_all(bio);
OCSP_REQ_CTX_free(rctx);
if (rv != 1) {
BIO_printf(bio_err, "Error loading %s from %s\n",
@@ -605,17 +644,18 @@ X509 *load_cert(const char *file, int format, const char *cert_descrip)
if (file == NULL) {
unbuffer(stdin);
cert = dup_bio_in(format);
} else
} else {
cert = bio_open_default(file, 'r', format);
}
if (cert == NULL)
goto end;
if (format == FORMAT_ASN1)
if (format == FORMAT_ASN1) {
x = d2i_X509_bio(cert, NULL);
else if (format == FORMAT_PEM)
} else if (format == FORMAT_PEM) {
x = PEM_read_bio_X509_AUX(cert, NULL,
(pem_password_cb *)password_callback, NULL);
else if (format == FORMAT_PKCS12) {
} else if (format == FORMAT_PKCS12) {
if (!load_pkcs12(cert, cert_descrip, NULL, NULL, NULL, &x, NULL))
goto end;
} else {
@@ -628,7 +668,7 @@ X509 *load_cert(const char *file, int format, const char *cert_descrip)
ERR_print_errors(bio_err);
}
BIO_free(cert);
return (x);
return x;
}
X509_CRL *load_crl(const char *infile, int format)
@@ -646,11 +686,11 @@ X509_CRL *load_crl(const char *infile, int format)
in = bio_open_default(infile, 'r', format);
if (in == NULL)
goto end;
if (format == FORMAT_ASN1)
if (format == FORMAT_ASN1) {
x = d2i_X509_CRL_bio(in, NULL);
else if (format == FORMAT_PEM)
} else if (format == FORMAT_PEM) {
x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
else {
} else {
BIO_printf(bio_err, "bad input format specified for input crl\n");
goto end;
}
@@ -662,7 +702,7 @@ X509_CRL *load_crl(const char *infile, int format)
end:
BIO_free(in);
return (x);
return x;
}
EVP_PKEY *load_key(const char *file, int format, int maybe_stdin,
@@ -680,9 +720,9 @@ EVP_PKEY *load_key(const char *file, int format, int maybe_stdin,
goto end;
}
if (format == FORMAT_ENGINE) {
if (e == NULL)
if (e == NULL) {
BIO_printf(bio_err, "no engine specified\n");
else {
} else {
#ifndef OPENSSL_NO_ENGINE
if (ENGINE_init(e)) {
pkey = ENGINE_load_private_key(e, file, ui_method, &cb_data);
@@ -701,8 +741,9 @@ EVP_PKEY *load_key(const char *file, int format, int maybe_stdin,
if (file == NULL && maybe_stdin) {
unbuffer(stdin);
key = dup_bio_in(format);
} else
} else {
key = bio_open_default(file, 'r', format);
}
if (key == NULL)
goto end;
if (format == FORMAT_ASN1) {
@@ -711,21 +752,19 @@ EVP_PKEY *load_key(const char *file, int format, int maybe_stdin,
pkey = PEM_read_bio_PrivateKey(key, NULL,
(pem_password_cb *)password_callback,
&cb_data);
}
else if (format == FORMAT_PKCS12) {
} else if (format == FORMAT_PKCS12) {
if (!load_pkcs12(key, key_descrip,
(pem_password_cb *)password_callback, &cb_data,
&pkey, NULL, NULL))
goto end;
}
#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) && !defined (OPENSSL_NO_RC4)
else if (format == FORMAT_MSBLOB)
} else if (format == FORMAT_MSBLOB) {
pkey = b2i_PrivateKey_bio(key);
else if (format == FORMAT_PVK)
} else if (format == FORMAT_PVK) {
pkey = b2i_PVK_bio(key, (pem_password_cb *)password_callback,
&cb_data);
#endif
else {
} else {
BIO_printf(bio_err, "bad input format specified for key file\n");
goto end;
}
@@ -735,7 +774,7 @@ EVP_PKEY *load_key(const char *file, int format, int maybe_stdin,
BIO_printf(bio_err, "unable to load %s\n", key_descrip);
ERR_print_errors(bio_err);
}
return (pkey);
return pkey;
}
EVP_PKEY *load_pubkey(const char *file, int format, int maybe_stdin,
@@ -753,9 +792,9 @@ EVP_PKEY *load_pubkey(const char *file, int format, int maybe_stdin,
goto end;
}
if (format == FORMAT_ENGINE) {
if (e == NULL)
if (e == NULL) {
BIO_printf(bio_err, "no engine specified\n");
else {
} else {
#ifndef OPENSSL_NO_ENGINE
pkey = ENGINE_load_public_key(e, file, ui_method, &cb_data);
if (pkey == NULL) {
@@ -771,14 +810,14 @@ EVP_PKEY *load_pubkey(const char *file, int format, int maybe_stdin,
if (file == NULL && maybe_stdin) {
unbuffer(stdin);
key = dup_bio_in(format);
} else
} else {
key = bio_open_default(file, 'r', format);
}
if (key == NULL)
goto end;
if (format == FORMAT_ASN1) {
pkey = d2i_PUBKEY_bio(key, NULL);
}
else if (format == FORMAT_ASN1RSA) {
} else if (format == FORMAT_ASN1RSA) {
#ifndef OPENSSL_NO_RSA
RSA *rsa;
rsa = d2i_RSAPublicKey_bio(key, NULL);
@@ -808,21 +847,20 @@ EVP_PKEY *load_pubkey(const char *file, int format, int maybe_stdin,
BIO_printf(bio_err, "RSA keys not supported\n");
#endif
pkey = NULL;
}
else if (format == FORMAT_PEM) {
} else if (format == FORMAT_PEM) {
pkey = PEM_read_bio_PUBKEY(key, NULL,
(pem_password_cb *)password_callback,
&cb_data);
}
#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA)
else if (format == FORMAT_MSBLOB)
} else if (format == FORMAT_MSBLOB) {
pkey = b2i_PublicKey_bio(key);
#endif
}
end:
BIO_free(key);
if (pkey == NULL)
BIO_printf(bio_err, "unable to load %s\n", key_descrip);
return (pkey);
return pkey;
}
static int load_certs_crls(const char *file, int format,
@@ -855,36 +893,36 @@ static int load_certs_crls(const char *file, int format,
BIO_free(bio);
if (pcerts && *pcerts == NULL) {
if (pcerts != NULL && *pcerts == NULL) {
*pcerts = sk_X509_new_null();
if (!*pcerts)
if (*pcerts == NULL)
goto end;
}
if (pcrls && *pcrls == NULL) {
if (pcrls != NULL && *pcrls == NULL) {
*pcrls = sk_X509_CRL_new_null();
if (!*pcrls)
if (*pcrls == NULL)
goto end;
}
for (i = 0; i < sk_X509_INFO_num(xis); i++) {
xi = sk_X509_INFO_value(xis, i);
if (xi->x509 && pcerts) {
if (xi->x509 != NULL && pcerts != NULL) {
if (!sk_X509_push(*pcerts, xi->x509))
goto end;
xi->x509 = NULL;
}
if (xi->crl && pcrls) {
if (xi->crl != NULL && pcrls != NULL) {
if (!sk_X509_CRL_push(*pcrls, xi->crl))
goto end;
xi->crl = NULL;
}
}
if (pcerts && sk_X509_num(*pcerts) > 0)
if (pcerts != NULL && sk_X509_num(*pcerts) > 0)
rv = 1;
if (pcrls && sk_X509_CRL_num(*pcrls) > 0)
if (pcrls != NULL && sk_X509_CRL_num(*pcrls) > 0)
rv = 1;
end:
@@ -892,11 +930,11 @@ static int load_certs_crls(const char *file, int format,
sk_X509_INFO_pop_free(xis, X509_INFO_free);
if (rv == 0) {
if (pcerts) {
if (pcerts != NULL) {
sk_X509_pop_free(*pcerts, X509_free);
*pcerts = NULL;
}
if (pcrls) {
if (pcrls != NULL) {
sk_X509_CRL_pop_free(*pcrls, X509_CRL_free);
*pcrls = NULL;
}
@@ -1101,8 +1139,9 @@ static int set_table_opts(unsigned long *flags, const char *arg,
} else if (c == '+') {
c = 1;
arg++;
} else
} else {
c = 1;
}
for (ptbl = in_tbl; ptbl->name; ptbl++) {
if (strcasecmp(arg, ptbl->name) == 0) {
@@ -1147,9 +1186,9 @@ void print_bignum_var(BIO *out, const BIGNUM *in, const char *var,
int len, unsigned char *buffer)
{
BIO_printf(out, " static unsigned char %s_%d[] = {", var, len);
if (BN_is_zero(in))
if (BN_is_zero(in)) {
BIO_printf(out, "\n\t0x00");
else {
} else {
int i, l;
l = BN_bn2bin(in, buffer);
@@ -1164,6 +1203,7 @@ void print_bignum_var(BIO *out, const BIGNUM *in, const char *var,
}
BIO_printf(out, "\n };\n");
}
void print_array(BIO *out, const char* title, int len, const unsigned char* d)
{
int i;
@@ -1197,8 +1237,9 @@ X509_STORE *setup_verify(const char *CAfile, const char *CApath, int noCAfile, i
BIO_printf(bio_err, "Error loading file %s\n", CAfile);
goto end;
}
} else
} else {
X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT);
}
}
if (CApath != NULL || !noCApath) {
@@ -1210,8 +1251,9 @@ X509_STORE *setup_verify(const char *CAfile, const char *CApath, int noCAfile, i
BIO_printf(bio_err, "Error loading directory %s\n", CApath);
goto end;
}
} else
} else {
X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
}
}
ERR_clear_error();
@@ -1242,7 +1284,7 @@ ENGINE *setup_engine(const char *engine, int debug)
ENGINE *e = NULL;
#ifndef OPENSSL_NO_ENGINE
if (engine) {
if (engine != NULL) {
if (strcmp(engine, "auto") == 0) {
BIO_printf(bio_err, "enabling auto ENGINE support\n");
ENGINE_register_all_complete();
@@ -1297,7 +1339,7 @@ static int index_serial_cmp(const OPENSSL_CSTRING *a,
for (aa = a[DB_serial]; *aa == '0'; aa++) ;
for (bb = b[DB_serial]; *bb == '0'; bb++) ;
return (strcmp(aa, bb));
return strcmp(aa, bb);
}
static int index_name_qual(char **a)
@@ -1312,7 +1354,7 @@ static unsigned long index_name_hash(const OPENSSL_CSTRING *a)
int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b)
{
return (strcmp(a[DB_name], b[DB_name]));
return strcmp(a[DB_name], b[DB_name]);
}
static IMPLEMENT_LHASH_HASH_FN(index_serial, OPENSSL_CSTRING)
@@ -1363,7 +1405,7 @@ BIGNUM *load_serial(const char *serialfile, int create, ASN1_INTEGER **retai)
err:
BIO_free(in);
ASN1_INTEGER_free(ai);
return (ret);
return ret;
}
int save_serial(const char *serialfile, const char *suffix, const BIGNUM *serial,
@@ -1413,7 +1455,7 @@ int save_serial(const char *serialfile, const char *suffix, const BIGNUM *serial
err:
BIO_free_all(out);
ASN1_INTEGER_free(ai);
return (ret);
return ret;
}
int rotate_serial(const char *serialfile, const char *new_suffix,
@@ -1464,15 +1506,11 @@ int rand_serial(BIGNUM *b, ASN1_INTEGER *ai)
BIGNUM *btmp;
int ret = 0;
if (b)
btmp = b;
else
btmp = BN_new();
btmp = b == NULL ? BN_new() : b;
if (btmp == NULL)
return 0;
if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0))
if (!BN_rand(btmp, SERIAL_RAND_BITS, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY))
goto error;
if (ai && !BN_to_ASN1_INTEGER(btmp, ai))
goto error;
@@ -1848,8 +1886,9 @@ static void nodes_print(const char *name, STACK_OF(X509_POLICY_NODE) *nodes)
node = sk_X509_POLICY_NODE_value(nodes, i);
X509_POLICY_NODE_print(bio_err, node, 2);
}
} else
} else {
BIO_puts(bio_err, " <empty>\n");
}
}
void policies_print(X509_STORE_CTX *ctx)
@@ -1892,10 +1931,11 @@ unsigned char *next_protos_parse(size_t *outlen, const char *in)
OPENSSL_free(out);
return NULL;
}
out[start] = i - start;
out[start] = (unsigned char)(i - start);
start = i + 1;
} else
} else {
out[i + 1] = in[i];
}
}
*outlen = len + 1;
@@ -2118,7 +2158,7 @@ double app_tminterval(int stop, int usertime)
ret = (__int64)(tmstop.QuadPart - tmstart.QuadPart) * 1e-7;
}
return (ret);
return ret;
}
#elif defined(OPENSSL_SYSTEM_VXWORKS)
# include <time.h>
@@ -2154,7 +2194,7 @@ double app_tminterval(int stop, int usertime)
else
ret = (now - tmstart) / (double)sysClkRateGet();
# endif
return (ret);
return ret;
}
#elif defined(OPENSSL_SYSTEM_VMS)
@@ -2188,7 +2228,7 @@ double app_tminterval(int stop, int usertime)
else
ret = (now - tmstart) / (double)(CLK_TCK);
return (ret);
return ret;
}
#elif defined(_SC_CLK_TCK) /* by means of unistd.h */
@@ -2204,14 +2244,14 @@ double app_tminterval(int stop, int usertime)
if (usertime)
now = rus.tms_utime;
if (stop == TM_START)
if (stop == TM_START) {
tmstart = now;
else {
} else {
long int tck = sysconf(_SC_CLK_TCK);
ret = (now - tmstart) / (double)tck;
}
return (ret);
return ret;
}
#else
@@ -2336,12 +2376,12 @@ int raw_read_stdin(void *buf, int siz)
{
DWORD n;
if (ReadFile(GetStdHandle(STD_INPUT_HANDLE), buf, siz, &n, NULL))
return (n);
return n;
else
return (-1);
return -1;
}
#elif defined(__VMS)
#include <sys/socket.h>
# include <sys/socket.h>
int raw_read_stdin(void *buf, int siz)
{
@@ -2359,9 +2399,9 @@ int raw_write_stdout(const void *buf, int siz)
{
DWORD n;
if (WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buf, siz, &n, NULL))
return (n);
return n;
else
return (-1);
return -1;
}
#else
int raw_write_stdout(const void *buf, int siz)
@@ -2388,14 +2428,26 @@ BIO *dup_bio_in(int format)
BIO_NOCLOSE | (istext(format) ? BIO_FP_TEXT : 0));
}
static BIO_METHOD *prefix_method = NULL;
BIO *dup_bio_out(int format)
{
BIO *b = BIO_new_fp(stdout,
BIO_NOCLOSE | (istext(format) ? BIO_FP_TEXT : 0));
void *prefix = NULL;
#ifdef OPENSSL_SYS_VMS
if (istext(format))
b = BIO_push(BIO_new(BIO_f_linebuffer()), b);
#endif
if (istext(format) && (prefix = getenv("HARNESS_OSSL_PREFIX")) != NULL) {
if (prefix_method == NULL)
prefix_method = apps_bf_prefix();
b = BIO_push(BIO_new(prefix_method), b);
BIO_ctrl(b, PREFIX_CTRL_SET_PREFIX, 0, prefix);
}
return b;
}
@@ -2410,6 +2462,12 @@ BIO *dup_bio_err(int format)
return b;
}
void destroy_prefix_method()
{
BIO_meth_free(prefix_method);
prefix_method = NULL;
}
void unbuffer(FILE *fp)
{
/*
@@ -2636,15 +2694,23 @@ int set_cert_times(X509 *x, const char *startdate, const char *enddate,
if (X509_gmtime_adj(X509_getm_notBefore(x), 0) == NULL)
return 0;
} else {
if (!ASN1_TIME_set_string(X509_getm_notBefore(x), startdate))
if (!ASN1_TIME_set_string_X509(X509_getm_notBefore(x), startdate))
return 0;
}
if (enddate == NULL) {
if (X509_time_adj_ex(X509_getm_notAfter(x), days, 0, NULL)
== NULL)
return 0;
} else if (!ASN1_TIME_set_string(X509_getm_notAfter(x), enddate)) {
} else if (!ASN1_TIME_set_string_X509(X509_getm_notAfter(x), enddate)) {
return 0;
}
return 1;
}
void make_uppercase(char *string)
{
int i;
for (i = 0; string[i] != '\0'; i++)
string[i] = toupper((unsigned char)string[i]);
}
+85 -41
View File
@@ -10,17 +10,14 @@
#ifndef HEADER_APPS_H
# define HEADER_APPS_H
# include "e_os.h"
# if defined(__unix) || defined(__unix__)
# include <sys/time.h> /* struct timeval for DTLS */
# endif
# include "e_os.h" /* struct timeval for DTLS */
# include "internal/nelem.h"
# include <assert.h>
# include <openssl/e_os2.h>
# include <openssl/ossl_typ.h>
# include <openssl/bio.h>
# include <openssl/x509.h>
# include <openssl/lhash.h>
# include <openssl/conf.h>
# include <openssl/txt_db.h>
# include <openssl/engine.h>
@@ -40,27 +37,38 @@
*/
#define _UC(c) ((unsigned char)(c))
int app_RAND_load_file(const char *file, int dont_warn);
int app_RAND_write_file(const char *file);
/*
* When `file' is NULL, use defaults. `bio_e' is for error messages.
*/
void app_RAND_allow_write_file(void);
long app_RAND_load_files(char *file); /* `file' is a list of files to read,
* separated by LIST_SEPARATOR_CHAR
* (see e_os.h). The string is
* destroyed! */
void app_RAND_load_conf(CONF *c, const char *section);
void app_RAND_write(void);
extern char *default_config_file;
extern BIO *bio_in;
extern BIO *bio_out;
extern BIO *bio_err;
extern const unsigned char tls13_aes128gcmsha256_id[];
extern const unsigned char tls13_aes256gcmsha384_id[];
extern BIO_ADDR *ourpeer;
BIO_METHOD *apps_bf_prefix(void);
/*
* The control used to set the prefix with BIO_ctrl()
* We make it high enough so the chance of ever clashing with the BIO library
* remains unlikely for the foreseeable future and beyond.
*/
#define PREFIX_CTRL_SET_PREFIX (1 << 15)
/*
* apps_bf_prefix() returns a dynamically created BIO_METHOD, which we
* need to destroy at some point. When created internally, it's stored
* in an internal pointer which can be freed with the following function
*/
void destroy_prefix_method(void);
BIO *dup_bio_in(int format);
BIO *dup_bio_out(int format);
BIO *dup_bio_err(int format);
BIO *bio_open_owner(const char *filename, int format, int private);
BIO *bio_open_default(const char *filename, char mode, int format);
BIO *bio_open_default_quiet(const char *filename, char mode, int format);
CONF *app_load_config_bio(BIO *in, const char *filename);
CONF *app_load_config(const char *filename);
CONF *app_load_config_quiet(const char *filename);
int app_load_modules(const CONF *config);
@@ -175,7 +183,7 @@ int set_cert_times(X509 *x, const char *startdate, const char *enddate,
case OPT_V_ALLOW_PROXY_CERTS
/*
* Common "extended"? options.
* Common "extended validation" options.
*/
# define OPT_X_ENUM \
OPT_X__FIRST=1000, \
@@ -210,18 +218,21 @@ int set_cert_times(X509 *x, const char *startdate, const char *enddate,
# define OPT_S_ENUM \
OPT_S__FIRST=3000, \
OPT_S_NOSSL3, OPT_S_NOTLS1, OPT_S_NOTLS1_1, OPT_S_NOTLS1_2, \
OPT_S_BUGS, OPT_S_NO_COMP, OPT_S_NOTICKET, \
OPT_S_NOTLS1_3, OPT_S_BUGS, OPT_S_NO_COMP, OPT_S_NOTICKET, \
OPT_S_SERVERPREF, OPT_S_LEGACYRENEG, OPT_S_LEGACYCONN, \
OPT_S_ONRESUMP, OPT_S_NOLEGACYCONN, OPT_S_STRICT, OPT_S_SIGALGS, \
OPT_S_CLIENTSIGALGS, OPT_S_CURVES, OPT_S_NAMEDCURVE, OPT_S_CIPHER, \
OPT_S_DEBUGBROKE, OPT_S_COMP, OPT_S_MINPROTO, OPT_S_MAXPROTO, \
OPT_S_NO_RENEGOTIATION, OPT_S__LAST
OPT_S_ONRESUMP, OPT_S_NOLEGACYCONN, OPT_S_ALLOW_NO_DHE_KEX, \
OPT_S_PRIORITIZE_CHACHA, \
OPT_S_STRICT, OPT_S_SIGALGS, OPT_S_CLIENTSIGALGS, OPT_S_GROUPS, \
OPT_S_CURVES, OPT_S_NAMEDCURVE, OPT_S_CIPHER, \
OPT_S_RECORD_PADDING, OPT_S_DEBUGBROKE, OPT_S_COMP, \
OPT_S_NO_RENEGOTIATION, OPT_S_NO_MIDDLEBOX, OPT_S__LAST
# define OPT_S_OPTIONS \
{"no_ssl3", OPT_S_NOSSL3, '-',"Just disable SSLv3" }, \
{"no_tls1", OPT_S_NOTLS1, '-', "Just disable TLSv1"}, \
{"no_tls1_1", OPT_S_NOTLS1_1, '-', "Just disable TLSv1.1" }, \
{"no_tls1_2", OPT_S_NOTLS1_2, '-', "Just disable TLSv1.2"}, \
{"no_tls1_3", OPT_S_NOTLS1_3, '-', "Just disable TLSv1.3"}, \
{"bugs", OPT_S_BUGS, '-', "Turn on SSL bug compatibility"}, \
{"no_comp", OPT_S_NO_COMP, '-', "Disable SSL/TLS compression (default)" }, \
{"comp", OPT_S_COMP, '-', "Use SSL/TLS-level compression" }, \
@@ -238,6 +249,10 @@ int set_cert_times(X509 *x, const char *startdate, const char *enddate,
"Disallow session resumption on renegotiation"}, \
{"no_legacy_server_connect", OPT_S_NOLEGACYCONN, '-', \
"Disallow initial connection to servers that don't support RI"}, \
{"allow_no_dhe_kex", OPT_S_ALLOW_NO_DHE_KEX, '-', \
"In TLSv1.3 allow non-(ec)dhe based key exchange on resumption"}, \
{"prioritize_chacha", OPT_S_PRIORITIZE_CHACHA, '-', \
"Prioritize ChaCha ciphers when preferred by clients"}, \
{"strict", OPT_S_STRICT, '-', \
"Enforce strict certificate checks as per TLS standard"}, \
{"sigalgs", OPT_S_SIGALGS, 's', \
@@ -245,15 +260,19 @@ int set_cert_times(X509 *x, const char *startdate, const char *enddate,
{"client_sigalgs", OPT_S_CLIENTSIGALGS, 's', \
"Signature algorithms to support for client certificate" \
" authentication (colon-separated list)" }, \
{"groups", OPT_S_GROUPS, 's', \
"Groups to advertise (colon-separated list)" }, \
{"curves", OPT_S_CURVES, 's', \
"Elliptic curves to advertise (colon-separated list)" }, \
"Groups to advertise (colon-separated list)" }, \
{"named_curve", OPT_S_NAMEDCURVE, 's', \
"Elliptic curve used for ECDHE (server-side only)" }, \
{"cipher", OPT_S_CIPHER, 's', "Specify cipher list to be used"}, \
{"min_protocol", OPT_S_MINPROTO, 's', "Specify the minimum protocol version to be used"}, \
{"max_protocol", OPT_S_MAXPROTO, 's', "Specify the maximum protocol version to be used"}, \
{"record_padding", OPT_S_RECORD_PADDING, 's', \
"Block size to pad TLS 1.3 records to."}, \
{"debug_broken_protocol", OPT_S_DEBUGBROKE, '-', \
"Perform all sorts of protocol violations for testing purposes"}
"Perform all sorts of protocol violations for testing purposes"}, \
{"no_middlebox", OPT_S_NO_MIDDLEBOX, '-', "Disable TLSv1.3 middlebox compat mode" }
# define OPT_S_CASES \
OPT_S__FIRST: case OPT_S__LAST: break; \
@@ -261,6 +280,7 @@ int set_cert_times(X509 *x, const char *startdate, const char *enddate,
case OPT_S_NOTLS1: \
case OPT_S_NOTLS1_1: \
case OPT_S_NOTLS1_2: \
case OPT_S_NOTLS1_3: \
case OPT_S_BUGS: \
case OPT_S_NO_COMP: \
case OPT_S_COMP: \
@@ -270,20 +290,37 @@ int set_cert_times(X509 *x, const char *startdate, const char *enddate,
case OPT_S_LEGACYCONN: \
case OPT_S_ONRESUMP: \
case OPT_S_NOLEGACYCONN: \
case OPT_S_ALLOW_NO_DHE_KEX: \
case OPT_S_PRIORITIZE_CHACHA: \
case OPT_S_STRICT: \
case OPT_S_SIGALGS: \
case OPT_S_CLIENTSIGALGS: \
case OPT_S_GROUPS: \
case OPT_S_CURVES: \
case OPT_S_NAMEDCURVE: \
case OPT_S_CIPHER: \
case OPT_S_MINPROTO: \
case OPT_S_MAXPROTO: \
case OPT_S_RECORD_PADDING: \
case OPT_S_NO_RENEGOTIATION: \
case OPT_S_DEBUGBROKE
case OPT_S_DEBUGBROKE: \
case OPT_S_NO_MIDDLEBOX
#define IS_NO_PROT_FLAG(o) \
(o == OPT_S_NOSSL3 || o == OPT_S_NOTLS1 || o == OPT_S_NOTLS1_1 \
|| o == OPT_S_NOTLS1_2)
|| o == OPT_S_NOTLS1_2 || o == OPT_S_NOTLS1_3)
/*
* Random state options.
*/
# define OPT_R_ENUM \
OPT_R__FIRST=1500, OPT_R_RAND, OPT_R_WRITERAND, OPT_R__LAST
# define OPT_R_OPTIONS \
{"rand", OPT_R_RAND, 's', "Load the file(s) into the random number generator"}, \
{"writerand", OPT_R_WRITERAND, '>', "Write random data to the specified file"}
# define OPT_R_CASES \
OPT_R__FIRST: case OPT_R__LAST: break; \
case OPT_R_RAND: case OPT_R_WRITERAND
/*
* Option parsing.
@@ -296,7 +333,7 @@ typedef struct options_st {
/*
* value type: - no value (also the value zero), n number, p positive
* number, u unsigned, l long, s string, < input file, > output file,
* f any format, F der/pem format , E der/pem/engine format identifier.
* f any format, F der/pem format, E der/pem/engine format identifier.
* l, n and u include zero; p does not.
*/
int valtype;
@@ -355,10 +392,10 @@ int opt_md(const char *name, const EVP_MD **mdp);
char *opt_arg(void);
char *opt_flag(void);
char *opt_unknown(void);
char *opt_reset(void);
char **opt_rest(void);
int opt_num_rest(void);
int opt_verify(int i, X509_VERIFY_PARAM *vpm);
int opt_rand(int i);
void opt_help(const OPTIONS * list);
int opt_format_error(const char *s, unsigned long flags);
@@ -391,6 +428,7 @@ int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_data);
int setup_ui_method(void);
void destroy_ui_method(void);
const UI_METHOD *get_ui_method(void);
int chopup_args(ARGS *arg, char *buf);
# ifdef HEADER_X509_H
@@ -401,6 +439,8 @@ void print_name(BIO *out, const char *title, X509_NAME *nm,
void print_bignum_var(BIO *, const BIGNUM *, const char*,
int, unsigned char *);
void print_array(BIO *, const char *, int, const unsigned char *);
int set_nameopt(const char *arg);
unsigned long get_nameopt(void);
int set_cert_ex(unsigned long *flags, const char *arg);
int set_name_ex(unsigned long *flags, const char *arg);
int set_ext_copy(int *copy_type, const char *arg);
@@ -458,9 +498,10 @@ int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold,
* disabled */
# define DB_NUMBER 6
# define DB_TYPE_REV 'R'
# define DB_TYPE_EXP 'E'
# define DB_TYPE_VAL 'V'
# define DB_TYPE_REV 'R' /* Revoked */
# define DB_TYPE_EXP 'E' /* Expired */
# define DB_TYPE_VAL 'V' /* Valid ; inserted with: ca ... -valid */
# define DB_TYPE_SUSP 'S' /* Suspended */
typedef struct db_attr_st {
int unique_subject;
@@ -490,8 +531,6 @@ int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b);
int parse_yesno(const char *str, int def);
X509_NAME *parse_name(const char *str, long chtype, int multirdn);
int args_verify(char ***pargs, int *pargc,
int *badarg, X509_VERIFY_PARAM **pm);
void policies_print(X509_STORE_CTX *ctx);
int bio_to_mem(unsigned char **out, int maxlen, BIO *in);
int pkey_ctrl_string(EVP_PKEY_CTX *ctx, const char *value);
@@ -503,9 +542,9 @@ int do_X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md,
STACK_OF(OPENSSL_STRING) *sigopts);
int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md,
STACK_OF(OPENSSL_STRING) *sigopts);
# ifndef OPENSSL_NO_PSK
extern char *psk_key;
# endif
unsigned char *next_protos_parse(size_t *outlen, const char *in);
@@ -546,7 +585,12 @@ void store_setup_crl_download(X509_STORE *st);
# 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_access(const char *, int flag);
@@ -559,6 +603,8 @@ int raw_write_stdout(const void *, int);
# define TM_STOP 1
double app_tminterval(int stop, int usertime);
void make_uppercase(char *string);
typedef struct verify_options_st {
int depth;
int quiet;
@@ -568,6 +614,4 @@ typedef struct verify_options_st {
extern VERIFY_CB_ARGS verify_args;
# include "progs.h"
#endif
+49 -22
View File
@@ -1,5 +1,5 @@
/*
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2018 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
@@ -7,28 +7,26 @@
* https://www.openssl.org/source/license.html
*/
/*
* A nice addition from Dr Stephen Henson <steve@openssl.org> to add the
* -strparse option which parses nested binary structures
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "apps.h"
#include "progs.h"
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/asn1t.h>
typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_INFORM, OPT_IN, OPT_OUT, OPT_INDENT, OPT_NOOUT,
OPT_OID, OPT_OFFSET, OPT_LENGTH, OPT_DUMP, OPT_DLIMIT,
OPT_STRPARSE, OPT_GENSTR, OPT_GENCONF, OPT_STRICTPEM
OPT_STRPARSE, OPT_GENSTR, OPT_GENCONF, OPT_STRICTPEM,
OPT_ITEM
} OPTION_CHOICE;
OPTIONS asn1parse_options[] = {
const OPTIONS asn1parse_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"inform", OPT_INFORM, 'F', "input format - one of DER PEM"},
{"in", OPT_IN, '<', "input file"},
@@ -49,6 +47,7 @@ OPTIONS asn1parse_options[] = {
{OPT_MORE_STR, 0, 0, "(-inform will be ignored)"},
{"strictpem", OPT_STRICTPEM, 0,
"do not attempt base64 decode outside PEM markers"},
{"item", OPT_ITEM, 's', "item to parse and print"},
{NULL}
};
@@ -71,6 +70,7 @@ int asn1parse_main(int argc, char **argv)
unsigned char *tmpbuf;
unsigned int length = 0;
OPTION_CHOICE o;
const ASN1_ITEM *it = NULL;
prog = opt_init(argc, argv, asn1parse_options);
@@ -134,6 +134,22 @@ int asn1parse_main(int argc, char **argv)
strictpem = 1;
informat = FORMAT_PEM;
break;
case OPT_ITEM:
it = ASN1_ITEM_lookup(opt_arg());
if (it == NULL) {
size_t tmp;
BIO_printf(bio_err, "Unknown item name %s\n", opt_arg());
BIO_puts(bio_err, "Supported types:\n");
for (tmp = 0;; tmp++) {
it = ASN1_ITEM_get(tmp);
if (it == NULL)
break;
BIO_printf(bio_err, " %s\n", it->sname);
}
goto end;
}
break;
}
}
argc = opt_num_rest();
@@ -174,9 +190,7 @@ int asn1parse_main(int argc, char **argv)
ERR_print_errors(bio_err);
goto end;
}
}
else {
} else {
if (informat == FORMAT_PEM) {
BIO *tmp;
@@ -253,18 +267,31 @@ int asn1parse_main(int argc, char **argv)
if ((length == 0) || ((long)length > num))
length = (unsigned int)num;
if (derout) {
if (derout != NULL) {
if (BIO_write(derout, str + offset, length) != (int)length) {
BIO_printf(bio_err, "Error writing output\n");
ERR_print_errors(bio_err);
goto end;
}
}
if (!noout &&
!ASN1_parse_dump(bio_out, &(str[offset]), length,
indent, dump)) {
ERR_print_errors(bio_err);
goto end;
if (!noout) {
const unsigned char *p = str + offset;
if (it != NULL) {
ASN1_VALUE *value = ASN1_item_d2i(NULL, &p, length, it);
if (value == NULL) {
BIO_printf(bio_err, "Error parsing item %s\n", it->sname);
ERR_print_errors(bio_err);
goto end;
}
ASN1_item_print(bio_out, value, 0, it, NULL);
ASN1_item_free(value, it);
} else {
if (!ASN1_parse_dump(bio_out, p, length, indent, dump)) {
ERR_print_errors(bio_err);
goto end;
}
}
}
ret = 0;
end:
@@ -280,7 +307,7 @@ int asn1parse_main(int argc, char **argv)
OPENSSL_free(str);
ASN1_TYPE_free(at);
sk_OPENSSL_STRING_free(osk);
return (ret);
return ret;
}
static int do_generate(char *genstr, const char *genconf, BUF_MEM *buf)
@@ -290,12 +317,12 @@ static int do_generate(char *genstr, const char *genconf, BUF_MEM *buf)
unsigned char *p;
ASN1_TYPE *atyp = NULL;
if (genconf) {
if (genconf != NULL) {
if ((cnf = app_load_config(genconf)) == NULL)
goto err;
if (!genstr)
if (genstr == NULL)
genstr = NCONF_get_string(cnf, "default", "asn1");
if (!genstr) {
if (genstr == NULL) {
BIO_printf(bio_err, "Can't find 'asn1' in '%s'\n", genconf);
goto err;
}
@@ -305,7 +332,7 @@ static int do_generate(char *genstr, const char *genconf, BUF_MEM *buf)
NCONF_free(cnf);
cnf = NULL;
if (!atyp)
if (atyp == NULL)
return -1;
len = i2d_ASN1_TYPE(atyp, NULL);
+177
View File
@@ -0,0 +1,177 @@
/*
* Copyright 2018 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
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <openssl/bio.h>
#include "apps.h"
static int prefix_write(BIO *b, const char *out, size_t outl,
size_t *numwritten);
static int prefix_read(BIO *b, char *buf, size_t size, size_t *numread);
static int prefix_puts(BIO *b, const char *str);
static int prefix_gets(BIO *b, char *str, int size);
static long prefix_ctrl(BIO *b, int cmd, long arg1, void *arg2);
static int prefix_create(BIO *b);
static int prefix_destroy(BIO *b);
static long prefix_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp);
static BIO_METHOD *prefix_meth = NULL;
BIO_METHOD *apps_bf_prefix(void)
{
if (prefix_meth == NULL) {
if ((prefix_meth =
BIO_meth_new(BIO_TYPE_FILTER, "Prefix filter")) == NULL
|| !BIO_meth_set_create(prefix_meth, prefix_create)
|| !BIO_meth_set_destroy(prefix_meth, prefix_destroy)
|| !BIO_meth_set_write_ex(prefix_meth, prefix_write)
|| !BIO_meth_set_read_ex(prefix_meth, prefix_read)
|| !BIO_meth_set_puts(prefix_meth, prefix_puts)
|| !BIO_meth_set_gets(prefix_meth, prefix_gets)
|| !BIO_meth_set_ctrl(prefix_meth, prefix_ctrl)
|| !BIO_meth_set_callback_ctrl(prefix_meth, prefix_callback_ctrl)) {
BIO_meth_free(prefix_meth);
prefix_meth = NULL;
}
}
return prefix_meth;
}
typedef struct prefix_ctx_st {
char *prefix;
int linestart; /* flag to indicate we're at the line start */
} PREFIX_CTX;
static int prefix_create(BIO *b)
{
PREFIX_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
if (ctx == NULL)
return 0;
ctx->prefix = NULL;
ctx->linestart = 1;
BIO_set_data(b, ctx);
BIO_set_init(b, 1);
return 1;
}
static int prefix_destroy(BIO *b)
{
PREFIX_CTX *ctx = BIO_get_data(b);
OPENSSL_free(ctx->prefix);
OPENSSL_free(ctx);
return 1;
}
static int prefix_read(BIO *b, char *in, size_t size, size_t *numread)
{
return BIO_read_ex(BIO_next(b), in, size, numread);
}
static int prefix_write(BIO *b, const char *out, size_t outl,
size_t *numwritten)
{
PREFIX_CTX *ctx = BIO_get_data(b);
if (ctx == NULL)
return 0;
/* If no prefix is set or if it's empty, we've got nothing to do here */
if (ctx->prefix == NULL || *ctx->prefix == '\0') {
/* We do note if what comes next will be a new line, though */
if (outl > 0)
ctx->linestart = (out[outl-1] == '\n');
return BIO_write_ex(BIO_next(b), out, outl, numwritten);
}
*numwritten = 0;
while (outl > 0) {
size_t i;
char c;
/* If we know that we're at the start of the line, output the prefix */
if (ctx->linestart) {
size_t dontcare;
if (!BIO_write_ex(BIO_next(b), ctx->prefix, strlen(ctx->prefix),
&dontcare))
return 0;
ctx->linestart = 0;
}
/* Now, go look for the next LF, or the end of the string */
for (i = 0, c = '\0'; i < outl && (c = out[i]) != '\n'; i++)
continue;
if (c == '\n')
i++;
/* Output what we found so far */
while (i > 0) {
size_t num = 0;
if (!BIO_write_ex(BIO_next(b), out, i, &num))
return 0;
out += num;
outl -= num;
*numwritten += num;
i -= num;
}
/* If we found a LF, what follows is a new line, so take note */
if (c == '\n')
ctx->linestart = 1;
}
return 1;
}
static long prefix_ctrl(BIO *b, int cmd, long num, void *ptr)
{
long ret = 0;
switch (cmd) {
case PREFIX_CTRL_SET_PREFIX:
{
PREFIX_CTX *ctx = BIO_get_data(b);
if (ctx == NULL)
break;
OPENSSL_free(ctx->prefix);
ctx->prefix = OPENSSL_strdup((const char *)ptr);
ret = ctx->prefix != NULL;
}
break;
default:
if (BIO_next(b) != NULL)
ret = BIO_ctrl(BIO_next(b), cmd, num, ptr);
break;
}
return ret;
}
static long prefix_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
{
return BIO_callback_ctrl(BIO_next(b), cmd, fp);
}
static int prefix_gets(BIO *b, char *buf, int size)
{
return BIO_gets(BIO_next(b), buf, size);
}
static int prefix_puts(BIO *b, const char *str)
{
return BIO_write(b, str, strlen(str));
}
+17 -11
View File
@@ -1,21 +1,27 @@
{- our $tsget_name = $config{target} =~ /^(VC|vms)-/ ? "tsget.pl" : "tsget";
our @apps_openssl_src =
( qw(openssl.c
asn1pars.c ca.c ciphers.c cms.c crl.c crl2p7.c dgst.c dhparam.c
dsa.c dsaparam.c ec.c ecparam.c enc.c engine.c errstr.c gendsa.c
genpkey.c genrsa.c nseq.c ocsp.c passwd.c pkcs12.c pkcs7.c pkcs8.c
pkey.c pkeyparam.c pkeyutl.c prime.c rand.c req.c rsa.c rsautl.c
s_client.c s_server.c s_time.c sess_id.c smime.c speed.c spkac.c
srp.c ts.c verify.c version.c x509.c rehash.c
apps.c opt.c s_cb.c s_socket.c
app_rand.c),
split(/\s+/, $target{apps_aux_src}) );
qw(openssl.c
asn1pars.c ca.c ciphers.c cms.c crl.c crl2p7.c dgst.c dhparam.c
dsa.c dsaparam.c ec.c ecparam.c enc.c engine.c errstr.c gendsa.c
genpkey.c genrsa.c nseq.c ocsp.c passwd.c pkcs12.c pkcs7.c pkcs8.c
pkey.c pkeyparam.c pkeyutl.c prime.c rand.c req.c rsa.c rsautl.c
s_client.c s_server.c s_time.c sess_id.c smime.c speed.c spkac.c
srp.c ts.c verify.c version.c x509.c rehash.c storeutl.c);
our @apps_lib_src =
( qw(apps.c opt.c s_cb.c s_socket.c app_rand.c bf_prefix.c),
split(/\s+/, $target{apps_aux_src}) );
our @apps_init_src = split(/\s+/, $target{apps_init_src});
"" -}
IF[{- !$disabled{apps} -}]
LIBS_NO_INST=libapps.a
SOURCE[libapps.a]={- join(" ", @apps_lib_src) -}
INCLUDE[libapps.a]=.. ../include
PROGRAMS=openssl
SOURCE[openssl]={- join(" ", @apps_init_src) -}
SOURCE[openssl]={- join(" ", @apps_openssl_src) -}
INCLUDE[openssl]=.. ../include
DEPEND[openssl]=../libssl
DEPEND[openssl]=libapps.a ../libssl
{- join("\n ", map { (my $x = $_) =~ s|\.c$|.o|; "DEPEND[$x]=progs.h" }
@apps_openssl_src) -}
+343 -353
View File
@@ -6,9 +6,6 @@
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
/* The PPKI stuff has been donated by Jeff Barber <jeffb@issl.atl.hp.com> */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -28,27 +25,24 @@
#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
#endif
#include "apps.h"
#include "progs.h"
#ifndef W_OK
# define F_OK 0
# define X_OK 1
# define W_OK 2
# define R_OK 4
#endif
#undef BSIZE
#define BSIZE 256
#ifndef PATH_MAX
# define PATH_MAX 4096
#endif
#define BASE_SECTION "ca"
@@ -60,6 +54,7 @@
#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"
@@ -82,12 +77,14 @@
#define ENV_DATABASE "database"
/* Additional revocation information types */
#define REV_NONE 0 /* No additional information */
#define REV_CRL_REASON 1 /* Value is CRL reason code */
#define REV_HOLD 2 /* Value is hold instruction */
#define REV_KEY_COMPROMISE 3 /* Value is cert key compromise time */
#define REV_CA_COMPROMISE 4 /* Value is CA key compromise time */
typedef enum {
REV_VALID = -1, /* Valid (not-revoked) status */
REV_NONE = 0, /* No additional information */
REV_CRL_REASON = 1, /* Value is CRL reason code */
REV_HOLD = 2, /* Value is hold instruction */
REV_KEY_COMPROMISE = 3, /* Value is cert key compromise time */
REV_CA_COMPROMISE = 4 /* Value is CA key compromise time */
} REVINFO_TYPE;
static char *lookup_conf(const CONF *conf, const char *group, const char *tag);
@@ -117,7 +114,6 @@ static int certify_spkac(X509 **xret, const char *infile, EVP_PKEY *pkey,
const char *enddate, long days, const char *ext_sect, CONF *conf,
int verbose, unsigned long certopt,
unsigned long nameopt, int default_op, int ext_copy);
static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext);
static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial,
@@ -126,13 +122,15 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
int batch, int verbose, X509_REQ *req, const char *ext_sect,
CONF *conf, unsigned long certopt, unsigned long nameopt,
int default_op, int ext_copy, int selfsign);
static int do_revoke(X509 *x509, CA_DB *db, int ext, char *extval);
static int get_certificate_status(const char *ser_status, CA_DB *db);
static int do_updatedb(CA_DB *db);
static int check_time_format(const char *str);
char *make_revocation_str(int rev_type, char *rev_arg);
int make_revoked(X509_REVOKED *rev, const char *str);
static int do_revoke(X509 *x509, CA_DB *db, REVINFO_TYPE rev_type,
const char *extval);
static char *make_revocation_str(REVINFO_TYPE rev_type, const char *rev_arg);
static int make_revoked(X509_REVOKED *rev, const char *str);
static int old_entry_print(const ASN1_OBJECT *obj, const ASN1_STRING *str);
static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext);
static CONF *extconf = NULL;
static int preserve = 0;
@@ -148,11 +146,13 @@ typedef enum OPTION_choice {
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_CRL_REASON, OPT_CRL_HOLD, OPT_CRL_COMPROMISE,
OPT_CRL_CA_COMPROMISE
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;
OPTIONS ca_options[] = {
const OPTIONS ca_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"verbose", OPT_VERBOSE, '-', "Verbose output during processing"},
{"config", OPT_CONFIG, 's', "A config file"},
@@ -161,6 +161,8 @@ OPTIONS ca_options[] = {
{"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"},
@@ -212,6 +214,7 @@ OPTIONS ca_options[] = {
"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
@@ -242,18 +245,21 @@ int ca_main(int argc, char **argv)
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 buf[3][BSIZE];
char *dbfile = NULL, *f;
char new_cert[PATH_MAX];
char tmp[10 + 1] = "\0";
char *const *pp;
const char *p;
size_t outdirlen = 0;
int create_ser = 0, free_key = 0, total = 0, total_done = 0;
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, rev_type = REV_NONE, 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;
OPTION_CHOICE o;
@@ -292,6 +298,9 @@ opthelp:
case OPT_UTF8:
chtype = MBSTRING_UTF8;
break;
case OPT_RAND_SERIAL:
rand_ser = 1;
break;
case OPT_CREATE_SERIAL:
create_ser = 1;
break;
@@ -323,6 +332,10 @@ opthelp:
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;
@@ -338,8 +351,7 @@ opthelp:
case OPT_SIGOPT:
if (sigopts == NULL)
sigopts = sk_OPENSSL_STRING_new_null();
if (sigopts == NULL
|| !sk_OPENSSL_STRING_push(sigopts, opt_arg()))
if (sigopts == NULL || !sk_OPENSSL_STRING_push(sigopts, opt_arg()))
goto end;
break;
case OPT_NOTEXT:
@@ -403,21 +415,12 @@ opthelp:
case OPT_CRLEXTS:
crl_ext = opt_arg();
break;
case OPT_CRL_REASON:
rev_arg = opt_arg();
rev_type = REV_CRL_REASON;
break;
case OPT_CRL_REASON: /* := REV_CRL_REASON */
case OPT_CRL_HOLD:
rev_arg = opt_arg();
rev_type = REV_HOLD;
break;
case OPT_CRL_COMPROMISE:
rev_arg = opt_arg();
rev_type = REV_KEY_COMPROMISE;
break;
case OPT_CRL_CA_COMPROMISE:
rev_arg = opt_arg();
rev_type = REV_CA_COMPROMISE;
rev_type = (o - OPT_CRL_REASON) + REV_CRL_REASON;
break;
case OPT_ENGINE:
e = setup_engine(opt_arg(), 0);
@@ -458,23 +461,20 @@ end_of_options:
goto end;
}
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;
@@ -482,9 +482,9 @@ end_of_options:
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();
/*****************************************************************/
@@ -513,7 +513,7 @@ end_of_options:
&& (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");
@@ -521,12 +521,11 @@ end_of_options:
}
}
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 */
@@ -561,37 +560,36 @@ end_of_options:
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 */
@@ -666,6 +664,10 @@ end_of_options:
goto end;
}
}
if (pp[DB_name][0] == '\0') {
BIO_printf(bio_err, "entry %d: bad Subject\n", i + 1);
goto end;
}
}
if (verbose) {
TXT_DB_write(bio_out, db->db);
@@ -698,8 +700,7 @@ end_of_options:
goto end;
if (verbose)
BIO_printf(bio_err,
"Done. %d entries marked as expired\n", i);
BIO_printf(bio_err, "Done. %d entries marked as expired\n", i);
}
}
@@ -731,8 +732,7 @@ end_of_options:
goto end;
}
if (md == NULL
&& (md = lookup_conf(conf, section, ENV_DEFAULT_MD)) == NULL)
if (md == NULL && (md = lookup_conf(conf, section, ENV_DEFAULT_MD)) == NULL)
goto end;
if (strcmp(md, "default") == 0) {
@@ -766,21 +766,25 @@ end_of_options:
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);
@@ -796,12 +800,11 @@ end_of_options:
}
if (startdate == NULL) {
startdate = NCONF_get_string(conf, section,
ENV_DEFAULT_STARTDATE);
startdate = NCONF_get_string(conf, section, ENV_DEFAULT_STARTDATE);
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;
@@ -814,7 +817,7 @@ end_of_options:
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;
@@ -824,24 +827,30 @@ end_of_options:
if (!NCONF_get_number(conf, section, ENV_DEFAULT_DAYS, &days))
days = 0;
}
if (!enddate && (days == 0)) {
BIO_printf(bio_err,
"cannot lookup how many days to certify for\n");
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);
}
}
}
@@ -859,7 +868,7 @@ end_of_options:
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;
@@ -884,7 +893,7 @@ end_of_options:
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;
@@ -904,7 +913,7 @@ end_of_options:
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) {
@@ -923,7 +932,7 @@ end_of_options:
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) {
@@ -948,14 +957,13 @@ end_of_options:
"\n%d out of %d certificate requests certified, commit? [y/n]",
total_done, total);
(void)BIO_flush(bio_err);
buf[0][0] = '\0';
if (!fgets(buf[0], 10, stdin)) {
BIO_printf(bio_err,
"CERTIFICATION CANCELED: I/O error\n");
tmp[0] = '\0';
if (fgets(tmp, sizeof(tmp), stdin) == NULL) {
BIO_printf(bio_err, "CERTIFICATION CANCELED: I/O error\n");
ret = 0;
goto end;
}
if ((buf[0][0] != 'y') && (buf[0][0] != 'Y')) {
if (tmp[0] != 'y' && tmp[0] != 'Y') {
BIO_printf(bio_err, "CERTIFICATION CANCELED\n");
ret = 0;
goto end;
@@ -965,45 +973,42 @@ end_of_options:
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))
goto end;
}
outdirlen = OPENSSL_strlcpy(new_cert, outdir, sizeof(new_cert));
#ifndef OPENSSL_SYS_VMS
outdirlen = OPENSSL_strlcat(new_cert, "/", sizeof(new_cert));
#endif
if (verbose)
BIO_printf(bio_err, "writing new certificates\n");
for (i = 0; i < sk_X509_num(cert_sk); i++) {
BIO *Cout = NULL;
X509 *xi = sk_X509_value(cert_sk, i);
ASN1_INTEGER *serialNumber = X509_get_serialNumber(xi);
int k;
char *n;
const unsigned char *psn = ASN1_STRING_get0_data(serialNumber);
const int snl = ASN1_STRING_length(serialNumber);
const int filen_len = 2 * (snl > 0 ? snl : 1) + sizeof(".pem");
char *n = new_cert + outdirlen;
j = ASN1_STRING_length(serialNumber);
p = (const char *)ASN1_STRING_get0_data(serialNumber);
if (strlen(outdir) >= (size_t)(j ? BSIZE - j * 2 - 6 : BSIZE - 8)) {
if (outdirlen + filen_len > PATH_MAX) {
BIO_printf(bio_err, "certificate file name too long\n");
goto end;
}
strcpy(buf[2], outdir);
if (snl > 0) {
static const char HEX_DIGITS[] = "0123456789ABCDEF";
#ifndef OPENSSL_SYS_VMS
OPENSSL_strlcat(buf[2], "/", sizeof(buf[2]));
#endif
n = (char *)&(buf[2][strlen(buf[2])]);
if (j > 0) {
for (k = 0; k < j; k++) {
if (n >= &(buf[2][sizeof(buf[2])]))
break;
BIO_snprintf(n,
&buf[2][0] + sizeof(buf[2]) - n,
"%02X", (unsigned char)*(p++));
n += 2;
for (j = 0; j < snl; j++, psn++) {
*n++ = HEX_DIGITS[*psn >> 4];
*n++ = HEX_DIGITS[*psn & 0x0F];
}
} else {
*(n++) = '0';
@@ -1013,13 +1018,13 @@ end_of_options:
*(n++) = 'p';
*(n++) = 'e';
*(n++) = 'm';
*n = '\0';
*n = '\0'; /* closing new_cert */
if (verbose)
BIO_printf(bio_err, "writing %s\n", buf[2]);
BIO_printf(bio_err, "writing %s\n", new_cert);
Cout = BIO_new_file(buf[2], "w");
Cout = BIO_new_file(new_cert, "w");
if (Cout == NULL) {
perror(buf[2]);
perror(new_cert);
goto end;
}
write_new_certificate(Cout, xi, 0, notext);
@@ -1042,20 +1047,19 @@ end_of_options:
/*****************************************************************/
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);
X509V3_set_nconf(&ctx, conf);
if (!X509V3_EXT_add_nconf(conf, &ctx, crl_ext, NULL)) {
BIO_printf(bio_err,
"Error Loading CRL extension section %s\n",
crl_ext);
"Error Loading CRL extension section %s\n", crl_ext);
ret = 1;
goto end;
}
@@ -1138,12 +1142,12 @@ end_of_options:
/* 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) {
@@ -1157,14 +1161,15 @@ end_of_options:
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);
@@ -1191,7 +1196,7 @@ end_of_options:
if (revcert == NULL)
goto end;
if (dorevoke == 2)
rev_type = -1;
rev_type = REV_VALID;
j = do_revoke(revcert, db, rev_type, rev_arg);
if (j <= 0)
goto end;
@@ -1206,17 +1211,16 @@ end_of_options:
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);
@@ -1229,7 +1233,7 @@ end_of_options:
NCONF_free(conf);
NCONF_free(extconf);
release_engine(e);
return (ret);
return ret;
}
static char *lookup_conf(const CONF *conf, const char *section, const char *tag)
@@ -1266,7 +1270,7 @@ static int certify(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509,
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");
@@ -1294,8 +1298,9 @@ static int certify(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509,
"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,
@@ -1305,7 +1310,7 @@ static int certify(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509,
end:
X509_REQ_free(req);
BIO_free(in);
return (ok);
return ok;
}
static int certify_cert(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509,
@@ -1343,8 +1348,9 @@ static int certify_cert(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x
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;
@@ -1357,7 +1363,7 @@ static int certify_cert(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x
end:
X509_REQ_free(rreq);
X509_free(req);
return (ok);
return ok;
}
static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
@@ -1369,13 +1375,12 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
CONF *lconf, unsigned long certopt, unsigned long nameopt,
int default_op, int ext_copy, int selfsign)
{
X509_NAME *name = NULL, *CAname = NULL, *subject = NULL;
X509_NAME *name = NULL, *CAname = NULL, *subject = NULL, *dn_subject = NULL;
const ASN1_TIME *tm;
ASN1_STRING *str, *str2;
ASN1_OBJECT *obj;
X509 *ret = NULL;
X509_NAME_ENTRY *ne;
X509_NAME_ENTRY *tne, *push;
X509_NAME_ENTRY *ne, *tne;
EVP_PKEY *pktmp;
int ok = -1, i, j, last, nid;
const char *p;
@@ -1400,49 +1405,48 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
}
if (default_op)
BIO_printf(bio_err,
"The Subject's Distinguished Name is as follows\n");
BIO_printf(bio_err, "The Subject's Distinguished Name is as follows\n");
name = X509_REQ_get_subject_name(req);
if (X509_NAME_entry_count(name) == 0) {
BIO_printf(bio_err, "Error: The supplied Subject is empty\n");
goto end;
}
for (i = 0; i < X509_NAME_entry_count(name); i++) {
ne = X509_NAME_get_entry(name, i);
str = X509_NAME_ENTRY_get_data(ne);
obj = X509_NAME_ENTRY_get_object(ne);
nid = OBJ_obj2nid(obj);
if (msie_hack) {
/* assume all type should be strings */
nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(ne));
if (str->type == V_ASN1_UNIVERSALSTRING)
ASN1_UNIVERSALSTRING_to_string(str);
if ((str->type == V_ASN1_IA5STRING) &&
(nid != NID_pkcs9_emailAddress))
if (str->type == V_ASN1_IA5STRING && nid != NID_pkcs9_emailAddress)
str->type = V_ASN1_T61STRING;
if ((nid == NID_pkcs9_emailAddress) &&
(str->type == V_ASN1_PRINTABLESTRING))
if (nid == NID_pkcs9_emailAddress
&& str->type == V_ASN1_PRINTABLESTRING)
str->type = V_ASN1_IA5STRING;
}
/* If no EMAIL is wanted in the subject */
if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (!email_dn))
if (nid == NID_pkcs9_emailAddress && !email_dn)
continue;
/* check some things */
if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
(str->type != V_ASN1_IA5STRING)) {
if (nid == NID_pkcs9_emailAddress && str->type != V_ASN1_IA5STRING) {
BIO_printf(bio_err,
"\nemailAddress type needs to be of type IA5STRING\n");
goto end;
}
if ((str->type != V_ASN1_BMPSTRING)
&& (str->type != V_ASN1_UTF8STRING)) {
if (str->type != V_ASN1_BMPSTRING && str->type != V_ASN1_UTF8STRING) {
j = ASN1_PRINTABLE_type(str->data, str->length);
if (((j == V_ASN1_T61STRING) &&
(str->type != V_ASN1_T61STRING)) ||
((j == V_ASN1_IA5STRING) &&
(str->type == V_ASN1_PRINTABLESTRING))) {
if ((j == V_ASN1_T61STRING && str->type != V_ASN1_T61STRING) ||
(j == V_ASN1_IA5STRING && str->type == V_ASN1_PRINTABLESTRING))
{
BIO_printf(bio_err,
"\nThe string contains characters that are illegal for the ASN.1 type\n");
goto end;
@@ -1480,6 +1484,8 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
last = -1;
for (;;) {
X509_NAME_ENTRY *push = NULL;
/* lookup the object in the supplied name list */
j = X509_NAME_get_index_by_OBJ(name, obj, last);
if (j < 0) {
@@ -1492,7 +1498,6 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
last = j;
/* depending on the 'policy', decide what to do. */
push = NULL;
if (strcmp(cv->value, "optional") == 0) {
if (tne != NULL)
push = tne;
@@ -1502,8 +1507,9 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
"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;
@@ -1521,8 +1527,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
if ((j < 0) && (last2 == -1)) {
BIO_printf(bio_err,
"The %s field does not exist in the CA certificate,\n"
"the 'policy' is misconfigured\n",
cv->name);
"the 'policy' is misconfigured\n", cv->name);
goto end;
}
if (j >= 0) {
@@ -1568,124 +1573,25 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
goto end;
}
/* We are now totally happy, lets make and sign the certificate */
if (verbose)
if (X509_NAME_entry_count(subject) == 0) {
BIO_printf(bio_err,
"Everything appears to be ok, creating and signing the certificate\n");
if ((ret = X509_new()) == NULL)
"Error: After applying policy the Subject is empty\n");
goto end;
#ifdef X509_V3
/* Make it an X509 v3 certificate. */
if (!X509_set_version(ret, 2))
goto end;
#endif
if (BN_to_ASN1_INTEGER(serial, X509_get_serialNumber(ret)) == NULL)
goto end;
if (selfsign) {
if (!X509_set_issuer_name(ret, subject))
goto end;
} else {
if (!X509_set_issuer_name(ret, X509_get_subject_name(x509)))
goto end;
}
if (!set_cert_times(ret, startdate, enddate, days))
goto end;
if (enddate != NULL) {
int tdays;
if (!ASN1_TIME_diff(&tdays, NULL, NULL, X509_get0_notAfter(ret)))
goto end;
days = tdays;
}
if (!X509_set_subject_name(ret, subject))
goto end;
pktmp = X509_REQ_get0_pubkey(req);
i = X509_set_pubkey(ret, pktmp);
if (!i)
goto end;
/* Lets add the extensions, if there are any */
if (ext_sect) {
X509V3_CTX ctx;
/* Initialize the context structure */
if (selfsign)
X509V3_set_ctx(&ctx, ret, ret, req, NULL, 0);
else
X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
if (extconf) {
if (verbose)
BIO_printf(bio_err, "Extra configuration file found\n");
/* Use the extconf configuration db LHASH */
X509V3_set_nconf(&ctx, extconf);
/* Test the structure (needed?) */
/* X509V3_set_ctx_test(&ctx); */
/* Adds exts contained in the configuration file */
if (!X509V3_EXT_add_nconf(extconf, &ctx, ext_sect, ret)) {
BIO_printf(bio_err,
"ERROR: adding extensions in section %s\n",
ext_sect);
ERR_print_errors(bio_err);
goto end;
}
if (verbose)
BIO_printf(bio_err,
"Successfully added extensions from file.\n");
} else if (ext_sect) {
/* We found extensions to be set from config file */
X509V3_set_nconf(&ctx, lconf);
if (!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret)) {
BIO_printf(bio_err,
"ERROR: adding extensions in section %s\n",
ext_sect);
ERR_print_errors(bio_err);
goto end;
}
if (verbose)
BIO_printf(bio_err,
"Successfully added extensions from config\n");
}
}
/* Copy extensions from request (if any) */
if (!copy_extensions(ret, req, ext_copy)) {
BIO_printf(bio_err, "ERROR: adding extensions from request\n");
ERR_print_errors(bio_err);
goto end;
}
{
const STACK_OF(X509_EXTENSION) *exts = X509_get0_extensions(ret);
if (exts != NULL && sk_X509_EXTENSION_num(exts) > 0)
/* Make it an X509 v3 certificate. */
if (!X509_set_version(ret, 2))
goto end;
}
if (verbose)
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. */
if (!email_dn) {
X509_NAME_ENTRY *tmpne;
X509_NAME *dn_subject;
/*
* 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) {
dn_subject = subject;
} else {
X509_NAME_ENTRY *tmpne;
/*
* Its best to dup the subject DN and then delete any email addresses
* because this retains its structure.
@@ -1701,18 +1607,6 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
X509_NAME_delete_entry(dn_subject, i);
X509_NAME_ENTRY_free(tmpne);
}
if (!X509_set_subject_name(ret, dn_subject)) {
X509_NAME_free(dn_subject);
goto end;
}
X509_NAME_free(dn_subject);
}
row[DB_name] = X509_NAME_oneline(X509_get_subject_name(ret), NULL, 0);
if (row[DB_name] == NULL) {
BIO_printf(bio_err, "Memory allocation failure\n");
goto end;
}
if (BN_is_zero(serial))
@@ -1724,20 +1618,6 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
goto end;
}
if (row[DB_name][0] == '\0') {
/*
* An empty subject! We'll use the serial number instead. If
* unique_subject is in use then we don't want different entries with
* empty subjects matching each other.
*/
OPENSSL_free(row[DB_name]);
row[DB_name] = OPENSSL_strdup(row[DB_serial]);
if (row[DB_name] == NULL) {
BIO_printf(bio_err, "Memory allocation failure\n");
goto end;
}
}
if (db->attributes.unique_subject) {
OPENSSL_STRING *crow = row;
@@ -1796,6 +1676,121 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
goto end;
}
/* We are now totally happy, lets make and sign the certificate */
if (verbose)
BIO_printf(bio_err,
"Everything appears to be ok, creating and signing the certificate\n");
if ((ret = X509_new()) == NULL)
goto end;
#ifdef X509_V3
/* Make it an X509 v3 certificate. */
if (!X509_set_version(ret, 2))
goto end;
#endif
if (BN_to_ASN1_INTEGER(serial, X509_get_serialNumber(ret)) == NULL)
goto end;
if (selfsign) {
if (!X509_set_issuer_name(ret, subject))
goto end;
} else {
if (!X509_set_issuer_name(ret, X509_get_subject_name(x509)))
goto end;
}
if (!set_cert_times(ret, startdate, enddate, days))
goto end;
if (enddate != NULL) {
int tdays;
if (!ASN1_TIME_diff(&tdays, NULL, NULL, X509_get0_notAfter(ret)))
goto end;
days = tdays;
}
if (!X509_set_subject_name(ret, subject))
goto end;
pktmp = X509_REQ_get0_pubkey(req);
i = X509_set_pubkey(ret, pktmp);
if (!i)
goto end;
/* Lets add the extensions, if there are any */
if (ext_sect) {
X509V3_CTX ctx;
/* Initialize the context structure */
if (selfsign)
X509V3_set_ctx(&ctx, ret, ret, req, NULL, 0);
else
X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
if (extconf != NULL) {
if (verbose)
BIO_printf(bio_err, "Extra configuration file found\n");
/* Use the extconf configuration db LHASH */
X509V3_set_nconf(&ctx, extconf);
/* Test the structure (needed?) */
/* X509V3_set_ctx_test(&ctx); */
/* Adds exts contained in the configuration file */
if (!X509V3_EXT_add_nconf(extconf, &ctx, ext_sect, ret)) {
BIO_printf(bio_err,
"ERROR: adding extensions in section %s\n",
ext_sect);
ERR_print_errors(bio_err);
goto end;
}
if (verbose)
BIO_printf(bio_err,
"Successfully added extensions from file.\n");
} else if (ext_sect) {
/* We found extensions to be set from config file */
X509V3_set_nconf(&ctx, lconf);
if (!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret)) {
BIO_printf(bio_err,
"ERROR: adding extensions in section %s\n",
ext_sect);
ERR_print_errors(bio_err);
goto end;
}
if (verbose)
BIO_printf(bio_err,
"Successfully added extensions from config\n");
}
}
/* Copy extensions from request (if any) */
if (!copy_extensions(ret, req, ext_copy)) {
BIO_printf(bio_err, "ERROR: adding extensions from request\n");
ERR_print_errors(bio_err);
goto end;
}
{
const STACK_OF(X509_EXTENSION) *exts = X509_get0_extensions(ret);
if (exts != NULL && sk_X509_EXTENSION_num(exts) > 0)
/* Make it an X509 v3 certificate. */
if (!X509_set_version(ret, 2))
goto end;
}
/* Set the right value for the noemailDN option */
if (email_dn == 0) {
if (!X509_set_subject_name(ret, dn_subject))
goto end;
}
if (!default_op) {
BIO_printf(bio_err, "Certificate Details:\n");
/*
@@ -1816,13 +1811,13 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
BIO_printf(bio_err, "Sign the certificate? [y/n]:");
(void)BIO_flush(bio_err);
buf[0] = '\0';
if (!fgets(buf, sizeof(buf) - 1, stdin)) {
if (fgets(buf, sizeof(buf), stdin) == NULL) {
BIO_printf(bio_err,
"CERTIFICATE WILL NOT BE CERTIFIED: I/O error\n");
ok = 0;
goto end;
}
if (!((buf[0] == 'y') || (buf[0] == 'Y'))) {
if (!(buf[0] == 'y' || buf[0] == 'Y')) {
BIO_printf(bio_err, "CERTIFICATE WILL NOT BE CERTIFIED\n");
ok = 0;
goto end;
@@ -1837,7 +1832,7 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
if (!do_X509_sign(ret, pkey, dgst, sigopts))
goto end;
/* We now just add it to the database */
/* We now just add it to the database as DB_TYPE_VAL('V') */
row[DB_type] = OPENSSL_strdup("V");
tm = X509_get0_notAfter(ret);
row[DB_exp_date] = app_malloc(tm->length + 1, "row expdate");
@@ -1845,6 +1840,8 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
row[DB_exp_date][tm->length] = '\0';
row[DB_rev_date] = NULL;
row[DB_file] = OPENSSL_strdup("unknown");
row[DB_name] = X509_NAME_oneline(X509_get_subject_name(ret), NULL, 0);
if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) ||
(row[DB_file] == NULL) || (row[DB_name] == NULL)) {
BIO_printf(bio_err, "Memory allocation failure\n");
@@ -1864,23 +1861,24 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
irow = NULL;
ok = 1;
end:
if (ok != 1) {
if (irow != NULL) {
for (i = 0; i < DB_NUMBER; i++)
OPENSSL_free(row[i]);
OPENSSL_free(irow);
}
OPENSSL_free(irow);
X509_NAME_free(CAname);
X509_NAME_free(subject);
if (dn_subject != subject)
X509_NAME_free(dn_subject);
if (ok <= 0)
X509_free(ret);
else
*xret = ret;
return (ok);
return ok;
}
static void write_new_certificate(BIO *bp, X509 *x, int output_der,
int notext)
static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext)
{
if (output_der) {
@@ -1996,8 +1994,7 @@ static int certify_spkac(X509 **xret, const char *infile, EVP_PKEY *pkey,
* Now extract the key from the SPKI structure.
*/
BIO_printf(bio_err,
"Check that the SPKAC request matches the signature\n");
BIO_printf(bio_err, "Check that the SPKAC request matches the signature\n");
if ((pktmp = NETSCAPE_SPKI_get_pubkey(spki)) == NULL) {
BIO_printf(bio_err, "error unpacking SPKAC public key\n");
@@ -2025,7 +2022,7 @@ static int certify_spkac(X509 **xret, const char *infile, EVP_PKEY *pkey,
NETSCAPE_SPKI_free(spki);
X509_NAME_ENTRY_free(ne);
return (ok);
return ok;
}
static int check_time_format(const char *str)
@@ -2033,7 +2030,8 @@ static int check_time_format(const char *str)
return ASN1_TIME_set_string(NULL, str);
}
static int do_revoke(X509 *x509, CA_DB *db, int type, char *value)
static int do_revoke(X509 *x509, CA_DB *db, REVINFO_TYPE rev_type,
const char *value)
{
const ASN1_TIME *tm = NULL;
char *row[DB_NUMBER], **rrow, **irow;
@@ -2052,11 +2050,6 @@ static int do_revoke(X509 *x509, CA_DB *db, int type, char *value)
else
row[DB_serial] = BN_bn2hex(bn);
BN_free(bn);
if (row[DB_name] != NULL && row[DB_name][0] == '\0') {
/* Entries with empty Subjects actually use the serial number instead */
OPENSSL_free(row[DB_name]);
row[DB_name] = OPENSSL_strdup(row[DB_serial]);
}
if ((row[DB_name] == NULL) || (row[DB_serial] == NULL)) {
BIO_printf(bio_err, "Memory allocation failure\n");
goto end;
@@ -2071,7 +2064,7 @@ static int do_revoke(X509 *x509, CA_DB *db, int type, char *value)
"Adding Entry with serial number %s to DB for %s\n",
row[DB_serial], row[DB_name]);
/* We now just add it to the database */
/* We now just add it to the database as DB_TYPE_REV('V') */
row[DB_type] = OPENSSL_strdup("V");
tm = X509_get0_notAfter(x509);
row[DB_exp_date] = app_malloc(tm->length + 1, "row exp_data");
@@ -2101,32 +2094,33 @@ static int do_revoke(X509 *x509, CA_DB *db, int type, char *value)
row[i] = NULL;
/* Revoke Certificate */
if (type == -1)
if (rev_type == REV_VALID)
ok = 1;
else
ok = do_revoke(x509, db, type, value);
/* Retry revocation after DB insertion */
ok = do_revoke(x509, db, rev_type, value);
goto end;
} else if (index_name_cmp_noconst(row, rrow)) {
BIO_printf(bio_err, "ERROR:name does not match %s\n", row[DB_name]);
goto end;
} else if (type == -1) {
} else if (rev_type == REV_VALID) {
BIO_printf(bio_err, "ERROR:Already present, serial number %s\n",
row[DB_serial]);
goto end;
} else if (rrow[DB_type][0] == 'R') {
} else if (rrow[DB_type][0] == DB_TYPE_REV) {
BIO_printf(bio_err, "ERROR:Already revoked, serial number %s\n",
row[DB_serial]);
goto end;
} else {
BIO_printf(bio_err, "Revoking Certificate %s.\n", rrow[DB_serial]);
rev_str = make_revocation_str(type, value);
rev_str = make_revocation_str(rev_type, value);
if (!rev_str) {
BIO_printf(bio_err, "Error in revocation arguments\n");
goto end;
}
rrow[DB_type][0] = 'R';
rrow[DB_type][0] = DB_TYPE_REV;
rrow[DB_type][1] = '\0';
rrow[DB_rev_date] = rev_str;
}
@@ -2134,7 +2128,7 @@ static int do_revoke(X509 *x509, CA_DB *db, int type, char *value)
end:
for (i = 0; i < DB_NUMBER; i++)
OPENSSL_free(row[i]);
return (ok);
return ok;
}
static int get_certificate_status(const char *serial, CA_DB *db)
@@ -2153,7 +2147,7 @@ static int get_certificate_status(const char *serial, CA_DB *db)
if (serial_len % 2) {
/*
* Set the first char to 0
*/ ;
*/
row[DB_serial][0] = '0';
/* Copy String from serial to row[DB_serial] */
@@ -2166,8 +2160,7 @@ static int get_certificate_status(const char *serial, CA_DB *db)
}
/* 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;
@@ -2177,19 +2170,19 @@ static int get_certificate_status(const char *serial, CA_DB *db)
BIO_printf(bio_err, "Serial %s not present in db.\n", row[DB_serial]);
ok = -1;
goto end;
} else if (rrow[DB_type][0] == 'V') {
} else if (rrow[DB_type][0] == DB_TYPE_VAL) {
BIO_printf(bio_err, "%s=Valid (%c)\n",
row[DB_serial], rrow[DB_type][0]);
goto end;
} else if (rrow[DB_type][0] == 'R') {
} else if (rrow[DB_type][0] == DB_TYPE_REV) {
BIO_printf(bio_err, "%s=Revoked (%c)\n",
row[DB_serial], rrow[DB_type][0]);
goto end;
} else if (rrow[DB_type][0] == 'E') {
} else if (rrow[DB_type][0] == DB_TYPE_EXP) {
BIO_printf(bio_err, "%s=Expired (%c)\n",
row[DB_serial], rrow[DB_type][0]);
goto end;
} else if (rrow[DB_type][0] == 'S') {
} else if (rrow[DB_type][0] == DB_TYPE_SUSP) {
BIO_printf(bio_err, "%s=Suspended (%c)\n",
row[DB_serial], rrow[DB_type][0]);
goto end;
@@ -2202,7 +2195,7 @@ static int get_certificate_status(const char *serial, CA_DB *db)
for (i = 0; i < DB_NUMBER; i++) {
OPENSSL_free(row[i]);
}
return (ok);
return ok;
}
static int do_updatedb(CA_DB *db)
@@ -2234,7 +2227,7 @@ static int do_updatedb(CA_DB *db)
for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
rrow = sk_OPENSSL_PSTRING_value(db->db->data, i);
if (rrow[DB_type][0] == 'V') {
if (rrow[DB_type][0] == DB_TYPE_VAL) {
/* ignore entries that are not valid */
if (strncmp(rrow[DB_exp_date], "49", 2) <= 0)
db_y2k = 1;
@@ -2244,14 +2237,14 @@ static int do_updatedb(CA_DB *db)
if (db_y2k == a_y2k) {
/* all on the same y2k side */
if (strcmp(rrow[DB_exp_date], a_tm_s) <= 0) {
rrow[DB_type][0] = 'E';
rrow[DB_type][0] = DB_TYPE_EXP;
rrow[DB_type][1] = '\0';
cnt++;
BIO_printf(bio_err, "%s=Expired\n", rrow[DB_serial]);
}
} else if (db_y2k < a_y2k) {
rrow[DB_type][0] = 'E';
rrow[DB_type][0] = DB_TYPE_EXP;
rrow[DB_type][1] = '\0';
cnt++;
@@ -2263,7 +2256,7 @@ static int do_updatedb(CA_DB *db)
ASN1_UTCTIME_free(a_tm);
OPENSSL_free(a_tm_s);
return (cnt);
return cnt;
}
static const char *crl_reasons[] = {
@@ -2291,16 +2284,17 @@ static const char *crl_reasons[] = {
* additional argument
*/
char *make_revocation_str(int rev_type, char *rev_arg)
static char *make_revocation_str(REVINFO_TYPE rev_type, const char *rev_arg)
{
char *str;
const char *other = NULL;
const char *reason = NULL;
const char *reason = NULL, *other = NULL;
ASN1_OBJECT *otmp;
ASN1_UTCTIME *revtm = NULL;
int i;
switch (rev_type) {
case REV_NONE:
case REV_VALID:
break;
case REV_CRL_REASON:
@@ -2318,7 +2312,6 @@ char *make_revocation_str(int rev_type, char *rev_arg)
case REV_HOLD:
/* Argument is an OID */
otmp = OBJ_txt2obj(rev_arg, 0);
ASN1_OBJECT_free(otmp);
@@ -2333,7 +2326,6 @@ char *make_revocation_str(int rev_type, char *rev_arg)
case REV_KEY_COMPROMISE:
case REV_CA_COMPROMISE:
/* Argument is the key compromise time */
if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg)) {
BIO_printf(bio_err,
@@ -2348,7 +2340,6 @@ char *make_revocation_str(int rev_type, char *rev_arg)
reason = "CAkeyTime";
break;
}
revtm = X509_gmtime_adj(NULL, 0);
@@ -2385,7 +2376,7 @@ char *make_revocation_str(int rev_type, char *rev_arg)
* 2 OK and some extensions added (i.e. V2 CRL)
*/
int make_revoked(X509_REVOKED *rev, const char *str)
static int make_revoked(X509_REVOKED *rev, const char *str)
{
char *tmp = NULL;
int reason_code = -1;
@@ -2535,9 +2526,9 @@ int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold,
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;
@@ -2546,8 +2537,7 @@ int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold,
hold = OBJ_txt2obj(arg_str, 0);
if (!hold) {
BIO_printf(bio_err, "invalid object identifier %s\n",
arg_str);
BIO_printf(bio_err, "invalid object identifier %s\n", arg_str);
goto end;
}
if (phold)
+24 -12
View File
@@ -1,5 +1,5 @@
/*
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2018 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
@@ -11,22 +11,25 @@
#include <stdlib.h>
#include <string.h>
#include "apps.h"
#include "progs.h"
#include <openssl/err.h>
#include <openssl/ssl.h>
typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_STDNAME,
OPT_CONVERT,
OPT_SSL3,
OPT_TLS1,
OPT_TLS1_1,
OPT_TLS1_2,
OPT_TLS1_3,
OPT_PSK,
OPT_SRP,
OPT_V, OPT_UPPER_V, OPT_S
} OPTION_CHOICE;
OPTIONS ciphers_options[] = {
const OPTIONS ciphers_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"v", OPT_V, '-', "Verbose listing of the SSL/TLS ciphers"},
{"V", OPT_UPPER_V, '-', "Even more verbose"},
@@ -43,15 +46,17 @@ OPTIONS ciphers_options[] = {
#ifndef OPENSSL_NO_TLS1_2
{"tls1_2", OPT_TLS1_2, '-', "TLS1.2 mode"},
#endif
#ifndef OPENSSL_NO_SSL_TRACE
{"stdname", OPT_STDNAME, '-', "Show standard cipher names"},
#ifndef OPENSSL_NO_TLS1_3
{"tls1_3", OPT_TLS1_3, '-', "TLS1.3 mode"},
#endif
{"stdname", OPT_STDNAME, '-', "Show standard cipher names"},
#ifndef OPENSSL_NO_PSK
{"psk", OPT_PSK, '-', "include ciphersuites requiring PSK"},
#endif
#ifndef OPENSSL_NO_SRP
{"srp", OPT_SRP, '-', "include ciphersuites requiring SRP"},
#endif
{"convert", OPT_CONVERT, 's', "Convert standard name into OpenSSL name"},
{NULL}
};
@@ -78,9 +83,7 @@ int ciphers_main(int argc, char **argv)
STACK_OF(SSL_CIPHER) *sk = NULL;
const SSL_METHOD *meth = TLS_server_method();
int ret = 1, i, verbose = 0, Verbose = 0, use_supported = 0;
#ifndef OPENSSL_NO_SSL_TRACE
int stdname = 0;
#endif
#ifndef OPENSSL_NO_PSK
int psk = 0;
#endif
@@ -88,7 +91,7 @@ int ciphers_main(int argc, char **argv)
int srp = 0;
#endif
const char *p;
char *ciphers = NULL, *prog;
char *ciphers = NULL, *prog, *convert = NULL;
char buf[512];
OPTION_CHOICE o;
int min_version = 0, max_version = 0;
@@ -115,9 +118,10 @@ int ciphers_main(int argc, char **argv)
use_supported = 1;
break;
case OPT_STDNAME:
#ifndef OPENSSL_NO_SSL_TRACE
stdname = verbose = 1;
#endif
break;
case OPT_CONVERT:
convert = opt_arg();
break;
case OPT_SSL3:
min_version = SSL3_VERSION;
@@ -135,6 +139,10 @@ int ciphers_main(int argc, char **argv)
min_version = TLS1_2_VERSION;
max_version = TLS1_2_VERSION;
break;
case OPT_TLS1_3:
min_version = TLS1_3_VERSION;
max_version = TLS1_3_VERSION;
break;
case OPT_PSK:
#ifndef OPENSSL_NO_PSK
psk = 1;
@@ -155,6 +163,12 @@ int ciphers_main(int argc, char **argv)
else if (argc != 0)
goto opthelp;
if (convert != NULL) {
BIO_printf(bio_out, "OpenSSL cipher name: %s\n",
OPENSSL_cipher_name(convert));
goto end;
}
ctx = SSL_CTX_new(meth);
if (ctx == NULL)
goto err;
@@ -217,14 +231,12 @@ int ciphers_main(int argc, char **argv)
else
BIO_printf(bio_out, "0x%02X,0x%02X,0x%02X,0x%02X - ", id0, id1, id2, id3); /* whatever */
}
#ifndef OPENSSL_NO_SSL_TRACE
if (stdname) {
const char *nm = SSL_CIPHER_standard_name(c);
if (nm == NULL)
nm = "UNKNOWN";
BIO_printf(bio_out, "%s - ", nm);
}
#endif
BIO_puts(bio_out, SSL_CIPHER_description(c, buf, sizeof(buf)));
}
}
@@ -238,5 +250,5 @@ int ciphers_main(int argc, char **argv)
sk_SSL_CIPHER_free(sk);
SSL_CTX_free(ctx);
SSL_free(ssl);
return (ret);
return ret;
}
+114 -123
View File
@@ -12,6 +12,7 @@
#include <stdio.h>
#include <string.h>
#include "apps.h"
#include "progs.h"
#ifndef OPENSSL_NO_CMS
@@ -76,15 +77,16 @@ typedef enum OPTION_choice {
OPT_RR_ALL, OPT_RR_FIRST, OPT_RCTFORM, OPT_CERTFILE, OPT_CAFILE,
OPT_CAPATH, OPT_NOCAPATH, OPT_NOCAFILE,OPT_CONTENT, OPT_PRINT,
OPT_SECRETKEY, OPT_SECRETKEYID, OPT_PWRI_PASSWORD, OPT_ECONTENT_TYPE,
OPT_RAND, OPT_PASSIN, OPT_TO, OPT_FROM, OPT_SUBJECT, OPT_SIGNER, OPT_RECIP,
OPT_PASSIN, OPT_TO, OPT_FROM, OPT_SUBJECT, OPT_SIGNER, OPT_RECIP,
OPT_CERTSOUT, OPT_MD, OPT_INKEY, OPT_KEYFORM, OPT_KEYOPT, OPT_RR_FROM,
OPT_RR_TO, OPT_AES128_WRAP, OPT_AES192_WRAP, OPT_AES256_WRAP,
OPT_3DES_WRAP, OPT_ENGINE,
OPT_R_ENUM,
OPT_V_ENUM,
OPT_CIPHER
} OPTION_CHOICE;
OPTIONS cms_options[] = {
const OPTIONS cms_options[] = {
{OPT_HELP_STR, 1, '-', "Usage: %s [options] cert.pem...\n"},
{OPT_HELP_STR, 1, '-',
" cert.pem... recipient certs for encryption\n"},
@@ -146,14 +148,12 @@ OPTIONS cms_options[] = {
"Do not load certificates from the default certificates directory"},
{"content", OPT_CONTENT, '<',
"Supply or override content for detached signature"},
{"print", OPT_PRINT, '-',
{"print", OPT_PRINT, '-',
"For the -cmsout operation print out all fields of the CMS structure"},
{"secretkey", OPT_SECRETKEY, 's'},
{"secretkeyid", OPT_SECRETKEYID, 's'},
{"pwri_password", OPT_PWRI_PASSWORD, 's'},
{"econtent_type", OPT_ECONTENT_TYPE, 's'},
{"rand", OPT_RAND, 's',
"Load the file(s) into the random number generator"},
{"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
{"to", OPT_TO, 's', "To address"},
{"from", OPT_FROM, 's', "From address"},
@@ -169,6 +169,7 @@ OPTIONS cms_options[] = {
{"receipt_request_from", OPT_RR_FROM, 's'},
{"receipt_request_to", OPT_RR_TO, 's'},
{"", OPT_CIPHER, '-', "Any supported cipher"},
OPT_R_OPTIONS,
OPT_V_OPTIONS,
{"aes128-wrap", OPT_AES128_WRAP, '-', "Use AES128 to wrap key"},
{"aes192-wrap", OPT_AES192_WRAP, '-', "Use AES192 to wrap key"},
@@ -202,16 +203,13 @@ int cms_main(int argc, char **argv)
const char *CAfile = NULL, *CApath = NULL;
char *certsoutfile = NULL;
int noCAfile = 0, noCApath = 0;
char *infile = NULL, *outfile = NULL, *rctfile = NULL, *inrand = NULL;
char *passinarg = NULL, *passin = NULL, *signerfile = NULL, *recipfile =
NULL;
char *infile = NULL, *outfile = NULL, *rctfile = NULL;
char *passinarg = NULL, *passin = NULL, *signerfile = NULL, *recipfile = NULL;
char *to = NULL, *from = NULL, *subject = NULL, *prog;
cms_key_param *key_first = NULL, *key_param = NULL;
int flags = CMS_DETACHED, noout = 0, print = 0, keyidx = -1, vpmtouched =
0;
int flags = CMS_DETACHED, noout = 0, print = 0, keyidx = -1, vpmtouched = 0;
int informat = FORMAT_SMIME, outformat = FORMAT_SMIME;
int need_rand = 0, operation = 0, ret = 1, rr_print = 0, rr_allorfirst =
-1;
int operation = 0, ret = 1, rr_print = 0, rr_allorfirst = -1;
int verify_retcode = 0, rctformat = FORMAT_SMIME, keyform = FORMAT_PEM;
size_t secret_keylen = 0, secret_keyidlen = 0;
unsigned char *pwri_pass = NULL, *pwri_tmp = NULL;
@@ -449,10 +447,6 @@ int cms_main(int argc, char **argv)
goto opthelp;
}
break;
case OPT_RAND:
inrand = opt_arg();
need_rand = 1;
break;
case OPT_ENGINE:
e = setup_engine(opt_arg(), 0);
break;
@@ -477,7 +471,7 @@ int cms_main(int argc, char **argv)
break;
case OPT_SIGNER:
/* If previous -signer argument add signer to list */
if (signerfile) {
if (signerfile != NULL) {
if (sksigners == NULL
&& (sksigners = sk_OPENSSL_STRING_new_null()) == NULL)
goto end;
@@ -494,7 +488,7 @@ int cms_main(int argc, char **argv)
break;
case OPT_INKEY:
/* If previous -inkey argument add signer to list */
if (keyfile) {
if (keyfile != NULL) {
if (signerfile == NULL) {
BIO_puts(bio_err, "Illegal -inkey without -signer\n");
goto end;
@@ -525,8 +519,9 @@ int cms_main(int argc, char **argv)
goto end;
sk_X509_push(encerts, cert);
cert = NULL;
} else
} else {
recipfile = opt_arg();
}
break;
case OPT_CIPHER:
if (!opt_cipher(opt_unknown(), &cipher))
@@ -535,12 +530,12 @@ int cms_main(int argc, char **argv)
case OPT_KEYOPT:
keyidx = -1;
if (operation == SMIME_ENCRYPT) {
if (encerts)
if (encerts != NULL)
keyidx += sk_X509_num(encerts);
} else {
if (keyfile || signerfile)
if (keyfile != NULL || signerfile != NULL)
keyidx++;
if (skkeys)
if (skkeys != NULL)
keyidx += sk_OPENSSL_STRING_num(skkeys);
}
if (keyidx < 0) {
@@ -567,6 +562,10 @@ int cms_main(int argc, char **argv)
goto end;
vpmtouched++;
break;
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
case OPT_3DES_WRAP:
# ifndef OPENSSL_NO_DES
wrap_cipher = EVP_des_ede3_wrap();
@@ -586,87 +585,77 @@ int cms_main(int argc, char **argv)
argc = opt_num_rest();
argv = opt_rest();
if (((rr_allorfirst != -1) || rr_from) && !rr_to) {
if ((rr_allorfirst != -1 || rr_from != NULL) && rr_to == NULL) {
BIO_puts(bio_err, "No Signed Receipts Recipients\n");
goto opthelp;
}
if (!(operation & SMIME_SIGNERS) && (rr_to || rr_from)) {
if (!(operation & SMIME_SIGNERS) && (rr_to != NULL || rr_from != NULL)) {
BIO_puts(bio_err, "Signed receipts only allowed with -sign\n");
goto opthelp;
}
if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners)) {
if (!(operation & SMIME_SIGNERS) && (skkeys != NULL || sksigners != NULL)) {
BIO_puts(bio_err, "Multiple signers or keys not allowed\n");
goto opthelp;
}
if (operation & SMIME_SIGNERS) {
if (keyfile && !signerfile) {
if (keyfile != NULL && signerfile == NULL) {
BIO_puts(bio_err, "Illegal -inkey without -signer\n");
goto opthelp;
}
/* Check to see if any final signer needs to be appended */
if (signerfile) {
if (!sksigners
if (signerfile != NULL) {
if (sksigners == NULL
&& (sksigners = sk_OPENSSL_STRING_new_null()) == NULL)
goto end;
sk_OPENSSL_STRING_push(sksigners, signerfile);
if (!skkeys && (skkeys = sk_OPENSSL_STRING_new_null()) == NULL)
if (skkeys == NULL && (skkeys = sk_OPENSSL_STRING_new_null()) == NULL)
goto end;
if (!keyfile)
if (keyfile == NULL)
keyfile = signerfile;
sk_OPENSSL_STRING_push(skkeys, keyfile);
}
if (!sksigners) {
if (sksigners == NULL) {
BIO_printf(bio_err, "No signer certificate specified\n");
goto opthelp;
}
signerfile = NULL;
keyfile = NULL;
need_rand = 1;
}
else if (operation == SMIME_DECRYPT) {
if (!recipfile && !keyfile && !secret_key && !pwri_pass) {
} else if (operation == SMIME_DECRYPT) {
if (recipfile == NULL && keyfile == NULL
&& secret_key == NULL && pwri_pass == NULL) {
BIO_printf(bio_err,
"No recipient certificate or key specified\n");
goto opthelp;
}
} else if (operation == SMIME_ENCRYPT) {
if (*argv == NULL && !secret_key && !pwri_pass && !encerts) {
if (*argv == NULL && secret_key == NULL
&& pwri_pass == NULL && encerts == NULL) {
BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n");
goto opthelp;
}
need_rand = 1;
} else if (!operation)
} else if (!operation) {
goto opthelp;
}
if (!app_passwd(passinarg, NULL, &passin, NULL)) {
BIO_printf(bio_err, "Error getting password\n");
goto end;
}
if (need_rand) {
app_RAND_load_file(NULL, (inrand != NULL));
if (inrand != NULL)
BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
app_RAND_load_files(inrand));
}
ret = 2;
if (!(operation & SMIME_SIGNERS))
flags &= ~CMS_DETACHED;
if (!(operation & SMIME_OP)) {
if (!(operation & SMIME_OP))
if (flags & CMS_BINARY)
outformat = FORMAT_BINARY;
}
if (!(operation & SMIME_IP)) {
if (!(operation & SMIME_IP))
if (flags & CMS_BINARY)
informat = FORMAT_BINARY;
}
if (operation == SMIME_ENCRYPT) {
if (!cipher) {
@@ -683,7 +672,7 @@ int cms_main(int argc, char **argv)
goto end;
}
if (*argv && !encerts)
if (*argv && encerts == NULL)
if ((encerts = sk_X509_new_null()) == NULL)
goto end;
while (*argv) {
@@ -696,7 +685,7 @@ int cms_main(int argc, char **argv)
}
}
if (certfile) {
if (certfile != NULL) {
if (!load_certs(certfile, &other, FORMAT_PEM, NULL,
"certificate file")) {
ERR_print_errors(bio_err);
@@ -704,7 +693,7 @@ int cms_main(int argc, char **argv)
}
}
if (recipfile && (operation == SMIME_DECRYPT)) {
if (recipfile != NULL && (operation == SMIME_DECRYPT)) {
if ((recip = load_cert(recipfile, FORMAT_PEM,
"recipient certificate file")) == NULL) {
ERR_print_errors(bio_err);
@@ -721,17 +710,18 @@ int cms_main(int argc, char **argv)
}
if (operation == SMIME_DECRYPT) {
if (!keyfile)
if (keyfile == NULL)
keyfile = recipfile;
} else if ((operation == SMIME_SIGN) || (operation == SMIME_SIGN_RECEIPT)) {
if (!keyfile)
if (keyfile == NULL)
keyfile = signerfile;
} else
} else {
keyfile = NULL;
}
if (keyfile) {
if (keyfile != NULL) {
key = load_key(keyfile, keyform, 0, passin, e, "signing key file");
if (!key)
if (key == NULL)
goto end;
}
@@ -740,29 +730,29 @@ int cms_main(int argc, char **argv)
goto end;
if (operation & SMIME_IP) {
if (informat == FORMAT_SMIME)
if (informat == FORMAT_SMIME) {
cms = SMIME_read_CMS(in, &indata);
else if (informat == FORMAT_PEM)
} else if (informat == FORMAT_PEM) {
cms = PEM_read_bio_CMS(in, NULL, NULL, NULL);
else if (informat == FORMAT_ASN1)
} else if (informat == FORMAT_ASN1) {
cms = d2i_CMS_bio(in, NULL);
else {
} else {
BIO_printf(bio_err, "Bad input format for CMS file\n");
goto end;
}
if (!cms) {
if (cms == NULL) {
BIO_printf(bio_err, "Error reading S/MIME message\n");
goto end;
}
if (contfile) {
if (contfile != NULL) {
BIO_free(indata);
if ((indata = BIO_new_file(contfile, "rb")) == NULL) {
BIO_printf(bio_err, "Can't read content file %s\n", contfile);
goto end;
}
}
if (certsoutfile) {
if (certsoutfile != NULL) {
STACK_OF(X509) *allcerts;
allcerts = CMS_get1_certs(cms);
if (!save_certs(certsoutfile, allcerts)) {
@@ -775,25 +765,25 @@ int cms_main(int argc, char **argv)
}
}
if (rctfile) {
if (rctfile != NULL) {
char *rctmode = (rctformat == FORMAT_ASN1) ? "rb" : "r";
if ((rctin = BIO_new_file(rctfile, rctmode)) == NULL) {
BIO_printf(bio_err, "Can't open receipt file %s\n", rctfile);
goto end;
}
if (rctformat == FORMAT_SMIME)
if (rctformat == FORMAT_SMIME) {
rcms = SMIME_read_CMS(rctin, NULL);
else if (rctformat == FORMAT_PEM)
} else if (rctformat == FORMAT_PEM) {
rcms = PEM_read_bio_CMS(rctin, NULL, NULL, NULL);
else if (rctformat == FORMAT_ASN1)
} else if (rctformat == FORMAT_ASN1) {
rcms = d2i_CMS_bio(rctin, NULL);
else {
} else {
BIO_printf(bio_err, "Bad input format for receipt\n");
goto end;
}
if (!rcms) {
if (rcms == NULL) {
BIO_printf(bio_err, "Error reading receipt\n");
goto end;
}
@@ -823,7 +813,7 @@ int cms_main(int argc, char **argv)
int i;
flags |= CMS_PARTIAL;
cms = CMS_encrypt(NULL, in, cipher, flags);
if (!cms)
if (cms == NULL)
goto end;
for (i = 0; i < sk_X509_num(encerts); i++) {
CMS_RecipientInfo *ri;
@@ -837,9 +827,9 @@ int cms_main(int argc, char **argv)
}
}
ri = CMS_add1_recipient_cert(cms, x, tflags);
if (!ri)
if (ri == NULL)
goto end;
if (kparam) {
if (kparam != NULL) {
EVP_PKEY_CTX *pctx;
pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
if (!cms_set_pkey_param(pctx, kparam->param))
@@ -853,7 +843,7 @@ int cms_main(int argc, char **argv)
}
}
if (secret_key) {
if (secret_key != NULL) {
if (!CMS_add0_recipient_key(cms, NID_undef,
secret_key, secret_keylen,
secret_keyid, secret_keyidlen,
@@ -863,13 +853,13 @@ int cms_main(int argc, char **argv)
secret_key = NULL;
secret_keyid = NULL;
}
if (pwri_pass) {
if (pwri_pass != NULL) {
pwri_tmp = (unsigned char *)OPENSSL_strdup((char *)pwri_pass);
if (!pwri_tmp)
if (pwri_tmp == NULL)
goto end;
if (!CMS_add0_recipient_password(cms,
-1, NID_undef, NID_undef,
pwri_tmp, -1, NULL))
if (CMS_add0_recipient_password(cms,
-1, NID_undef, NID_undef,
pwri_tmp, -1, NULL) == NULL)
goto end;
pwri_tmp = NULL;
}
@@ -886,11 +876,11 @@ int cms_main(int argc, char **argv)
STACK_OF(CMS_SignerInfo) *sis;
CMS_SignerInfo *si;
sis = CMS_get0_SignerInfos(cms);
if (!sis)
if (sis == NULL)
goto end;
si = sk_CMS_SignerInfo_value(sis, 0);
srcms = CMS_sign_receipt(si, signer, key, other, flags);
if (!srcms)
if (srcms == NULL)
goto end;
CMS_ContentInfo_free(cms);
cms = srcms;
@@ -908,21 +898,22 @@ int cms_main(int argc, char **argv)
}
flags |= CMS_PARTIAL;
cms = CMS_sign(NULL, NULL, other, in, flags);
if (!cms)
if (cms == NULL)
goto end;
if (econtent_type)
if (econtent_type != NULL)
CMS_set1_eContentType(cms, econtent_type);
if (rr_to) {
if (rr_to != NULL) {
rr = make_receipt_request(rr_to, rr_allorfirst, rr_from);
if (!rr) {
if (rr == NULL) {
BIO_puts(bio_err,
"Signed Receipt Request Creation Error\n");
goto end;
}
}
} else
} else {
flags |= CMS_REUSE_DIGEST;
}
for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++) {
CMS_SignerInfo *si;
cms_key_param *kparam;
@@ -931,12 +922,12 @@ int cms_main(int argc, char **argv)
keyfile = sk_OPENSSL_STRING_value(skkeys, i);
signer = load_cert(signerfile, FORMAT_PEM, "signer certificate");
if (!signer) {
if (signer == NULL) {
ret = 2;
goto end;
}
key = load_key(keyfile, keyform, 0, passin, e, "signing key file");
if (!key) {
if (key == NULL) {
ret = 2;
goto end;
}
@@ -947,15 +938,15 @@ int cms_main(int argc, char **argv)
}
}
si = CMS_add1_signer(cms, signer, key, sign_md, tflags);
if (!si)
if (si == NULL)
goto end;
if (kparam) {
if (kparam != NULL) {
EVP_PKEY_CTX *pctx;
pctx = CMS_SignerInfo_get0_pkey_ctx(si);
if (!cms_set_pkey_param(pctx, kparam->param))
goto end;
}
if (rr && !CMS_add1_ReceiptRequest(si, rr))
if (rr != NULL && !CMS_add1_ReceiptRequest(si, rr))
goto end;
X509_free(signer);
signer = NULL;
@@ -969,7 +960,7 @@ int cms_main(int argc, char **argv)
}
}
if (!cms) {
if (cms == NULL) {
BIO_printf(bio_err, "Error creating CMS structure\n");
goto end;
}
@@ -979,7 +970,7 @@ int cms_main(int argc, char **argv)
if (flags & CMS_DEBUG_DECRYPT)
CMS_decrypt(cms, NULL, NULL, NULL, NULL, flags);
if (secret_key) {
if (secret_key != NULL) {
if (!CMS_decrypt_set1_key(cms,
secret_key, secret_keylen,
secret_keyid, secret_keyidlen)) {
@@ -988,14 +979,14 @@ int cms_main(int argc, char **argv)
}
}
if (key) {
if (key != NULL) {
if (!CMS_decrypt_set1_pkey(cms, key, recip)) {
BIO_puts(bio_err, "Error decrypting CMS using private key\n");
goto end;
}
}
if (pwri_pass) {
if (pwri_pass != NULL) {
if (!CMS_decrypt_set1_password(cms, pwri_pass, -1)) {
BIO_puts(bio_err, "Error decrypting CMS using password\n");
goto end;
@@ -1013,9 +1004,9 @@ int cms_main(int argc, char **argv)
if (!CMS_uncompress(cms, indata, out, flags))
goto end;
} else if (operation == SMIME_DIGEST_VERIFY) {
if (CMS_digest_verify(cms, indata, out, flags) > 0)
if (CMS_digest_verify(cms, indata, out, flags) > 0) {
BIO_printf(bio_err, "Verification successful\n");
else {
} else {
BIO_printf(bio_err, "Verification failure\n");
goto end;
}
@@ -1024,15 +1015,15 @@ int cms_main(int argc, char **argv)
indata, out, flags))
goto end;
} else if (operation == SMIME_VERIFY) {
if (CMS_verify(cms, other, store, indata, out, flags) > 0)
if (CMS_verify(cms, other, store, indata, out, flags) > 0) {
BIO_printf(bio_err, "Verification successful\n");
else {
} else {
BIO_printf(bio_err, "Verification failure\n");
if (verify_retcode)
ret = verify_err + 32;
goto end;
}
if (signerfile) {
if (signerfile != NULL) {
STACK_OF(X509) *signers;
signers = CMS_get0_signers(cms);
if (!save_certs(signerfile, signers)) {
@@ -1047,9 +1038,9 @@ int cms_main(int argc, char **argv)
receipt_request_print(cms);
} else if (operation == SMIME_VERIFY_RECEIPT) {
if (CMS_verify_receipt(rcms, cms, other, store, flags) > 0)
if (CMS_verify_receipt(rcms, cms, other, store, flags) > 0) {
BIO_printf(bio_err, "Verification successful\n");
else {
} else {
BIO_printf(bio_err, "Verification failure\n");
goto end;
}
@@ -1068,11 +1059,11 @@ int cms_main(int argc, char **argv)
ret = SMIME_write_CMS(out, cms, indata, flags);
else
ret = SMIME_write_CMS(out, cms, in, flags);
} else if (outformat == FORMAT_PEM)
} else if (outformat == FORMAT_PEM) {
ret = PEM_write_bio_CMS_stream(out, cms, in, flags);
else if (outformat == FORMAT_ASN1)
} else if (outformat == FORMAT_ASN1) {
ret = i2d_CMS_bio_stream(out, cms, in, flags);
else {
} else {
BIO_printf(bio_err, "Bad output format for CMS file\n");
goto end;
}
@@ -1085,8 +1076,6 @@ int cms_main(int argc, char **argv)
end:
if (ret)
ERR_print_errors(bio_err);
if (need_rand)
app_RAND_write_file(NULL);
sk_X509_pop_free(encerts, X509_free);
sk_X509_pop_free(other, X509_free);
X509_VERIFY_PARAM_free(vpm);
@@ -1119,17 +1108,17 @@ int cms_main(int argc, char **argv)
BIO_free(indata);
BIO_free_all(out);
OPENSSL_free(passin);
return (ret);
return ret;
}
static int save_certs(char *signerfile, STACK_OF(X509) *signers)
{
int i;
BIO *tmp;
if (!signerfile)
if (signerfile == NULL)
return 1;
tmp = BIO_new_file(signerfile, "w");
if (!tmp)
if (tmp == NULL)
return 0;
for (i = 0; i < sk_X509_num(signers); i++)
PEM_write_bio_X509(tmp, sk_X509_value(signers, i));
@@ -1189,9 +1178,9 @@ static void receipt_request_print(CMS_ContentInfo *cms)
si = sk_CMS_SignerInfo_value(sis, i);
rv = CMS_get1_ReceiptRequest(si, &rr);
BIO_printf(bio_err, "Signer %d:\n", i + 1);
if (rv == 0)
if (rv == 0) {
BIO_puts(bio_err, " No Receipt Request\n");
else if (rv < 0) {
} else if (rv < 0) {
BIO_puts(bio_err, " Receipt Request Parse Error\n");
ERR_print_errors(bio_err);
} else {
@@ -1204,15 +1193,16 @@ static void receipt_request_print(CMS_ContentInfo *cms)
id = (const char *)ASN1_STRING_get0_data(scid);
BIO_dump_indent(bio_err, id, idlen, 4);
BIO_puts(bio_err, " Receipts From");
if (rlist) {
if (rlist != NULL) {
BIO_puts(bio_err, " List:\n");
gnames_stack_print(rlist);
} else if (allorfirst == 1)
} else if (allorfirst == 1) {
BIO_puts(bio_err, ": First Tier\n");
else if (allorfirst == 0)
} else if (allorfirst == 0) {
BIO_puts(bio_err, ": All\n");
else
} else {
BIO_printf(bio_err, " Unknown (%d)\n", allorfirst);
}
BIO_puts(bio_err, " Receipts To:\n");
gnames_stack_print(rto);
}
@@ -1227,12 +1217,12 @@ static STACK_OF(GENERAL_NAMES) *make_names_stack(STACK_OF(OPENSSL_STRING) *ns)
GENERAL_NAMES *gens = NULL;
GENERAL_NAME *gen = NULL;
ret = sk_GENERAL_NAMES_new_null();
if (!ret)
if (ret == NULL)
goto err;
for (i = 0; i < sk_OPENSSL_STRING_num(ns); i++) {
char *str = sk_OPENSSL_STRING_value(ns, i);
gen = a2i_GENERAL_NAME(NULL, NULL, NULL, GEN_EMAIL, str, 0);
if (!gen)
if (gen == NULL)
goto err;
gens = GENERAL_NAMES_new();
if (gens == NULL)
@@ -1261,14 +1251,15 @@ static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING)
STACK_OF(GENERAL_NAMES) *rct_to = NULL, *rct_from = NULL;
CMS_ReceiptRequest *rr;
rct_to = make_names_stack(rr_to);
if (!rct_to)
if (rct_to == NULL)
goto err;
if (rr_from) {
if (rr_from != NULL) {
rct_from = make_names_stack(rr_from);
if (!rct_from)
if (rct_from == NULL)
goto err;
} else
} else {
rct_from = NULL;
}
rr = CMS_ReceiptRequest_create0(NULL, -1, rr_allorfirst, rct_from,
rct_to);
return rr;
+7 -12
View File
@@ -1,5 +1,5 @@
/*
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2018 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
@@ -11,6 +11,7 @@
#include <stdlib.h>
#include <string.h>
#include "apps.h"
#include "progs.h"
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/x509.h>
@@ -26,7 +27,7 @@ typedef enum OPTION_choice {
OPT_NOOUT, OPT_NAMEOPT, OPT_MD
} OPTION_CHOICE;
OPTIONS crl_options[] = {
const OPTIONS crl_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"inform", OPT_INFORM, 'F', "Input format; default PEM"},
{"in", OPT_IN, '<', "Input file - default stdin"},
@@ -69,8 +70,6 @@ int crl_main(int argc, char **argv)
X509_OBJECT *xobj = NULL;
EVP_PKEY *pkey;
const EVP_MD *digest = EVP_sha1();
unsigned long nmflag = 0;
char nmflag_set = 0;
char *infile = NULL, *outfile = NULL, *crldiff = NULL, *keyfile = NULL;
const char *CAfile = NULL, *CApath = NULL, *prog;
OPTION_CHOICE o;
@@ -169,8 +168,7 @@ int crl_main(int argc, char **argv)
badsig = 1;
break;
case OPT_NAMEOPT:
nmflag_set = 1;
if (!set_name_ex(&nmflag, opt_arg()))
if (!set_nameopt(opt_arg()))
goto opthelp;
break;
case OPT_MD:
@@ -182,9 +180,6 @@ int crl_main(int argc, char **argv)
if (argc != 0)
goto opthelp;
if (!nmflag_set)
nmflag = XN_FLAG_ONELINE;
x = load_crl(infile, informat);
if (x == NULL)
goto end;
@@ -260,7 +255,7 @@ int crl_main(int argc, char **argv)
for (i = 1; i <= num; i++) {
if (issuer == i) {
print_name(bio_out, "issuer=", X509_CRL_get_issuer(x),
nmflag);
get_nameopt());
}
if (crlnumber == i) {
ASN1_INTEGER *crlnum;
@@ -319,7 +314,7 @@ int crl_main(int argc, char **argv)
goto end;
if (text)
X509_CRL_print(out, x);
X509_CRL_print_ex(out, x, get_nameopt());
if (noout) {
ret = 0;
@@ -343,5 +338,5 @@ int crl_main(int argc, char **argv)
X509_CRL_free(x);
X509_STORE_CTX_free(ctx);
X509_STORE_free(store);
return (ret);
return ret;
}
+6 -5
View File
@@ -1,5 +1,5 @@
/*
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2018 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
@@ -11,6 +11,7 @@
#include <string.h>
#include <sys/types.h>
#include "apps.h"
#include "progs.h"
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
@@ -25,7 +26,7 @@ typedef enum OPTION_choice {
OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_NOCRL, OPT_CERTFILE
} OPTION_CHOICE;
OPTIONS crl2pkcs7_options[] = {
const OPTIONS crl2pkcs7_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"inform", OPT_INFORM, 'F', "Input format - DER or PEM"},
{"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"},
@@ -131,7 +132,7 @@ int crl2pkcs7_main(int argc, char **argv)
goto end;
p7s->cert = cert_stack;
if (certflst)
if (certflst != NULL)
for (i = 0; i < sk_OPENSSL_STRING_num(certflst); i++) {
certfile = sk_OPENSSL_STRING_value(certflst, i);
if (add_certs_from_file(cert_stack, certfile) < 0) {
@@ -162,7 +163,7 @@ int crl2pkcs7_main(int argc, char **argv)
PKCS7_free(p7);
X509_CRL_free(crl);
return (ret);
return ret;
}
/*-
@@ -212,5 +213,5 @@ static int add_certs_from_file(STACK_OF(X509) *stack, char *certfile)
/* never need to OPENSSL_free x */
BIO_free(in);
sk_X509_INFO_free(sk);
return (ret);
return ret;
}
+8 -33
View File
@@ -1,34 +1,9 @@
enabled_logs=pilot,aviator,rocketeer,digicert,certly,izempe,symantec,venafi
[pilot]
description = Google Pilot Log
key = MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEfahLEimAoz2t01p3uMziiLOl/fHTDM0YDOhBRuiBARsV4UvxG2LdNgoIGLrtCzWE0J5APC2em4JlvR8EEEFMoA==
[aviator]
description = Google Aviator log
key = MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE1/TMabLkDpCjiupacAlP7xNi0I1JYP8bQFAHDG1xhtolSY1l4QgNRzRrvSe8liE+NPWHdjGxfx3JhTsN9x8/6Q==
[rocketeer]
description = Google Rocketeer log
key = MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIFsYyDzBi7MxCAC/oJBXK7dHjG+1aLCOkHjpoHPqTyghLpzA9BYbqvnV16mAw04vUjyYASVGJCUoI3ctBcJAeg==
[digicert]
description = DigiCert Log Server
key = MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEAkbFvhu7gkAW6MHSrBlpE1n4+HCFRkC5OLAjgqhkTH+/uzSfSl8ois8ZxAD2NgaTZe1M9akhYlrYkes4JECs6A==
[certly]
description = Certly.IO log
key = MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAECyPLhWKYYUgEc+tUXfPQB4wtGS2MNvXrjwFCCnyYJifBtd2Sk7Cu+Js9DNhMTh35FftHaHu6ZrclnNBKwmbbSA==
[izempe]
description = Izempe log
key = MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEJ2Q5DC3cUBj4IQCiDu0s6j51up+TZAkAEcQRF6tczw90rLWXkJMAW7jr9yc92bIKgV8vDXU4lDeZHvYHduDuvg==
[symantec]
description = Symantec log
key = MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEluqsHEYMG1XcDfy1lCdGV0JwOmkY4r87xNuroPS2bMBTP01CEDPwWJePa75y9CrsHEKqAy8afig1dpkIPSEUhg==
[venafi]
description = Venafi log
key = MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAolpIHxdSlTXLo1s6H1OCdpSj/4DyHDc8wLG9wVmLqy1lk9fz4ATVmm+/1iN2Nk8jmctUKK2MFUtlWXZBSpym97M7frGlSaQXUWyA3CqQUEuIJOmlEjKTBEiQAvpfDjCHjlV2Be4qTM6jamkJbiWtgnYPhJL6ONaGTiSPm7Byy57iaz/hbckldSOIoRhYBiMzeNoA0DiRZ9KmfSeXZ1rB8y8X5urSW+iBzf2SaOfzBvDpcoTuAaWx2DPazoOl28fP1hZ+kHUYvxbcMjttjauCFx+JII0dmuZNIwjfeG/GBb9frpSX219k1O4Wi6OEbHEr8at/XQ0y7gTikOxBn/s5wQIDAQAB
# This file specifies the Certificate Transparency logs
# that are to be trusted.
# Google's list of logs can be found here:
# www.certificate-transparency.org/known-logs
# A Python program to convert the log list to OpenSSL's format can be
# found here:
# https://github.com/google/certificate-transparency/blob/master/python/utilities/log_list/print_log_list.py
# Use the "--openssl_output" flag.
-14
View File
@@ -1,14 +0,0 @@
subject=/C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo server
issuer= /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA
-----BEGIN X509 CERTIFICATE-----
MIIBgjCCASwCAQQwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV
BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MTAwOTIz
MzIwNVoXDTk4MDcwNTIzMzIwNVowYDELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM
RDEZMBcGA1UEChMQTWluY29tIFB0eS4gTHRkLjELMAkGA1UECxMCQ1MxGzAZBgNV
BAMTElNTTGVheSBkZW1vIHNlcnZlcjBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC3
LCXcScWua0PFLkHBLm2VejqpA1F4RQ8q0VjRiPafjx/Z/aWH3ipdMVvuJGa/wFXb
/nDFLDlfWp+oCPwhBtVPAgMBAAEwDQYJKoZIhvcNAQEEBQADQQArNFsihWIjBzb0
DCsU0BvL2bvSwJrPEqFlkDq3F4M6EGutL9axEcANWgbbEdAvNJD1dmEmoWny27Pn
IMs6ZOZB
-----END X509 CERTIFICATE-----
-39
View File
@@ -1,39 +0,0 @@
R 980705233205Z 951009233205Z 01 certs/00000001 /CN=Eric Young
E 951009233205Z 02 certs/00000002 /CN=Duncan Young
R 980705233205Z 951201010000Z 03 certs/00000003 /CN=Tim Hudson
V 980705233205Z 04 certs/00000004 /CN=Eric Young4
V 980705233205Z 05 certs/00000004 /CN=Eric Young5
V 980705233205Z 06 certs/00000004 /CN=Eric Young6
V 980705233205Z 07 certs/00000004 /CN=Eric Young7
V 980705233205Z 08 certs/00000004 /CN=Eric Young8
V 980705233205Z 09 certs/00000004 /CN=Eric Young9
V 980705233205Z 0A certs/00000004 /CN=Eric YoungA
V 980705233205Z 0B certs/00000004 /CN=Eric YoungB
V 980705233205Z 0C certs/00000004 /CN=Eric YoungC
V 980705233205Z 0D certs/00000004 /CN=Eric YoungD
V 980705233205Z 0E certs/00000004 /CN=Eric YoungE
V 980705233205Z 0F certs/00000004 /CN=Eric YoungF
V 980705233205Z 10 certs/00000004 /CN=Eric Young10
V 980705233205Z 11 certs/00000004 /CN=Eric Young11
V 980705233205Z 12 certs/00000004 /CN=Eric Young12
V 980705233205Z 13 certs/00000004 /CN=Eric Young13
V 980705233205Z 14 certs/00000004 /CN=Eric Young14
V 980705233205Z 15 certs/00000004 /CN=Eric Young15
V 980705233205Z 16 certs/00000004 /CN=Eric Young16
V 980705233205Z 17 certs/00000004 /CN=Eric Young17
V 961206150305Z 010C unknown /C=AU/SP=QLD/O=Mincom Pty. Ltd./OU=MTR/CN=Eric Young/Email=eay@mincom.oz.au
V 961206153245Z 010D unknown /C=AU/SP=Queensland/O=Mincom Pty Ltd/OU=MTR/CN=Eric Young/Email=eay@mincom.oz.au
V 970322074816Z 010E unknown /CN=Eric Young/Email=eay@mincom.oz.au
V 970322075152Z 010F unknown /CN=Eric Young
V 970322075906Z 0110 unknown /CN=Eric Youngg
V 970324092238Z 0111 unknown /C=AU/SP=Queensland/CN=Eric Young
V 970324221931Z 0112 unknown /CN=Fred
V 970324224934Z 0113 unknown /C=AU/CN=eay
V 971001005237Z 0114 unknown /C=AU/SP=QLD/O=Mincom Pty Ltd/OU=MTR/CN=x509v3 test
V 971001010331Z 0115 unknown /C=AU/SP=Queensland/O=Mincom Pty Ltd/OU=MTR/CN=test again - x509v3
V 971001013945Z 0117 unknown /C=AU/SP=Queensland/O=Mincom Pty Ltd/OU=MTR/CN=x509v3 test
V 971014225415Z 0118 unknown /C=AU/SP=Queensland/CN=test
V 971015004448Z 0119 unknown /C=AU/SP=Queensland/O=Mincom Pty Ltd/OU=MTR/CN=test2
V 971016035001Z 011A unknown /C=AU/SP=Queensland/O=Mincom Pty Ltd/OU=MTR/CN=test64
V 971016080129Z 011B unknown /C=FR/O=ALCATEL/OU=Alcatel Mobile Phones/CN=bourque/Email=bourque@art.alcatel.fr
V 971016224000Z 011D unknown /L=Bedford/O=Cranfield University/OU=Computer Centre/CN=Peter R Lister/Email=P.Lister@cranfield.ac.uk
-24
View File
@@ -1,24 +0,0 @@
issuer= /C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=CA
subject=/C=AU/SOP=QLD/O=Mincom Pty. Ltd./OU=CS/CN=SSLeay demo server
-----BEGIN X509 CERTIFICATE-----
MIIBgjCCASwCAQQwDQYJKoZIhvcNAQEEBQAwODELMAkGA1UEBhMCQVUxDDAKBgNV
BAgTA1FMRDEbMBkGA1UEAxMSU1NMZWF5L3JzYSB0ZXN0IENBMB4XDTk1MTAwOTIz
MzIwNVoXDTk4MDcwNTIzMzIwNVowYDELMAkGA1UEBhMCQVUxDDAKBgNVBAgTA1FM
RDEZMBcGA1UEChMQTWluY29tIFB0eS4gTHRkLjELMAkGA1UECxMCQ1MxGzAZBgNV
BAMTElNTTGVheSBkZW1vIHNlcnZlcjBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC3
LCXcScWua0PFLkHBLm2VejqpA1F4RQ8q0VjRiPafjx/Z/aWH3ipdMVvuJGa/wFXb
/nDFLDlfWp+oCPwhBtVPAgMBAAEwDQYJKoZIhvcNAQEEBQADQQArNFsihWIjBzb0
DCsU0BvL2bvSwJrPEqFlkDq3F4M6EGutL9axEcANWgbbEdAvNJD1dmEmoWny27Pn
IMs6ZOZB
-----END X509 CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
MIIBPAIBAAJBALcsJdxJxa5rQ8UuQcEubZV6OqkDUXhFDyrRWNGI9p+PH9n9pYfe
Kl0xW+4kZr/AVdv+cMUsOV9an6gI/CEG1U8CAwEAAQJAXJMBZ34ZXHd1vtgL/3hZ
hexKbVTx/djZO4imXO/dxPGRzG2ylYZpHmG32/T1kaHpZlCHoEPgHoSzmxYXfxjG
sQIhAPmZ/bQOjmRUHM/VM2X5zrjjM6z18R1P6l3ObFwt9FGdAiEAu943Yh9SqMRw
tL0xHGxKmM/YJueUw1gB6sLkETN71NsCIQCeT3RhoqXfrpXDoEcEU+gwzjI1bpxq
agiNTOLfqGoA5QIhAIQFYjgzONxex7FLrsKBm16N2SFl5pXsN9SpRqqL2n63AiEA
g9VNIQ3xwpw7og3IbONifeku+J9qGMGQJMKwSTwrFtI=
-----END RSA PRIVATE KEY-----
-1
View File
@@ -1 +0,0 @@
011E
+40 -39
View File
@@ -1,5 +1,5 @@
/*
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2018 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
@@ -11,6 +11,7 @@
#include <string.h>
#include <stdlib.h>
#include "apps.h"
#include "progs.h"
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/evp.h>
@@ -29,22 +30,21 @@ int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_C, OPT_R, OPT_RAND, OPT_OUT, OPT_SIGN, OPT_PASSIN, OPT_VERIFY,
OPT_C, OPT_R, OPT_OUT, OPT_SIGN, OPT_PASSIN, OPT_VERIFY,
OPT_PRVERIFY, OPT_SIGNATURE, OPT_KEYFORM, OPT_ENGINE, OPT_ENGINE_IMPL,
OPT_HEX, OPT_BINARY, OPT_DEBUG, OPT_FIPS_FINGERPRINT,
OPT_HMAC, OPT_MAC, OPT_SIGOPT, OPT_MACOPT,
OPT_DIGEST
OPT_DIGEST,
OPT_R_ENUM
} OPTION_CHOICE;
OPTIONS dgst_options[] = {
const OPTIONS dgst_options[] = {
{OPT_HELP_STR, 1, '-', "Usage: %s [options] [file...]\n"},
{OPT_HELP_STR, 1, '-',
" file... files to digest (default is stdin)\n"},
{"help", OPT_HELP, '-', "Display this summary"},
{"c", OPT_C, '-', "Print the digest with separating colons"},
{"r", OPT_R, '-', "Print the digest in coreutils format"},
{"rand", OPT_RAND, 's',
"Use file(s) containing random data to seed RNG or an EGD sock"},
{"out", OPT_OUT, '>', "Output to filename rather than stdout"},
{"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
{"sign", OPT_SIGN, 's', "Sign digest using private key"},
@@ -65,6 +65,7 @@ OPTIONS dgst_options[] = {
{"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"},
{"macopt", OPT_MACOPT, 's', "MAC algorithm parameters in n:v form or key"},
{"", OPT_DIGEST, '-', "Any supported digest"},
OPT_R_OPTIONS,
#ifndef OPENSSL_NO_ENGINE
{"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"},
{"engine_impl", OPT_ENGINE_IMPL, '-',
@@ -84,7 +85,7 @@ int dgst_main(int argc, char **argv)
char *passinarg = NULL, *passin = NULL;
const EVP_MD *md = NULL, *m;
const char *outfile = NULL, *keyfile = NULL, *prog = NULL;
const char *sigfile = NULL, *randfile = NULL;
const char *sigfile = NULL;
OPTION_CHOICE o;
int separator = 0, debug = 0, keyform = FORMAT_PEM, siglen = 0;
int i, ret = 1, out_bin = -1, want_pub = 0, do_verify = 0;
@@ -113,8 +114,9 @@ int dgst_main(int argc, char **argv)
case OPT_R:
separator = 2;
break;
case OPT_RAND:
randfile = opt_arg();
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
case OPT_OUT:
outfile = opt_arg();
@@ -190,7 +192,7 @@ int dgst_main(int argc, char **argv)
goto end;
}
if (do_verify && !sigfile) {
if (do_verify && sigfile == NULL) {
BIO_printf(bio_err,
"No signature to verify: use the -signature option\n");
goto end;
@@ -217,30 +219,27 @@ int dgst_main(int argc, char **argv)
}
if (out_bin == -1) {
if (keyfile)
if (keyfile != NULL)
out_bin = 1;
else
out_bin = 0;
}
if (randfile)
app_RAND_load_file(randfile, 0);
out = bio_open_default(outfile, 'w', out_bin ? FORMAT_BINARY : FORMAT_TEXT);
if (out == NULL)
goto end;
if ((! !mac_name + ! !keyfile + ! !hmac_key) > 1) {
if ((!(mac_name == NULL) + !(keyfile == NULL) + !(hmac_key == NULL)) > 1) {
BIO_printf(bio_err, "MAC and Signing key cannot both be specified\n");
goto end;
}
if (keyfile) {
if (keyfile != NULL) {
if (want_pub)
sigkey = load_pubkey(keyfile, keyform, 0, NULL, e, "key file");
else
sigkey = load_key(keyfile, keyform, 0, passin, e, "key file");
if (!sigkey) {
if (sigkey == NULL) {
/*
* load_[pub]key() has already printed an appropriate message
*/
@@ -248,12 +247,12 @@ int dgst_main(int argc, char **argv)
}
}
if (mac_name) {
if (mac_name != NULL) {
EVP_PKEY_CTX *mac_ctx = NULL;
int r = 0;
if (!init_gen_str(&mac_ctx, mac_name, impl, 0))
goto mac_end;
if (macopts) {
if (macopts != NULL) {
char *macopt;
for (i = 0; i < sk_OPENSSL_STRING_num(macopts); i++) {
macopt = sk_OPENSSL_STRING_value(macopts, i);
@@ -277,14 +276,14 @@ int dgst_main(int argc, char **argv)
goto end;
}
if (hmac_key) {
if (hmac_key != NULL) {
sigkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, impl,
(unsigned char *)hmac_key, -1);
if (!sigkey)
if (sigkey == NULL)
goto end;
}
if (sigkey) {
if (sigkey != NULL) {
EVP_MD_CTX *mctx = NULL;
EVP_PKEY_CTX *pctx = NULL;
int r;
@@ -302,7 +301,7 @@ int dgst_main(int argc, char **argv)
ERR_print_errors(bio_err);
goto end;
}
if (sigopts) {
if (sigopts != NULL) {
char *sigopt;
for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) {
sigopt = sk_OPENSSL_STRING_value(sigopts, i);
@@ -331,9 +330,9 @@ int dgst_main(int argc, char **argv)
}
}
if (sigfile && sigkey) {
if (sigfile != NULL && sigkey != NULL) {
BIO *sigbio = BIO_new_file(sigfile, "rb");
if (!sigbio) {
if (sigbio == NULL) {
BIO_printf(bio_err, "Error opening signature file %s\n", sigfile);
ERR_print_errors(bio_err);
goto end;
@@ -363,14 +362,14 @@ int dgst_main(int argc, char **argv)
} else {
const char *md_name = NULL, *sig_name = NULL;
if (!out_bin) {
if (sigkey) {
if (sigkey != NULL) {
const EVP_PKEY_ASN1_METHOD *ameth;
ameth = EVP_PKEY_get0_asn1(sigkey);
if (ameth)
EVP_PKEY_asn1_get0_info(NULL, NULL,
NULL, NULL, &sig_name, ameth);
}
if (md)
if (md != NULL)
md_name = EVP_MD_name(md);
}
ret = 0;
@@ -380,9 +379,10 @@ int dgst_main(int argc, char **argv)
perror(argv[i]);
ret++;
continue;
} else
} else {
r = do_fp(out, buf, inp, separator, out_bin, sigkey, sigbuf,
siglen, sig_name, md_name, argv[i]);
}
if (r)
ret = r;
(void)BIO_reset(bmd);
@@ -399,7 +399,7 @@ int dgst_main(int argc, char **argv)
OPENSSL_free(sigbuf);
BIO_free(bmd);
release_engine(e);
return (ret);
return ret;
}
int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
@@ -420,13 +420,13 @@ int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
if (i == 0)
break;
}
if (sigin) {
if (sigin != NULL) {
EVP_MD_CTX *ctx;
BIO_get_md_ctx(bp, &ctx);
i = EVP_DigestVerifyFinal(ctx, sigin, (unsigned int)siglen);
if (i > 0)
if (i > 0) {
BIO_printf(out, "Verified OK\n");
else if (i == 0) {
} else if (i == 0) {
BIO_printf(out, "Verification Failure\n");
return 1;
} else {
@@ -436,7 +436,7 @@ int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
}
return 0;
}
if (key) {
if (key != NULL) {
EVP_MD_CTX *ctx;
BIO_get_md_ctx(bp, &ctx);
len = BUFSIZE;
@@ -453,22 +453,23 @@ int do_fp(BIO *out, unsigned char *buf, BIO *bp, int sep, int binout,
}
}
if (binout)
if (binout) {
BIO_write(out, buf, len);
else if (sep == 2) {
} else if (sep == 2) {
for (i = 0; i < (int)len; i++)
BIO_printf(out, "%02x", buf[i]);
BIO_printf(out, " *%s\n", file);
} else {
if (sig_name) {
if (sig_name != NULL) {
BIO_puts(out, sig_name);
if (md_name)
if (md_name != NULL)
BIO_printf(out, "-%s", md_name);
BIO_printf(out, "(%s)= ", file);
} else if (md_name)
} else if (md_name != NULL) {
BIO_printf(out, "%s(%s)= ", md_name, file);
else
} else {
BIO_printf(out, "(%s)= ", file);
}
for (i = 0; i < (int)len; i++) {
if (sep && (i != 0))
BIO_printf(out, ":");
+15 -20
View File
@@ -1,5 +1,5 @@
/*
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2018 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
@@ -17,6 +17,7 @@ NON_EMPTY_TRANSLATION_UNIT
# include <time.h>
# include <string.h>
# include "apps.h"
# include "progs.h"
# include <openssl/bio.h>
# include <openssl/err.h>
# include <openssl/bn.h>
@@ -36,10 +37,11 @@ typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT,
OPT_ENGINE, OPT_CHECK, OPT_TEXT, OPT_NOOUT,
OPT_RAND, OPT_DSAPARAM, OPT_C, OPT_2, OPT_5
OPT_DSAPARAM, OPT_C, OPT_2, OPT_5,
OPT_R_ENUM
} OPTION_CHOICE;
OPTIONS dhparam_options[] = {
const OPTIONS dhparam_options[] = {
{OPT_HELP_STR, 1, '-', "Usage: %s [flags] [numbits]\n"},
{OPT_HELP_STR, 1, '-', "Valid options are:\n"},
{"help", OPT_HELP, '-', "Display this summary"},
@@ -50,8 +52,7 @@ OPTIONS dhparam_options[] = {
{"check", OPT_CHECK, '-', "Check the DH parameters"},
{"text", OPT_TEXT, '-', "Print a text form of the DH parameters"},
{"noout", OPT_NOOUT, '-', "Don't output any DH parameters"},
{"rand", OPT_RAND, 's',
"Load the file(s) into the random number generator"},
OPT_R_OPTIONS,
{"C", OPT_C, '-', "Print C code"},
{"2", OPT_2, '-', "Generate parameters using 2 as the generator value"},
{"5", OPT_5, '-', "Generate parameters using 5 as the generator value"},
@@ -69,7 +70,7 @@ int dhparam_main(int argc, char **argv)
{
BIO *in = NULL, *out = NULL;
DH *dh = NULL;
char *infile = NULL, *outfile = NULL, *prog, *inrand = NULL;
char *infile = NULL, *outfile = NULL, *prog;
ENGINE *e = NULL;
#ifndef OPENSSL_NO_DSA
int dsaparam = 0;
@@ -130,15 +131,16 @@ int dhparam_main(int argc, char **argv)
case OPT_NOOUT:
noout = 1;
break;
case OPT_RAND:
inrand = opt_arg();
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
}
}
argc = opt_num_rest();
argv = opt_rest();
if (argv[0] && (!opt_int(argv[0], &num) || num <= 0))
if (argv[0] != NULL && (!opt_int(argv[0], &num) || num <= 0))
goto end;
if (g && !num)
@@ -165,13 +167,6 @@ int dhparam_main(int argc, char **argv)
}
BN_GENCB_set(cb, dh_cb, bio_err);
if (!app_RAND_load_file(NULL, 1) && inrand == NULL) {
BIO_printf(bio_err,
"warning, not much extra random data, consider using the -rand option\n");
}
if (inrand != NULL)
BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
app_RAND_load_files(inrand));
# ifndef OPENSSL_NO_DSA
if (dsaparam) {
@@ -211,7 +206,6 @@ int dhparam_main(int argc, char **argv)
}
BN_GENCB_free(cb);
app_RAND_write_file(NULL);
} else {
in = bio_open_default(infile, 'r', informat);
@@ -354,10 +348,11 @@ int dhparam_main(int argc, char **argv)
i = i2d_DHxparams_bio(out, dh);
else
i = i2d_DHparams_bio(out, dh);
} else if (q != NULL)
} else if (q != NULL) {
i = PEM_write_bio_DHxparams(out, dh);
else
} else {
i = PEM_write_bio_DHparams(out, dh);
}
if (!i) {
BIO_printf(bio_err, "unable to write DH parameters\n");
ERR_print_errors(bio_err);
@@ -370,7 +365,7 @@ int dhparam_main(int argc, char **argv)
BIO_free_all(out);
DH_free(dh);
release_engine(e);
return (ret);
return ret;
}
static int dh_cb(int p, int n, BN_GENCB *cb)
+11 -11
View File
@@ -1,5 +1,5 @@
/*
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2018 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
@@ -17,6 +17,7 @@ NON_EMPTY_TRANSLATION_UNIT
# include <string.h>
# include <time.h>
# include "apps.h"
# include "progs.h"
# include <openssl/bio.h>
# include <openssl/err.h>
# include <openssl/dsa.h>
@@ -34,7 +35,7 @@ typedef enum OPTION_choice {
OPT_PUBOUT, OPT_CIPHER, OPT_PASSIN, OPT_PASSOUT
} OPTION_CHOICE;
OPTIONS dsa_options[] = {
const OPTIONS dsa_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"inform", OPT_INFORM, 'f', "Input format, DER PEM PVK"},
{"outform", OPT_OUTFORM, 'f', "Output format, DER PEM PVK"},
@@ -161,7 +162,7 @@ int dsa_main(int argc, char **argv)
else
pkey = load_key(infile, informat, 1, passin, e, "Private Key");
if (pkey) {
if (pkey != NULL) {
dsa = EVP_PKEY_get1_DSA(pkey);
EVP_PKEY_free(pkey);
}
@@ -199,16 +200,16 @@ int dsa_main(int argc, char **argv)
}
BIO_printf(bio_err, "writing DSA key\n");
if (outformat == FORMAT_ASN1) {
if (pubin || pubout)
if (pubin || pubout) {
i = i2d_DSA_PUBKEY_bio(out, dsa);
else {
} else {
assert(private);
i = i2d_DSAPrivateKey_bio(out, dsa);
}
} else if (outformat == FORMAT_PEM) {
if (pubin || pubout)
if (pubin || pubout) {
i = PEM_write_bio_DSA_PUBKEY(out, dsa);
else {
} else {
assert(private);
i = PEM_write_bio_DSAPrivateKey(out, dsa, enc,
NULL, 0, NULL, passout);
@@ -235,10 +236,9 @@ int dsa_main(int argc, char **argv)
# else
i = i2b_PVK_bio(out, pk, pvk_encr, 0, passout);
# endif
}
else if (pubin || pubout)
} else if (pubin || pubout) {
i = i2b_PublicKey_bio(out, pk);
else {
} else {
assert(private);
i = i2b_PrivateKey_bio(out, pk);
}
@@ -260,6 +260,6 @@ int dsa_main(int argc, char **argv)
release_engine(e);
OPENSSL_free(passin);
OPENSSL_free(passout);
return (ret);
return ret;
}
#endif
+14 -77
View File
@@ -17,6 +17,7 @@ NON_EMPTY_TRANSLATION_UNIT
# include <time.h>
# include <string.h>
# include "apps.h"
# include "progs.h"
# include <openssl/bio.h>
# include <openssl/err.h>
# include <openssl/bn.h>
@@ -24,27 +25,15 @@ NON_EMPTY_TRANSLATION_UNIT
# include <openssl/x509.h>
# include <openssl/pem.h>
# ifdef GENCB_TEST
static int stop_keygen_flag = 0;
static void timebomb_sigalarm(int foo)
{
stop_keygen_flag = 1;
}
# endif
static int dsa_cb(int p, int n, BN_GENCB *cb);
typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_TEXT, OPT_C,
OPT_NOOUT, OPT_GENKEY, OPT_RAND, OPT_ENGINE,
OPT_TIMEBOMB
OPT_NOOUT, OPT_GENKEY, OPT_ENGINE, OPT_R_ENUM
} OPTION_CHOICE;
OPTIONS dsaparam_options[] = {
const OPTIONS dsaparam_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"inform", OPT_INFORM, 'F', "Input format - DER or PEM"},
{"in", OPT_IN, '<', "Input file"},
@@ -54,10 +43,7 @@ OPTIONS dsaparam_options[] = {
{"C", OPT_C, '-', "Output C code"},
{"noout", OPT_NOOUT, '-', "No output"},
{"genkey", OPT_GENKEY, '-', "Generate a DSA key"},
{"rand", OPT_RAND, 's', "Files to use for random number input"},
# ifdef GENCB_TEST
{"timebomb", OPT_TIMEBOMB, 'p', "Interrupt keygen after 'pnum' seconds"},
# endif
OPT_R_OPTIONS,
# ifndef OPENSSL_NO_ENGINE
{"engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device"},
# endif
@@ -70,13 +56,10 @@ int dsaparam_main(int argc, char **argv)
DSA *dsa = NULL;
BIO *in = NULL, *out = NULL;
BN_GENCB *cb = NULL;
int numbits = -1, num = 0, genkey = 0, need_rand = 0;
int numbits = -1, num = 0, genkey = 0;
int informat = FORMAT_PEM, outformat = FORMAT_PEM, noout = 0, C = 0;
int ret = 1, i, text = 0, private = 0;
# ifdef GENCB_TEST
int timebomb = 0;
# endif
char *infile = NULL, *outfile = NULL, *prog, *inrand = NULL;
char *infile = NULL, *outfile = NULL, *prog;
OPTION_CHOICE o;
prog = opt_init(argc, argv, dsaparam_options);
@@ -108,11 +91,6 @@ int dsaparam_main(int argc, char **argv)
case OPT_ENGINE:
e = setup_engine(opt_arg(), 0);
break;
case OPT_TIMEBOMB:
# ifdef GENCB_TEST
timebomb = atoi(opt_arg());
break;
# endif
case OPT_TEXT:
text = 1;
break;
@@ -120,11 +98,11 @@ int dsaparam_main(int argc, char **argv)
C = 1;
break;
case OPT_GENKEY:
genkey = need_rand = 1;
genkey = 1;
break;
case OPT_RAND:
inrand = opt_arg();
need_rand = 1;
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
case OPT_NOOUT:
noout = 1;
@@ -139,7 +117,6 @@ int dsaparam_main(int argc, char **argv)
goto end;
/* generate a key */
numbits = num;
need_rand = 1;
}
private = genkey ? 1 : 0;
@@ -150,13 +127,6 @@ int dsaparam_main(int argc, char **argv)
if (out == NULL)
goto end;
if (need_rand) {
app_RAND_load_file(NULL, (inrand != NULL));
if (inrand != NULL)
BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
app_RAND_load_files(inrand));
}
if (numbits > 0) {
cb = BN_GENCB_new();
if (cb == NULL) {
@@ -164,7 +134,6 @@ int dsaparam_main(int argc, char **argv)
goto end;
}
BN_GENCB_set(cb, dsa_cb, bio_err);
assert(need_rand);
dsa = DSA_new();
if (dsa == NULL) {
BIO_printf(bio_err, "Error allocating DSA object\n");
@@ -173,38 +142,16 @@ int dsaparam_main(int argc, char **argv)
BIO_printf(bio_err, "Generating DSA parameters, %d bit long prime\n",
num);
BIO_printf(bio_err, "This could take some time\n");
# ifdef GENCB_TEST
if (timebomb > 0) {
struct sigaction act;
act.sa_handler = timebomb_sigalarm;
act.sa_flags = 0;
BIO_printf(bio_err,
"(though I'll stop it if not done within %d secs)\n",
timebomb);
if (sigaction(SIGALRM, &act, NULL) != 0) {
BIO_printf(bio_err, "Error, couldn't set SIGALRM handler\n");
goto end;
}
alarm(timebomb);
}
# endif
if (!DSA_generate_parameters_ex(dsa, num, NULL, 0, NULL, NULL, cb)) {
# ifdef GENCB_TEST
if (stop_keygen_flag) {
BIO_printf(bio_err, "DSA key generation time-stopped\n");
/* This is an asked-for behaviour! */
ret = 0;
goto end;
}
# endif
ERR_print_errors(bio_err);
BIO_printf(bio_err, "Error, DSA key generation failed\n");
goto end;
}
} else if (informat == FORMAT_ASN1)
} else if (informat == FORMAT_ASN1) {
dsa = d2i_DSAparams_bio(in, NULL);
else
} else {
dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL);
}
if (dsa == NULL) {
BIO_printf(bio_err, "unable to load DSA parameters\n");
ERR_print_errors(bio_err);
@@ -248,9 +195,6 @@ int dsaparam_main(int argc, char **argv)
OPENSSL_free(data);
}
if (outformat == FORMAT_ASN1 && genkey)
noout = 1;
if (!noout) {
if (outformat == FORMAT_ASN1)
i = i2d_DSAparams_bio(out, dsa);
@@ -265,7 +209,6 @@ int dsaparam_main(int argc, char **argv)
if (genkey) {
DSA *dsakey;
assert(need_rand);
if ((dsakey = DSAparams_dup(dsa)) == NULL)
goto end;
if (!DSA_generate_key(dsakey)) {
@@ -281,8 +224,6 @@ int dsaparam_main(int argc, char **argv)
NULL);
DSA_free(dsakey);
}
if (need_rand)
app_RAND_write_file(NULL);
ret = 0;
end:
BN_GENCB_free(cb);
@@ -290,7 +231,7 @@ int dsaparam_main(int argc, char **argv)
BIO_free_all(out);
DSA_free(dsa);
release_engine(e);
return (ret);
return ret;
}
static int dsa_cb(int p, int n, BN_GENCB *cb)
@@ -307,10 +248,6 @@ static int dsa_cb(int p, int n, BN_GENCB *cb)
c = '\n';
BIO_write(BN_GENCB_get_arg(cb), &c, 1);
(void)BIO_flush(BN_GENCB_get_arg(cb));
# ifdef GENCB_TEST
if (stop_keygen_flag)
return 0;
# endif
return 1;
}
#endif
+13 -11
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2002-2018 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
@@ -16,6 +16,7 @@ NON_EMPTY_TRANSLATION_UNIT
# include <stdlib.h>
# include <string.h>
# include "apps.h"
# include "progs.h"
# include <openssl/bio.h>
# include <openssl/err.h>
# include <openssl/evp.h>
@@ -42,7 +43,7 @@ typedef enum OPTION_choice {
OPT_NO_PUBLIC, OPT_CHECK
} OPTION_CHOICE;
OPTIONS ec_options[] = {
const OPTIONS ec_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"in", OPT_IN, 's', "Input file"},
{"inform", OPT_INFORM, 'f', "Input format - DER or PEM"},
@@ -185,7 +186,7 @@ int ec_main(int argc, char **argv)
} else if (informat == FORMAT_ENGINE) {
EVP_PKEY *pkey;
if (pubin)
pkey = load_pubkey(infile, informat , 1, passin, e, "Public Key");
pkey = load_pubkey(infile, informat, 1, passin, e, "Public Key");
else
pkey = load_key(infile, informat, 1, passin, e, "Private Key");
if (pkey != NULL) {
@@ -244,20 +245,20 @@ int ec_main(int argc, char **argv)
BIO_printf(bio_err, "writing EC key\n");
if (outformat == FORMAT_ASN1) {
if (param_out)
if (param_out) {
i = i2d_ECPKParameters_bio(out, group);
else if (pubin || pubout)
} else if (pubin || pubout) {
i = i2d_EC_PUBKEY_bio(out, eckey);
else {
} else {
assert(private);
i = i2d_ECPrivateKey_bio(out, eckey);
}
} else {
if (param_out)
if (param_out) {
i = PEM_write_bio_ECPKParameters(out, group);
else if (pubin || pubout)
} else if (pubin || pubout) {
i = PEM_write_bio_EC_PUBKEY(out, eckey);
else {
} else {
assert(private);
i = PEM_write_bio_ECPrivateKey(out, eckey, enc,
NULL, 0, NULL, passout);
@@ -267,8 +268,9 @@ int ec_main(int argc, char **argv)
if (!i) {
BIO_printf(bio_err, "unable to write private key\n");
ERR_print_errors(bio_err);
} else
} else {
ret = 0;
}
end:
BIO_free(in);
BIO_free_all(out);
@@ -276,6 +278,6 @@ int ec_main(int argc, char **argv)
release_engine(e);
OPENSSL_free(passin);
OPENSSL_free(passout);
return (ret);
return ret;
}
#endif
+18 -45
View File
@@ -1,5 +1,6 @@
/*
* Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. 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
@@ -7,20 +8,6 @@
* https://www.openssl.org/source/license.html
*/
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
*
* Portions of the attached software ("Contribution") are developed by
* SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
*
* The Contribution is licensed pursuant to the OpenSSL open source
* license provided above.
*
* The elliptic curve binary polynomial software is originally written by
* Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
*
*/
#include <openssl/opensslconf.h>
#ifdef OPENSSL_NO_EC
NON_EMPTY_TRANSLATION_UNIT
@@ -31,6 +18,7 @@ NON_EMPTY_TRANSLATION_UNIT
# include <time.h>
# include <string.h>
# include "apps.h"
# include "progs.h"
# include <openssl/bio.h>
# include <openssl/err.h>
# include <openssl/bn.h>
@@ -42,10 +30,11 @@ typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_TEXT, OPT_C,
OPT_CHECK, OPT_LIST_CURVES, OPT_NO_SEED, OPT_NOOUT, OPT_NAME,
OPT_CONV_FORM, OPT_PARAM_ENC, OPT_GENKEY, OPT_RAND, OPT_ENGINE
OPT_CONV_FORM, OPT_PARAM_ENC, OPT_GENKEY, OPT_ENGINE,
OPT_R_ENUM
} OPTION_CHOICE;
OPTIONS ecparam_options[] = {
const OPTIONS ecparam_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"inform", OPT_INFORM, 'F', "Input format - default PEM (DER or PEM)"},
{"outform", OPT_OUTFORM, 'F', "Output format - default PEM"},
@@ -65,7 +54,7 @@ OPTIONS ecparam_options[] = {
{"param_enc", OPT_PARAM_ENC, 's',
"Specifies the way the ec parameters are encoded"},
{"genkey", OPT_GENKEY, '-', "Generate ec key"},
{"rand", OPT_RAND, 's', "Files to use for random number input"},
OPT_R_OPTIONS,
# ifndef OPENSSL_NO_ENGINE
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
# endif
@@ -93,7 +82,7 @@ int ecparam_main(int argc, char **argv)
BIO *in = NULL, *out = NULL;
EC_GROUP *group = NULL;
point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED;
char *curve_name = NULL, *inrand = NULL;
char *curve_name = NULL;
char *infile = NULL, *outfile = NULL, *prog;
unsigned char *buffer = NULL;
OPTION_CHOICE o;
@@ -101,7 +90,7 @@ int ecparam_main(int argc, char **argv)
int informat = FORMAT_PEM, outformat = FORMAT_PEM, noout = 0, C = 0;
int ret = 1, private = 0;
int list_curves = 0, no_seed = 0, check = 0, new_form = 0;
int text = 0, i, need_rand = 0, genkey = 0;
int text = 0, i, genkey = 0;
prog = opt_init(argc, argv, ecparam_options);
while ((o = opt_next()) != OPT_EOF) {
@@ -162,11 +151,11 @@ int ecparam_main(int argc, char **argv)
new_asn1_flag = 1;
break;
case OPT_GENKEY:
genkey = need_rand = 1;
genkey = 1;
break;
case OPT_RAND:
inrand = opt_arg();
need_rand = 1;
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
case OPT_ENGINE:
e = setup_engine(opt_arg(), 0);
@@ -232,8 +221,9 @@ int ecparam_main(int argc, char **argv)
BIO_printf(bio_err, "using curve name prime256v1 "
"instead of secp256r1\n");
nid = NID_X9_62_prime256v1;
} else
} else {
nid = OBJ_sn2nid(curve_name);
}
if (nid == 0)
nid = EC_curve_nist2nid(curve_name);
@@ -250,10 +240,11 @@ int ecparam_main(int argc, char **argv)
}
EC_GROUP_set_asn1_flag(group, asn1_flag);
EC_GROUP_set_point_conversion_form(group, form);
} else if (informat == FORMAT_ASN1)
} else if (informat == FORMAT_ASN1) {
group = d2i_ECPKParameters_bio(in, NULL);
else
} else {
group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL);
}
if (group == NULL) {
BIO_printf(bio_err, "unable to load elliptic curve parameters\n");
ERR_print_errors(bio_err);
@@ -393,9 +384,6 @@ int ecparam_main(int argc, char **argv)
"}\n");
}
if (outformat == FORMAT_ASN1 && genkey)
noout = 1;
if (!noout) {
if (outformat == FORMAT_ASN1)
i = i2d_ECPKParameters_bio(out, group);
@@ -409,21 +397,12 @@ int ecparam_main(int argc, char **argv)
}
}
if (need_rand) {
app_RAND_load_file(NULL, (inrand != NULL));
if (inrand != NULL)
BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
app_RAND_load_files(inrand));
}
if (genkey) {
EC_KEY *eckey = EC_KEY_new();
if (eckey == NULL)
goto end;
assert(need_rand);
if (EC_KEY_set_group(eckey, group) == 0) {
BIO_printf(bio_err, "unable to set group when generating key\n");
EC_KEY_free(eckey);
@@ -431,9 +410,6 @@ int ecparam_main(int argc, char **argv)
goto end;
}
if (new_form)
EC_KEY_set_conv_form(eckey, form);
if (!EC_KEY_generate_key(eckey)) {
BIO_printf(bio_err, "unable to generate key\n");
EC_KEY_free(eckey);
@@ -449,9 +425,6 @@ int ecparam_main(int argc, char **argv)
EC_KEY_free(eckey);
}
if (need_rand)
app_RAND_write_file(NULL);
ret = 0;
end:
BN_free(ec_p);
@@ -465,7 +438,7 @@ int ecparam_main(int argc, char **argv)
release_engine(e);
BIO_free(in);
BIO_free_all(out);
return (ret);
return ret;
}
#endif
+93 -41
View File
@@ -12,6 +12,7 @@
#include <string.h>
#include <limits.h>
#include "apps.h"
#include "progs.h"
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/evp.h>
@@ -29,7 +30,7 @@
#define SIZE (512)
#define BSIZE (8*1024)
static int set_hex(char *in, unsigned char *out, int size);
static int set_hex(const char *in, unsigned char *out, int size);
static void show_ciphers(const OBJ_NAME *name, void *bio_);
struct doall_enc_ciphers {
@@ -43,10 +44,11 @@ typedef enum OPTION_choice {
OPT_E, OPT_IN, OPT_OUT, OPT_PASS, OPT_ENGINE, OPT_D, OPT_P, OPT_V,
OPT_NOPAD, OPT_SALT, OPT_NOSALT, OPT_DEBUG, OPT_UPPER_P, OPT_UPPER_A,
OPT_A, OPT_Z, OPT_BUFSIZE, OPT_K, OPT_KFILE, OPT_UPPER_K, OPT_NONE,
OPT_UPPER_S, OPT_IV, OPT_MD, OPT_CIPHER
OPT_UPPER_S, OPT_IV, OPT_MD, OPT_ITER, OPT_PBKDF2, OPT_CIPHER,
OPT_R_ENUM
} OPTION_CHOICE;
OPTIONS enc_options[] = {
const OPTIONS enc_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"ciphers", OPT_LIST, '-', "List ciphers"},
{"in", OPT_IN, '<', "Input file"},
@@ -72,8 +74,11 @@ OPTIONS enc_options[] = {
{"S", OPT_UPPER_S, 's', "Salt, in hex"},
{"iv", OPT_IV, 's', "IV in hex"},
{"md", OPT_MD, 's', "Use specified digest to create a key from the passphrase"},
{"iter", OPT_ITER, 'p', "Specify the iteration count and force use of PBKDF2"},
{"pbkdf2", OPT_PBKDF2, '-', "Use password-based key derivation function 2"},
{"none", OPT_NONE, '-', "Don't encrypt"},
{"", OPT_CIPHER, '-', "Any supported cipher"},
OPT_R_OPTIONS,
#ifdef ZLIB
{"z", OPT_Z, '-', "Use zlib as the 'encryption'"},
#endif
@@ -104,6 +109,8 @@ int enc_main(int argc, char **argv)
int ret = 1, inl, nopad = 0;
unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
unsigned char *buff = NULL, salt[PKCS5_SALT_LEN];
int pbkdf2 = 0;
int iter = 0;
long n;
struct doall_enc_ciphers dec;
#ifdef ZLIB
@@ -113,13 +120,13 @@ int enc_main(int argc, char **argv)
/* first check the program name */
prog = opt_progname(argv[0]);
if (strcmp(prog, "base64") == 0)
if (strcmp(prog, "base64") == 0) {
base64 = 1;
#ifdef ZLIB
else if (strcmp(prog, "zlib") == 0)
} else if (strcmp(prog, "zlib") == 0) {
do_zlib = 1;
#endif
else {
} else {
cipher = EVP_get_cipherbyname(prog);
if (cipher == NULL && strcmp(prog, "enc") != 0) {
BIO_printf(bio_err, "%s is not a known cipher\n", prog);
@@ -252,9 +259,23 @@ int enc_main(int argc, char **argv)
goto opthelp;
cipher = c;
break;
case OPT_ITER:
if (!opt_int(opt_arg(), &iter))
goto opthelp;
pbkdf2 = 1;
break;
case OPT_PBKDF2:
pbkdf2 = 1;
if (iter == 0) /* do not overwrite a chosen value */
iter = 10000;
break;
case OPT_NONE:
cipher = NULL;
break;
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
}
}
if (opt_num_rest() != 0) {
@@ -275,6 +296,9 @@ int enc_main(int argc, char **argv)
if (dgst == NULL)
dgst = EVP_sha256();
if (iter == 0)
iter = 1;
/* It must be large enough for a base64 encoded line */
if (base64 && bsize < 80)
bsize = 80;
@@ -296,12 +320,13 @@ int enc_main(int argc, char **argv)
if (infile == NULL) {
in = dup_bio_in(informat);
} else
} else {
in = bio_open_default(infile, 'r', informat);
}
if (in == NULL)
goto end;
if (!str && passarg) {
if (str == NULL && passarg != NULL) {
if (!app_passwd(passarg, NULL, &pass, NULL)) {
BIO_printf(bio_err, "Error getting password\n");
goto end;
@@ -311,13 +336,13 @@ int enc_main(int argc, char **argv)
if ((str == NULL) && (cipher != NULL) && (hkey == NULL)) {
if (1) {
#ifndef OPENSSL_NO_UI
#ifndef OPENSSL_NO_UI_CONSOLE
for (;;) {
char prompt[200];
BIO_snprintf(prompt, sizeof(prompt), "enter %s %s password:",
OBJ_nid2ln(EVP_CIPHER_nid(cipher)),
(enc) ? "encryption" : "decryption");
OBJ_nid2ln(EVP_CIPHER_nid(cipher)),
(enc) ? "encryption" : "decryption");
strbuf[0] = '\0';
i = EVP_read_pw_string((char *)strbuf, SIZE, prompt, enc);
if (i == 0) {
@@ -397,17 +422,18 @@ int enc_main(int argc, char **argv)
unsigned char *sptr;
size_t str_len = strlen(str);
if (nosalt)
if (nosalt) {
sptr = NULL;
else {
} else {
if (enc) {
if (hsalt) {
if (!set_hex(hsalt, salt, sizeof(salt))) {
BIO_printf(bio_err, "invalid hex salt value\n");
goto end;
}
} else if (RAND_bytes(salt, sizeof(salt)) <= 0)
} else if (RAND_bytes(salt, sizeof(salt)) <= 0) {
goto end;
}
/*
* If -P option then don't bother writing
*/
@@ -430,19 +456,41 @@ int enc_main(int argc, char **argv)
BIO_printf(bio_err, "bad magic number\n");
goto end;
}
sptr = salt;
}
if (!EVP_BytesToKey(cipher, dgst, sptr,
(unsigned char *)str,
str_len, 1, key, iv)) {
BIO_printf(bio_err, "EVP_BytesToKey failed\n");
goto end;
if (pbkdf2 == 1) {
/*
* derive key and default iv
* concatenated into a temporary buffer
*/
unsigned char tmpkeyiv[EVP_MAX_KEY_LENGTH + EVP_MAX_IV_LENGTH];
int iklen = EVP_CIPHER_key_length(cipher);
int ivlen = EVP_CIPHER_iv_length(cipher);
/* not needed if HASH_UPDATE() is fixed : */
int islen = (sptr != NULL ? sizeof(salt) : 0);
if (!PKCS5_PBKDF2_HMAC(str, str_len, sptr, islen,
iter, dgst, iklen+ivlen, tmpkeyiv)) {
BIO_printf(bio_err, "PKCS5_PBKDF2_HMAC failed\n");
goto end;
}
/* split and move data back to global buffer */
memcpy(key, tmpkeyiv, iklen);
memcpy(iv, tmpkeyiv+iklen, ivlen);
} else {
BIO_printf(bio_err, "*** WARNING : "
"deprecated key derivation used.\n"
"Using -iter or -pbkdf2 would be better.\n");
if (!EVP_BytesToKey(cipher, dgst, sptr,
(unsigned char *)str, str_len,
1, key, iv)) {
BIO_printf(bio_err, "EVP_BytesToKey failed\n");
goto end;
}
}
/*
* zero the complete buffer or the string passed from the command
* line bug picked up by Larry J. Hughes Jr. <hughes@indiana.edu>
* line.
*/
if (str == strbuf)
OPENSSL_cleanse(str, SIZE);
@@ -453,7 +501,7 @@ int enc_main(int argc, char **argv)
int siz = EVP_CIPHER_iv_length(cipher);
if (siz == 0) {
BIO_printf(bio_err, "warning: iv not use by this cipher\n");
} else if (!set_hex(hiv, iv, sizeof(iv))) {
} else if (!set_hex(hiv, iv, siz)) {
BIO_printf(bio_err, "invalid hex iv value\n");
goto end;
}
@@ -461,16 +509,19 @@ int enc_main(int argc, char **argv)
if ((hiv == NULL) && (str == NULL)
&& EVP_CIPHER_iv_length(cipher) != 0) {
/*
* No IV was explicitly set and no IV was generated during
* EVP_BytesToKey. Hence the IV is undefined, making correct
* decryption impossible.
* No IV was explicitly set and no IV was generated.
* Hence the IV is undefined, making correct decryption impossible.
*/
BIO_printf(bio_err, "iv undefined\n");
goto end;
}
if ((hkey != NULL) && !set_hex(hkey, key, EVP_CIPHER_key_length(cipher))) {
BIO_printf(bio_err, "invalid hex key value\n");
goto end;
if (hkey != NULL) {
if (!set_hex(hkey, key, EVP_CIPHER_key_length(cipher))) {
BIO_printf(bio_err, "invalid hex key value\n");
goto end;
}
/* wiping secret data as we no longer need it */
OPENSSL_cleanse(hkey, strlen(hkey));
}
if ((benc = BIO_new(BIO_f_cipher())) == NULL)
@@ -551,8 +602,8 @@ int enc_main(int argc, char **argv)
ret = 0;
if (verbose) {
BIO_printf(bio_err, "bytes read :%8"BIO_PRI64"u\n", BIO_number_read(in));
BIO_printf(bio_err, "bytes written:%8"BIO_PRI64"u\n", BIO_number_written(out));
BIO_printf(bio_err, "bytes read : %8ju\n", BIO_number_read(in));
BIO_printf(bio_err, "bytes written: %8ju\n", BIO_number_written(out));
}
end:
ERR_print_errors(bio_err);
@@ -567,7 +618,7 @@ int enc_main(int argc, char **argv)
#endif
release_engine(e);
OPENSSL_free(pass);
return (ret);
return ret;
}
static void show_ciphers(const OBJ_NAME *name, void *arg)
@@ -593,25 +644,26 @@ static void show_ciphers(const OBJ_NAME *name, void *arg)
BIO_printf(dec->bio, " ");
}
static int set_hex(char *in, unsigned char *out, int size)
static int set_hex(const char *in, unsigned char *out, int size)
{
int i, n;
unsigned char j;
i = size * 2;
n = strlen(in);
if (n > (size * 2)) {
BIO_printf(bio_err, "hex string is too long\n");
return (0);
if (n > i) {
BIO_printf(bio_err, "hex string is too long, ignoring excess\n");
n = i; /* ignore exceeding part */
} else if (n < i) {
BIO_printf(bio_err, "hex string is too short, padding with zero bytes to length\n");
}
memset(out, 0, size);
for (i = 0; i < n; i++) {
j = (unsigned char)*in;
*(in++) = '\0';
if (j == 0)
break;
j = (unsigned char)*in++;
if (!isxdigit(j)) {
BIO_printf(bio_err, "non-hex digit\n");
return (0);
return 0;
}
j = (unsigned char)OPENSSL_hexchar2int(j);
if (i & 1)
@@ -619,5 +671,5 @@ static int set_hex(char *in, unsigned char *out, int size)
else
out[i / 2] = (j << 4);
}
return (1);
return 1;
}
+71 -28
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2000-2018 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
@@ -13,12 +13,14 @@ NON_EMPTY_TRANSLATION_UNIT
#else
# include "apps.h"
# include "progs.h"
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <openssl/err.h>
# include <openssl/engine.h>
# include <openssl/ssl.h>
# include <openssl/store.h>
typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
@@ -26,7 +28,7 @@ typedef enum OPTION_choice {
OPT_V = 100, OPT_VV, OPT_VVV, OPT_VVVV
} OPTION_CHOICE;
OPTIONS engine_options[] = {
const OPTIONS engine_options[] = {
{OPT_HELP_STR, 1, '-', "Usage: %s [options] engine...\n"},
{OPT_HELP_STR, 1, '-',
" engine... Engines to load\n"},
@@ -47,28 +49,38 @@ OPTIONS engine_options[] = {
static int append_buf(char **buf, int *size, const char *s)
{
if (*buf == NULL) {
*size = 256;
*buf = app_malloc(*size, "engine buffer");
**buf = '\0';
}
const int expand = 256;
int len = strlen(s) + 1;
char *p = *buf;
if (strlen(*buf) + strlen(s) >= (unsigned int)*size) {
char *tmp;
*size += 256;
tmp = OPENSSL_realloc(*buf, *size);
if (tmp == NULL) {
OPENSSL_free(*buf);
*buf = NULL;
return 0;
if (p == NULL) {
*size = ((len + expand - 1) / expand) * expand;
p = *buf = app_malloc(*size, "engine buffer");
} else {
const int blen = strlen(p);
if (blen > 0)
len += 2 + blen;
if (len > *size) {
*size = ((len + expand - 1) / expand) * expand;
p = OPENSSL_realloc(p, *size);
if (p == NULL) {
OPENSSL_free(*buf);
*buf = NULL;
return 0;
}
*buf = p;
}
if (blen > 0) {
p += blen;
*p++ = ',';
*p++ = ' ';
}
*buf = tmp;
}
if (**buf != '\0')
OPENSSL_strlcat(*buf, ", ", *size);
OPENSSL_strlcat(*buf, s, *size);
strcpy(p, s);
return 1;
}
@@ -147,7 +159,7 @@ static int util_verbose(ENGINE *e, int verbose, BIO *out, const char *indent)
}
cmds = sk_OPENSSL_STRING_new_null();
if (!cmds)
if (cmds == NULL)
goto err;
do {
@@ -249,15 +261,34 @@ static void util_do_cmds(ENGINE *e, STACK_OF(OPENSSL_STRING) *cmds,
if (!ENGINE_ctrl_cmd_string(e, buf, arg, 0))
res = 0;
}
if (res)
if (res) {
BIO_printf(out, "[Success]: %s\n", cmd);
else {
} else {
BIO_printf(out, "[Failure]: %s\n", cmd);
ERR_print_errors(out);
}
}
}
struct util_store_cap_data {
ENGINE *engine;
char **cap_buf;
int *cap_size;
int ok;
};
static void util_store_cap(const OSSL_STORE_LOADER *loader, void *arg)
{
struct util_store_cap_data *ctx = arg;
if (OSSL_STORE_LOADER_get0_engine(loader) == ctx->engine) {
char buf[256];
BIO_snprintf(buf, sizeof(buf), "STORE(%s)",
OSSL_STORE_LOADER_get0_scheme(loader));
if (!append_buf(ctx->cap_buf, ctx->cap_size, buf))
ctx->ok = 0;
}
}
int engine_main(int argc, char **argv)
{
int ret = 1, i;
@@ -380,7 +411,7 @@ int engine_main(int argc, char **argv)
goto end;
fn_c = ENGINE_get_ciphers(e);
if (!fn_c)
if (fn_c == NULL)
goto skip_ciphers;
n = fn_c(e, NULL, &nids, 0);
for (k = 0; k < n; ++k)
@@ -389,7 +420,7 @@ int engine_main(int argc, char **argv)
skip_ciphers:
fn_d = ENGINE_get_digests(e);
if (!fn_d)
if (fn_d == NULL)
goto skip_digests;
n = fn_d(e, NULL, &nids, 0);
for (k = 0; k < n; ++k)
@@ -398,14 +429,26 @@ int engine_main(int argc, char **argv)
skip_digests:
fn_pk = ENGINE_get_pkey_meths(e);
if (!fn_pk)
if (fn_pk == NULL)
goto skip_pmeths;
n = fn_pk(e, NULL, &nids, 0);
for (k = 0; k < n; ++k)
if (!append_buf(&cap_buf, &cap_size, OBJ_nid2sn(nids[k])))
goto end;
skip_pmeths:
if (cap_buf && (*cap_buf != '\0'))
{
struct util_store_cap_data store_ctx;
store_ctx.engine = e;
store_ctx.cap_buf = &cap_buf;
store_ctx.cap_size = &cap_size;
store_ctx.ok = 1;
OSSL_STORE_do_all_loaders(util_store_cap, &store_ctx);
if (!store_ctx.ok)
goto end;
}
if (cap_buf != NULL && (*cap_buf != '\0'))
BIO_printf(out, " [%s]\n", cap_buf);
OPENSSL_free(cap_buf);
@@ -441,6 +484,6 @@ int engine_main(int argc, char **argv)
sk_OPENSSL_STRING_free(pre_cmds);
sk_OPENSSL_STRING_free(post_cmds);
BIO_free_all(out);
return (ret);
return ret;
}
#endif
+6 -6
View File
@@ -1,5 +1,5 @@
/*
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2018 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
@@ -11,8 +11,8 @@
#include <stdlib.h>
#include <string.h>
#include "apps.h"
#include "progs.h"
#include <openssl/bio.h>
#include <openssl/lhash.h>
#include <openssl/err.h>
#include <openssl/ssl.h>
@@ -20,7 +20,7 @@ typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP
} OPTION_CHOICE;
OPTIONS errstr_options[] = {
const OPTIONS errstr_options[] = {
{OPT_HELP_STR, 1, '-', "Usage: %s [options] errnum...\n"},
{OPT_HELP_STR, 1, '-', " errnum Error number\n"},
{"help", OPT_HELP, '-', "Display this summary"},
@@ -50,9 +50,9 @@ int errstr_main(int argc, char **argv)
ret = 0;
for (argv = opt_rest(); *argv; argv++) {
if (sscanf(*argv, "%lx", &l) == 0)
if (sscanf(*argv, "%lx", &l) == 0) {
ret++;
else {
} else {
/* We're not really an SSL application so this won't auto-init, but
* we're still interested in SSL error strings
*/
@@ -63,5 +63,5 @@ int errstr_main(int argc, char **argv)
}
}
end:
return (ret);
return ret;
}
+11 -19
View File
@@ -1,5 +1,5 @@
/*
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2018 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
@@ -17,6 +17,7 @@ NON_EMPTY_TRANSLATION_UNIT
# include <sys/types.h>
# include <sys/stat.h>
# include "apps.h"
# include "progs.h"
# include <openssl/bio.h>
# include <openssl/err.h>
# include <openssl/bn.h>
@@ -26,17 +27,17 @@ NON_EMPTY_TRANSLATION_UNIT
typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_OUT, OPT_PASSOUT, OPT_ENGINE, OPT_RAND, OPT_CIPHER
OPT_OUT, OPT_PASSOUT, OPT_ENGINE, OPT_CIPHER,
OPT_R_ENUM
} OPTION_CHOICE;
OPTIONS gendsa_options[] = {
const OPTIONS gendsa_options[] = {
{OPT_HELP_STR, 1, '-', "Usage: %s [args] dsaparam-file\n"},
{OPT_HELP_STR, 1, '-', "Valid options are:\n"},
{"help", OPT_HELP, '-', "Display this summary"},
{"out", OPT_OUT, '>', "Output the key to the specified file"},
{"passout", OPT_PASSOUT, 's', "Output file pass phrase source"},
{"rand", OPT_RAND, 's',
"Load the file(s) into the random number generator"},
OPT_R_OPTIONS,
{"", OPT_CIPHER, '-', "Encrypt the output with any supported cipher"},
# ifndef OPENSSL_NO_ENGINE
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
@@ -50,7 +51,7 @@ int gendsa_main(int argc, char **argv)
BIO *out = NULL, *in = NULL;
DSA *dsa = NULL;
const EVP_CIPHER *enc = NULL;
char *inrand = NULL, *dsaparams = NULL;
char *dsaparams = NULL;
char *outfile = NULL, *passoutarg = NULL, *passout = NULL, *prog;
OPTION_CHOICE o;
int ret = 1, private = 0;
@@ -77,8 +78,9 @@ int gendsa_main(int argc, char **argv)
case OPT_ENGINE:
e = setup_engine(opt_arg(), 0);
break;
case OPT_RAND:
inrand = opt_arg();
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
case OPT_CIPHER:
if (!opt_cipher(opt_unknown(), &enc))
@@ -114,21 +116,11 @@ int gendsa_main(int argc, char **argv)
if (out == NULL)
goto end2;
if (!app_RAND_load_file(NULL, 1) && inrand == NULL) {
BIO_printf(bio_err,
"warning, not much extra random data, consider using the -rand option\n");
}
if (inrand != NULL)
BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
app_RAND_load_files(inrand));
DSA_get0_pqg(dsa, &p, NULL, NULL);
BIO_printf(bio_err, "Generating DSA key, %d bits\n", BN_num_bits(p));
if (!DSA_generate_key(dsa))
goto end;
app_RAND_write_file(NULL);
assert(private);
if (!PEM_write_bio_DSAPrivateKey(out, dsa, enc, NULL, 0, NULL, passout))
goto end;
@@ -142,6 +134,6 @@ int gendsa_main(int argc, char **argv)
DSA_free(dsa);
release_engine(e);
OPENSSL_free(passout);
return (ret);
return ret;
}
#endif
+5 -4
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2006-2018 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
@@ -10,6 +10,7 @@
#include <stdio.h>
#include <string.h>
#include "apps.h"
#include "progs.h"
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/evp.h>
@@ -26,7 +27,7 @@ typedef enum OPTION_choice {
OPT_ALGORITHM, OPT_PKEYOPT, OPT_GENPARAM, OPT_TEXT, OPT_CIPHER
} OPTION_CHOICE;
OPTIONS genpkey_options[] = {
const OPTIONS genpkey_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"out", OPT_OUT, '>', "Output file"},
{"outform", OPT_OUTFORM, 'F', "output format (DER or PEM)"},
@@ -156,9 +157,9 @@ int genpkey_main(int argc, char **argv)
}
}
if (do_param)
if (do_param) {
rv = PEM_write_bio_Parameters(out, pkey);
else if (outformat == FORMAT_PEM) {
} else if (outformat == FORMAT_PEM) {
assert(private);
rv = PEM_write_bio_PrivateKey(out, pkey, cipher, NULL, 0, NULL, pass);
} else if (outformat == FORMAT_ASN1) {
+21 -23
View File
@@ -17,6 +17,7 @@ NON_EMPTY_TRANSLATION_UNIT
# include <sys/types.h>
# include <sys/stat.h>
# include "apps.h"
# include "progs.h"
# include <openssl/bio.h>
# include <openssl/err.h>
# include <openssl/bn.h>
@@ -27,28 +28,30 @@ NON_EMPTY_TRANSLATION_UNIT
# include <openssl/rand.h>
# define DEFBITS 2048
# define DEFPRIMES 2
static int genrsa_cb(int p, int n, BN_GENCB *cb);
typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_3, OPT_F4, OPT_ENGINE,
OPT_OUT, OPT_RAND, OPT_PASSOUT, OPT_CIPHER
OPT_OUT, OPT_PASSOUT, OPT_CIPHER, OPT_PRIMES,
OPT_R_ENUM
} OPTION_CHOICE;
OPTIONS genrsa_options[] = {
const OPTIONS genrsa_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"3", OPT_3, '-', "Use 3 for the E value"},
{"F4", OPT_F4, '-', "Use F4 (0x10001) for the E value"},
{"f4", OPT_F4, '-', "Use F4 (0x10001) for the E value"},
{"out", OPT_OUT, 's', "Output the key to specified file"},
{"rand", OPT_RAND, 's',
"Load the file(s) into the random number generator"},
OPT_R_OPTIONS,
{"passout", OPT_PASSOUT, 's', "Output file pass phrase source"},
{"", OPT_CIPHER, '-', "Encrypt the output with any supported cipher"},
# ifndef OPENSSL_NO_ENGINE
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
# endif
{"primes", OPT_PRIMES, 'p', "Specify number of primes"},
{NULL}
};
@@ -62,10 +65,10 @@ int genrsa_main(int argc, char **argv)
const BIGNUM *e;
RSA *rsa = NULL;
const EVP_CIPHER *enc = NULL;
int ret = 1, num = DEFBITS, private = 0;
int ret = 1, num = DEFBITS, private = 0, primes = DEFPRIMES;
unsigned long f4 = RSA_F4;
char *outfile = NULL, *passoutarg = NULL, *passout = NULL;
char *inrand = NULL, *prog, *hexe, *dece;
char *prog, *hexe, *dece;
OPTION_CHOICE o;
if (bn == NULL || cb == NULL)
@@ -97,8 +100,9 @@ opthelp:
case OPT_ENGINE:
eng = setup_engine(opt_arg(), 0);
break;
case OPT_RAND:
inrand = opt_arg();
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
case OPT_PASSOUT:
passoutarg = opt_arg();
@@ -107,6 +111,10 @@ opthelp:
if (!opt_cipher(opt_unknown(), &enc))
goto end;
break;
case OPT_PRIMES:
if (!opt_int(opt_arg(), &primes))
goto end;
break;
}
}
argc = opt_num_rest();
@@ -130,26 +138,16 @@ opthelp:
if (out == NULL)
goto end;
if (!app_RAND_load_file(NULL, 1) && inrand == NULL
&& !RAND_status()) {
BIO_printf(bio_err,
"warning, not much extra random data, consider using the -rand option\n");
}
if (inrand != NULL)
BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
app_RAND_load_files(inrand));
BIO_printf(bio_err, "Generating RSA private key, %d bit long modulus\n",
num);
BIO_printf(bio_err, "Generating RSA private key, %d bit long modulus (%d primes)\n",
num, primes);
rsa = eng ? RSA_new_method(eng) : RSA_new();
if (rsa == NULL)
goto end;
if (!BN_set_word(bn, f4) || !RSA_generate_key_ex(rsa, num, bn, cb))
if (!BN_set_word(bn, f4)
|| !RSA_generate_multi_prime_key(rsa, num, primes, bn, cb))
goto end;
app_RAND_write_file(NULL);
RSA_get0_key(rsa, NULL, &e, NULL);
hexe = BN_bn2hex(e);
dece = BN_bn2dec(e);
@@ -176,7 +174,7 @@ opthelp:
OPENSSL_free(passout);
if (ret != 0)
ERR_print_errors(bio_err);
return (ret);
return ret;
}
static int genrsa_cb(int p, int n, BN_GENCB *cb)
+4 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1999-2018 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
@@ -10,6 +10,7 @@
#include <stdio.h>
#include <string.h>
#include "apps.h"
#include "progs.h"
#include <openssl/pem.h>
#include <openssl/err.h>
@@ -18,7 +19,7 @@ typedef enum OPTION_choice {
OPT_TOSEQ, OPT_IN, OPT_OUT
} OPTION_CHOICE;
OPTIONS nseq_options[] = {
const OPTIONS nseq_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"toseq", OPT_TOSEQ, '-', "Output NS Sequence file"},
{"in", OPT_IN, '<', "Input file"},
@@ -109,5 +110,5 @@ int nseq_main(int argc, char **argv)
BIO_free_all(out);
NETSCAPE_CERT_SEQUENCE_free(seq);
return (ret);
return ret;
}
+136 -105
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2001-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2001-2018 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
@@ -17,8 +17,6 @@ NON_EMPTY_TRANSLATION_UNIT
* on OpenVMS */
# endif
# define USE_SOCKETS
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
@@ -27,6 +25,7 @@ NON_EMPTY_TRANSLATION_UNIT
/* Needs to be included before the openssl headers */
# include "apps.h"
# include "progs.h"
# include <openssl/e_os2.h>
# include <openssl/crypto.h>
# include <openssl/err.h>
@@ -35,21 +34,6 @@ NON_EMPTY_TRANSLATION_UNIT
# include <openssl/bn.h>
# include <openssl/x509v3.h>
# if defined(NETWARE_CLIB)
# ifdef NETWARE_BSDSOCK
# include <sys/socket.h>
# include <sys/bsdskt.h>
# else
# include <novsock2.h>
# endif
# elif defined(NETWARE_LIBC)
# ifdef NETWARE_BSDSOCK
# include <sys/select.h>
# else
# include <novsock2.h>
# endif
# endif
/* Maximum leeway in validity period: default 5 minutes */
# define MAX_VALIDITY_PERIOD (5 * 60)
@@ -63,9 +47,10 @@ static void print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
STACK_OF(OPENSSL_STRING) *names,
STACK_OF(OCSP_CERTID) *ids, long nsec,
long maxage);
static void make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req,
CA_DB *db, X509 *ca, X509 *rcert,
static void make_ocsp_response(BIO *err, OCSP_RESPONSE **resp, OCSP_REQUEST *req,
CA_DB *db, STACK_OF(X509) *ca, X509 *rcert,
EVP_PKEY *rkey, const EVP_MD *md,
STACK_OF(OPENSSL_STRING) *sigopts,
STACK_OF(X509) *rother, unsigned long flags,
int nmin, int ndays, int badsig);
@@ -94,12 +79,12 @@ typedef enum OPTION_choice {
OPT_VALIDITY_PERIOD, OPT_STATUS_AGE, OPT_SIGNKEY, OPT_REQOUT,
OPT_RESPOUT, OPT_PATH, OPT_ISSUER, OPT_CERT, OPT_SERIAL,
OPT_INDEX, OPT_CA, OPT_NMIN, OPT_REQUEST, OPT_NDAYS, OPT_RSIGNER,
OPT_RKEY, OPT_ROTHER, OPT_RMD, OPT_HEADER,
OPT_RKEY, OPT_ROTHER, OPT_RMD, OPT_RSIGOPT, OPT_HEADER,
OPT_V_ENUM,
OPT_MD
} OPTION_CHOICE;
OPTIONS ocsp_options[] = {
const OPTIONS ocsp_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"out", OPT_OUTFILE, '>', "Output filename"},
{"timeout", OPT_TIMEOUT, 'p',
@@ -108,7 +93,7 @@ OPTIONS ocsp_options[] = {
{"host", OPT_HOST, 's', "TCP/IP hostname:port to connect to"},
{"port", OPT_PORT, 'p', "Port to run responder on"},
{"ignore_err", OPT_IGNORE_ERR, '-',
"Ignore Error response from OCSP responder, and retry "},
"Ignore error on OCSP request or response and continue running"},
{"noverify", OPT_NOVERIFY, '-', "Don't verify response at all"},
{"nonce", OPT_NONCE, '-', "Add OCSP nonce to request"},
{"no_nonce", OPT_NO_NONCE, '-', "Don't add OCSP nonce to request"},
@@ -171,6 +156,7 @@ OPTIONS ocsp_options[] = {
{"rkey", OPT_RKEY, '<', "Responder key to sign responses with"},
{"rother", OPT_ROTHER, '<', "Other certificates to include in response"},
{"rmd", OPT_RMD, 's', "Digest Algorithm to use in signature of OCSP response"},
{"rsigopt", OPT_RSIGOPT, 's', "OCSP response signature parameter in n:v form"},
{"header", OPT_HEADER, 's', "key=value header to add"},
{"", OPT_MD, '-', "Any supported digest algorithm (sha1,sha256, ... )"},
OPT_V_OPTIONS,
@@ -181,6 +167,7 @@ int ocsp_main(int argc, char **argv)
{
BIO *acbio = NULL, *cbio = NULL, *derbio = NULL, *out = NULL;
const EVP_MD *cert_id_md = NULL, *rsign_md = NULL;
STACK_OF(OPENSSL_STRING) *rsign_sigopts = NULL;
int trailing_md = 0;
CA_DB *rdb = NULL;
EVP_PKEY *key = NULL, *rkey = NULL;
@@ -192,7 +179,8 @@ int ocsp_main(int argc, char **argv)
STACK_OF(OPENSSL_STRING) *reqnames = NULL;
STACK_OF(X509) *sign_other = NULL, *verify_other = NULL, *rother = NULL;
STACK_OF(X509) *issuers = NULL;
X509 *issuer = NULL, *cert = NULL, *rca_cert = NULL;
X509 *issuer = NULL, *cert = NULL;
STACK_OF(X509) *rca_cert = NULL;
X509 *signer = NULL, *rsigner = NULL;
X509_STORE *store = NULL;
X509_VERIFY_PARAM *vpm = NULL;
@@ -218,10 +206,10 @@ int ocsp_main(int argc, char **argv)
char *prog;
reqnames = sk_OPENSSL_STRING_new_null();
if (!reqnames)
if (reqnames == NULL)
goto end;
ids = sk_OCSP_CERTID_new_null();
if (!ids)
if (ids == NULL)
goto end;
if ((vpm = X509_VERIFY_PARAM_new()) == NULL)
return 1;
@@ -435,6 +423,12 @@ int ocsp_main(int argc, char **argv)
if (!opt_md(opt_arg(), &rsign_md))
goto end;
break;
case OPT_RSIGOPT:
if (rsign_sigopts == NULL)
rsign_sigopts = sk_OPENSSL_STRING_new_null();
if (rsign_sigopts == NULL || !sk_OPENSSL_STRING_push(rsign_sigopts, opt_arg()))
goto end;
break;
case OPT_HEADER:
header = opt_arg();
value = strchr(header, '=');
@@ -470,62 +464,65 @@ int ocsp_main(int argc, char **argv)
goto opthelp;
/* Have we anything to do? */
if (!req && !reqin && !respin && !(port && ridx_filename))
if (req == NULL&& reqin == NULL
&& respin == NULL && !(port != NULL && ridx_filename != NULL))
goto opthelp;
out = bio_open_default(outfile, 'w', FORMAT_TEXT);
if (out == NULL)
goto end;
if (!req && (add_nonce != 2))
if (req == NULL && (add_nonce != 2))
add_nonce = 0;
if (!req && reqin) {
if (req == NULL && reqin != NULL) {
derbio = bio_open_default(reqin, 'r', FORMAT_ASN1);
if (derbio == NULL)
goto end;
req = d2i_OCSP_REQUEST_bio(derbio, NULL);
BIO_free(derbio);
if (!req) {
if (req == NULL) {
BIO_printf(bio_err, "Error reading OCSP request\n");
goto end;
}
}
if (!req && port) {
if (req == NULL && port != NULL) {
acbio = init_responder(port);
if (!acbio)
if (acbio == NULL)
goto end;
}
if (rsignfile) {
if (!rkeyfile)
if (rsignfile != NULL) {
if (rkeyfile == NULL)
rkeyfile = rsignfile;
rsigner = load_cert(rsignfile, FORMAT_PEM, "responder certificate");
if (!rsigner) {
if (rsigner == NULL) {
BIO_printf(bio_err, "Error loading responder certificate\n");
goto end;
}
rca_cert = load_cert(rca_filename, FORMAT_PEM, "CA certificate");
if (rcertfile) {
if (!load_certs(rca_filename, &rca_cert, FORMAT_PEM,
NULL, "CA certificate"))
goto end;
if (rcertfile != NULL) {
if (!load_certs(rcertfile, &rother, FORMAT_PEM, NULL,
"responder other certificates"))
goto end;
}
rkey = load_key(rkeyfile, FORMAT_PEM, 0, NULL, NULL,
"responder private key");
if (!rkey)
if (rkey == NULL)
goto end;
}
if (acbio)
if (acbio != NULL)
BIO_printf(bio_err, "Waiting for OCSP client connections...\n");
redo_accept:
redo_accept:
if (acbio) {
if (acbio != NULL) {
if (!do_responder(&req, &cbio, acbio))
goto end;
if (!req) {
if (req == NULL) {
resp =
OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST,
NULL);
@@ -534,30 +531,32 @@ int ocsp_main(int argc, char **argv)
}
}
if (!req && (signfile || reqout || host || add_nonce || ridx_filename)) {
if (req == NULL
&& (signfile != NULL || reqout != NULL
|| host != NULL || add_nonce || ridx_filename != NULL)) {
BIO_printf(bio_err, "Need an OCSP request for this operation!\n");
goto end;
}
if (req && add_nonce)
if (req != NULL && add_nonce)
OCSP_request_add1_nonce(req, NULL, -1);
if (signfile) {
if (!keyfile)
if (signfile != NULL) {
if (keyfile == NULL)
keyfile = signfile;
signer = load_cert(signfile, FORMAT_PEM, "signer certificate");
if (!signer) {
if (signer == NULL) {
BIO_printf(bio_err, "Error loading signer certificate\n");
goto end;
}
if (sign_certfile) {
if (sign_certfile != NULL) {
if (!load_certs(sign_certfile, &sign_other, FORMAT_PEM, NULL,
"signer certificates"))
goto end;
}
key = load_key(keyfile, FORMAT_PEM, 0, NULL, NULL,
"signer private key");
if (!key)
if (key == NULL)
goto end;
if (!OCSP_request_sign
@@ -567,10 +566,10 @@ int ocsp_main(int argc, char **argv)
}
}
if (req_text && req)
if (req_text && req != NULL)
OCSP_REQUEST_print(out, req, 0);
if (reqout) {
if (reqout != NULL) {
derbio = bio_open_default(reqout, 'w', FORMAT_ASN1);
if (derbio == NULL)
goto end;
@@ -578,43 +577,44 @@ int ocsp_main(int argc, char **argv)
BIO_free(derbio);
}
if (ridx_filename && (!rkey || !rsigner || !rca_cert)) {
if (ridx_filename != NULL
&& (rkey == NULL || rsigner == NULL || rca_cert == NULL)) {
BIO_printf(bio_err,
"Need a responder certificate, key and CA for this operation!\n");
goto end;
}
if (ridx_filename && !rdb) {
if (ridx_filename != NULL && rdb == NULL) {
rdb = load_index(ridx_filename, NULL);
if (!rdb)
if (rdb == NULL)
goto end;
if (!index_index(rdb))
goto end;
}
if (rdb) {
make_ocsp_response(&resp, req, rdb, rca_cert, rsigner, rkey,
rsign_md, rother, rflags, nmin, ndays, badsig);
if (cbio)
if (rdb != NULL) {
make_ocsp_response(bio_err, &resp, req, rdb, rca_cert, rsigner, rkey,
rsign_md, rsign_sigopts, rother, rflags, nmin, ndays, badsig);
if (cbio != NULL)
send_ocsp_response(cbio, resp);
} else if (host) {
} else if (host != NULL) {
# ifndef OPENSSL_NO_SOCK
resp = process_responder(req, host, path,
port, use_ssl, headers, req_timeout);
if (!resp)
if (resp == NULL)
goto end;
# else
BIO_printf(bio_err,
"Error creating connect BIO - sockets not supported.\n");
goto end;
# endif
} else if (respin) {
} else if (respin != NULL) {
derbio = bio_open_default(respin, 'r', FORMAT_ASN1);
if (derbio == NULL)
goto end;
resp = d2i_OCSP_RESPONSE_bio(derbio, NULL);
BIO_free(derbio);
if (!resp) {
if (resp == NULL) {
BIO_printf(bio_err, "Error reading OCSP response\n");
goto end;
}
@@ -625,7 +625,7 @@ int ocsp_main(int argc, char **argv)
done_resp:
if (respout) {
if (respout != NULL) {
derbio = bio_open_default(respout, 'w', FORMAT_ASN1);
if (derbio == NULL)
goto end;
@@ -647,7 +647,7 @@ int ocsp_main(int argc, char **argv)
OCSP_RESPONSE_print(out, resp, 0);
/* If running as responder don't verify our own response */
if (cbio) {
if (cbio != NULL) {
/* If not unlimited, see if we took all we should. */
if (accept_count != -1 && --accept_count <= 0) {
ret = 0;
@@ -661,26 +661,26 @@ int ocsp_main(int argc, char **argv)
resp = NULL;
goto redo_accept;
}
if (ridx_filename) {
if (ridx_filename != NULL) {
ret = 0;
goto end;
}
if (!store) {
if (store == NULL) {
store = setup_verify(CAfile, CApath, noCAfile, noCApath);
if (!store)
goto end;
}
if (vpmtouched)
X509_STORE_set1_param(store, vpm);
if (verify_certfile) {
if (verify_certfile != NULL) {
if (!load_certs(verify_certfile, &verify_other, FORMAT_PEM, NULL,
"validator certificate"))
goto end;
}
bs = OCSP_response_get1_basic(resp);
if (!bs) {
if (bs == NULL) {
BIO_printf(bio_err, "Error parsing response\n");
goto end;
}
@@ -688,7 +688,7 @@ int ocsp_main(int argc, char **argv)
ret = 0;
if (!noverify) {
if (req && ((i = OCSP_check_nonce(req, bs)) <= 0)) {
if (req != NULL && ((i = OCSP_check_nonce(req, bs)) <= 0)) {
if (i == -1)
BIO_printf(bio_err, "WARNING: no nonce in response\n");
else {
@@ -708,9 +708,9 @@ int ocsp_main(int argc, char **argv)
BIO_printf(bio_err, "Response Verify Failure\n");
ERR_print_errors(bio_err);
ret = 1;
} else
} else {
BIO_printf(bio_err, "Response verify OK\n");
}
}
print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage);
@@ -720,16 +720,17 @@ int ocsp_main(int argc, char **argv)
X509_free(signer);
X509_STORE_free(store);
X509_VERIFY_PARAM_free(vpm);
sk_OPENSSL_STRING_free(rsign_sigopts);
EVP_PKEY_free(key);
EVP_PKEY_free(rkey);
X509_free(cert);
sk_X509_pop_free(issuers, X509_free);
X509_free(rsigner);
X509_free(rca_cert);
sk_X509_pop_free(rca_cert, X509_free);
free_index(rdb);
BIO_free_all(cbio);
BIO_free_all(acbio);
BIO_free(out);
BIO_free_all(out);
OCSP_REQUEST_free(req);
OCSP_RESPONSE_free(resp);
OCSP_BASICRESP_free(bs);
@@ -742,7 +743,7 @@ int ocsp_main(int argc, char **argv)
OPENSSL_free(tport);
OPENSSL_free(tpath);
return (ret);
return ret;
}
static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert,
@@ -750,7 +751,8 @@ static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert,
STACK_OF(OCSP_CERTID) *ids)
{
OCSP_CERTID *id;
if (!issuer) {
if (issuer == NULL) {
BIO_printf(bio_err, "No issuer certificate specified\n");
return 0;
}
@@ -759,7 +761,7 @@ static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert,
if (*req == NULL)
goto err;
id = OCSP_cert_to_id(cert_id_md, cert, issuer);
if (!id || !sk_OCSP_CERTID_push(ids, id))
if (id == NULL || !sk_OCSP_CERTID_push(ids, id))
goto err;
if (!OCSP_request_add0_id(*req, id))
goto err;
@@ -778,7 +780,8 @@ static int add_ocsp_serial(OCSP_REQUEST **req, char *serial,
X509_NAME *iname;
ASN1_BIT_STRING *ikey;
ASN1_INTEGER *sno;
if (!issuer) {
if (issuer == NULL) {
BIO_printf(bio_err, "No issuer certificate specified\n");
return 0;
}
@@ -789,7 +792,7 @@ static int add_ocsp_serial(OCSP_REQUEST **req, char *serial,
iname = X509_get_subject_name(issuer);
ikey = X509_get0_pubkey_bitstr(issuer);
sno = s2i_ASN1_INTEGER(NULL, serial);
if (!sno) {
if (sno == NULL) {
BIO_printf(bio_err, "Error converting serial number %s\n", serial);
return 0;
}
@@ -816,7 +819,7 @@ static void print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
int i, status, reason;
ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
if (!bs || !req || !sk_OPENSSL_STRING_num(names)
if (bs == NULL || req == NULL || !sk_OPENSSL_STRING_num(names)
|| !sk_OCSP_CERTID_num(ids))
return;
@@ -863,16 +866,19 @@ static void print_ocsp_summary(BIO *out, OCSP_BASICRESP *bs, OCSP_REQUEST *req,
}
}
static void make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req,
CA_DB *db, X509 *ca, X509 *rcert,
static void make_ocsp_response(BIO *err, OCSP_RESPONSE **resp, OCSP_REQUEST *req,
CA_DB *db, STACK_OF(X509) *ca, X509 *rcert,
EVP_PKEY *rkey, const EVP_MD *rmd,
STACK_OF(OPENSSL_STRING) *sigopts,
STACK_OF(X509) *rother, unsigned long flags,
int nmin, int ndays, int badsig)
{
ASN1_TIME *thisupd = NULL, *nextupd = NULL;
OCSP_CERTID *cid, *ca_id = NULL;
OCSP_CERTID *cid;
OCSP_BASICRESP *bs = NULL;
int i, id_count;
EVP_MD_CTX *mctx = NULL;
EVP_PKEY_CTX *pkctx = NULL;
id_count = OCSP_request_onereq_count(req);
@@ -892,6 +898,8 @@ static void make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req,
OCSP_ONEREQ *one;
ASN1_INTEGER *serial;
char **inf;
int jj;
int found = 0;
ASN1_OBJECT *cert_id_md_oid;
const EVP_MD *cert_id_md;
one = OCSP_request_onereq_get0(req, i);
@@ -900,16 +908,22 @@ static void make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req,
OCSP_id_get0_info(NULL, &cert_id_md_oid, NULL, NULL, cid);
cert_id_md = EVP_get_digestbyobj(cert_id_md_oid);
if (!cert_id_md) {
if (cert_id_md == NULL) {
*resp = OCSP_response_create(OCSP_RESPONSE_STATUS_INTERNALERROR,
NULL);
goto end;
}
OCSP_CERTID_free(ca_id);
ca_id = OCSP_cert_to_id(cert_id_md, NULL, ca);
for (jj = 0; jj < sk_X509_num(ca) && !found; jj++) {
X509 *ca_cert = sk_X509_value(ca, jj);
OCSP_CERTID *ca_id = OCSP_cert_to_id(cert_id_md, NULL, ca_cert);
/* Is this request about our CA? */
if (OCSP_id_issuer_cmp(ca_id, cid)) {
if (OCSP_id_issuer_cmp(ca_id, cid) == 0)
found = 1;
OCSP_CERTID_free(ca_id);
}
if (!found) {
OCSP_basic_add1_status(bs, cid,
V_OCSP_CERTSTATUS_UNKNOWN,
0, NULL, thisupd, nextupd);
@@ -917,15 +931,15 @@ static void make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req,
}
OCSP_id_get0_info(NULL, NULL, NULL, &serial, cid);
inf = lookup_serial(db, serial);
if (!inf)
if (inf == NULL) {
OCSP_basic_add1_status(bs, cid,
V_OCSP_CERTSTATUS_UNKNOWN,
0, NULL, thisupd, nextupd);
else if (inf[DB_type][0] == DB_TYPE_VAL)
} else if (inf[DB_type][0] == DB_TYPE_VAL) {
OCSP_basic_add1_status(bs, cid,
V_OCSP_CERTSTATUS_GOOD,
0, NULL, thisupd, nextupd);
else if (inf[DB_type][0] == DB_TYPE_REV) {
} else if (inf[DB_type][0] == DB_TYPE_REV) {
ASN1_OBJECT *inst = NULL;
ASN1_TIME *revtm = NULL;
ASN1_GENERALIZEDTIME *invtm = NULL;
@@ -935,10 +949,10 @@ static void make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req,
single = OCSP_basic_add1_status(bs, cid,
V_OCSP_CERTSTATUS_REVOKED,
reason, revtm, thisupd, nextupd);
if (invtm)
if (invtm != NULL)
OCSP_SINGLERESP_add1_ext_i2d(single, NID_invalidity_date,
invtm, 0, 0);
else if (inst)
else if (inst != NULL)
OCSP_SINGLERESP_add1_ext_i2d(single,
NID_hold_instruction_code, inst,
0, 0);
@@ -950,7 +964,23 @@ static void make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req,
OCSP_copy_nonce(bs, req);
OCSP_basic_sign(bs, rcert, rkey, rmd, rother, flags);
mctx = EVP_MD_CTX_new();
if ( mctx == NULL || !EVP_DigestSignInit(mctx, &pkctx, rmd, NULL, rkey)) {
*resp = OCSP_response_create(OCSP_RESPONSE_STATUS_INTERNALERROR, NULL);
goto end;
}
for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) {
char *sigopt = sk_OPENSSL_STRING_value(sigopts, i);
if (pkey_ctrl_string(pkctx, sigopt) <= 0) {
BIO_printf(err, "parameter error \"%s\"\n", sigopt);
ERR_print_errors(bio_err);
*resp = OCSP_response_create(OCSP_RESPONSE_STATUS_INTERNALERROR,
NULL);
goto end;
}
}
OCSP_basic_sign_ctx(bs, rcert, mctx, rother, flags);
if (badsig) {
const ASN1_OCTET_STRING *sig = OCSP_resp_get0_signature(bs);
@@ -960,9 +990,9 @@ static void make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req,
*resp = OCSP_response_create(OCSP_RESPONSE_STATUS_SUCCESSFUL, bs);
end:
EVP_MD_CTX_free(mctx);
ASN1_TIME_free(thisupd);
ASN1_TIME_free(nextupd);
OCSP_CERTID_free(ca_id);
OCSP_BASICRESP_free(bs);
}
@@ -1092,7 +1122,7 @@ static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio)
if (*q == ' ')
break;
if (strncmp(q, " HTTP/1.", 8) != 0) {
BIO_printf(bio_err, "Invalid request -- bad HTTP vesion\n");
BIO_printf(bio_err, "Invalid request -- bad HTTP version\n");
return 1;
}
*q = '\0';
@@ -1124,13 +1154,14 @@ static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio)
}
/* Try to read OCSP request */
if (getbio) {
if (getbio != NULL) {
req = d2i_OCSP_REQUEST_bio(getbio, NULL);
BIO_free_all(getbio);
} else
} else {
req = d2i_OCSP_REQUEST_bio(cbio, NULL);
}
if (!req) {
if (req == NULL) {
BIO_printf(bio_err, "Error parsing OCSP request\n");
ERR_print_errors(bio_err);
}
@@ -1146,7 +1177,7 @@ static int send_ocsp_response(BIO *cbio, OCSP_RESPONSE *resp)
char http_resp[] =
"HTTP/1.0 200 OK\r\nContent-type: application/ocsp-response\r\n"
"Content-Length: %d\r\n\r\n";
if (!cbio)
if (cbio == NULL)
return 0;
BIO_printf(cbio, http_resp, i2d_OCSP_RESPONSE(resp, NULL));
i2d_OCSP_RESPONSE_bio(cbio, resp);
@@ -1224,11 +1255,11 @@ static OCSP_RESPONSE *query_responder(BIO *cbio, const char *host,
openssl_fdset(fd, &confds);
tv.tv_usec = 0;
tv.tv_sec = req_timeout;
if (BIO_should_read(cbio))
if (BIO_should_read(cbio)) {
rv = select(fd + 1, (void *)&confds, NULL, NULL, &tv);
else if (BIO_should_write(cbio))
} else if (BIO_should_write(cbio)) {
rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv);
else {
} else {
BIO_puts(bio_err, "Unexpected retry condition\n");
goto err;
}
@@ -1259,11 +1290,11 @@ OCSP_RESPONSE *process_responder(OCSP_REQUEST *req,
OCSP_RESPONSE *resp = NULL;
cbio = BIO_new_connect(host);
if (!cbio) {
if (cbio == NULL) {
BIO_printf(bio_err, "Error creating connect BIO\n");
goto end;
}
if (port)
if (port != NULL)
BIO_set_conn_port(cbio, port);
if (use_ssl == 1) {
BIO *sbio;
@@ -1278,7 +1309,7 @@ OCSP_RESPONSE *process_responder(OCSP_REQUEST *req,
}
resp = query_responder(cbio, host, path, headers, req, req_timeout);
if (!resp)
if (resp == NULL)
BIO_printf(bio_err, "Error querying OCSP responder\n");
end:
BIO_free_all(cbio);
+2
View File
@@ -344,3 +344,5 @@ tsa_name = yes # Must the TSA name be included in the reply?
# (optional, default: no)
ess_cert_id_chain = no # Must the ESS cert id chain be included?
# (optional, default: no)
ess_cert_id_alg = sha1 # algorithm to compute certificate
# identifier (optional, default: sha1)
+193 -73
View File
@@ -7,6 +7,7 @@
* https://www.openssl.org/source/license.html
*/
#include <internal/cryptlib.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -21,26 +22,22 @@
# include <openssl/engine.h>
#endif
#include <openssl/err.h>
#ifdef OPENSSL_FIPS
# include <openssl/fips.h>
#endif
#define USE_SOCKETS /* needed for the _O_BINARY defs in the MS world */
#include "s_apps.h"
/* Needed to get the other O_xxx flags. */
#ifdef OPENSSL_SYS_VMS
# include <unixio.h>
#endif
#define INCLUDE_FUNCTION_TABLE
#include "apps.h"
#define INCLUDE_FUNCTION_TABLE
#include "progs.h"
#ifdef OPENSSL_NO_CAMELLIA
# define FORMAT "%-15s"
# define COLUMNS 5
#else
# define FORMAT "%-18s"
# define COLUMNS 4
#endif
/* Structure to hold the number of columns to be displayed and the
* field width used to display them.
*/
typedef struct {
int columns;
int width;
} DISPLAY_COLUMNS;
/* Special sentinel to exit the program. */
#define EXIT_THE_PROGRAM (-1)
@@ -54,7 +51,8 @@
static LHASH_OF(FUNCTION) *prog_init(void);
static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[]);
static void list_pkey(void);
static void list_type(FUNC_TYPE ft);
static void list_pkey_meth(void);
static void list_type(FUNC_TYPE ft, int one);
static void list_disabled(void);
char *default_config_file = NULL;
@@ -62,6 +60,20 @@ BIO *bio_in = NULL;
BIO *bio_out = NULL;
BIO *bio_err = NULL;
static void calculate_columns(DISPLAY_COLUMNS *dc)
{
FUNCTION *f;
int len, maxlen = 0;
for (f = functions; f->name != NULL; ++f)
if (f->type == FT_general || f->type == FT_md || f->type == FT_cipher)
if ((len = strlen(f->name)) > maxlen)
maxlen = len;
dc->width = maxlen + 2;
dc->columns = (80 - 1) / dc->width;
}
static int apps_startup()
{
#ifdef SIGPIPE
@@ -73,18 +85,15 @@ static int apps_startup()
| OPENSSL_INIT_LOAD_CONFIG, NULL))
return 0;
#ifndef OPENSSL_NO_UI
setup_ui_method();
#endif
return 1;
}
static void apps_shutdown()
{
#ifndef OPENSSL_NO_UI
destroy_ui_method();
#endif
destroy_prefix_method();
}
static char *make_config_name()
@@ -143,15 +152,8 @@ int main(int argc, char *argv[])
CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
if (getenv("OPENSSL_FIPS")) {
#ifdef OPENSSL_FIPS
if (!FIPS_mode_set(1)) {
ERR_print_errors(bio_err);
return 1;
}
#else
BIO_printf(bio_err, "FIPS mode not supported.\n");
return 1;
#endif
}
if (!apps_startup()) {
@@ -254,6 +256,7 @@ int main(int argc, char *argv[])
OPENSSL_free(default_config_file);
lh_FUNCTION_free(prog);
OPENSSL_free(arg.argv);
app_RAND_write();
BIO_free(bio_in);
BIO_free_all(bio_out);
@@ -266,19 +269,15 @@ int main(int argc, char *argv[])
EXIT(ret);
}
OPTIONS exit_options[] = {
{NULL}
};
static void list_cipher_fn(const EVP_CIPHER *c,
const char *from, const char *to, void *arg)
{
if (c)
if (c != NULL) {
BIO_printf(arg, "%s\n", EVP_CIPHER_name(c));
else {
if (!from)
} else {
if (from == NULL)
from = "<undefined>";
if (!to)
if (to == NULL)
to = "<undefined>";
BIO_printf(arg, "%s => %s\n", from, to);
}
@@ -287,27 +286,74 @@ static void list_cipher_fn(const EVP_CIPHER *c,
static void list_md_fn(const EVP_MD *m,
const char *from, const char *to, void *arg)
{
if (m)
if (m != NULL) {
BIO_printf(arg, "%s\n", EVP_MD_name(m));
else {
if (!from)
} else {
if (from == NULL)
from = "<undefined>";
if (!to)
if (to == NULL)
to = "<undefined>";
BIO_printf((BIO *)arg, "%s => %s\n", from, to);
}
}
static void list_missing_help(void)
{
const FUNCTION *fp;
const OPTIONS *o;
for (fp = functions; fp->name != NULL; fp++) {
if ((o = fp->help) != NULL) {
/* If there is help, list what flags are not documented. */
for ( ; o->name != NULL; o++) {
if (o->helpstr == NULL)
BIO_printf(bio_out, "%s %s\n", fp->name, o->name);
}
} else if (fp->func != dgst_main) {
/* If not aliased to the dgst command, */
BIO_printf(bio_out, "%s *\n", fp->name);
}
}
}
static void list_options_for_command(const char *command)
{
const FUNCTION *fp;
const OPTIONS *o;
for (fp = functions; fp->name != NULL; fp++)
if (strcmp(fp->name, command) == 0)
break;
if (fp->name == NULL) {
BIO_printf(bio_err, "Invalid command '%s'; type \"help\" for a list.\n",
command);
return;
}
if ((o = fp->help) == NULL)
return;
for ( ; o->name != NULL; o++) {
if (o->name == OPT_HELP_STR
|| o->name == OPT_MORE_STR
|| o->name[0] == '\0')
continue;
BIO_printf(bio_out, "%s %c\n", o->name, o->valtype);
}
}
/* Unified enum for help and list commands. */
typedef enum HELPLIST_CHOICE {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_COMMANDS, OPT_DIGEST_COMMANDS,
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_ONE,
OPT_COMMANDS, OPT_DIGEST_COMMANDS, OPT_OPTIONS,
OPT_DIGEST_ALGORITHMS, OPT_CIPHER_COMMANDS, OPT_CIPHER_ALGORITHMS,
OPT_PK_ALGORITHMS, OPT_DISABLED
OPT_PK_ALGORITHMS, OPT_PK_METHOD, OPT_DISABLED, OPT_MISSING_HELP
} HELPLIST_CHOICE;
OPTIONS list_options[] = {
const OPTIONS list_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"1", OPT_ONE, '-', "List in one column"},
{"commands", OPT_COMMANDS, '-', "List of standard commands"},
{"digest-commands", OPT_DIGEST_COMMANDS, '-',
"List of message digest commands"},
@@ -318,8 +364,14 @@ OPTIONS list_options[] = {
"List of cipher algorithms"},
{"public-key-algorithms", OPT_PK_ALGORITHMS, '-',
"List of public key algorithms"},
{"public-key-methods", OPT_PK_METHOD, '-',
"List of public key methods"},
{"disabled", OPT_DISABLED, '-',
"List of disabled features"},
{"missing-help", OPT_MISSING_HELP, '-',
"List missing detailed help strings"},
{"options", OPT_OPTIONS, 's',
"List options for specified command"},
{NULL}
};
@@ -327,7 +379,7 @@ int list_main(int argc, char **argv)
{
char *prog;
HELPLIST_CHOICE o;
int done = 0;
int one = 0, done = 0;
prog = opt_init(argc, argv, list_options);
while ((o = opt_next()) != OPT_EOF) {
@@ -340,17 +392,20 @@ opthelp:
case OPT_HELP:
opt_help(list_options);
break;
case OPT_ONE:
one = 1;
break;
case OPT_COMMANDS:
list_type(FT_general);
list_type(FT_general, one);
break;
case OPT_DIGEST_COMMANDS:
list_type(FT_md);
list_type(FT_md, one);
break;
case OPT_DIGEST_ALGORITHMS:
EVP_MD_do_all_sorted(list_md_fn, bio_out);
break;
case OPT_CIPHER_COMMANDS:
list_type(FT_cipher);
list_type(FT_cipher, one);
break;
case OPT_CIPHER_ALGORITHMS:
EVP_CIPHER_do_all_sorted(list_cipher_fn, bio_out);
@@ -358,9 +413,18 @@ opthelp:
case OPT_PK_ALGORITHMS:
list_pkey();
break;
case OPT_PK_METHOD:
list_pkey_meth();
break;
case OPT_DISABLED:
list_disabled();
break;
case OPT_MISSING_HELP:
list_missing_help();
break;
case OPT_OPTIONS:
list_options_for_command(opt_arg());
break;
}
done = 1;
}
@@ -375,42 +439,60 @@ opthelp:
return 0;
}
OPTIONS help_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
typedef enum HELP_CHOICE {
OPT_hERR = -1, OPT_hEOF = 0, OPT_hHELP
} HELP_CHOICE;
const OPTIONS help_options[] = {
{OPT_HELP_STR, 1, '-', "Usage: help [options]\n"},
{OPT_HELP_STR, 1, '-', " help [command]\n"},
{"help", OPT_hHELP, '-', "Display this summary"},
{NULL}
};
int help_main(int argc, char **argv)
{
FUNCTION *fp;
int i, nl;
FUNC_TYPE tp;
char *prog;
HELPLIST_CHOICE o;
HELP_CHOICE o;
DISPLAY_COLUMNS dc;
prog = opt_init(argc, argv, help_options);
while ((o = opt_next()) != OPT_EOF) {
while ((o = opt_next()) != OPT_hEOF) {
switch (o) {
default:
case OPT_hERR:
case OPT_hEOF:
BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
return 1;
case OPT_HELP:
case OPT_hHELP:
opt_help(help_options);
return 0;
}
}
if (opt_num_rest() == 1) {
char *new_argv[3];
new_argv[0] = opt_rest()[0];
new_argv[1] = "--help";
new_argv[2] = NULL;
return do_cmd(prog_init(), 2, new_argv);
}
if (opt_num_rest() != 0) {
BIO_printf(bio_err, "Usage: %s\n", prog);
return 1;
}
BIO_printf(bio_err, "\nStandard commands");
calculate_columns(&dc);
BIO_printf(bio_err, "Standard commands");
i = 0;
tp = FT_none;
for (fp = functions; fp->name != NULL; fp++) {
nl = 0;
if (((i++) % COLUMNS) == 0) {
if (i++ % dc.columns == 0) {
BIO_printf(bio_err, "\n");
nl = 1;
}
@@ -428,29 +510,35 @@ int help_main(int argc, char **argv)
"\nCipher commands (see the `enc' command for more details)\n");
}
}
BIO_printf(bio_err, FORMAT, fp->name);
BIO_printf(bio_err, "%-*s", dc.width, fp->name);
}
BIO_printf(bio_err, "\n\n");
return 0;
}
int exit_main(int argc, char **argv)
{
return EXIT_THE_PROGRAM;
}
static void list_type(FUNC_TYPE ft)
static void list_type(FUNC_TYPE ft, int one)
{
FUNCTION *fp;
int i = 0;
DISPLAY_COLUMNS dc = {0};
for (fp = functions; fp->name != NULL; fp++)
if (fp->type == ft) {
if ((i++ % COLUMNS) == 0)
if (!one)
calculate_columns(&dc);
for (fp = functions; fp->name != NULL; fp++) {
if (fp->type != ft)
continue;
if (one) {
BIO_printf(bio_out, "%s\n", fp->name);
} else {
if (i % dc.columns == 0 && i > 0)
BIO_printf(bio_out, "\n");
BIO_printf(bio_out, FORMAT, fp->name);
BIO_printf(bio_out, "%-*s", dc.width, fp->name);
i++;
}
BIO_printf(bio_out, "\n");
}
if (!one)
BIO_printf(bio_out, "\n\n");
}
static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[])
@@ -458,7 +546,7 @@ static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[])
FUNCTION f, *fp;
if (argc <= 0 || argv[0] == NULL)
return (0);
return 0;
f.name = argv[0];
fp = lh_FUNCTION_retrieve(prog, &f);
if (fp == NULL) {
@@ -473,7 +561,7 @@ static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[])
}
}
if (fp != NULL) {
return (fp->func(argc, argv));
return fp->func(argc, argv);
}
if ((strncmp(argv[0], "no-", 3)) == 0) {
/*
@@ -483,7 +571,7 @@ static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[])
f.name = argv[0] + 3;
if (lh_FUNCTION_retrieve(prog, &f) == NULL) {
BIO_printf(bio_out, "%s\n", argv[0]);
return (0);
return 0;
}
BIO_printf(bio_out, "%s\n", argv[0] + 3);
return 1;
@@ -495,7 +583,7 @@ static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[])
BIO_printf(bio_err, "Invalid command '%s'; type \"help\" for a list.\n",
argv[0]);
return (1);
return 1;
}
static void list_pkey(void)
@@ -527,6 +615,22 @@ static void list_pkey(void)
}
}
static void list_pkey_meth(void)
{
size_t i;
size_t meth_count = EVP_PKEY_meth_get_count();
for (i = 0; i < meth_count; i++) {
const EVP_PKEY_METHOD *pmeth = EVP_PKEY_meth_get0(i);
int pkey_id, pkey_flags;
EVP_PKEY_meth_get0_info(&pkey_id, &pkey_flags, pmeth);
BIO_printf(bio_out, "%s\n", OBJ_nid2ln(pkey_id));
BIO_printf(bio_out, "\tType: %s Algorithm\n",
pkey_flags & ASN1_PKEY_DYNAMIC ? "External" : "Builtin");
}
}
static int function_cmp(const FUNCTION * a, const FUNCTION * b)
{
return strncmp(a->name, b->name, 8);
@@ -550,6 +654,9 @@ static int SortFnByName(const void *_f1, const void *_f2)
static void list_disabled(void)
{
BIO_puts(bio_out, "Disabled algorithms:\n");
#ifdef OPENSSL_NO_ARIA
BIO_puts(bio_out, "ARIA\n");
#endif
#ifdef OPENSSL_NO_BF
BIO_puts(bio_out, "BF\n");
#endif
@@ -655,6 +762,12 @@ static void list_disabled(void)
#ifdef OPENSSL_NO_SEED
BIO_puts(bio_out, "SEED\n");
#endif
#ifdef OPENSSL_NO_SM3
BIO_puts(bio_out, "SM3\n");
#endif
#ifdef OPENSSL_NO_SM4
BIO_puts(bio_out, "SM4\n");
#endif
#ifdef OPENSSL_NO_SOCK
BIO_puts(bio_out, "SOCK\n");
#endif
@@ -686,18 +799,25 @@ static void list_disabled(void)
static LHASH_OF(FUNCTION) *prog_init(void)
{
LHASH_OF(FUNCTION) *ret;
static LHASH_OF(FUNCTION) *ret = NULL;
static int prog_inited = 0;
FUNCTION *f;
size_t i;
if (prog_inited)
return ret;
prog_inited = 1;
/* Sort alphabetically within category. For nicer help displays. */
for (i = 0, f = functions; f->name != NULL; ++f, ++i) ;
for (i = 0, f = functions; f->name != NULL; ++f, ++i)
;
qsort(functions, i, sizeof(*functions), SortFnByName);
if ((ret = lh_FUNCTION_new(function_hash, function_cmp)) == NULL)
return (NULL);
return NULL;
for (f = functions; f->name != NULL; f++)
(void)lh_FUNCTION_insert(ret, f);
return (ret);
return ret;
}
+2
View File
@@ -344,3 +344,5 @@ tsa_name = yes # Must the TSA name be included in the reply?
# (optional, default: no)
ess_cert_id_chain = no # Must the ESS cert id chain be included?
# (optional, default: no)
ess_cert_id_alg = sha1 # algorithm to compute certificate
# identifier (optional, default: sha1)
+37 -105
View File
@@ -1,13 +1,11 @@
/*
* Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2015-2018 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
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
/* #define COMPILE_STANDALONE_TEST_DRIVER */
#include "apps.h"
#include <string.h>
#if !defined(OPENSSL_SYS_MSDOS)
@@ -183,10 +181,10 @@ int opt_format_error(const char *s, unsigned long flags)
{
OPT_PAIR *ap;
if (flags == OPT_FMT_PEMDER)
if (flags == OPT_FMT_PEMDER) {
BIO_printf(bio_err, "%s: Bad format \"%s\"; must be pem or der\n",
prog, s);
else {
} else {
BIO_printf(bio_err, "%s: Bad format \"%s\"; must be one of:\n",
prog, s);
for (ap = formats; ap->name; ap++)
@@ -266,8 +264,9 @@ int opt_format(const char *s, unsigned long flags, int *result)
if ((flags & OPT_FMT_PKCS12) == 0)
return opt_format_error(s, flags);
*result = FORMAT_PKCS12;
} else
} else {
return 0;
}
break;
}
return 1;
@@ -277,9 +276,9 @@ int opt_format(const char *s, unsigned long flags, int *result)
int opt_cipher(const char *name, const EVP_CIPHER **cipherp)
{
*cipherp = EVP_get_cipherbyname(name);
if (*cipherp)
if (*cipherp != NULL)
return 1;
BIO_printf(bio_err, "%s: Unknown cipher %s\n", prog, name);
BIO_printf(bio_err, "%s: Unrecognized flag %s\n", prog, name);
return 0;
}
@@ -289,9 +288,9 @@ int opt_cipher(const char *name, const EVP_CIPHER **cipherp)
int opt_md(const char *name, const EVP_MD **mdp)
{
*mdp = EVP_get_digestbyname(name);
if (*mdp)
if (*mdp != NULL)
return 1;
BIO_printf(bio_err, "%s: Unknown digest %s\n", prog, name);
BIO_printf(bio_err, "%s: Unrecognized flag %s\n", prog, name);
return 0;
}
@@ -327,6 +326,30 @@ int opt_int(const char *value, int *result)
return 1;
}
static void opt_number_error(const char *v)
{
size_t i = 0;
struct strstr_pair_st {
char *prefix;
char *name;
} b[] = {
{"0x", "a hexadecimal"},
{"0X", "a hexadecimal"},
{"0", "an octal"}
};
for (i = 0; i < OSSL_NELEM(b); i++) {
if (strncmp(v, b[i].prefix, strlen(b[i].prefix)) == 0) {
BIO_printf(bio_err,
"%s: Can't parse \"%s\" as %s number\n",
prog, v, b[i].name);
return;
}
}
BIO_printf(bio_err, "%s: Can't parse \"%s\" as a number\n", prog, v);
return;
}
/* Parse a long, put it into *result; return 0 on failure, else 1. */
int opt_long(const char *value, long *result)
{
@@ -340,8 +363,7 @@ int opt_long(const char *value, long *result)
|| endp == value
|| ((l == LONG_MAX || l == LONG_MIN) && errno == ERANGE)
|| (l == 0 && errno != 0)) {
BIO_printf(bio_err, "%s: Can't parse \"%s\" as a number\n",
prog, value);
opt_number_error(value);
errno = oerrno;
return 0;
}
@@ -366,8 +388,7 @@ int opt_imax(const char *value, intmax_t *result)
|| endp == value
|| ((m == INTMAX_MAX || m == INTMAX_MIN) && errno == ERANGE)
|| (m == 0 && errno != 0)) {
BIO_printf(bio_err, "%s: Can't parse \"%s\" as a number\n",
prog, value);
opt_number_error(value);
errno = oerrno;
return 0;
}
@@ -389,8 +410,7 @@ int opt_umax(const char *value, uintmax_t *result)
|| endp == value
|| (m == UINTMAX_MAX && errno == ERANGE)
|| (m == 0 && errno != 0)) {
BIO_printf(bio_err, "%s: Can't parse \"%s\" as a number\n",
prog, value);
opt_number_error(value);
errno = oerrno;
return 0;
}
@@ -415,8 +435,7 @@ int opt_ulong(const char *value, unsigned long *result)
|| endptr == value
|| ((l == ULONG_MAX) && errno == ERANGE)
|| (l == 0 && errno != 0)) {
BIO_printf(bio_err, "%s: Can't parse \"%s\" as an unsigned number\n",
prog, value);
opt_number_error(value);
errno = oerrno;
return 0;
}
@@ -888,90 +907,3 @@ void opt_help(const OPTIONS *list)
BIO_printf(bio_err, "%s %s\n", start, help);
}
}
#ifdef COMPILE_STANDALONE_TEST_DRIVER
# include <sys/stat.h>
typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_IN, OPT_INFORM, OPT_OUT, OPT_COUNT, OPT_U, OPT_FLAG,
OPT_STR, OPT_NOTUSED
} OPTION_CHOICE;
static OPTIONS options[] = {
{OPT_HELP_STR, 1, '-', "Usage: %s flags\n"},
{OPT_HELP_STR, 1, '-', "Valid options are:\n"},
{"help", OPT_HELP, '-', "Display this summary"},
{"in", OPT_IN, '<', "input file"},
{OPT_MORE_STR, 1, '-', "more detail about input"},
{"inform", OPT_INFORM, 'f', "input file format; defaults to pem"},
{"out", OPT_OUT, '>', "output file"},
{"count", OPT_COUNT, 'p', "a counter greater than zero"},
{"u", OPT_U, 'u', "an unsigned number"},
{"flag", OPT_FLAG, 0, "just some flag"},
{"str", OPT_STR, 's', "the magic word"},
{"areallyverylongoption", OPT_HELP, '-', "long way for help"},
{NULL}
};
BIO *bio_err;
int app_isdir(const char *name)
{
struct stat sb;
return name != NULL && stat(name, &sb) >= 0 && S_ISDIR(sb.st_mode);
}
int main(int ac, char **av)
{
OPTION_CHOICE o;
char **rest;
char *prog;
bio_err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT);
prog = opt_init(ac, av, options);
while ((o = opt_next()) != OPT_EOF) {
switch (c) {
case OPT_NOTUSED:
case OPT_EOF:
case OPT_ERR:
printf("%s: Usage error; try -help.\n", prog);
return 1;
case OPT_HELP:
opt_help(options);
return 0;
case OPT_IN:
printf("in %s\n", opt_arg());
break;
case OPT_INFORM:
printf("inform %s\n", opt_arg());
break;
case OPT_OUT:
printf("out %s\n", opt_arg());
break;
case OPT_COUNT:
printf("count %s\n", opt_arg());
break;
case OPT_U:
printf("u %s\n", opt_arg());
break;
case OPT_FLAG:
printf("flag\n");
break;
case OPT_STR:
printf("str %s\n", opt_arg());
break;
}
}
argc = opt_num_rest();
argv = opt_rest();
printf("args = %d\n", argc);
if (argc)
while (*argv)
printf(" %s\n", *argv++);
return 0;
}
#endif
+468 -127
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2000-2018 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
@@ -7,26 +7,20 @@
* https://www.openssl.org/source/license.html
*/
#if defined OPENSSL_NO_MD5 || defined CHARSET_EBCDIC
# define NO_MD5CRYPT_1
#include <string.h>
#include "apps.h"
#include "progs.h"
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#ifndef OPENSSL_NO_DES
# include <openssl/des.h>
#endif
#if !defined(OPENSSL_NO_DES) || !defined(NO_MD5CRYPT_1)
# include <string.h>
# include "apps.h"
# include <openssl/bio.h>
# include <openssl/err.h>
# include <openssl/evp.h>
# include <openssl/rand.h>
# ifndef OPENSSL_NO_DES
# include <openssl/des.h>
# endif
# ifndef NO_MD5CRYPT_1
# include <openssl/md5.h>
# endif
#include <openssl/md5.h>
#include <openssl/sha.h>
static unsigned const char cov_2char[64] = {
/* from crypto/des/fcrypt.c */
@@ -40,19 +34,31 @@ static unsigned const char cov_2char[64] = {
0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
};
static const char ascii_dollar[] = { 0x24, 0x00 };
typedef enum {
passwd_unset = 0,
passwd_crypt,
passwd_md5,
passwd_apr1,
passwd_sha256,
passwd_sha512,
passwd_aixmd5
} passwd_modes;
static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p,
char *passwd, BIO *out, int quiet, int table,
int reverse, size_t pw_maxlen, int usecrypt, int use1,
int useapr1);
int reverse, size_t pw_maxlen, passwd_modes mode);
typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_IN,
OPT_NOVERIFY, OPT_QUIET, OPT_TABLE, OPT_REVERSE, OPT_APR1,
OPT_1, OPT_CRYPT, OPT_SALT, OPT_STDIN
OPT_1, OPT_5, OPT_6, OPT_CRYPT, OPT_AIXMD5, OPT_SALT, OPT_STDIN,
OPT_R_ENUM
} OPTION_CHOICE;
OPTIONS passwd_options[] = {
const OPTIONS passwd_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"in", OPT_IN, '<', "Read passwords from file"},
{"noverify", OPT_NOVERIFY, '-',
@@ -62,13 +68,15 @@ OPTIONS passwd_options[] = {
{"reverse", OPT_REVERSE, '-', "Switch table columns"},
{"salt", OPT_SALT, 's', "Use provided salt"},
{"stdin", OPT_STDIN, '-', "Read passwords from stdin"},
# ifndef NO_MD5CRYPT_1
{"6", OPT_6, '-', "SHA512-based password algorithm"},
{"5", OPT_5, '-', "SHA256-based password algorithm"},
{"apr1", OPT_APR1, '-', "MD5-based password algorithm, Apache variant"},
{"1", OPT_1, '-', "MD5-based password algorithm"},
# endif
# ifndef OPENSSL_NO_DES
{"aixmd5", OPT_AIXMD5, '-', "AIX MD5-based password algorithm"},
#ifndef OPENSSL_NO_DES
{"crypt", OPT_CRYPT, '-', "Standard Unix password algorithm (default)"},
# endif
#endif
OPT_R_OPTIONS,
{NULL}
};
@@ -79,12 +87,15 @@ int passwd_main(int argc, char **argv)
char *salt_malloc = NULL, *passwd_malloc = NULL, *prog;
OPTION_CHOICE o;
int in_stdin = 0, pw_source_defined = 0;
# ifndef OPENSSL_NO_UI
#ifndef OPENSSL_NO_UI_CONSOLE
int in_noverify = 0;
# endif
#endif
int passed_salt = 0, quiet = 0, table = 0, reverse = 0;
int ret = 1, usecrypt = 0, use1 = 0, useapr1 = 0;
size_t passwd_malloc_size = 0, pw_maxlen = 256;
int ret = 1;
passwd_modes mode = passwd_unset;
size_t passwd_malloc_size = 0;
size_t pw_maxlen = 256; /* arbitrary limit, should be enough for most
* passwords */
prog = opt_init(argc, argv, passwd_options);
while ((o = opt_next()) != OPT_EOF) {
@@ -105,9 +116,9 @@ int passwd_main(int argc, char **argv)
pw_source_defined = 1;
break;
case OPT_NOVERIFY:
# ifndef OPENSSL_NO_UI
#ifndef OPENSSL_NO_UI_CONSOLE
in_noverify = 1;
# endif
#endif
break;
case OPT_QUIET:
quiet = 1;
@@ -119,13 +130,36 @@ int passwd_main(int argc, char **argv)
reverse = 1;
break;
case OPT_1:
use1 = 1;
if (mode != passwd_unset)
goto opthelp;
mode = passwd_md5;
break;
case OPT_5:
if (mode != passwd_unset)
goto opthelp;
mode = passwd_sha256;
break;
case OPT_6:
if (mode != passwd_unset)
goto opthelp;
mode = passwd_sha512;
break;
case OPT_APR1:
useapr1 = 1;
if (mode != passwd_unset)
goto opthelp;
mode = passwd_apr1;
break;
case OPT_AIXMD5:
if (mode != passwd_unset)
goto opthelp;
mode = passwd_aixmd5;
break;
case OPT_CRYPT:
usecrypt = 1;
#ifndef OPENSSL_NO_DES
if (mode != passwd_unset)
goto opthelp;
mode = passwd_crypt;
#endif
break;
case OPT_SALT:
passed_salt = 1;
@@ -137,35 +171,31 @@ int passwd_main(int argc, char **argv)
in_stdin = 1;
pw_source_defined = 1;
break;
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
}
}
argc = opt_num_rest();
argv = opt_rest();
if (*argv) {
if (*argv != NULL) {
if (pw_source_defined)
goto opthelp;
pw_source_defined = 1;
passwds = argv;
}
if (!usecrypt && !use1 && !useapr1) {
if (mode == passwd_unset) {
/* use default */
usecrypt = 1;
}
if (usecrypt + use1 + useapr1 > 1) {
/* conflict */
goto opthelp;
mode = passwd_crypt;
}
# ifdef OPENSSL_NO_DES
if (usecrypt)
#ifdef OPENSSL_NO_DES
if (mode == passwd_crypt)
goto opthelp;
# endif
# ifdef NO_MD5CRYPT_1
if (use1 || useapr1)
goto opthelp;
# endif
#endif
if (infile != NULL && in_stdin) {
BIO_printf(bio_err, "%s: Can't combine -in and -stdin\n", prog);
@@ -182,11 +212,8 @@ int passwd_main(int argc, char **argv)
goto end;
}
if (usecrypt)
if (mode == passwd_crypt)
pw_maxlen = 8;
else if (use1 || useapr1)
pw_maxlen = 256; /* arbitrary limit, should be enough for most
* passwords */
if (passwds == NULL) {
/* no passwords on the command line */
@@ -204,7 +231,7 @@ int passwd_main(int argc, char **argv)
* avoid rot of not-frequently-used code.
*/
if (1) {
# ifndef OPENSSL_NO_UI
#ifndef OPENSSL_NO_UI_CONSOLE
/* build a null-terminated list */
static char *passwds_static[2] = { NULL, NULL };
@@ -217,7 +244,7 @@ int passwd_main(int argc, char **argv)
}
passwds[0] = passwd_malloc;
} else {
# endif
#endif
BIO_printf(bio_err, "password required\n");
goto end;
}
@@ -230,8 +257,7 @@ int passwd_main(int argc, char **argv)
do { /* loop over list of passwords */
passwd = *passwds++;
if (!do_passwd(passed_salt, &salt, &salt_malloc, passwd, bio_out,
quiet, table, reverse, pw_maxlen, usecrypt, use1,
useapr1))
quiet, table, reverse, pw_maxlen, mode))
goto end;
} while (*passwds != NULL);
} else {
@@ -255,7 +281,7 @@ int passwd_main(int argc, char **argv)
if (!do_passwd
(passed_salt, &salt, &salt_malloc, passwd, bio_out, quiet,
table, reverse, pw_maxlen, usecrypt, use1, useapr1))
table, reverse, pw_maxlen, mode))
goto end;
}
done = (r <= 0);
@@ -264,14 +290,15 @@ int passwd_main(int argc, char **argv)
ret = 0;
end:
#if 0
ERR_print_errors(bio_err);
#endif
OPENSSL_free(salt_malloc);
OPENSSL_free(passwd_malloc);
BIO_free(in);
return (ret);
return ret;
}
# ifndef NO_MD5CRYPT_1
/*
* MD5-based password algorithm (should probably be available as a library
* function; then the static buffer would not be acceptable). For magic
@@ -286,6 +313,9 @@ static char *md5crypt(const char *passwd, const char *magic, const char *salt)
/* "$apr1$..salt..$.......md5hash..........\0" */
static char out_buf[6 + 9 + 24 + 2];
unsigned char buf[MD5_DIGEST_LENGTH];
char ascii_magic[5]; /* "apr1" plus '\0' */
char ascii_salt[9]; /* Max 8 chars plus '\0' */
char *ascii_passwd = NULL;
char *salt_out;
int n;
unsigned int i;
@@ -293,41 +323,72 @@ static char *md5crypt(const char *passwd, const char *magic, const char *salt)
size_t passwd_len, salt_len, magic_len;
passwd_len = strlen(passwd);
out_buf[0] = '$';
out_buf[1] = 0;
out_buf[0] = 0;
magic_len = strlen(magic);
OPENSSL_strlcpy(ascii_magic, magic, sizeof(ascii_magic));
#ifdef CHARSET_EBCDIC
if ((magic[0] & 0x80) != 0) /* High bit is 1 in EBCDIC alnums */
ebcdic2ascii(ascii_magic, ascii_magic, magic_len);
#endif
if (magic_len > 4) /* assert it's "1" or "apr1" */
/* The salt gets truncated to 8 chars */
OPENSSL_strlcpy(ascii_salt, salt, sizeof(ascii_salt));
salt_len = strlen(ascii_salt);
#ifdef CHARSET_EBCDIC
ebcdic2ascii(ascii_salt, ascii_salt, salt_len);
#endif
#ifdef CHARSET_EBCDIC
ascii_passwd = OPENSSL_strdup(passwd);
if (ascii_passwd == NULL)
return NULL;
ebcdic2ascii(ascii_passwd, ascii_passwd, passwd_len);
passwd = ascii_passwd;
#endif
OPENSSL_strlcat(out_buf, magic, sizeof(out_buf));
OPENSSL_strlcat(out_buf, "$", sizeof(out_buf));
OPENSSL_strlcat(out_buf, salt, sizeof(out_buf));
if (magic_len > 0) {
OPENSSL_strlcat(out_buf, ascii_dollar, sizeof(out_buf));
if (magic_len > 4) /* assert it's "1" or "apr1" */
goto err;
OPENSSL_strlcat(out_buf, ascii_magic, sizeof(out_buf));
OPENSSL_strlcat(out_buf, ascii_dollar, sizeof(out_buf));
}
OPENSSL_strlcat(out_buf, ascii_salt, sizeof(out_buf));
if (strlen(out_buf) > 6 + 8) /* assert "$apr1$..salt.." */
return NULL;
goto err;
salt_out = out_buf + 2 + magic_len;
salt_len = strlen(salt_out);
salt_out = out_buf;
if (magic_len > 0)
salt_out += 2 + magic_len;
if (salt_len > 8)
return NULL;
goto err;
md = EVP_MD_CTX_new();
if (md == NULL
|| !EVP_DigestInit_ex(md, EVP_md5(), NULL)
|| !EVP_DigestUpdate(md, passwd, passwd_len)
|| !EVP_DigestUpdate(md, "$", 1)
|| !EVP_DigestUpdate(md, magic, magic_len)
|| !EVP_DigestUpdate(md, "$", 1)
|| !EVP_DigestUpdate(md, salt_out, salt_len))
|| !EVP_DigestUpdate(md, passwd, passwd_len))
goto err;
if (magic_len > 0)
if (!EVP_DigestUpdate(md, ascii_dollar, 1)
|| !EVP_DigestUpdate(md, ascii_magic, magic_len)
|| !EVP_DigestUpdate(md, ascii_dollar, 1))
goto err;
if (!EVP_DigestUpdate(md, ascii_salt, salt_len))
goto err;
md2 = EVP_MD_CTX_new();
if (md2 == NULL
|| !EVP_DigestInit_ex(md2, EVP_md5(), NULL)
|| !EVP_DigestUpdate(md2, passwd, passwd_len)
|| !EVP_DigestUpdate(md2, salt_out, salt_len)
|| !EVP_DigestUpdate(md2, ascii_salt, salt_len)
|| !EVP_DigestUpdate(md2, passwd, passwd_len)
|| !EVP_DigestFinal_ex(md2, buf, NULL))
goto err;
@@ -356,7 +417,7 @@ static char *md5crypt(const char *passwd, const char *magic, const char *salt)
(i & 1) ? passwd_len : sizeof(buf)))
goto err;
if (i % 3) {
if (!EVP_DigestUpdate(md2, salt_out, salt_len))
if (!EVP_DigestUpdate(md2, ascii_salt, salt_len))
goto err;
}
if (i % 7) {
@@ -387,15 +448,15 @@ static char *md5crypt(const char *passwd, const char *magic, const char *salt)
buf_perm[dest] = buf[source];
buf_perm[14] = buf[5];
buf_perm[15] = buf[11];
# ifndef PEDANTIC /* Unfortunately, this generates a "no
# ifndef PEDANTIC /* Unfortunately, this generates a "no
* effect" warning */
assert(16 == sizeof(buf_perm));
# endif
# endif
output = salt_out + salt_len;
assert(output == out_buf + strlen(out_buf));
*output++ = '$';
*output++ = ascii_dollar[0];
for (i = 0; i < 15; i += 3) {
*output++ = cov_2char[buf_perm[i + 2] & 0x3f];
@@ -410,21 +471,309 @@ static char *md5crypt(const char *passwd, const char *magic, const char *salt)
*output++ = cov_2char[buf_perm[i] >> 6];
*output = 0;
assert(strlen(out_buf) < sizeof(out_buf));
#ifdef CHARSET_EBCDIC
ascii2ebcdic(out_buf, out_buf, strlen(out_buf));
#endif
}
return out_buf;
err:
OPENSSL_free(ascii_passwd);
EVP_MD_CTX_free(md2);
EVP_MD_CTX_free(md);
return NULL;
}
/*
* SHA based password algorithm, describe by Ulrich Drepper here:
* https://www.akkadia.org/drepper/SHA-crypt.txt
* (note that it's in the public domain)
*/
static char *shacrypt(const char *passwd, const char *magic, const char *salt)
{
/* Prefix for optional rounds specification. */
static const char rounds_prefix[] = "rounds=";
/* Maximum salt string length. */
# define SALT_LEN_MAX 16
/* Default number of rounds if not explicitly specified. */
# define ROUNDS_DEFAULT 5000
/* Minimum number of rounds. */
# define ROUNDS_MIN 1000
/* Maximum number of rounds. */
# define ROUNDS_MAX 999999999
/* "$6$rounds=<N>$......salt......$...shahash(up to 86 chars)...\0" */
static char out_buf[3 + 17 + 17 + 86 + 1];
unsigned char buf[SHA512_DIGEST_LENGTH];
unsigned char temp_buf[SHA512_DIGEST_LENGTH];
size_t buf_size = 0;
char ascii_magic[2];
char ascii_salt[17]; /* Max 16 chars plus '\0' */
char *ascii_passwd = NULL;
size_t n;
EVP_MD_CTX *md = NULL, *md2 = NULL;
const EVP_MD *sha = NULL;
size_t passwd_len, salt_len, magic_len;
unsigned int rounds = 5000; /* Default */
char rounds_custom = 0;
char *p_bytes = NULL;
char *s_bytes = NULL;
char *cp = NULL;
passwd_len = strlen(passwd);
magic_len = strlen(magic);
/* assert it's "5" or "6" */
if (magic_len != 1)
return NULL;
switch (magic[0]) {
case '5':
sha = EVP_sha256();
buf_size = 32;
break;
case '6':
sha = EVP_sha512();
buf_size = 64;
break;
default:
return NULL;
}
if (strncmp(salt, rounds_prefix, sizeof(rounds_prefix) - 1) == 0) {
const char *num = salt + sizeof(rounds_prefix) - 1;
char *endp;
unsigned long int srounds = strtoul (num, &endp, 10);
if (*endp == '$') {
salt = endp + 1;
if (srounds > ROUNDS_MAX)
rounds = ROUNDS_MAX;
else if (srounds < ROUNDS_MIN)
rounds = ROUNDS_MIN;
else
rounds = (unsigned int)srounds;
rounds_custom = 1;
} else {
return NULL;
}
}
OPENSSL_strlcpy(ascii_magic, magic, sizeof(ascii_magic));
#ifdef CHARSET_EBCDIC
if ((magic[0] & 0x80) != 0) /* High bit is 1 in EBCDIC alnums */
ebcdic2ascii(ascii_magic, ascii_magic, magic_len);
#endif
/* The salt gets truncated to 16 chars */
OPENSSL_strlcpy(ascii_salt, salt, sizeof(ascii_salt));
salt_len = strlen(ascii_salt);
#ifdef CHARSET_EBCDIC
ebcdic2ascii(ascii_salt, ascii_salt, salt_len);
#endif
#ifdef CHARSET_EBCDIC
ascii_passwd = OPENSSL_strdup(passwd);
if (ascii_passwd == NULL)
return NULL;
ebcdic2ascii(ascii_passwd, ascii_passwd, passwd_len);
passwd = ascii_passwd;
#endif
out_buf[0] = 0;
OPENSSL_strlcat(out_buf, ascii_dollar, sizeof(out_buf));
OPENSSL_strlcat(out_buf, ascii_magic, sizeof(out_buf));
OPENSSL_strlcat(out_buf, ascii_dollar, sizeof(out_buf));
if (rounds_custom) {
char tmp_buf[80]; /* "rounds=999999999" */
sprintf(tmp_buf, "rounds=%u", rounds);
#ifdef CHARSET_EBCDIC
/* In case we're really on a ASCII based platform and just pretend */
if (tmp_buf[0] != 0x72) /* ASCII 'r' */
ebcdic2ascii(tmp_buf, tmp_buf, strlen(tmp_buf));
#endif
OPENSSL_strlcat(out_buf, tmp_buf, sizeof(out_buf));
OPENSSL_strlcat(out_buf, ascii_dollar, sizeof(out_buf));
}
OPENSSL_strlcat(out_buf, ascii_salt, sizeof(out_buf));
/* assert "$5$rounds=999999999$......salt......" */
if (strlen(out_buf) > 3 + 17 * rounds_custom + salt_len )
goto err;
md = EVP_MD_CTX_new();
if (md == NULL
|| !EVP_DigestInit_ex(md, sha, NULL)
|| !EVP_DigestUpdate(md, passwd, passwd_len)
|| !EVP_DigestUpdate(md, ascii_salt, salt_len))
goto err;
md2 = EVP_MD_CTX_new();
if (md2 == NULL
|| !EVP_DigestInit_ex(md2, sha, NULL)
|| !EVP_DigestUpdate(md2, passwd, passwd_len)
|| !EVP_DigestUpdate(md2, ascii_salt, salt_len)
|| !EVP_DigestUpdate(md2, passwd, passwd_len)
|| !EVP_DigestFinal_ex(md2, buf, NULL))
goto err;
for (n = passwd_len; n > buf_size; n -= buf_size) {
if (!EVP_DigestUpdate(md, buf, buf_size))
goto err;
}
if (!EVP_DigestUpdate(md, buf, n))
goto err;
n = passwd_len;
while (n) {
if (!EVP_DigestUpdate(md,
(n & 1) ? buf : (unsigned const char *)passwd,
(n & 1) ? buf_size : passwd_len))
goto err;
n >>= 1;
}
if (!EVP_DigestFinal_ex(md, buf, NULL))
return NULL;
/* P sequence */
if (!EVP_DigestInit_ex(md2, sha, NULL))
goto err;
for (n = passwd_len; n > 0; n--)
if (!EVP_DigestUpdate(md2, passwd, passwd_len))
goto err;
if (!EVP_DigestFinal_ex(md2, temp_buf, NULL))
return NULL;
if ((p_bytes = OPENSSL_zalloc(passwd_len)) == NULL)
goto err;
for (cp = p_bytes, n = passwd_len; n > buf_size; n -= buf_size, cp += buf_size)
memcpy(cp, temp_buf, buf_size);
memcpy(cp, temp_buf, n);
/* S sequence */
if (!EVP_DigestInit_ex(md2, sha, NULL))
goto err;
for (n = 16 + buf[0]; n > 0; n--)
if (!EVP_DigestUpdate(md2, ascii_salt, salt_len))
goto err;
if (!EVP_DigestFinal_ex(md2, temp_buf, NULL))
return NULL;
if ((s_bytes = OPENSSL_zalloc(salt_len)) == NULL)
goto err;
for (cp = s_bytes, n = salt_len; n > buf_size; n -= buf_size, cp += buf_size)
memcpy(cp, temp_buf, buf_size);
memcpy(cp, temp_buf, n);
for (n = 0; n < rounds; n++) {
if (!EVP_DigestInit_ex(md2, sha, NULL))
goto err;
if (!EVP_DigestUpdate(md2,
(n & 1) ? (unsigned const char *)p_bytes : buf,
(n & 1) ? passwd_len : buf_size))
goto err;
if (n % 3) {
if (!EVP_DigestUpdate(md2, s_bytes, salt_len))
goto err;
}
if (n % 7) {
if (!EVP_DigestUpdate(md2, p_bytes, passwd_len))
goto err;
}
if (!EVP_DigestUpdate(md2,
(n & 1) ? buf : (unsigned const char *)p_bytes,
(n & 1) ? buf_size : passwd_len))
goto err;
if (!EVP_DigestFinal_ex(md2, buf, NULL))
goto err;
}
EVP_MD_CTX_free(md2);
EVP_MD_CTX_free(md);
md2 = NULL;
md = NULL;
OPENSSL_free(p_bytes);
OPENSSL_free(s_bytes);
p_bytes = NULL;
s_bytes = NULL;
cp = out_buf + strlen(out_buf);
*cp++ = ascii_dollar[0];
# define b64_from_24bit(B2, B1, B0, N) \
do { \
unsigned int w = ((B2) << 16) | ((B1) << 8) | (B0); \
int i = (N); \
while (i-- > 0) \
{ \
*cp++ = cov_2char[w & 0x3f]; \
w >>= 6; \
} \
} while (0)
switch (magic[0]) {
case '5':
b64_from_24bit (buf[0], buf[10], buf[20], 4);
b64_from_24bit (buf[21], buf[1], buf[11], 4);
b64_from_24bit (buf[12], buf[22], buf[2], 4);
b64_from_24bit (buf[3], buf[13], buf[23], 4);
b64_from_24bit (buf[24], buf[4], buf[14], 4);
b64_from_24bit (buf[15], buf[25], buf[5], 4);
b64_from_24bit (buf[6], buf[16], buf[26], 4);
b64_from_24bit (buf[27], buf[7], buf[17], 4);
b64_from_24bit (buf[18], buf[28], buf[8], 4);
b64_from_24bit (buf[9], buf[19], buf[29], 4);
b64_from_24bit (0, buf[31], buf[30], 3);
break;
case '6':
b64_from_24bit (buf[0], buf[21], buf[42], 4);
b64_from_24bit (buf[22], buf[43], buf[1], 4);
b64_from_24bit (buf[44], buf[2], buf[23], 4);
b64_from_24bit (buf[3], buf[24], buf[45], 4);
b64_from_24bit (buf[25], buf[46], buf[4], 4);
b64_from_24bit (buf[47], buf[5], buf[26], 4);
b64_from_24bit (buf[6], buf[27], buf[48], 4);
b64_from_24bit (buf[28], buf[49], buf[7], 4);
b64_from_24bit (buf[50], buf[8], buf[29], 4);
b64_from_24bit (buf[9], buf[30], buf[51], 4);
b64_from_24bit (buf[31], buf[52], buf[10], 4);
b64_from_24bit (buf[53], buf[11], buf[32], 4);
b64_from_24bit (buf[12], buf[33], buf[54], 4);
b64_from_24bit (buf[34], buf[55], buf[13], 4);
b64_from_24bit (buf[56], buf[14], buf[35], 4);
b64_from_24bit (buf[15], buf[36], buf[57], 4);
b64_from_24bit (buf[37], buf[58], buf[16], 4);
b64_from_24bit (buf[59], buf[17], buf[38], 4);
b64_from_24bit (buf[18], buf[39], buf[60], 4);
b64_from_24bit (buf[40], buf[61], buf[19], 4);
b64_from_24bit (buf[62], buf[20], buf[41], 4);
b64_from_24bit (0, 0, buf[63], 2);
break;
default:
goto err;
}
*cp = '\0';
#ifdef CHARSET_EBCDIC
ascii2ebcdic(out_buf, out_buf, strlen(out_buf));
#endif
return out_buf;
err:
EVP_MD_CTX_free(md2);
EVP_MD_CTX_free(md);
OPENSSL_free(p_bytes);
OPENSSL_free(s_bytes);
OPENSSL_free(ascii_passwd);
return NULL;
}
# endif
static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p,
char *passwd, BIO *out, int quiet, int table,
int reverse, size_t pw_maxlen, int usecrypt, int use1,
int useapr1)
int reverse, size_t pw_maxlen, passwd_modes mode)
{
char *hash = NULL;
@@ -433,36 +782,34 @@ static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p,
/* first make sure we have a salt */
if (!passed_salt) {
# ifndef OPENSSL_NO_DES
if (usecrypt) {
if (*salt_malloc_p == NULL)
*salt_p = *salt_malloc_p = app_malloc(3, "salt buffer");
if (RAND_bytes((unsigned char *)*salt_p, 2) <= 0)
goto end;
(*salt_p)[0] = cov_2char[(*salt_p)[0] & 0x3f]; /* 6 bits */
(*salt_p)[1] = cov_2char[(*salt_p)[1] & 0x3f]; /* 6 bits */
(*salt_p)[2] = 0;
# ifdef CHARSET_EBCDIC
ascii2ebcdic(*salt_p, *salt_p, 2); /* des_crypt will convert back
* to ASCII */
# endif
}
# endif /* !OPENSSL_NO_DES */
size_t saltlen = 0;
size_t i;
# ifndef NO_MD5CRYPT_1
if (use1 || useapr1) {
int i;
#ifndef OPENSSL_NO_DES
if (mode == passwd_crypt)
saltlen = 2;
#endif /* !OPENSSL_NO_DES */
if (*salt_malloc_p == NULL)
*salt_p = *salt_malloc_p = app_malloc(9, "salt buffer");
if (RAND_bytes((unsigned char *)*salt_p, 8) <= 0)
goto end;
if (mode == passwd_md5 || mode == passwd_apr1 || mode == passwd_aixmd5)
saltlen = 8;
for (i = 0; i < 8; i++)
(*salt_p)[i] = cov_2char[(*salt_p)[i] & 0x3f]; /* 6 bits */
(*salt_p)[8] = 0;
}
# endif /* !NO_MD5CRYPT_1 */
if (mode == passwd_sha256 || mode == passwd_sha512)
saltlen = 16;
assert(saltlen != 0);
if (*salt_malloc_p == NULL)
*salt_p = *salt_malloc_p = app_malloc(saltlen + 1, "salt buffer");
if (RAND_bytes((unsigned char *)*salt_p, saltlen) <= 0)
goto end;
for (i = 0; i < saltlen; i++)
(*salt_p)[i] = cov_2char[(*salt_p)[i] & 0x3f]; /* 6 bits */
(*salt_p)[i] = 0;
# ifdef CHARSET_EBCDIC
/* The password encryption funtion will convert back to ASCII */
ascii2ebcdic(*salt_p, *salt_p, saltlen);
# endif
}
assert(*salt_p != NULL);
@@ -481,14 +828,16 @@ static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p,
assert(strlen(passwd) <= pw_maxlen);
/* now compute password hash */
# ifndef OPENSSL_NO_DES
if (usecrypt)
#ifndef OPENSSL_NO_DES
if (mode == passwd_crypt)
hash = DES_crypt(passwd, *salt_p);
# endif
# ifndef NO_MD5CRYPT_1
if (use1 || useapr1)
hash = md5crypt(passwd, (use1 ? "1" : "apr1"), *salt_p);
# endif
#endif
if (mode == passwd_md5 || mode == passwd_apr1)
hash = md5crypt(passwd, (mode == passwd_md5 ? "1" : "apr1"), *salt_p);
if (mode == passwd_aixmd5)
hash = md5crypt(passwd, "", *salt_p);
if (mode == passwd_sha256 || mode == passwd_sha512)
hash = shacrypt(passwd, (mode == passwd_sha256 ? "5" : "6"), *salt_p);
assert(hash != NULL);
if (table && !reverse)
@@ -502,11 +851,3 @@ static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p,
end:
return 0;
}
#else
int passwd_main(int argc, char **argv)
{
BIO_printf(bio_err, "Program not available.\n");
return (1);
}
#endif
+72 -46
View File
@@ -1,5 +1,5 @@
/*
* Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1999-2018 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
@@ -16,6 +16,7 @@ NON_EMPTY_TRANSLATION_UNIT
# include <stdlib.h>
# include <string.h>
# include "apps.h"
# include "progs.h"
# include <openssl/crypto.h>
# include <openssl/err.h>
# include <openssl/pem.h>
@@ -27,6 +28,8 @@ NON_EMPTY_TRANSLATION_UNIT
# define CLCERTS 0x8
# define CACERTS 0x10
#define PASSWD_BUF_SIZE 2048
static int get_cert_chain(X509 *cert, X509_STORE *store,
STACK_OF(X509) **chain);
int dump_certs_keys_p12(BIO *out, const PKCS12 *p12,
@@ -51,12 +54,13 @@ typedef enum OPTION_choice {
OPT_CACERTS, OPT_NOOUT, OPT_INFO, OPT_CHAIN, OPT_TWOPASS, OPT_NOMACVER,
OPT_DESCERT, OPT_EXPORT, OPT_NOITER, OPT_MACITER, OPT_NOMACITER,
OPT_NOMAC, OPT_LMK, OPT_NODES, OPT_MACALG, OPT_CERTPBE, OPT_KEYPBE,
OPT_RAND, OPT_INKEY, OPT_CERTFILE, OPT_NAME, OPT_CSP, OPT_CANAME,
OPT_INKEY, OPT_CERTFILE, OPT_NAME, OPT_CSP, OPT_CANAME,
OPT_IN, OPT_OUT, OPT_PASSIN, OPT_PASSOUT, OPT_PASSWORD, OPT_CAPATH,
OPT_CAFILE, OPT_NOCAPATH, OPT_NOCAFILE, OPT_ENGINE
OPT_CAFILE, OPT_NOCAPATH, OPT_NOCAFILE, OPT_ENGINE,
OPT_R_ENUM
} OPTION_CHOICE;
OPTIONS pkcs12_options[] = {
const OPTIONS pkcs12_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"nokeys", OPT_NOKEYS, '-', "Don't output private keys"},
{"keyex", OPT_KEYEX, '-', "Set MS key exchange type"},
@@ -89,8 +93,7 @@ OPTIONS pkcs12_options[] = {
{"macalg", OPT_MACALG, 's',
"Digest algorithm used in MAC (default SHA1)"},
{"keypbe", OPT_KEYPBE, 's', "Private key PBE algorithm (default 3DES)"},
{"rand", OPT_RAND, 's',
"Load the file(s) into the random number generator"},
OPT_R_OPTIONS,
{"inkey", OPT_INKEY, 's', "Private key if not infile"},
{"certfile", OPT_CERTFILE, '<', "Load certs from file"},
{"name", OPT_NAME, 's', "Use name as friendly name"},
@@ -119,7 +122,7 @@ int pkcs12_main(int argc, char **argv)
{
char *infile = NULL, *outfile = NULL, *keyname = NULL, *certfile = NULL;
char *name = NULL, *csp_name = NULL;
char pass[2048] = "", macpass[2048] = "";
char pass[PASSWD_BUF_SIZE] = "", macpass[PASSWD_BUF_SIZE] = "";
int export_cert = 0, options = 0, chain = 0, twopass = 0, keytype = 0;
int iter = PKCS12_DEFAULT_ITER, maciter = PKCS12_DEFAULT_ITER;
# ifndef OPENSSL_NO_RC2
@@ -131,7 +134,7 @@ int pkcs12_main(int argc, char **argv)
int ret = 1, macver = 1, add_lmk = 0, private = 0;
int noprompt = 0;
char *passinarg = NULL, *passoutarg = NULL, *passarg = NULL;
char *passin = NULL, *passout = NULL, *inrand = NULL, *macalg = NULL;
char *passin = NULL, *passout = NULL, *macalg = NULL;
char *cpass = NULL, *mpass = NULL, *badpass = NULL;
const char *CApath = NULL, *CAfile = NULL, *prog;
int noCApath = 0, noCAfile = 0;
@@ -223,8 +226,9 @@ int pkcs12_main(int argc, char **argv)
if (!set_pbe(&key_pbe, opt_arg()))
goto opthelp;
break;
case OPT_RAND:
inrand = opt_arg();
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
case OPT_INKEY:
keyname = opt_arg();
@@ -285,7 +289,7 @@ int pkcs12_main(int argc, char **argv)
private = 1;
if (passarg) {
if (passarg != NULL) {
if (export_cert)
passoutarg = passarg;
else
@@ -297,14 +301,14 @@ int pkcs12_main(int argc, char **argv)
goto end;
}
if (!cpass) {
if (cpass == NULL) {
if (export_cert)
cpass = passout;
else
cpass = passin;
}
if (cpass) {
if (cpass != NULL) {
mpass = cpass;
noprompt = 1;
} else {
@@ -312,18 +316,12 @@ int pkcs12_main(int argc, char **argv)
mpass = macpass;
}
if (export_cert || inrand) {
app_RAND_load_file(NULL, (inrand != NULL));
if (inrand != NULL)
BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
app_RAND_load_files(inrand));
}
if (twopass) {
/* To avoid bit rot */
if (1) {
#ifndef OPENSSL_NO_UI
if (EVP_read_pw_string
(macpass, sizeof(macpass), "Enter MAC Password:", export_cert)) {
#ifndef OPENSSL_NO_UI_CONSOLE
if (EVP_read_pw_string(
macpass, sizeof(macpass), "Enter MAC Password:", export_cert)) {
BIO_printf(bio_err, "Can't read Password\n");
goto end;
}
@@ -353,7 +351,7 @@ int pkcs12_main(int argc, char **argv)
if (!(options & NOKEYS)) {
key = load_key(keyname ? keyname : infile,
FORMAT_PEM, 1, passin, e, "private key");
if (!key)
if (key == NULL)
goto export_end;
}
@@ -363,7 +361,7 @@ int pkcs12_main(int argc, char **argv)
"certificates"))
goto export_end;
if (key) {
if (key != NULL) {
/* Look for matching private key */
for (i = 0; i < sk_X509_num(certs); i++) {
x = sk_X509_value(certs, i);
@@ -377,7 +375,7 @@ int pkcs12_main(int argc, char **argv)
break;
}
}
if (!ucert) {
if (ucert == NULL) {
BIO_printf(bio_err,
"No certificate matches private key\n");
goto export_end;
@@ -387,7 +385,7 @@ int pkcs12_main(int argc, char **argv)
}
/* Add any more certificates asked for */
if (certfile) {
if (certfile != NULL) {
if (!load_certs(certfile, &certs, FORMAT_PEM, NULL,
"certificates from certfile"))
goto export_end;
@@ -429,19 +427,20 @@ int pkcs12_main(int argc, char **argv)
X509_alias_set1(sk_X509_value(certs, i), catmp, -1);
}
if (csp_name && key)
if (csp_name != NULL && key != NULL)
EVP_PKEY_add1_attr_by_NID(key, NID_ms_csp_name,
MBSTRING_ASC, (unsigned char *)csp_name,
-1);
if (add_lmk && key)
if (add_lmk && key != NULL)
EVP_PKEY_add1_attr_by_NID(key, NID_LocalKeySet, 0, NULL, -1);
if (!noprompt) {
/* To avoid bit rot */
if (1) {
#ifndef OPENSSL_NO_UI
if (EVP_read_pw_string(pass, sizeof(pass), "Enter Export Password:",
1)) {
#ifndef OPENSSL_NO_UI_CONSOLE
if (EVP_read_pw_string(pass, sizeof(pass),
"Enter Export Password:", 1)) {
BIO_printf(bio_err, "Can't read Password\n");
goto export_end;
}
@@ -505,7 +504,7 @@ int pkcs12_main(int argc, char **argv)
if (!noprompt) {
if (1) {
#ifndef OPENSSL_NO_UI
#ifndef OPENSSL_NO_UI_CONSOLE
if (EVP_read_pw_string(pass, sizeof(pass), "Enter Import Password:",
0)) {
BIO_printf(bio_err, "Can't read Password\n");
@@ -525,12 +524,20 @@ int pkcs12_main(int argc, char **argv)
const ASN1_INTEGER *tmaciter;
const X509_ALGOR *macalgid;
const ASN1_OBJECT *macobj;
PKCS12_get0_mac(NULL, &macalgid, NULL, &tmaciter, p12);
const ASN1_OCTET_STRING *tmac;
const ASN1_OCTET_STRING *tsalt;
PKCS12_get0_mac(&tmac, &macalgid, &tsalt, &tmaciter, p12);
/* current hash algorithms do not use parameters so extract just name,
in future alg_print() may be needed */
X509_ALGOR_get0(&macobj, NULL, NULL, macalgid);
BIO_puts(bio_err, "MAC:");
BIO_puts(bio_err, "MAC: ");
i2a_ASN1_OBJECT(bio_err, macobj);
BIO_printf(bio_err, " Iteration %ld\n",
tmaciter != NULL ? ASN1_INTEGER_get(tmaciter) : 1L);
BIO_printf(bio_err, ", Iteration %ld\n",
tmaciter != NULL ? ASN1_INTEGER_get(tmaciter) : 1L);
BIO_printf(bio_err, "MAC length: %ld, salt length: %ld\n",
tmac != NULL ? ASN1_STRING_length(tmac) : 0L,
tsalt != NULL ? ASN1_STRING_length(tsalt) : 0L);
}
if (macver) {
/* If we enter empty password try no password first */
@@ -572,8 +579,6 @@ int pkcs12_main(int argc, char **argv)
ret = 0;
end:
PKCS12_free(p12);
if (export_cert || inrand)
app_RAND_write_file(NULL);
release_engine(e);
BIO_free(in);
BIO_free_all(out);
@@ -581,7 +586,7 @@ int pkcs12_main(int argc, char **argv)
OPENSSL_free(badpass);
OPENSSL_free(passin);
OPENSSL_free(passout);
return (ret);
return ret;
}
int dump_certs_keys_p12(BIO *out, const PKCS12 *p12, const char *pass,
@@ -609,8 +614,9 @@ int dump_certs_keys_p12(BIO *out, const PKCS12 *p12, const char *pass,
alg_print(p7->d.encrypted->enc_data->algorithm);
}
bags = PKCS12_unpack_p7encdata(p7, pass, passlen);
} else
} else {
continue;
}
if (!bags)
goto err;
if (!dump_certs_pkeys_bags(out, bags, pass, passlen,
@@ -785,7 +791,7 @@ static int alg_print(const X509_ALGOR *alg)
if (aparamtype == V_ASN1_SEQUENCE)
pbe2 = ASN1_item_unpack(aparam, ASN1_ITEM_rptr(PBE2PARAM));
if (pbe2 == NULL) {
BIO_puts(bio_err, "<unsupported parameters>");
BIO_puts(bio_err, ", <unsupported parameters>");
goto done;
}
X509_ALGOR_get0(&aoid, &aparamtype, &aparam, pbe2->keyfunc);
@@ -801,7 +807,7 @@ static int alg_print(const X509_ALGOR *alg)
if (aparamtype == V_ASN1_SEQUENCE)
kdf = ASN1_item_unpack(aparam, ASN1_ITEM_rptr(PBKDF2PARAM));
if (kdf == NULL) {
BIO_puts(bio_err, "<unsupported parameters>");
BIO_puts(bio_err, ", <unsupported parameters>");
goto done;
}
@@ -814,13 +820,31 @@ static int alg_print(const X509_ALGOR *alg)
BIO_printf(bio_err, ", Iteration %ld, PRF %s",
ASN1_INTEGER_get(kdf->iter), OBJ_nid2sn(prfnid));
PBKDF2PARAM_free(kdf);
#ifndef OPENSSL_NO_SCRYPT
} else if (pbenid == NID_id_scrypt) {
SCRYPT_PARAMS *kdf = NULL;
if (aparamtype == V_ASN1_SEQUENCE)
kdf = ASN1_item_unpack(aparam, ASN1_ITEM_rptr(SCRYPT_PARAMS));
if (kdf == NULL) {
BIO_puts(bio_err, ", <unsupported parameters>");
goto done;
}
BIO_printf(bio_err, ", Salt length: %d, Cost(N): %ld, "
"Block size(r): %ld, Paralelizm(p): %ld",
ASN1_STRING_length(kdf->salt),
ASN1_INTEGER_get(kdf->costParameter),
ASN1_INTEGER_get(kdf->blockSize),
ASN1_INTEGER_get(kdf->parallelizationParameter));
SCRYPT_PARAMS_free(kdf);
#endif
}
PBE2PARAM_free(pbe2);
} else {
if (aparamtype == V_ASN1_SEQUENCE)
pbe = ASN1_item_unpack(aparam, ASN1_ITEM_rptr(PBEPARAM));
if (pbe == NULL) {
BIO_puts(bio_err, "<unsupported parameters>");
BIO_puts(bio_err, ", <unsupported parameters>");
goto done;
}
BIO_printf(bio_err, ", Iteration %ld", ASN1_INTEGER_get(pbe->iter));
@@ -874,8 +898,9 @@ int print_attribs(BIO *out, const STACK_OF(X509_ATTRIBUTE) *attrlst,
if (attr_nid == NID_undef) {
i2a_ASN1_OBJECT(out, attr_obj);
BIO_printf(out, ": ");
} else
} else {
BIO_printf(out, "%s: ", OBJ_nid2ln(attr_nid));
}
if (X509_ATTRIBUTE_count(attr)) {
av = X509_ATTRIBUTE_get0_type(attr, 0);
@@ -903,8 +928,9 @@ int print_attribs(BIO *out, const STACK_OF(X509_ATTRIBUTE) *attrlst,
BIO_printf(out, "<Unsupported tag %d>\n", av->type);
break;
}
} else
} else {
BIO_printf(out, "<No Values>\n");
}
}
return 1;
}
+5 -4
View File
@@ -1,5 +1,5 @@
/*
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2018 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
@@ -12,6 +12,7 @@
#include <string.h>
#include <time.h>
#include "apps.h"
#include "progs.h"
#include <openssl/err.h>
#include <openssl/objects.h>
#include <openssl/evp.h>
@@ -25,7 +26,7 @@ typedef enum OPTION_choice {
OPT_TEXT, OPT_PRINT, OPT_PRINT_CERTS, OPT_ENGINE
} OPTION_CHOICE;
OPTIONS pkcs7_options[] = {
const OPTIONS pkcs7_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"inform", OPT_INFORM, 'F', "Input format - DER or PEM"},
{"in", OPT_IN, '<', "Input file"},
@@ -163,7 +164,7 @@ int pkcs7_main(int argc, char **argv)
for (i = 0; i < sk_X509_CRL_num(crls); i++) {
crl = sk_X509_CRL_value(crls, i);
X509_CRL_print(out, crl);
X509_CRL_print_ex(out, crl, get_nameopt());
if (!noout)
PEM_write_bio_X509_CRL(out, crl);
@@ -193,5 +194,5 @@ int pkcs7_main(int argc, char **argv)
release_engine(e);
BIO_free(in);
BIO_free_all(out);
return (ret);
return ret;
}
+30 -24
View File
@@ -1,5 +1,5 @@
/*
* Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1999-2018 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
@@ -11,6 +11,7 @@
#include <stdlib.h>
#include <string.h>
#include "apps.h"
#include "progs.h"
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/evp.h>
@@ -24,10 +25,11 @@ typedef enum OPTION_choice {
OPT_SCRYPT, OPT_SCRYPT_N, OPT_SCRYPT_R, OPT_SCRYPT_P,
#endif
OPT_V2, OPT_V1, OPT_V2PRF, OPT_ITER, OPT_PASSIN, OPT_PASSOUT,
OPT_TRADITIONAL
OPT_TRADITIONAL,
OPT_R_ENUM
} OPTION_CHOICE;
OPTIONS pkcs8_options[] = {
const OPTIONS pkcs8_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"inform", OPT_INFORM, 'F', "Input format (DER or PEM)"},
{"outform", OPT_OUTFORM, 'F', "Output format (DER or PEM)"},
@@ -36,6 +38,7 @@ OPTIONS pkcs8_options[] = {
{"topk8", OPT_TOPK8, '-', "Output PKCS8 file"},
{"noiter", OPT_NOITER, '-', "Use 1 as iteration count"},
{"nocrypt", OPT_NOCRYPT, '-', "Use or expect unencrypted private key"},
OPT_R_OPTIONS,
{"v2", OPT_V2, 's', "Use PKCS#5 v2.0 and cipher"},
{"v1", OPT_V1, 's', "Use PKCS#5 v1.5 and cipher"},
{"v2prf", OPT_V2PRF, 's', "Set the PRF algorithm to use with PKCS#5 v2.0"},
@@ -65,7 +68,7 @@ int pkcs8_main(int argc, char **argv)
const EVP_CIPHER *cipher = NULL;
char *infile = NULL, *outfile = NULL;
char *passinarg = NULL, *passoutarg = NULL, *prog;
#ifndef OPENSSL_NO_UI
#ifndef OPENSSL_NO_UI_CONSOLE
char pass[APP_PASS_LEN];
#endif
char *passin = NULL, *passout = NULL, *p8pass = NULL;
@@ -112,6 +115,10 @@ int pkcs8_main(int argc, char **argv)
case OPT_NOCRYPT:
nocrypt = 1;
break;
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
case OPT_TRADITIONAL:
traditional = 1;
break;
@@ -196,7 +203,7 @@ int pkcs8_main(int argc, char **argv)
if (topk8) {
pkey = load_key(infile, informat, 1, passin, e, "key");
if (!pkey)
if (pkey == NULL)
goto end;
if ((p8inf = EVP_PKEY2PKCS8(pkey)) == NULL) {
BIO_printf(bio_err, "Error converting key\n");
@@ -205,11 +212,11 @@ int pkcs8_main(int argc, char **argv)
}
if (nocrypt) {
assert(private);
if (outformat == FORMAT_PEM)
if (outformat == FORMAT_PEM) {
PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8inf);
else if (outformat == FORMAT_ASN1)
} else if (outformat == FORMAT_ASN1) {
i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8inf);
else {
} else {
BIO_printf(bio_err, "Bad format specified for key\n");
goto end;
}
@@ -232,10 +239,11 @@ int pkcs8_main(int argc, char **argv)
ERR_print_errors(bio_err);
goto end;
}
if (passout)
if (passout != NULL) {
p8pass = passout;
else if (1) {
#ifndef OPENSSL_NO_UI
} else if (1) {
/* To avoid bit rot */
#ifndef OPENSSL_NO_UI_CONSOLE
p8pass = pass;
if (EVP_read_pw_string
(pass, sizeof(pass), "Enter Encryption Password:", 1)) {
@@ -247,7 +255,6 @@ int pkcs8_main(int argc, char **argv)
BIO_printf(bio_err, "Password required\n");
goto end;
}
app_RAND_load_file(NULL, 0);
p8 = PKCS8_set0_pbe(p8pass, strlen(p8pass), p8inf, pbe);
if (p8 == NULL) {
X509_ALGOR_free(pbe);
@@ -255,7 +262,6 @@ int pkcs8_main(int argc, char **argv)
ERR_print_errors(bio_err);
goto end;
}
app_RAND_write_file(NULL);
assert(private);
if (outformat == FORMAT_PEM)
PEM_write_bio_PKCS8(out, p8);
@@ -272,33 +278,33 @@ int pkcs8_main(int argc, char **argv)
}
if (nocrypt) {
if (informat == FORMAT_PEM)
if (informat == FORMAT_PEM) {
p8inf = PEM_read_bio_PKCS8_PRIV_KEY_INFO(in, NULL, NULL, NULL);
else if (informat == FORMAT_ASN1)
} else if (informat == FORMAT_ASN1) {
p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(in, NULL);
else {
} else {
BIO_printf(bio_err, "Bad format specified for key\n");
goto end;
}
} else {
if (informat == FORMAT_PEM)
if (informat == FORMAT_PEM) {
p8 = PEM_read_bio_PKCS8(in, NULL, NULL, NULL);
else if (informat == FORMAT_ASN1)
} else if (informat == FORMAT_ASN1) {
p8 = d2i_PKCS8_bio(in, NULL);
else {
} else {
BIO_printf(bio_err, "Bad format specified for key\n");
goto end;
}
if (!p8) {
if (p8 == NULL) {
BIO_printf(bio_err, "Error reading key\n");
ERR_print_errors(bio_err);
goto end;
}
if (passin)
if (passin != NULL) {
p8pass = passin;
else if (1) {
#ifndef OPENSSL_NO_UI
} else if (1) {
#ifndef OPENSSL_NO_UI_CONSOLE
p8pass = pass;
if (EVP_read_pw_string(pass, sizeof(pass), "Enter Password:", 0)) {
BIO_printf(bio_err, "Can't read Password\n");
@@ -312,7 +318,7 @@ int pkcs8_main(int argc, char **argv)
p8inf = PKCS8_decrypt(p8, p8pass, strlen(p8pass));
}
if (!p8inf) {
if (p8inf == NULL) {
BIO_printf(bio_err, "Error decrypting key\n");
ERR_print_errors(bio_err);
goto end;
+57 -12
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2006-2018 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
@@ -10,6 +10,7 @@
#include <stdio.h>
#include <string.h>
#include "apps.h"
#include "progs.h"
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/evp.h>
@@ -18,10 +19,10 @@ typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_INFORM, OPT_OUTFORM, OPT_PASSIN, OPT_PASSOUT, OPT_ENGINE,
OPT_IN, OPT_OUT, OPT_PUBIN, OPT_PUBOUT, OPT_TEXT_PUB,
OPT_TEXT, OPT_NOOUT, OPT_MD, OPT_TRADITIONAL
OPT_TEXT, OPT_NOOUT, OPT_MD, OPT_TRADITIONAL, OPT_CHECK, OPT_PUB_CHECK
} OPTION_CHOICE;
OPTIONS pkey_options[] = {
const OPTIONS pkey_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"inform", OPT_INFORM, 'f', "Input format (DER or PEM)"},
{"outform", OPT_OUTFORM, 'F', "Output format (DER or PEM)"},
@@ -41,6 +42,8 @@ OPTIONS pkey_options[] = {
#ifndef OPENSSL_NO_ENGINE
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
#endif
{"check", OPT_CHECK, '-', "Check key consistency"},
{"pubcheck", OPT_PUB_CHECK, '-', "Check public key consistency"},
{NULL}
};
@@ -55,7 +58,7 @@ int pkey_main(int argc, char **argv)
OPTION_CHOICE o;
int informat = FORMAT_PEM, outformat = FORMAT_PEM;
int pubin = 0, pubout = 0, pubtext = 0, text = 0, noout = 0, ret = 1;
int private = 0, traditional = 0;
int private = 0, traditional = 0, check = 0, pub_check = 0;
prog = opt_init(argc, argv, pkey_options);
while ((o = opt_next()) != OPT_EOF) {
@@ -110,6 +113,12 @@ int pkey_main(int argc, char **argv)
case OPT_TRADITIONAL:
traditional = 1;
break;
case OPT_CHECK:
check = 1;
break;
case OPT_PUB_CHECK:
pub_check = 1;
break;
case OPT_MD:
if (!opt_cipher(opt_unknown(), &cipher))
goto opthelp;
@@ -136,14 +145,49 @@ int pkey_main(int argc, char **argv)
pkey = load_pubkey(infile, informat, 1, passin, e, "Public Key");
else
pkey = load_key(infile, informat, 1, passin, e, "key");
if (!pkey)
if (pkey == NULL)
goto end;
if (check || pub_check) {
int r;
EVP_PKEY_CTX *ctx;
ctx = EVP_PKEY_CTX_new(pkey, e);
if (ctx == NULL) {
ERR_print_errors(bio_err);
goto end;
}
if (check)
r = EVP_PKEY_check(ctx);
else
r = EVP_PKEY_public_check(ctx);
if (r == 1) {
BIO_printf(out, "Key is valid\n");
} else {
/*
* Note: at least for RSA keys if this function returns
* -1, there will be no error reasons.
*/
unsigned long err;
BIO_printf(out, "Key is invalid\n");
while ((err = ERR_peek_error()) != 0) {
BIO_printf(out, "Detailed error: %s\n",
ERR_reason_error_string(err));
ERR_get_error(); /* remove err from error stack */
}
}
EVP_PKEY_CTX_free(ctx);
}
if (!noout) {
if (outformat == FORMAT_PEM) {
if (pubout)
if (pubout) {
PEM_write_bio_PUBKEY(out, pkey);
else {
} else {
assert(private);
if (traditional)
PEM_write_bio_PrivateKey_traditional(out, pkey, cipher,
@@ -154,9 +198,9 @@ int pkey_main(int argc, char **argv)
NULL, 0, NULL, passout);
}
} else if (outformat == FORMAT_ASN1) {
if (pubout)
if (pubout) {
i2d_PUBKEY_bio(out, pkey);
else {
} else {
assert(private);
i2d_PrivateKey_bio(out, pkey);
}
@@ -164,13 +208,12 @@ int pkey_main(int argc, char **argv)
BIO_printf(bio_err, "Bad format specified for key\n");
goto end;
}
}
if (text) {
if (pubtext)
if (pubtext) {
EVP_PKEY_print_public(out, pkey, 0, NULL);
else {
} else {
assert(private);
EVP_PKEY_print_private(out, pkey, 0, NULL);
}
@@ -179,6 +222,8 @@ int pkey_main(int argc, char **argv)
ret = 0;
end:
if (ret != 0)
ERR_print_errors(bio_err);
EVP_PKEY_free(pkey);
release_engine(e);
BIO_free_all(out);
+43 -5
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2006-2018 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
@@ -10,16 +10,18 @@
#include <stdio.h>
#include <string.h>
#include "apps.h"
#include "progs.h"
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/evp.h>
typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_IN, OPT_OUT, OPT_TEXT, OPT_NOOUT, OPT_ENGINE
OPT_IN, OPT_OUT, OPT_TEXT, OPT_NOOUT,
OPT_ENGINE, OPT_CHECK
} OPTION_CHOICE;
OPTIONS pkeyparam_options[] = {
const OPTIONS pkeyparam_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"in", OPT_IN, '<', "Input file"},
{"out", OPT_OUT, '>', "Output file"},
@@ -28,6 +30,7 @@ OPTIONS pkeyparam_options[] = {
#ifndef OPENSSL_NO_ENGINE
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
#endif
{"check", OPT_CHECK, '-', "Check key param consistency"},
{NULL}
};
@@ -36,7 +39,7 @@ int pkeyparam_main(int argc, char **argv)
ENGINE *e = NULL;
BIO *in = NULL, *out = NULL;
EVP_PKEY *pkey = NULL;
int text = 0, noout = 0, ret = 1;
int text = 0, noout = 0, ret = 1, check = 0;
OPTION_CHOICE o;
char *infile = NULL, *outfile = NULL, *prog;
@@ -67,6 +70,9 @@ int pkeyparam_main(int argc, char **argv)
case OPT_NOOUT:
noout = 1;
break;
case OPT_CHECK:
check = 1;
break;
}
}
argc = opt_num_rest();
@@ -80,12 +86,44 @@ int pkeyparam_main(int argc, char **argv)
if (out == NULL)
goto end;
pkey = PEM_read_bio_Parameters(in, NULL);
if (!pkey) {
if (pkey == NULL) {
BIO_printf(bio_err, "Error reading parameters\n");
ERR_print_errors(bio_err);
goto end;
}
if (check) {
int r;
EVP_PKEY_CTX *ctx;
ctx = EVP_PKEY_CTX_new(pkey, e);
if (ctx == NULL) {
ERR_print_errors(bio_err);
goto end;
}
r = EVP_PKEY_param_check(ctx);
if (r == 1) {
BIO_printf(out, "Parameters are valid\n");
} else {
/*
* Note: at least for RSA keys if this function returns
* -1, there will be no error reasons.
*/
unsigned long err;
BIO_printf(out, "Parameters are invalid\n");
while ((err = ERR_peek_error()) != 0) {
BIO_printf(out, "Detailed error: %s\n",
ERR_reason_error_string(err));
ERR_get_error(); /* remove err from error stack */
}
}
EVP_PKEY_CTX_free(ctx);
}
if (!noout)
PEM_write_bio_Parameters(out, pkey);
+32 -40
View File
@@ -8,6 +8,7 @@
*/
#include "apps.h"
#include "progs.h"
#include <string.h>
#include <openssl/err.h>
#include <openssl/pem.h>
@@ -36,10 +37,11 @@ typedef enum OPTION_choice {
OPT_PUBIN, OPT_CERTIN, OPT_ASN1PARSE, OPT_HEXDUMP, OPT_SIGN,
OPT_VERIFY, OPT_VERIFYRECOVER, OPT_REV, OPT_ENCRYPT, OPT_DECRYPT,
OPT_DERIVE, OPT_SIGFILE, OPT_INKEY, OPT_PEERKEY, OPT_PASSIN,
OPT_PEERFORM, OPT_KEYFORM, OPT_PKEYOPT, OPT_KDF, OPT_KDFLEN
OPT_PEERFORM, OPT_KEYFORM, OPT_PKEYOPT, OPT_KDF, OPT_KDFLEN,
OPT_R_ENUM
} OPTION_CHOICE;
OPTIONS pkeyutl_options[] = {
const OPTIONS pkeyutl_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"in", OPT_IN, '<', "Input file - default stdin"},
{"out", OPT_OUT, '>', "Output file - default stdout"},
@@ -64,6 +66,7 @@ OPTIONS pkeyutl_options[] = {
{"peerform", OPT_PEERFORM, 'E', "Peer key format - default PEM"},
{"keyform", OPT_KEYFORM, 'E', "Private key format - default PEM"},
{"pkeyopt", OPT_PKEYOPT, 's', "Public key options as opt:value"},
OPT_R_OPTIONS,
#ifndef OPENSSL_NO_ENGINE
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
{"engine_impl", OPT_ENGINE_IMPL, '-',
@@ -81,7 +84,8 @@ int pkeyutl_main(int argc, char **argv)
char hexdump = 0, asn1parse = 0, rev = 0, *prog;
unsigned char *buf_in = NULL, *buf_out = NULL, *sig = NULL;
OPTION_CHOICE o;
int buf_inlen = 0, siglen = -1, keyform = FORMAT_PEM, peerform = FORMAT_PEM;
int buf_inlen = 0, siglen = -1, keyform = FORMAT_PEM, peerform =
FORMAT_PEM;
int keysize = -1, pkey_op = EVP_PKEY_OP_SIGN, key_type = KEY_PRIVKEY;
int engine_impl = 0;
int ret = 1, rv = -1;
@@ -133,6 +137,10 @@ int pkeyutl_main(int argc, char **argv)
if (!opt_format(opt_arg(), OPT_FMT_PDE, &keyform))
goto opthelp;
break;
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
case OPT_ENGINE:
e = setup_engine(opt_arg(), 0);
break;
@@ -192,18 +200,10 @@ int pkeyutl_main(int argc, char **argv)
goto opthelp;
if (kdfalg != NULL) {
if (kdflen == 0) {
BIO_printf(bio_err,
"%s: no KDF length given (-kdflen parameter).\n", prog);
if (kdflen == 0)
goto opthelp;
}
} else if (inkey == NULL) {
BIO_printf(bio_err,
"%s: no private key given (-inkey parameter).\n", prog);
goto opthelp;
} else if (peerkey != NULL && pkey_op != EVP_PKEY_OP_DERIVE) {
BIO_printf(bio_err,
"%s: no peer key given (-peerkey parameter).\n", prog);
} else if ((inkey == NULL)
|| (peerkey != NULL && pkey_op != EVP_PKEY_OP_DERIVE)) {
goto opthelp;
}
ctx = init_ctx(kdfalg, &keysize, inkey, keyform, key_type,
@@ -226,29 +226,25 @@ int pkeyutl_main(int argc, char **argv)
const char *opt = sk_OPENSSL_STRING_value(pkeyopts, i);
if (pkey_ctrl_string(ctx, opt) <= 0) {
BIO_printf(bio_err, "%s: Can't set parameter \"%s\":\n",
prog, opt);
BIO_printf(bio_err, "%s: Can't set parameter:\n", prog);
ERR_print_errors(bio_err);
goto end;
}
}
}
if (sigfile && (pkey_op != EVP_PKEY_OP_VERIFY)) {
if (sigfile != NULL && (pkey_op != EVP_PKEY_OP_VERIFY)) {
BIO_printf(bio_err,
"%s: Signature file specified for non verify\n", prog);
goto end;
}
if (!sigfile && (pkey_op == EVP_PKEY_OP_VERIFY)) {
if (sigfile == NULL && (pkey_op == EVP_PKEY_OP_VERIFY)) {
BIO_printf(bio_err,
"%s: No signature file specified for verify\n", prog);
goto end;
}
/* FIXME: seed PRNG only if needed */
app_RAND_load_file(NULL, 0);
if (pkey_op != EVP_PKEY_OP_DERIVE) {
in = bio_open_default(infile, 'r', FORMAT_BINARY);
if (in == NULL)
@@ -258,9 +254,10 @@ int pkeyutl_main(int argc, char **argv)
if (out == NULL)
goto end;
if (sigfile) {
if (sigfile != NULL) {
BIO *sigbio = BIO_new_file(sigfile, "rb");
if (!sigbio) {
if (sigbio == NULL) {
BIO_printf(bio_err, "Can't open signature file %s\n", sigfile);
goto end;
}
@@ -272,7 +269,7 @@ int pkeyutl_main(int argc, char **argv)
}
}
if (in) {
if (in != NULL) {
/* Read the input data */
buf_inlen = bio_to_mem(&buf_in, keysize * 10, in);
if (buf_inlen < 0) {
@@ -297,8 +294,9 @@ int pkeyutl_main(int argc, char **argv)
if (rv == 1) {
BIO_puts(out, "Signature Verified Successfully\n");
ret = 0;
} else
} else {
BIO_puts(out, "Signature Verification Failure\n");
}
goto end;
}
if (kdflen != 0) {
@@ -315,11 +313,7 @@ int pkeyutl_main(int argc, char **argv)
buf_in, (size_t)buf_inlen);
}
if (rv <= 0) {
if (pkey_op != EVP_PKEY_OP_DERIVE) {
BIO_puts(bio_err, "Public Key operation error\n");
} else {
BIO_puts(bio_err, "Key derivation failed\n");
}
BIO_puts(bio_err, "Public Key operation error\n");
ERR_print_errors(bio_err);
goto end;
}
@@ -328,10 +322,11 @@ int pkeyutl_main(int argc, char **argv)
if (asn1parse) {
if (!ASN1_parse_dump(out, buf_out, buf_outlen, 1, -1))
ERR_print_errors(bio_err);
} else if (hexdump)
} else if (hexdump) {
BIO_dump(out, (char *)buf_out, buf_outlen);
else
} else {
BIO_write(out, buf_out, buf_outlen);
}
end:
EVP_PKEY_CTX_free(ctx);
@@ -393,16 +388,13 @@ static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize,
impl = e;
#endif
if (kdfalg) {
if (kdfalg != NULL) {
int kdfnid = OBJ_sn2nid(kdfalg);
if (kdfnid == NID_undef) {
kdfnid = OBJ_ln2nid(kdfalg);
if (kdfnid == NID_undef) {
BIO_printf(bio_err, "The given KDF \"%s\" is unknown.\n",
kdfalg);
if (kdfnid == NID_undef)
goto end;
}
}
ctx = EVP_PKEY_CTX_new_id(kdfnid, impl);
} else {
@@ -454,16 +446,16 @@ static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize,
}
static int setup_peer(EVP_PKEY_CTX *ctx, int peerform, const char *file,
ENGINE *e)
ENGINE* e)
{
EVP_PKEY *peer = NULL;
ENGINE *engine = NULL;
ENGINE* engine = NULL;
int ret;
if (peerform == FORMAT_ENGINE)
engine = e;
peer = load_pubkey(file, peerform, 0, NULL, engine, "Peer Key");
if (!peer) {
if (peer == NULL) {
BIO_printf(bio_err, "Error reading peer key %s\n", file);
ERR_print_errors(bio_err);
return 0;
+3 -2
View File
@@ -10,6 +10,7 @@
#include <string.h>
#include "apps.h"
#include "progs.h"
#include <openssl/bn.h>
typedef enum OPTION_choice {
@@ -17,7 +18,7 @@ typedef enum OPTION_choice {
OPT_HEX, OPT_GENERATE, OPT_BITS, OPT_SAFE, OPT_CHECKS
} OPTION_CHOICE;
OPTIONS prime_options[] = {
const OPTIONS prime_options[] = {
{OPT_HELP_STR, 1, '-', "Usage: %s [options] [number...]\n"},
{OPT_HELP_STR, 1, '-',
" number Number to check for primality\n"},
@@ -112,7 +113,7 @@ opthelp:
else
r = BN_dec2bn(&bn, argv[0]);
if(!r) {
if (!r) {
BIO_printf(bio_err, "Failed to process value (%s)\n", argv[0]);
goto end;
}
+84 -72
View File
@@ -14,24 +14,24 @@ use warnings;
use lib '.';
use configdata qw/@disablables %unified_info/;
my %commands = ();
my $cmdre = qr/^\s*int\s+([a-z_][a-z0-9_]*)_main\(\s*int\s+argc\s*,/;
my %commands = ();
my $cmdre = qr/^\s*int\s+([a-z_][a-z0-9_]*)_main\(\s*int\s+argc\s*,/;
my $apps_openssl = shift @ARGV;
# because the program apps/openssl has object files as sources, and
# they then have the corresponding C files as source, we need to chain
# the lookups in %unified_info
my @openssl_source =
map { @{$unified_info{sources}->{$_}} }
@{$unified_info{sources}->{$apps_openssl}};
@{$unified_info{sources}->{$apps_openssl}};
foreach my $filename (@openssl_source) {
open F, $filename or die "Couldn't open $filename: $!\n";
foreach (grep /$cmdre/, <F>) {
my @foo = /$cmdre/;
$commands{$1} = 1;
}
close F;
open F, $filename or die "Couldn't open $filename: $!\n";
foreach ( grep /$cmdre/, <F> ) {
my @foo = /$cmdre/;
$commands{$1} = 1;
}
close F;
}
@ARGV = sort keys %commands;
@@ -66,17 +66,15 @@ DEFINE_LHASH_OF(FUNCTION);
EOF
foreach (@ARGV) {
printf "extern int %s_main(int argc, char *argv[]);\n", $_;
printf "extern int %s_main(int argc, char *argv[]);\n", $_;
}
print "\n";
foreach (@ARGV) {
printf "extern OPTIONS %s_options[];\n", $_;
printf "extern const OPTIONS %s_options[];\n", $_;
}
print "\n";
print "\n#ifdef INCLUDE_FUNCTION_TABLE\n";
print "static FUNCTION functions[] = {\n";
my %cmd_disabler = (
ciphers => "sock",
genrsa => "rsa",
@@ -87,78 +85,92 @@ my %cmd_disabler = (
dhparam => "dh",
ecparam => "ec",
pkcs12 => "des",
);
foreach my $cmd (@ARGV) {
my $str=" { FT_general, \"$cmd\", ${cmd}_main, ${cmd}_options },\n";
if ($cmd =~ /^s_/) {
print "#ifndef OPENSSL_NO_SOCK\n${str}#endif\n";
} elsif (grep { $cmd eq $_ } @disablables) {
print "#ifndef OPENSSL_NO_".uc($cmd)."\n${str}#endif\n";
} elsif (my $disabler = $cmd_disabler{$cmd}) {
print "#ifndef OPENSSL_NO_".uc($disabler)."\n${str}#endif\n";
} else {
print $str;
}
);
print "#ifdef INCLUDE_FUNCTION_TABLE\n";
print "static FUNCTION functions[] = {\n";
foreach my $cmd ( @ARGV ) {
my $str = " {FT_general, \"$cmd\", ${cmd}_main, ${cmd}_options},\n";
if ($cmd =~ /^s_/) {
print "#ifndef OPENSSL_NO_SOCK\n${str}#endif\n";
} elsif (grep { $cmd eq $_ } @disablables) {
print "#ifndef OPENSSL_NO_" . uc($cmd) . "\n${str}#endif\n";
} elsif (my $disabler = $cmd_disabler{$cmd}) {
print "#ifndef OPENSSL_NO_" . uc($disabler) . "\n${str}#endif\n";
} else {
print $str;
}
}
my %md_disabler = (
blake2b512 => "blake2",
blake2s256 => "blake2",
);
);
foreach my $cmd (
"md2", "md4", "md5",
"gost",
"sha1", "sha224", "sha256", "sha384", "sha512",
"mdc2", "rmd160", "blake2b512", "blake2s256"
"md2", "md4", "md5",
"gost",
"sha1", "sha224", "sha256", "sha384", "sha512",
"mdc2", "rmd160", "blake2b512", "blake2s256",
"sm3"
) {
my $str = " { FT_md, \"".$cmd."\", dgst_main},\n";
if (grep { $cmd eq $_ } @disablables) {
print "#ifndef OPENSSL_NO_".uc($cmd)."\n${str}#endif\n";
} elsif (my $disabler = $md_disabler{$cmd}) {
print "#ifndef OPENSSL_NO_".uc($disabler)."\n${str}#endif\n";
} else {
print $str;
}
my $str = " {FT_md, \"$cmd\", dgst_main},\n";
if (grep { $cmd eq $_ } @disablables) {
print "#ifndef OPENSSL_NO_" . uc($cmd) . "\n${str}#endif\n";
} elsif (my $disabler = $md_disabler{$cmd}) {
print "#ifndef OPENSSL_NO_" . uc($disabler) . "\n${str}#endif\n";
} else {
print $str;
}
}
my %cipher_disabler = (
des3 => "des",
desx => "des",
cast5 => "cast",
);
);
foreach my $cmd (
"aes-128-cbc", "aes-128-ecb",
"aes-192-cbc", "aes-192-ecb",
"aes-256-cbc", "aes-256-ecb",
"camellia-128-cbc", "camellia-128-ecb",
"camellia-192-cbc", "camellia-192-ecb",
"camellia-256-cbc", "camellia-256-ecb",
"base64", "zlib",
"des", "des3", "desx", "idea", "seed", "rc4", "rc4-40",
"rc2", "bf", "cast", "rc5",
"des-ecb", "des-ede", "des-ede3",
"des-cbc", "des-ede-cbc","des-ede3-cbc",
"des-cfb", "des-ede-cfb","des-ede3-cfb",
"des-ofb", "des-ede-ofb","des-ede3-ofb",
"idea-cbc","idea-ecb", "idea-cfb", "idea-ofb",
"seed-cbc","seed-ecb", "seed-cfb", "seed-ofb",
"rc2-cbc", "rc2-ecb", "rc2-cfb","rc2-ofb", "rc2-64-cbc", "rc2-40-cbc",
"bf-cbc", "bf-ecb", "bf-cfb", "bf-ofb",
"cast5-cbc","cast5-ecb", "cast5-cfb","cast5-ofb",
"cast-cbc", "rc5-cbc", "rc5-ecb", "rc5-cfb", "rc5-ofb"
"aes-128-cbc", "aes-128-ecb",
"aes-192-cbc", "aes-192-ecb",
"aes-256-cbc", "aes-256-ecb",
"aria-128-cbc", "aria-128-cfb",
"aria-128-ctr", "aria-128-ecb", "aria-128-ofb",
"aria-128-cfb1", "aria-128-cfb8",
"aria-192-cbc", "aria-192-cfb",
"aria-192-ctr", "aria-192-ecb", "aria-192-ofb",
"aria-192-cfb1", "aria-192-cfb8",
"aria-256-cbc", "aria-256-cfb",
"aria-256-ctr", "aria-256-ecb", "aria-256-ofb",
"aria-256-cfb1", "aria-256-cfb8",
"camellia-128-cbc", "camellia-128-ecb",
"camellia-192-cbc", "camellia-192-ecb",
"camellia-256-cbc", "camellia-256-ecb",
"base64", "zlib",
"des", "des3", "desx", "idea", "seed", "rc4", "rc4-40",
"rc2", "bf", "cast", "rc5",
"des-ecb", "des-ede", "des-ede3",
"des-cbc", "des-ede-cbc","des-ede3-cbc",
"des-cfb", "des-ede-cfb","des-ede3-cfb",
"des-ofb", "des-ede-ofb","des-ede3-ofb",
"idea-cbc","idea-ecb", "idea-cfb", "idea-ofb",
"seed-cbc","seed-ecb", "seed-cfb", "seed-ofb",
"rc2-cbc", "rc2-ecb", "rc2-cfb","rc2-ofb", "rc2-64-cbc", "rc2-40-cbc",
"bf-cbc", "bf-ecb", "bf-cfb", "bf-ofb",
"cast5-cbc","cast5-ecb", "cast5-cfb","cast5-ofb",
"cast-cbc", "rc5-cbc", "rc5-ecb", "rc5-cfb", "rc5-ofb",
"sm4-cbc", "sm4-ecb", "sm4-cfb", "sm4-ofb", "sm4-ctr"
) {
my $str=" { FT_cipher, \"$cmd\", enc_main, enc_options },\n";
(my $algo= $cmd) =~ s/-.*//g;
if ($cmd eq "zlib") {
print "#ifdef ZLIB\n${str}#endif\n";
} elsif (grep { $algo eq $_ } @disablables) {
print "#ifndef OPENSSL_NO_".uc($algo)."\n${str}#endif\n";
} elsif (my $disabler = $cipher_disabler{$algo}) {
print "#ifndef OPENSSL_NO_".uc($disabler)."\n${str}#endif\n";
} else {
print $str;
}
my $str = " {FT_cipher, \"$cmd\", enc_main, enc_options},\n";
(my $algo = $cmd) =~ s/-.*//g;
if ($cmd eq "zlib") {
print "#ifdef ZLIB\n${str}#endif\n";
} elsif (grep { $algo eq $_ } @disablables) {
print "#ifndef OPENSSL_NO_" . uc($algo) . "\n${str}#endif\n";
} elsif (my $disabler = $cipher_disabler{$algo}) {
print "#ifndef OPENSSL_NO_" . uc($disabler) . "\n${str}#endif\n";
} else {
print $str;
}
}
print " { 0, NULL, NULL}\n};\n";
print " {0, NULL, NULL}\n};\n";
print "#endif\n";
+11 -14
View File
@@ -8,6 +8,7 @@
*/
#include "apps.h"
#include "progs.h"
#include <ctype.h>
#include <stdio.h>
@@ -19,16 +20,16 @@
typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_OUT, OPT_ENGINE, OPT_RAND, OPT_BASE64, OPT_HEX
OPT_OUT, OPT_ENGINE, OPT_BASE64, OPT_HEX,
OPT_R_ENUM
} OPTION_CHOICE;
OPTIONS rand_options[] = {
const OPTIONS rand_options[] = {
{OPT_HELP_STR, 1, '-', "Usage: %s [flags] num\n"},
{OPT_HELP_STR, 1, '-', "Valid options are:\n"},
{"help", OPT_HELP, '-', "Display this summary"},
{"out", OPT_OUT, '>', "Output file"},
{"rand", OPT_RAND, 's',
"Load the file(s) into the random number generator"},
OPT_R_OPTIONS,
{"base64", OPT_BASE64, '-', "Base64 encode output"},
{"hex", OPT_HEX, '-', "Hex encode output"},
#ifndef OPENSSL_NO_ENGINE
@@ -41,7 +42,7 @@ int rand_main(int argc, char **argv)
{
ENGINE *e = NULL;
BIO *out = NULL;
char *inrand = NULL, *outfile = NULL, *prog;
char *outfile = NULL, *prog;
OPTION_CHOICE o;
int format = FORMAT_BINARY, i, num = -1, r, ret = 1;
@@ -63,8 +64,9 @@ int rand_main(int argc, char **argv)
case OPT_ENGINE:
e = setup_engine(opt_arg(), 0);
break;
case OPT_RAND:
inrand = opt_arg();
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
case OPT_BASE64:
format = FORMAT_BASE64;
@@ -84,11 +86,6 @@ int rand_main(int argc, char **argv)
goto opthelp;
}
app_RAND_load_file(NULL, (inrand != NULL));
if (inrand != NULL)
BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
app_RAND_load_files(inrand));
out = bio_open_default(outfile, 'w', format);
if (out == NULL)
goto end;
@@ -122,7 +119,7 @@ int rand_main(int argc, char **argv)
}
if (format == FORMAT_TEXT)
BIO_puts(out, "\n");
if (BIO_flush(out) <= 0 || !app_RAND_write_file(NULL))
if (BIO_flush(out) <= 0)
goto end;
ret = 0;
@@ -132,5 +129,5 @@ int rand_main(int argc, char **argv)
ERR_print_errors(bio_err);
release_engine(e);
BIO_free_all(out);
return (ret);
return ret;
}
+11 -15
View File
@@ -1,5 +1,6 @@
/*
* Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2013-2014 Timo Teräs <timo.teras@gmail.com>
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -7,13 +8,8 @@
* https://www.openssl.org/source/license.html
*/
/*
* C implementation based on the original Perl and shell versions
*
* Copyright (c) 2013-2014 Timo Teräs <timo.teras@iki.fi>
*/
#include "apps.h"
#include "progs.h"
#if defined(OPENSSL_SYS_UNIX) || defined(__APPLE__) || \
(defined(__VMS) && defined(__DECC) && __CRTL_VER >= 80300000)
@@ -254,11 +250,11 @@ static int do_file(const char *filename, const char *fullpath, enum Hash h)
goto end;
}
x = sk_X509_INFO_value(inf, 0);
if (x->x509) {
if (x->x509 != NULL) {
type = TYPE_CERT;
name = X509_get_subject_name(x->x509);
X509_digest(x->x509, evpmd, digest, NULL);
} else if (x->crl) {
} else if (x->crl != NULL) {
type = TYPE_CRL;
name = X509_CRL_get_issuer(x->crl);
X509_CRL_digest(x->crl, evpmd, digest, NULL);
@@ -266,7 +262,7 @@ static int do_file(const char *filename, const char *fullpath, enum Hash h)
++errs;
goto end;
}
if (name) {
if (name != NULL) {
if ((h == HASH_NEW) || (h == HASH_BOTH))
errs += add_entry(type, X509_NAME_hash(name), filename, digest, 1, ~0);
if ((h == HASH_OLD) || (h == HASH_BOTH))
@@ -448,7 +444,7 @@ typedef enum OPTION_choice {
OPT_COMPAT, OPT_OLD, OPT_N, OPT_VERBOSE
} OPTION_CHOICE;
OPTIONS rehash_options[] = {
const OPTIONS rehash_options[] = {
{OPT_HELP_STR, 1, '-', "Usage: %s [options] [cert-directory...]\n"},
{OPT_HELP_STR, 1, '-', "Valid options are:\n"},
{"help", OPT_HELP, '-', "Display this summary"},
@@ -499,8 +495,8 @@ int rehash_main(int argc, char **argv)
evpmd = EVP_sha1();
evpmdsize = EVP_MD_size(evpmd);
if (*argv) {
while (*argv)
if (*argv != NULL) {
while (*argv != NULL)
errs += do_dir(*argv++, h);
} else if ((env = getenv("SSL_CERT_DIR")) != NULL) {
m = OPENSSL_strdup(env);
@@ -516,14 +512,14 @@ int rehash_main(int argc, char **argv)
}
#else
OPTIONS rehash_options[] = {
const OPTIONS rehash_options[] = {
{NULL}
};
int rehash_main(int argc, char **argv)
{
BIO_printf(bio_err, "Not available; use c_rehash script\n");
return (1);
return 1;
}
#endif /* defined(OPENSSL_SYS_UNIX) || defined(__APPLE__) */
+209 -129
View File
@@ -1,5 +1,5 @@
/*
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2018 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
@@ -12,6 +12,7 @@
#include <time.h>
#include <string.h>
#include "apps.h"
#include "progs.h"
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/conf.h>
@@ -64,25 +65,29 @@ static int add_DN_object(X509_NAME *n, char *text, const char *def,
static int genpkey_cb(EVP_PKEY_CTX *ctx);
static int req_check_len(int len, int n_min, int n_max);
static int check_end(const char *str, const char *end);
static int join(char buf[], size_t buf_size, const char *name,
const char *tail, const char *desc);
static EVP_PKEY_CTX *set_keygen_ctx(const char *gstr,
int *pkey_type, long *pkeylen,
char **palgnam, ENGINE *keygen_engine);
static CONF *req_conf = NULL;
static CONF *addext_conf = NULL;
static int batch = 0;
typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_INFORM, OPT_OUTFORM, OPT_ENGINE, OPT_KEYGEN_ENGINE, OPT_KEY,
OPT_PUBKEY, OPT_NEW, OPT_CONFIG, OPT_KEYFORM, OPT_IN, OPT_OUT,
OPT_KEYOUT, OPT_PASSIN, OPT_PASSOUT, OPT_RAND, OPT_NEWKEY,
OPT_KEYOUT, OPT_PASSIN, OPT_PASSOUT, OPT_NEWKEY,
OPT_PKEYOPT, OPT_SIGOPT, OPT_BATCH, OPT_NEWHDR, OPT_MODULUS,
OPT_VERIFY, OPT_NODES, OPT_NOOUT, OPT_VERBOSE, OPT_UTF8,
OPT_NAMEOPT, OPT_REQOPT, OPT_SUBJ, OPT_SUBJECT, OPT_TEXT, OPT_X509,
OPT_MULTIVALUE_RDN, OPT_DAYS, OPT_SET_SERIAL, OPT_EXTENSIONS,
OPT_REQEXTS, OPT_MD
OPT_MULTIVALUE_RDN, OPT_DAYS, OPT_SET_SERIAL, OPT_ADDEXT, OPT_EXTENSIONS,
OPT_REQEXTS, OPT_PRECERT, OPT_MD,
OPT_R_ENUM
} OPTION_CHOICE;
OPTIONS req_options[] = {
const OPTIONS req_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"inform", OPT_INFORM, 'F', "Input format - DER or PEM"},
{"outform", OPT_OUTFORM, 'F', "Output format - DER or PEM"},
@@ -96,8 +101,7 @@ OPTIONS req_options[] = {
{"keyout", OPT_KEYOUT, '>', "File to send the key to"},
{"passin", OPT_PASSIN, 's', "Private key password source"},
{"passout", OPT_PASSOUT, 's', "Output file pass phrase source"},
{"rand", OPT_RAND, 's',
"Load the file(s) into the random number generator"},
OPT_R_OPTIONS,
{"newkey", OPT_NEWKEY, 's', "Specify as type:bits"},
{"pkeyopt", OPT_PKEYOPT, 's', "Public key options as opt:value"},
{"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"},
@@ -122,10 +126,13 @@ OPTIONS req_options[] = {
"Enable support for multivalued RDNs"},
{"days", OPT_DAYS, 'p', "Number of days cert is valid for"},
{"set_serial", OPT_SET_SERIAL, 's', "Serial number to use"},
{"addext", OPT_ADDEXT, 's',
"Additional cert extension key=value pair (may be given more than once)"},
{"extensions", OPT_EXTENSIONS, 's',
"Cert extension section (override value in config file)"},
{"reqexts", OPT_REQEXTS, 's',
"Request extension section (override value in config file)"},
{"precert", OPT_PRECERT, '-', "Add a poison extension (implies -new)"},
{"", OPT_MD, '-', "Any supported digest"},
#ifndef OPENSSL_NO_ENGINE
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
@@ -147,8 +154,9 @@ int req_main(int argc, char **argv)
X509_REQ *req = NULL;
const EVP_CIPHER *cipher = NULL;
const EVP_MD *md_alg = NULL, *digest = NULL;
BIO *addext_bio = NULL;
char *extensions = NULL, *infile = NULL;
char *outfile = NULL, *keyfile = NULL, *inrand = NULL;
char *outfile = NULL, *keyfile = NULL;
char *keyalgstr = NULL, *p, *prog, *passargin = NULL, *passargout = NULL;
char *passin = NULL, *passout = NULL;
char *nofree_passin = NULL, *nofree_passout = NULL;
@@ -156,14 +164,13 @@ int req_main(int argc, char **argv)
char *template = default_config_file, *keyout = NULL;
const char *keyalg = NULL;
OPTION_CHOICE o;
int ret = 1, x509 = 0, days = 30, i = 0, newreq = 0, verbose = 0;
int ret = 1, x509 = 0, days = 0, i = 0, newreq = 0, verbose = 0;
int pkey_type = -1, private = 0;
int informat = FORMAT_PEM, outformat = FORMAT_PEM, keyform = FORMAT_PEM;
int modulus = 0, multirdn = 0, verify = 0, noout = 0, text = 0;
int nodes = 0, newhdr = 0, subject = 0, pubkey = 0;
int nodes = 0, newhdr = 0, subject = 0, pubkey = 0, precert = 0;
long newkey = -1;
unsigned long chtype = MBSTRING_ASC, nmflag = 0, reqflag = 0;
char nmflag_set = 0;
unsigned long chtype = MBSTRING_ASC, reqflag = 0;
#ifndef OPENSSL_NO_DES
cipher = EVP_des_ede3_cbc();
@@ -232,8 +239,9 @@ int req_main(int argc, char **argv)
case OPT_PASSOUT:
passargout = opt_arg();
break;
case OPT_RAND:
inrand = opt_arg();
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
case OPT_NEWKEY:
keyalg = opt_arg();
@@ -276,8 +284,7 @@ int req_main(int argc, char **argv)
chtype = MBSTRING_UTF8;
break;
case OPT_NAMEOPT:
nmflag_set = 1;
if (!set_name_ex(&nmflag, opt_arg()))
if (!set_nameopt(opt_arg()))
goto opthelp;
break;
case OPT_REQOPT:
@@ -311,12 +318,23 @@ int req_main(int argc, char **argv)
case OPT_MULTIVALUE_RDN:
multirdn = 1;
break;
case OPT_ADDEXT:
if (addext_bio == NULL) {
addext_bio = BIO_new(BIO_s_mem());
}
if (addext_bio == NULL
|| BIO_printf(addext_bio, "%s\n", opt_arg()) < 0)
goto end;
break;
case OPT_EXTENSIONS:
extensions = opt_arg();
break;
case OPT_REQEXTS:
req_exts = opt_arg();
break;
case OPT_PRECERT:
newreq = precert = 1;
break;
case OPT_MD:
if (!opt_md(opt_unknown(), &md_alg))
goto opthelp;
@@ -328,12 +346,11 @@ int req_main(int argc, char **argv)
if (argc != 0)
goto opthelp;
if (days && !x509)
BIO_printf(bio_err, "Ignoring -days; not generating a certificate\n");
if (x509 && infile == NULL)
newreq = 1;
if (!nmflag_set)
nmflag = XN_FLAG_ONELINE;
/* TODO: simplify this as pkey is still always NULL here */
private = newreq && (pkey == NULL) ? 1 : 0;
@@ -345,6 +362,12 @@ int req_main(int argc, char **argv)
if (verbose)
BIO_printf(bio_err, "Using configuration from %s\n", template);
req_conf = app_load_config(template);
if (addext_bio) {
if (verbose)
BIO_printf(bio_err,
"Using additional configuraton from command line\n");
addext_conf = app_load_config_bio(addext_bio, NULL);
}
if (template != default_config_file && !app_load_modules(req_conf))
goto end;
@@ -372,21 +395,21 @@ int req_main(int argc, char **argv)
if (md_alg == NULL) {
p = NCONF_get_string(req_conf, SECTION, "default_md");
if (p == NULL)
if (p == NULL) {
ERR_clear_error();
else {
} else {
if (!opt_md(p, &md_alg))
goto opthelp;
digest = md_alg;
}
}
if (!extensions) {
if (extensions == NULL) {
extensions = NCONF_get_string(req_conf, SECTION, V3_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);
@@ -397,6 +420,16 @@ int req_main(int argc, char **argv)
goto end;
}
}
if (addext_conf != NULL) {
/* Check syntax of command line extensions */
X509V3_CTX ctx;
X509V3_set_ctx_test(&ctx);
X509V3_set_nconf(&ctx, addext_conf);
if (!X509V3_EXT_add_nconf(addext_conf, &ctx, "default", NULL)) {
BIO_printf(bio_err, "Error Loading command line extensions\n");
goto end;
}
}
if (passin == NULL) {
passin = nofree_passin =
@@ -413,28 +446,28 @@ int req_main(int argc, char **argv)
}
p = NCONF_get_string(req_conf, SECTION, STRING_MASK);
if (!p)
if (p == NULL)
ERR_clear_error();
if (p && !ASN1_STRING_set_default_mask_asc(p)) {
if (p != NULL && !ASN1_STRING_set_default_mask_asc(p)) {
BIO_printf(bio_err, "Invalid global string mask setting %s\n", p);
goto end;
}
if (chtype != MBSTRING_UTF8) {
p = NCONF_get_string(req_conf, SECTION, UTF8_IN);
if (!p)
if (p == NULL)
ERR_clear_error();
else if (strcmp(p, "yes") == 0)
chtype = MBSTRING_UTF8;
}
if (!req_exts) {
if (req_exts == NULL) {
req_exts = NCONF_get_string(req_conf, SECTION, REQ_EXTENSIONS);
if (!req_exts)
if (req_exts == NULL)
ERR_clear_error();
}
if (req_exts) {
if (req_exts != NULL) {
/* Check syntax of file */
X509V3_CTX ctx;
X509V3_set_ctx_test(&ctx);
@@ -449,33 +482,25 @@ int req_main(int argc, char **argv)
if (keyfile != NULL) {
pkey = load_key(keyfile, keyform, 0, passin, e, "Private Key");
if (!pkey) {
if (pkey == NULL) {
/* load_key() has already printed an appropriate message */
goto end;
} else {
char *randfile = NCONF_get_string(req_conf, SECTION, "RANDFILE");
if (randfile == NULL)
ERR_clear_error();
app_RAND_load_file(randfile, 0);
app_RAND_load_conf(req_conf, SECTION);
}
}
if (newreq && (pkey == NULL)) {
char *randfile = NCONF_get_string(req_conf, SECTION, "RANDFILE");
if (randfile == NULL)
ERR_clear_error();
app_RAND_load_file(randfile, 0);
if (inrand)
app_RAND_load_files(inrand);
app_RAND_load_conf(req_conf, SECTION);
if (!NCONF_get_number(req_conf, SECTION, BITS, &newkey)) {
newkey = DEFAULT_KEY_LENGTH;
}
if (keyalg) {
if (keyalg != NULL) {
genctx = set_keygen_ctx(keyalg, &pkey_type, &newkey,
&keyalgstr, gen_eng);
if (!genctx)
if (genctx == NULL)
goto end;
}
@@ -487,14 +512,14 @@ int req_main(int argc, char **argv)
goto end;
}
if (!genctx) {
if (genctx == NULL) {
genctx = set_keygen_ctx(NULL, &pkey_type, &newkey,
&keyalgstr, gen_eng);
if (!genctx)
goto end;
}
if (pkeyopts) {
if (pkeyopts != NULL) {
char *genopt;
for (i = 0; i < sk_OPENSSL_STRING_num(pkeyopts); i++) {
genopt = sk_OPENSSL_STRING_value(pkeyopts, i);
@@ -524,8 +549,6 @@ int req_main(int argc, char **argv)
EVP_PKEY_CTX_free(genctx);
genctx = NULL;
app_RAND_write_file(randfile);
if (keyout == NULL) {
keyout = NCONF_get_string(req_conf, SECTION, KEYFILE);
if (keyout == NULL)
@@ -611,9 +634,10 @@ int req_main(int argc, char **argv)
goto end;
/* Set version to V3 */
if (extensions && !X509_set_version(x509ss, 2))
if ((extensions != NULL || addext_conf != NULL)
&& !X509_set_version(x509ss, 2))
goto end;
if (serial) {
if (serial != NULL) {
if (!X509_set_serialNumber(x509ss, serial))
goto end;
} else {
@@ -623,6 +647,10 @@ int req_main(int argc, char **argv)
if (!X509_set_issuer_name(x509ss, X509_REQ_get_subject_name(req)))
goto end;
if (days == 0) {
/* set default days if it's not specified */
days = 30;
}
if (!set_cert_times(x509ss, NULL, NULL, days))
goto end;
if (!X509_set_subject_name
@@ -638,13 +666,28 @@ int req_main(int argc, char **argv)
X509V3_set_nconf(&ext_ctx, req_conf);
/* Add extensions */
if (extensions && !X509V3_EXT_add_nconf(req_conf,
&ext_ctx, extensions,
x509ss)) {
if (extensions != NULL && !X509V3_EXT_add_nconf(req_conf,
&ext_ctx, extensions,
x509ss)) {
BIO_printf(bio_err, "Error Loading extension section %s\n",
extensions);
goto end;
}
if (addext_conf != NULL
&& !X509V3_EXT_add_nconf(addext_conf, &ext_ctx, "default",
x509ss)) {
BIO_printf(bio_err, "Error Loading command line extensions\n");
goto end;
}
/* If a pre-cert was requested, we need to add a poison extension */
if (precert) {
if (X509_add1_ext_i2d(x509ss, NID_ct_precert_poison, NULL, 1, 0)
!= 1) {
BIO_printf(bio_err, "Error adding poison extension\n");
goto end;
}
}
i = do_X509_sign(x509ss, pkey, digest, sigopts);
if (!i) {
@@ -660,13 +703,19 @@ int req_main(int argc, char **argv)
X509V3_set_nconf(&ext_ctx, req_conf);
/* Add extensions */
if (req_exts && !X509V3_EXT_REQ_add_nconf(req_conf,
&ext_ctx, req_exts,
req)) {
if (req_exts != NULL
&& !X509V3_EXT_REQ_add_nconf(req_conf, &ext_ctx,
req_exts, req)) {
BIO_printf(bio_err, "Error Loading extension section %s\n",
req_exts);
goto end;
}
if (addext_conf != NULL
&& !X509V3_EXT_REQ_add_nconf(addext_conf, &ext_ctx, "default",
req)) {
BIO_printf(bio_err, "Error Loading command line extensions\n");
goto end;
}
i = do_X509_REQ_sign(req, pkey, digest, sigopts);
if (!i) {
ERR_print_errors(bio_err);
@@ -684,7 +733,7 @@ int req_main(int argc, char **argv)
if (verbose) {
BIO_printf(bio_err, "Modifying Request's Subject\n");
print_name(bio_err, "old subject=",
X509_REQ_get_subject_name(req), nmflag);
X509_REQ_get_subject_name(req), get_nameopt());
}
if (build_subject(req, subj, chtype, multirdn) == 0) {
@@ -695,7 +744,7 @@ int req_main(int argc, char **argv)
if (verbose) {
print_name(bio_err, "new subject=",
X509_REQ_get_subject_name(req), nmflag);
X509_REQ_get_subject_name(req), get_nameopt());
}
}
@@ -715,8 +764,9 @@ int req_main(int argc, char **argv)
} else if (i == 0) {
BIO_printf(bio_err, "verify failure\n");
ERR_print_errors(bio_err);
} else /* if (i > 0) */
} else { /* if (i > 0) */
BIO_printf(bio_err, "verify OK\n");
}
}
if (noout && !text && !modulus && !subject && !pubkey) {
@@ -744,18 +794,18 @@ int req_main(int argc, char **argv)
if (text) {
if (x509)
X509_print_ex(out, x509ss, nmflag, reqflag);
X509_print_ex(out, x509ss, get_nameopt(), reqflag);
else
X509_REQ_print_ex(out, req, nmflag, reqflag);
X509_REQ_print_ex(out, req, get_nameopt(), reqflag);
}
if (subject) {
if (x509)
print_name(out, "subject=", X509_get_subject_name(x509ss),
nmflag);
get_nameopt());
else
print_name(out, "subject=", X509_REQ_get_subject_name(req),
nmflag);
get_nameopt());
}
if (modulus) {
@@ -809,6 +859,7 @@ int req_main(int argc, char **argv)
ERR_print_errors(bio_err);
}
NCONF_free(req_conf);
BIO_free(addext_bio);
BIO_free(in);
BIO_free_all(out);
EVP_PKEY_free(pkey);
@@ -827,7 +878,7 @@ int req_main(int argc, char **argv)
OPENSSL_free(passin);
if (passout != nofree_passout)
OPENSSL_free(passout);
return (ret);
return ret;
}
static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, char *subj, int multirdn,
@@ -887,7 +938,7 @@ static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, char *subj, int multirdn,
ret = 1;
err:
return (ret);
return ret;
}
/*
@@ -943,7 +994,8 @@ static int prompt_info(X509_REQ *req,
if (sk_CONF_VALUE_num(dn_sk)) {
i = -1;
start:for (;;) {
start:
for ( ; ; ) {
i++;
if (sk_CONF_VALUE_num(dn_sk) <= i)
break;
@@ -968,35 +1020,36 @@ static int prompt_info(X509_REQ *req,
if (*type == '+') {
mval = -1;
type++;
} else
} else {
mval = 0;
}
/* If OBJ not recognised ignore it */
if ((nid = OBJ_txt2nid(type)) == NID_undef)
goto start;
if (BIO_snprintf(buf, sizeof(buf), "%s_default", v->name)
>= (int)sizeof(buf)) {
BIO_printf(bio_err, "Name '%s' too long\n", v->name);
if (!join(buf, sizeof(buf), v->name, "_default", "Name"))
return 0;
}
if ((def = NCONF_get_string(req_conf, dn_sect, buf)) == NULL) {
ERR_clear_error();
def = "";
}
BIO_snprintf(buf, sizeof(buf), "%s_value", v->name);
if (!join(buf, sizeof(buf), v->name, "_value", "Name"))
return 0;
if ((value = NCONF_get_string(req_conf, dn_sect, buf)) == NULL) {
ERR_clear_error();
value = NULL;
}
BIO_snprintf(buf, sizeof(buf), "%s_min", v->name);
if (!join(buf, sizeof(buf), v->name, "_min", "Name"))
return 0;
if (!NCONF_get_number(req_conf, dn_sect, buf, &n_min)) {
ERR_clear_error();
n_min = -1;
}
BIO_snprintf(buf, sizeof(buf), "%s_max", v->name);
if (!join(buf, sizeof(buf), v->name, "_max", "Name"))
return 0;
if (!NCONF_get_number(req_conf, dn_sect, buf, &n_max)) {
ERR_clear_error();
n_max = -1;
@@ -1022,7 +1075,8 @@ static int prompt_info(X509_REQ *req,
}
i = -1;
start2: for (;;) {
start2:
for ( ; ; ) {
i++;
if ((attr_sk == NULL) || (sk_CONF_VALUE_num(attr_sk) <= i))
break;
@@ -1032,32 +1086,31 @@ static int prompt_info(X509_REQ *req,
if ((nid = OBJ_txt2nid(type)) == NID_undef)
goto start2;
if (BIO_snprintf(buf, sizeof(buf), "%s_default", type)
>= (int)sizeof(buf)) {
BIO_printf(bio_err, "Name '%s' too long\n", v->name);
if (!join(buf, sizeof(buf), type, "_default", "Name"))
return 0;
}
if ((def = NCONF_get_string(req_conf, attr_sect, buf))
== NULL) {
ERR_clear_error();
def = "";
}
BIO_snprintf(buf, sizeof(buf), "%s_value", type);
if (!join(buf, sizeof(buf), type, "_value", "Name"))
return 0;
if ((value = NCONF_get_string(req_conf, attr_sect, buf))
== NULL) {
ERR_clear_error();
value = NULL;
}
BIO_snprintf(buf, sizeof(buf), "%s_min", type);
if (!join(buf, sizeof(buf), type,"_min", "Name"))
return 0;
if (!NCONF_get_number(req_conf, attr_sect, buf, &n_min)) {
ERR_clear_error();
n_min = -1;
}
BIO_snprintf(buf, sizeof(buf), "%s_max", type);
if (!join(buf, sizeof(buf), type, "_max", "Name"))
return 0;
if (!NCONF_get_number(req_conf, attr_sect, buf, &n_max)) {
ERR_clear_error();
n_max = -1;
@@ -1120,8 +1173,9 @@ static int auto_info(X509_REQ *req, STACK_OF(CONF_VALUE) *dn_sk,
if (plus_char) {
type++;
mval = -1;
} else
} else {
mval = 0;
}
if (!X509_NAME_add_entry_by_txt(subj, type, chtype,
(unsigned char *)v->value, -1, -1,
mval))
@@ -1155,8 +1209,8 @@ static int add_DN_object(X509_NAME *n, char *text, const char *def,
BIO_printf(bio_err, "%s [%s]:", text, def);
(void)BIO_flush(bio_err);
if (value != NULL) {
OPENSSL_strlcpy(buf, value, sizeof(buf));
OPENSSL_strlcat(buf, "\n", sizeof(buf));
if (!join(buf, sizeof(buf), value, "\n", "DN value"))
return 0;
BIO_printf(bio_err, "%s\n", value);
} else {
buf[0] = '\0';
@@ -1170,19 +1224,20 @@ static int add_DN_object(X509_NAME *n, char *text, const char *def,
}
if (buf[0] == '\0')
return (0);
else if (buf[0] == '\n') {
return 0;
if (buf[0] == '\n') {
if ((def == NULL) || (def[0] == '\0'))
return (1);
OPENSSL_strlcpy(buf, def, sizeof(buf));
OPENSSL_strlcat(buf, "\n", sizeof(buf));
} else if ((buf[0] == '.') && (buf[1] == '\n'))
return (1);
return 1;
if (!join(buf, sizeof(buf), def, "\n", "DN default"))
return 0;
} else if ((buf[0] == '.') && (buf[1] == '\n')) {
return 1;
}
i = strlen(buf);
if (buf[i - 1] != '\n') {
BIO_printf(bio_err, "weird input :-(\n");
return (0);
return 0;
}
buf[--i] = '\0';
#ifdef CHARSET_EBCDIC
@@ -1199,7 +1254,7 @@ static int add_DN_object(X509_NAME *n, char *text, const char *def,
goto err;
ret = 1;
err:
return (ret);
return ret;
}
static int add_attribute_object(X509_REQ *req, char *text, const char *def,
@@ -1214,8 +1269,8 @@ static int add_attribute_object(X509_REQ *req, char *text, const char *def,
BIO_printf(bio_err, "%s [%s]:", text, def);
(void)BIO_flush(bio_err);
if (value != NULL) {
OPENSSL_strlcpy(buf, value, sizeof(buf));
OPENSSL_strlcat(buf, "\n", sizeof(buf));
if (!join(buf, sizeof(buf), value, "\n", "Attribute value"))
return 0;
BIO_printf(bio_err, "%s\n", value);
} else {
buf[0] = '\0';
@@ -1229,19 +1284,20 @@ static int add_attribute_object(X509_REQ *req, char *text, const char *def,
}
if (buf[0] == '\0')
return (0);
else if (buf[0] == '\n') {
return 0;
if (buf[0] == '\n') {
if ((def == NULL) || (def[0] == '\0'))
return (1);
OPENSSL_strlcpy(buf, def, sizeof(buf));
OPENSSL_strlcat(buf, "\n", sizeof(buf));
} else if ((buf[0] == '.') && (buf[1] == '\n'))
return (1);
return 1;
if (!join(buf, sizeof(buf), def, "\n", "Attribute default"))
return 0;
} else if ((buf[0] == '.') && (buf[1] == '\n')) {
return 1;
}
i = strlen(buf);
if (buf[i - 1] != '\n') {
BIO_printf(bio_err, "weird input :-(\n");
return (0);
return 0;
}
buf[--i] = '\0';
#ifdef CHARSET_EBCDIC
@@ -1260,9 +1316,9 @@ static int add_attribute_object(X509_REQ *req, char *text, const char *def,
goto err;
}
return (1);
return 1;
err:
return (0);
return 0;
}
static int req_check_len(int len, int n_min, int n_max)
@@ -1271,22 +1327,23 @@ static int req_check_len(int len, int n_min, int n_max)
BIO_printf(bio_err,
"string is too short, it needs to be at least %d bytes long\n",
n_min);
return (0);
return 0;
}
if ((n_max >= 0) && (len > n_max)) {
BIO_printf(bio_err,
"string is too long, it needs to be no more than %d bytes long\n",
n_max);
return (0);
return 0;
}
return (1);
return 1;
}
/* Check if the end of a string matches 'end' */
static int check_end(const char *str, const char *end)
{
int elen, slen;
size_t elen, slen;
const char *tmp;
elen = strlen(end);
slen = strlen(str);
if (elen > slen)
@@ -1295,6 +1352,24 @@ static int check_end(const char *str, const char *end)
return strcmp(tmp, end);
}
/*
* Merge the two strings together into the result buffer checking for
* overflow and producing an error message if there is.
*/
static int join(char buf[], size_t buf_size, const char *name,
const char *tail, const char *desc)
{
const size_t name_len = strlen(name), tail_len = strlen(tail);
if (name_len + tail_len + 1 > buf_size) {
BIO_printf(bio_err, "%s '%s' too long\n", desc, name);
return 0;
}
memcpy(buf, name, name_len);
memcpy(buf + name_len, tail, tail_len + 1);
return 1;
}
static EVP_PKEY_CTX *set_keygen_ctx(const char *gstr,
int *pkey_type, long *pkeylen,
char **palgnam, ENGINE *keygen_engine)
@@ -1312,15 +1387,15 @@ static EVP_PKEY_CTX *set_keygen_ctx(const char *gstr,
*pkey_type = EVP_PKEY_RSA;
keylen = atol(gstr);
*pkeylen = keylen;
} else if (strncmp(gstr, "param:", 6) == 0)
} else if (strncmp(gstr, "param:", 6) == 0) {
paramfile = gstr + 6;
else {
} else {
const char *p = strchr(gstr, ':');
int len;
ENGINE *tmpeng;
const EVP_PKEY_ASN1_METHOD *ameth;
if (p)
if (p != NULL)
len = p - gstr;
else
len = strlen(gstr);
@@ -1331,7 +1406,7 @@ static EVP_PKEY_CTX *set_keygen_ctx(const char *gstr,
ameth = EVP_PKEY_asn1_find_str(&tmpeng, gstr, len);
if (!ameth) {
if (ameth == NULL) {
BIO_printf(bio_err, "Unknown algorithm %.*s\n", len, gstr);
return NULL;
}
@@ -1341,28 +1416,31 @@ static EVP_PKEY_CTX *set_keygen_ctx(const char *gstr,
ENGINE_finish(tmpeng);
#endif
if (*pkey_type == EVP_PKEY_RSA) {
if (p) {
if (p != NULL) {
keylen = atol(p + 1);
*pkeylen = keylen;
} else
} else {
keylen = *pkeylen;
} else if (p)
}
} else if (p != NULL) {
paramfile = p + 1;
}
}
if (paramfile) {
if (paramfile != NULL) {
pbio = BIO_new_file(paramfile, "r");
if (!pbio) {
if (pbio == NULL) {
BIO_printf(bio_err, "Can't open parameter file %s\n", paramfile);
return NULL;
}
param = PEM_read_bio_Parameters(pbio, NULL);
if (!param) {
if (param == NULL) {
X509 *x;
(void)BIO_reset(pbio);
x = PEM_read_bio_X509(pbio, NULL, NULL, NULL);
if (x) {
if (x != NULL) {
param = X509_get_pubkey(x);
X509_free(x);
}
@@ -1370,25 +1448,26 @@ static EVP_PKEY_CTX *set_keygen_ctx(const char *gstr,
BIO_free(pbio);
if (!param) {
if (param == NULL) {
BIO_printf(bio_err, "Error reading parameter file %s\n", paramfile);
return NULL;
}
if (*pkey_type == -1)
if (*pkey_type == -1) {
*pkey_type = EVP_PKEY_id(param);
else if (*pkey_type != EVP_PKEY_base_id(param)) {
} else if (*pkey_type != EVP_PKEY_base_id(param)) {
BIO_printf(bio_err, "Key Type does not match parameters\n");
EVP_PKEY_free(param);
return NULL;
}
}
if (palgnam) {
if (palgnam != NULL) {
const EVP_PKEY_ASN1_METHOD *ameth;
ENGINE *tmpeng;
const char *anam;
ameth = EVP_PKEY_asn1_find(&tmpeng, *pkey_type);
if (!ameth) {
if (ameth == NULL) {
BIO_puts(bio_err, "Internal error: can't find key algorithm\n");
return NULL;
}
@@ -1399,12 +1478,13 @@ static EVP_PKEY_CTX *set_keygen_ctx(const char *gstr,
#endif
}
if (param) {
if (param != NULL) {
gctx = EVP_PKEY_CTX_new(param, keygen_engine);
*pkeylen = EVP_PKEY_bits(param);
EVP_PKEY_free(param);
} else
} else {
gctx = EVP_PKEY_CTX_new_id(*pkey_type, keygen_engine);
}
if (gctx == NULL) {
BIO_puts(bio_err, "Error allocating keygen context\n");
+14 -11
View File
@@ -1,5 +1,5 @@
/*
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2018 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
@@ -17,6 +17,7 @@ NON_EMPTY_TRANSLATION_UNIT
# include <string.h>
# include <time.h>
# include "apps.h"
# include "progs.h"
# include <openssl/bio.h>
# include <openssl/err.h>
# include <openssl/rsa.h>
@@ -35,7 +36,7 @@ typedef enum OPTION_choice {
OPT_NOOUT, OPT_TEXT, OPT_MODULUS, OPT_CHECK, OPT_CIPHER
} OPTION_CHOICE;
OPTIONS rsa_options[] = {
const OPTIONS rsa_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"inform", OPT_INFORM, 'f', "Input format, one of DER NET PEM"},
{"outform", OPT_OUTFORM, 'f', "Output format, one of DER NET PEM PVK"},
@@ -176,12 +177,14 @@ int rsa_main(int argc, char **argv)
tmpformat = FORMAT_PEMRSA;
else if (informat == FORMAT_ASN1)
tmpformat = FORMAT_ASN1RSA;
} else
} else {
tmpformat = informat;
}
pkey = load_pubkey(infile, tmpformat, 1, passin, e, "Public Key");
} else
} else {
pkey = load_key(infile, informat, 1, passin, e, "Private Key");
}
if (pkey != NULL)
rsa = EVP_PKEY_get1_RSA(pkey);
@@ -217,9 +220,9 @@ int rsa_main(int argc, char **argv)
if (check) {
int r = RSA_check_key_ex(rsa, NULL);
if (r == 1)
if (r == 1) {
BIO_printf(out, "RSA key ok\n");
else if (r == 0) {
} else if (r == 0) {
unsigned long err;
while ((err = ERR_peek_error()) != 0 &&
@@ -228,7 +231,7 @@ int rsa_main(int argc, char **argv)
ERR_GET_REASON(err) != ERR_R_MALLOC_FAILURE) {
BIO_printf(out, "RSA key error: %s\n",
ERR_reason_error_string(err));
ERR_get_error(); /* remove e from error stack */
ERR_get_error(); /* remove err from error stack */
}
} else if (r == -1) {
ERR_print_errors(bio_err);
@@ -251,8 +254,7 @@ int rsa_main(int argc, char **argv)
assert(private);
i = i2d_RSAPrivateKey_bio(out, rsa);
}
}
else if (outformat == FORMAT_PEM) {
} else if (outformat == FORMAT_PEM) {
if (pubout || pubin) {
if (pubout == 2)
i = PEM_write_bio_RSAPublicKey(out, rsa);
@@ -297,14 +299,15 @@ int rsa_main(int argc, char **argv)
if (i <= 0) {
BIO_printf(bio_err, "unable to write key\n");
ERR_print_errors(bio_err);
} else
} else {
ret = 0;
}
end:
release_engine(e);
BIO_free_all(out);
RSA_free(rsa);
OPENSSL_free(passin);
OPENSSL_free(passout);
return (ret);
return ret;
}
#endif
+15 -11
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2000-2018 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
@@ -13,6 +13,7 @@ NON_EMPTY_TRANSLATION_UNIT
#else
# include "apps.h"
# include "progs.h"
# include <string.h>
# include <openssl/err.h>
# include <openssl/pem.h>
@@ -32,10 +33,11 @@ typedef enum OPTION_choice {
OPT_ENGINE, OPT_IN, OPT_OUT, OPT_ASN1PARSE, OPT_HEXDUMP,
OPT_RAW, OPT_OAEP, OPT_SSL, OPT_PKCS, OPT_X931,
OPT_SIGN, OPT_VERIFY, OPT_REV, OPT_ENCRYPT, OPT_DECRYPT,
OPT_PUBIN, OPT_CERTIN, OPT_INKEY, OPT_PASSIN, OPT_KEYFORM
OPT_PUBIN, OPT_CERTIN, OPT_INKEY, OPT_PASSIN, OPT_KEYFORM,
OPT_R_ENUM
} OPTION_CHOICE;
OPTIONS rsautl_options[] = {
const OPTIONS rsautl_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"in", OPT_IN, '<', "Input file"},
{"out", OPT_OUT, '>', "Output file"},
@@ -57,6 +59,7 @@ OPTIONS rsautl_options[] = {
{"encrypt", OPT_ENCRYPT, '-', "Encrypt with public key"},
{"decrypt", OPT_DECRYPT, '-', "Decrypt with private key"},
{"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
OPT_R_OPTIONS,
# ifndef OPENSSL_NO_ENGINE
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
# endif
@@ -153,6 +156,10 @@ int rsautl_main(int argc, char **argv)
case OPT_PASSIN:
passinarg = opt_arg();
break;
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
}
}
argc = opt_num_rest();
@@ -169,9 +176,6 @@ int rsautl_main(int argc, char **argv)
goto end;
}
/* FIXME: seed PRNG only if needed */
app_RAND_load_file(NULL, 0);
switch (key_type) {
case KEY_PRIVKEY:
pkey = load_key(keyfile, keyformat, 0, passin, e, "Private Key");
@@ -190,14 +194,13 @@ int rsautl_main(int argc, char **argv)
break;
}
if (!pkey) {
if (pkey == NULL)
return 1;
}
rsa = EVP_PKEY_get1_RSA(pkey);
EVP_PKEY_free(pkey);
if (!rsa) {
if (rsa == NULL) {
BIO_printf(bio_err, "Error getting RSA key\n");
ERR_print_errors(bio_err);
goto end;
@@ -261,10 +264,11 @@ int rsautl_main(int argc, char **argv)
if (!ASN1_parse_dump(out, rsa_out, rsa_outlen, 1, -1)) {
ERR_print_errors(bio_err);
}
} else if (hexdump)
} else if (hexdump) {
BIO_dump(out, (char *)rsa_out, rsa_outlen);
else
} else {
BIO_write(out, rsa_out, rsa_outlen);
}
end:
RSA_free(rsa);
release_engine(e);
+8 -30
View File
@@ -1,5 +1,5 @@
/*
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2018 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
@@ -17,37 +17,12 @@
# define _kbhit kbhit
#endif
#if defined(OPENSSL_SYS_VMS) && !defined(FD_SET)
/*
* VAX C does not defined fd_set and friends, but it's actually quite simple
*/
/* These definitions are borrowed from SOCKETSHR. /Richard Levitte */
# define MAX_NOFILE 32
# define NBBY 8 /* number of bits in a byte */
# ifndef FD_SETSIZE
# define FD_SETSIZE MAX_NOFILE
# endif /* FD_SETSIZE */
/* How many things we'll allow select to use. 0 if unlimited */
# define MAXSELFD MAX_NOFILE
typedef int fd_mask; /* int here! VMS prototypes int, not long */
# define NFDBITS (sizeof(fd_mask) * NBBY)/* bits per mask (power of 2!) */
# define NFDSHIFT 5 /* Shift based on above */
typedef fd_mask fd_set;
# define FD_SET(n, p) (*(p) |= (1 << ((n) % NFDBITS)))
# define FD_CLR(n, p) (*(p) &= ~(1 << ((n) % NFDBITS)))
# define FD_ISSET(n, p) (*(p) & (1 << ((n) % NFDBITS)))
# define FD_ZERO(p) memset((p), 0, sizeof(*(p)))
#endif
#define PORT "4433"
#define PROTOCOL "tcp"
typedef int (*do_server_cb)(int s, int stype, unsigned char *context);
typedef int (*do_server_cb)(int s, int stype, int prot, unsigned char *context);
int do_server(int *accept_sock, const char *host, const char *port,
int family, int type,
int family, int type, int protocol,
do_server_cb cb,
unsigned char *context, int naccept);
#ifdef HEADER_X509_H
@@ -59,11 +34,12 @@ int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key,
STACK_OF(X509) *chain, int build_chain);
int ssl_print_sigalgs(BIO *out, SSL *s);
int ssl_print_point_formats(BIO *out, SSL *s);
int ssl_print_curves(BIO *out, SSL *s, int noshared);
int ssl_print_groups(BIO *out, SSL *s, int noshared);
#endif
int ssl_print_tmp_key(BIO *out, SSL *s);
int init_client(int *sock, const char *host, const char *port,
int family, int type);
const char *bindhost, const char *bindport,
int family, int type, int protocol);
int should_retry(int i);
long bio_dump_callback(BIO *bio, int cmd, const char *argp,
@@ -99,4 +75,6 @@ int ssl_load_stores(SSL_CTX *ctx, const char *vfyCApath,
const char *chCAfile, STACK_OF(X509_CRL) *crls,
int crl_download);
void ssl_ctx_security_debug(SSL_CTX *ctx, int verbose);
int set_keylog_file(SSL_CTX *ctx, const char *keylog_file);
void print_ca_names(BIO *bio, SSL *s);
#endif
+234 -117
View File
@@ -1,5 +1,5 @@
/*
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2018 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
@@ -11,9 +11,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h> /* for memcpy() and strcmp() */
#define USE_SOCKETS
#include "apps.h"
#undef USE_SOCKETS
#include <openssl/err.h>
#include <openssl/rand.h>
#include <openssl/x509.h>
@@ -32,6 +30,7 @@ VERIFY_CB_ARGS verify_args = { 0, 0, X509_V_OK, 0 };
static unsigned char cookie_secret[COOKIE_SECRET_LENGTH];
static int cookie_initialized = 0;
#endif
static BIO *bio_keylog = NULL;
static const char *lookup(int val, const STRINT_PAIR* list, const char* def)
{
@@ -52,13 +51,14 @@ int verify_callback(int ok, X509_STORE_CTX *ctx)
if (!verify_args.quiet || !ok) {
BIO_printf(bio_err, "depth=%d ", depth);
if (err_cert) {
if (err_cert != NULL) {
X509_NAME_print_ex(bio_err,
X509_get_subject_name(err_cert),
0, XN_FLAG_ONELINE);
0, get_nameopt());
BIO_puts(bio_err, "\n");
} else
} else {
BIO_puts(bio_err, "<no cert>\n");
}
}
if (!ok) {
BIO_printf(bio_err, "verify error:num=%d:%s\n", err,
@@ -76,7 +76,7 @@ int verify_callback(int ok, X509_STORE_CTX *ctx)
case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
BIO_puts(bio_err, "issuer= ");
X509_NAME_print_ex(bio_err, X509_get_issuer_name(err_cert),
0, XN_FLAG_ONELINE);
0, get_nameopt());
BIO_puts(bio_err, "\n");
break;
case X509_V_ERR_CERT_NOT_YET_VALID:
@@ -100,7 +100,7 @@ int verify_callback(int ok, X509_STORE_CTX *ctx)
policies_print(ctx);
if (ok && !verify_args.quiet)
BIO_printf(bio_err, "verify return:%d\n", ok);
return (ok);
return ok;
}
int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file)
@@ -111,7 +111,7 @@ int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file)
BIO_printf(bio_err, "unable to get certificate from '%s'\n",
cert_file);
ERR_print_errors(bio_err);
return (0);
return 0;
}
if (key_file == NULL)
key_file = cert_file;
@@ -119,7 +119,7 @@ int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file)
BIO_printf(bio_err, "unable to get private key from '%s'\n",
key_file);
ERR_print_errors(bio_err);
return (0);
return 0;
}
/*
@@ -134,10 +134,10 @@ int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file)
if (!SSL_CTX_check_private_key(ctx)) {
BIO_printf(bio_err,
"Private key does not match the certificate public key\n");
return (0);
return 0;
}
}
return (1);
return 1;
}
int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key,
@@ -205,7 +205,7 @@ static void ssl_print_client_cert_types(BIO *bio, SSL *s)
if (i)
BIO_puts(bio, ", ");
if (cname)
if (cname != NULL)
BIO_puts(bio, cname);
else
BIO_printf(bio, "UNKNOWN (%d),", cert_type);
@@ -213,12 +213,35 @@ static void ssl_print_client_cert_types(BIO *bio, SSL *s)
BIO_puts(bio, "\n");
}
static const char *get_sigtype(int nid)
{
switch (nid) {
case EVP_PKEY_RSA:
return "RSA";
case EVP_PKEY_RSA_PSS:
return "RSA-PSS";
case EVP_PKEY_DSA:
return "DSA";
case EVP_PKEY_EC:
return "ECDSA";
case NID_ED25519:
return "Ed25519";
default:
return NULL;
}
}
static int do_print_sigalgs(BIO *out, SSL *s, int shared)
{
int i, nsig, client;
client = SSL_is_server(s) ? 0 : 1;
if (shared)
nsig = SSL_get_shared_sigalgs(s, -1, NULL, NULL, NULL, NULL, NULL);
nsig = SSL_get_shared_sigalgs(s, 0, NULL, NULL, NULL, NULL, NULL);
else
nsig = SSL_get_sigalgs(s, -1, NULL, NULL, NULL, NULL, NULL);
if (nsig == 0)
@@ -241,20 +264,15 @@ static int do_print_sigalgs(BIO *out, SSL *s, int shared)
SSL_get_sigalgs(s, i, &sign_nid, &hash_nid, NULL, &rsign, &rhash);
if (i)
BIO_puts(out, ":");
if (sign_nid == EVP_PKEY_RSA)
sstr = "RSA";
else if (sign_nid == EVP_PKEY_DSA)
sstr = "DSA";
else if (sign_nid == EVP_PKEY_EC)
sstr = "ECDSA";
sstr = get_sigtype(sign_nid);
if (sstr)
BIO_printf(out, "%s+", sstr);
BIO_printf(out, "%s", sstr);
else
BIO_printf(out, "0x%02X+", (int)rsign);
BIO_printf(out, "0x%02X", (int)rsign);
if (hash_nid != NID_undef)
BIO_printf(out, "%s", OBJ_nid2sn(hash_nid));
else
BIO_printf(out, "0x%02X", (int)rhash);
BIO_printf(out, "+%s", OBJ_nid2sn(hash_nid));
else if (sstr == NULL)
BIO_printf(out, "+0x%02X", (int)rhash);
}
BIO_puts(out, "\n");
return 1;
@@ -262,13 +280,15 @@ static int do_print_sigalgs(BIO *out, SSL *s, int shared)
int ssl_print_sigalgs(BIO *out, SSL *s)
{
int mdnid;
int nid;
if (!SSL_is_server(s))
ssl_print_client_cert_types(out, s);
do_print_sigalgs(out, s, 0);
do_print_sigalgs(out, s, 1);
if (SSL_get_peer_signature_nid(s, &mdnid))
BIO_printf(out, "Peer signing digest: %s\n", OBJ_nid2sn(mdnid));
if (SSL_get_peer_signature_nid(s, &nid) && nid != NID_undef)
BIO_printf(out, "Peer signing digest: %s\n", OBJ_nid2sn(nid));
if (SSL_get_peer_signature_type_nid(s, &nid))
BIO_printf(out, "Peer signature type: %s\n", get_sigtype(nid));
return 1;
}
@@ -307,55 +327,58 @@ int ssl_print_point_formats(BIO *out, SSL *s)
return 1;
}
int ssl_print_curves(BIO *out, SSL *s, int noshared)
int ssl_print_groups(BIO *out, SSL *s, int noshared)
{
int i, ncurves, *curves, nid;
const char *cname;
int i, ngroups, *groups, nid;
const char *gname;
ncurves = SSL_get1_curves(s, NULL);
if (ncurves <= 0)
ngroups = SSL_get1_groups(s, NULL);
if (ngroups <= 0)
return 1;
curves = app_malloc(ncurves * sizeof(int), "curves to print");
SSL_get1_curves(s, curves);
groups = app_malloc(ngroups * sizeof(int), "groups to print");
SSL_get1_groups(s, groups);
BIO_puts(out, "Supported Elliptic Curves: ");
for (i = 0; i < ncurves; i++) {
BIO_puts(out, "Supported Elliptic Groups: ");
for (i = 0; i < ngroups; i++) {
if (i)
BIO_puts(out, ":");
nid = curves[i];
nid = groups[i];
/* If unrecognised print out hex version */
if (nid & TLSEXT_nid_unknown)
if (nid & TLSEXT_nid_unknown) {
BIO_printf(out, "0x%04X", nid & 0xFFFF);
else {
} else {
/* TODO(TLS1.3): Get group name here */
/* Use NIST name for curve if it exists */
cname = EC_curve_nid2nist(nid);
if (!cname)
cname = OBJ_nid2sn(nid);
BIO_printf(out, "%s", cname);
gname = EC_curve_nid2nist(nid);
if (gname == NULL)
gname = OBJ_nid2sn(nid);
BIO_printf(out, "%s", gname);
}
}
OPENSSL_free(curves);
OPENSSL_free(groups);
if (noshared) {
BIO_puts(out, "\n");
return 1;
}
BIO_puts(out, "\nShared Elliptic curves: ");
ncurves = SSL_get_shared_curve(s, -1);
for (i = 0; i < ncurves; i++) {
BIO_puts(out, "\nShared Elliptic groups: ");
ngroups = SSL_get_shared_group(s, -1);
for (i = 0; i < ngroups; i++) {
if (i)
BIO_puts(out, ":");
nid = SSL_get_shared_curve(s, i);
cname = EC_curve_nid2nist(nid);
if (!cname)
cname = OBJ_nid2sn(nid);
BIO_printf(out, "%s", cname);
nid = SSL_get_shared_group(s, i);
/* TODO(TLS1.3): Convert for DH groups */
gname = EC_curve_nid2nist(nid);
if (gname == NULL)
gname = OBJ_nid2sn(nid);
BIO_printf(out, "%s", gname);
}
if (ncurves == 0)
if (ngroups == 0)
BIO_puts(out, "NONE");
BIO_puts(out, "\n");
return 1;
}
#endif
int ssl_print_tmp_key(BIO *out, SSL *s)
{
EVP_PKEY *key;
@@ -379,7 +402,7 @@ int ssl_print_tmp_key(BIO *out, SSL *s)
nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
EC_KEY_free(ec);
cname = EC_curve_nid2nist(nid);
if (!cname)
if (cname == NULL)
cname = OBJ_nid2sn(nid);
BIO_printf(out, "ECDH, %s, %d bits\n", cname, EVP_PKEY_bits(key));
}
@@ -400,19 +423,19 @@ long bio_dump_callback(BIO *bio, int cmd, const char *argp,
out = (BIO *)BIO_get_callback_arg(bio);
if (out == NULL)
return (ret);
return ret;
if (cmd == (BIO_CB_READ | BIO_CB_RETURN)) {
BIO_printf(out, "read from %p [%p] (%lu bytes => %ld (0x%lX))\n",
(void *)bio, (void *)argp, (unsigned long)argi, ret, ret);
BIO_dump(out, argp, (int)ret);
return (ret);
return ret;
} else if (cmd == (BIO_CB_WRITE | BIO_CB_RETURN)) {
BIO_printf(out, "write to %p [%p] (%lu bytes => %ld (0x%lX))\n",
(void *)bio, (void *)argp, (unsigned long)argi, ret, ret);
BIO_dump(out, argp, (int)ret);
}
return (ret);
return ret;
}
void apps_ssl_info_callback(const SSL *s, int where, int ret)
@@ -441,10 +464,9 @@ void apps_ssl_info_callback(const SSL *s, int where, int ret)
if (ret == 0)
BIO_printf(bio_err, "%s:failed in %s\n",
str, SSL_state_string_long(s));
else if (ret < 0) {
else if (ret < 0)
BIO_printf(bio_err, "%s:error in %s\n",
str, SSL_state_string_long(s));
}
}
}
@@ -453,12 +475,15 @@ static STRINT_PAIR ssl_versions[] = {
{"TLS 1.0", TLS1_VERSION},
{"TLS 1.1", TLS1_1_VERSION},
{"TLS 1.2", TLS1_2_VERSION},
{"TLS 1.3", TLS1_3_VERSION},
{"DTLS 1.0", DTLS1_VERSION},
{"DTLS 1.0 (bad)", DTLS1_BAD_VER},
{NULL}
};
static STRINT_PAIR alert_types[] = {
{" close_notify", 0},
{" end_of_early_data", 1},
{" unexpected_message", 10},
{" bad_record_mac", 20},
{" decryption_failed", 21},
@@ -479,33 +504,43 @@ static STRINT_PAIR alert_types[] = {
{" protocol_version", 70},
{" insufficient_security", 71},
{" internal_error", 80},
{" inappropriate_fallback", 86},
{" user_canceled", 90},
{" no_renegotiation", 100},
{" missing_extension", 109},
{" unsupported_extension", 110},
{" certificate_unobtainable", 111},
{" unrecognized_name", 112},
{" bad_certificate_status_response", 113},
{" bad_certificate_hash_value", 114},
{" unknown_psk_identity", 115},
{" certificate_required", 116},
{NULL}
};
static STRINT_PAIR handshakes[] = {
{", HelloRequest", 0},
{", ClientHello", 1},
{", ServerHello", 2},
{", HelloVerifyRequest", 3},
{", NewSessionTicket", 4},
{", Certificate", 11},
{", ServerKeyExchange", 12},
{", CertificateRequest", 13},
{", ServerHelloDone", 14},
{", CertificateVerify", 15},
{", ClientKeyExchange", 16},
{", Finished", 20},
{", HelloRequest", SSL3_MT_HELLO_REQUEST},
{", ClientHello", SSL3_MT_CLIENT_HELLO},
{", ServerHello", SSL3_MT_SERVER_HELLO},
{", HelloVerifyRequest", DTLS1_MT_HELLO_VERIFY_REQUEST},
{", NewSessionTicket", SSL3_MT_NEWSESSION_TICKET},
{", EndOfEarlyData", SSL3_MT_END_OF_EARLY_DATA},
{", EncryptedExtensions", SSL3_MT_ENCRYPTED_EXTENSIONS},
{", Certificate", SSL3_MT_CERTIFICATE},
{", ServerKeyExchange", SSL3_MT_SERVER_KEY_EXCHANGE},
{", CertificateRequest", SSL3_MT_CERTIFICATE_REQUEST},
{", ServerHelloDone", SSL3_MT_SERVER_DONE},
{", CertificateVerify", SSL3_MT_CERTIFICATE_VERIFY},
{", ClientKeyExchange", SSL3_MT_CLIENT_KEY_EXCHANGE},
{", Finished", SSL3_MT_FINISHED},
{", CertificateUrl", 21},
{", CertificateStatus", 22},
{", CertificateStatus", SSL3_MT_CERTIFICATE_STATUS},
{", SupplementalData", 23},
{", KeyUpdate", SSL3_MT_KEY_UPDATE},
#ifndef OPENSSL_NO_NEXTPROTONEG
{", NextProto", SSL3_MT_NEXT_PROTO},
#endif
{", MessageHash", SSL3_MT_MESSAGE_HASH},
{NULL}
};
@@ -522,13 +557,14 @@ void msg_cb(int write_p, int version, int content_type, const void *buf,
version == TLS1_VERSION ||
version == TLS1_1_VERSION ||
version == TLS1_2_VERSION ||
version == TLS1_3_VERSION ||
version == DTLS1_VERSION || version == DTLS1_BAD_VER) {
switch (content_type) {
case 20:
str_content_type = "ChangeCipherSpec";
str_content_type = ", ChangeCipherSpec";
break;
case 21:
str_content_type = "Alert";
str_content_type = ", Alert";
str_details1 = ", ???";
if (len == 2) {
switch (bp[0]) {
@@ -543,13 +579,13 @@ void msg_cb(int write_p, int version, int content_type, const void *buf,
}
break;
case 22:
str_content_type = "Handshake";
str_content_type = ", Handshake";
str_details1 = "???";
if (len > 0)
str_details1 = lookup((int)bp[0], handshakes, "???");
break;
case 23:
str_content_type = "ApplicationData";
str_content_type = ", ApplicationData";
break;
#ifndef OPENSSL_NO_HEARTBEATS
case 24:
@@ -602,7 +638,7 @@ static STRINT_PAIR tlsext_types[] = {
{"client authz", TLSEXT_TYPE_client_authz},
{"server authz", TLSEXT_TYPE_server_authz},
{"cert type", TLSEXT_TYPE_cert_type},
{"elliptic curves", TLSEXT_TYPE_elliptic_curves},
{"supported_groups", TLSEXT_TYPE_supported_groups},
{"EC point formats", TLSEXT_TYPE_ec_point_formats},
{"SRP", TLSEXT_TYPE_srp},
{"signature algorithms", TLSEXT_TYPE_signature_algorithms},
@@ -625,6 +661,12 @@ static STRINT_PAIR tlsext_types[] = {
#ifdef TLSEXT_TYPE_extended_master_secret
{"extended master secret", TLSEXT_TYPE_extended_master_secret},
#endif
{"key share", TLSEXT_TYPE_key_share},
{"supported versions", TLSEXT_TYPE_supported_versions},
{"psk", TLSEXT_TYPE_psk},
{"psk kex modes", TLSEXT_TYPE_psk_kex_modes},
{"certificate authorities", TLSEXT_TYPE_certificate_authorities},
{"post handshake auth", TLSEXT_TYPE_post_handshake_auth},
{NULL}
};
@@ -645,9 +687,9 @@ int generate_cookie_callback(SSL *ssl, unsigned char *cookie,
unsigned int *cookie_len)
{
unsigned char *buffer;
size_t length;
size_t length = 0;
unsigned short port;
BIO_ADDR *peer = NULL;
BIO_ADDR *lpeer = NULL, *peer = NULL;
/* Initialize a random secret */
if (!cookie_initialized) {
@@ -658,17 +700,24 @@ int generate_cookie_callback(SSL *ssl, unsigned char *cookie,
cookie_initialized = 1;
}
peer = BIO_ADDR_new();
if (peer == NULL) {
BIO_printf(bio_err, "memory full\n");
return 0;
if (SSL_is_dtls(ssl)) {
lpeer = peer = BIO_ADDR_new();
if (peer == NULL) {
BIO_printf(bio_err, "memory full\n");
return 0;
}
/* Read peer information */
(void)BIO_dgram_get_peer(SSL_get_rbio(ssl), peer);
} else {
peer = ourpeer;
}
/* Read peer information */
(void)BIO_dgram_get_peer(SSL_get_rbio(ssl), peer);
/* Create buffer with peer's address and port */
BIO_ADDR_rawaddress(peer, NULL, &length);
if (!BIO_ADDR_rawaddress(peer, NULL, &length)) {
BIO_printf(bio_err, "Failed getting peer address\n");
return 0;
}
OPENSSL_assert(length != 0);
port = BIO_ADDR_rawport(peer);
length += sizeof(port);
@@ -682,7 +731,7 @@ int generate_cookie_callback(SSL *ssl, unsigned char *cookie,
buffer, length, cookie, cookie_len);
OPENSSL_free(buffer);
BIO_ADDR_free(peer);
BIO_ADDR_free(lpeer);
return 1;
}
@@ -774,24 +823,24 @@ static int set_cert_cb(SSL *ssl, void *arg)
#endif
SSL_certs_clear(ssl);
if (!exc)
if (exc == NULL)
return 1;
/*
* Go to end of list and traverse backwards since we prepend newer
* entries this retains the original order.
*/
while (exc->next)
while (exc->next != NULL)
exc = exc->next;
i = 0;
while (exc) {
while (exc != NULL) {
i++;
rv = SSL_check_chain(ssl, exc->cert, exc->key, exc->chain);
BIO_printf(bio_err, "Checking cert chain %d:\nSubject: ", i);
X509_NAME_print_ex(bio_err, X509_get_subject_name(exc->cert), 0,
XN_FLAG_ONELINE);
get_nameopt());
BIO_puts(bio_err, "\n");
print_chain_flags(ssl, rv);
if (rv & CERT_PKEY_VALID) {
@@ -807,8 +856,9 @@ static int set_cert_cb(SSL *ssl, void *arg)
if (exc->build_chain) {
if (!SSL_build_cert_chain(ssl, 0))
return 0;
} else if (exc->chain)
} else if (exc->chain != NULL) {
SSL_set1_chain(ssl, exc->chain);
}
}
exc = exc->prev;
}
@@ -845,7 +895,7 @@ void ssl_excert_free(SSL_EXCERT *exc)
{
SSL_EXCERT *curr;
if (!exc)
if (exc == NULL)
return;
while (exc) {
X509_free(exc->cert);
@@ -860,33 +910,33 @@ void ssl_excert_free(SSL_EXCERT *exc)
int load_excert(SSL_EXCERT **pexc)
{
SSL_EXCERT *exc = *pexc;
if (!exc)
if (exc == NULL)
return 1;
/* If nothing in list, free and set to NULL */
if (!exc->certfile && !exc->next) {
if (exc->certfile == NULL && exc->next == NULL) {
ssl_excert_free(exc);
*pexc = NULL;
return 1;
}
for (; exc; exc = exc->next) {
if (!exc->certfile) {
if (exc->certfile == NULL) {
BIO_printf(bio_err, "Missing filename\n");
return 0;
}
exc->cert = load_cert(exc->certfile, exc->certform,
"Server Certificate");
if (!exc->cert)
if (exc->cert == NULL)
return 0;
if (exc->keyfile) {
if (exc->keyfile != NULL) {
exc->key = load_key(exc->keyfile, exc->keyform,
0, NULL, NULL, "Server Key");
} else {
exc->key = load_key(exc->certfile, exc->certform,
0, NULL, NULL, "Server Key");
}
if (!exc->key)
if (exc->key == NULL)
return 0;
if (exc->chainfile) {
if (exc->chainfile != NULL) {
if (!load_certs(exc->chainfile, &exc->chain, FORMAT_PEM, NULL,
"Server Chain"))
return 0;
@@ -918,7 +968,7 @@ int args_excert(int opt, SSL_EXCERT **pexc)
case OPT_X__LAST:
return 0;
case OPT_X_CERT:
if (exc->certfile && !ssl_excert_prepend(&exc)) {
if (exc->certfile != NULL && !ssl_excert_prepend(&exc)) {
BIO_printf(bio_err, "%s: Error adding xcert\n", opt_getprog());
goto err;
}
@@ -926,14 +976,14 @@ int args_excert(int opt, SSL_EXCERT **pexc)
exc->certfile = opt_arg();
break;
case OPT_X_KEY:
if (exc->keyfile) {
if (exc->keyfile != NULL) {
BIO_printf(bio_err, "%s: Key already specified\n", opt_getprog());
goto err;
}
exc->keyfile = opt_arg();
break;
case OPT_X_CHAIN:
if (exc->chainfile) {
if (exc->chainfile != NULL) {
BIO_printf(bio_err, "%s: Chain already specified\n",
opt_getprog());
goto err;
@@ -976,11 +1026,11 @@ static void print_raw_cipherlist(SSL *s)
const SSL_CIPHER *c = SSL_CIPHER_find(s, rlist);
if (i)
BIO_puts(bio_err, ":");
if (c)
if (c != NULL) {
BIO_puts(bio_err, SSL_CIPHER_get_name(c));
else if (!memcmp(rlist, scsv_id, num))
} else if (memcmp(rlist, scsv_id, num) == 0) {
BIO_puts(bio_err, "SCSV");
else {
} else {
size_t j;
BIO_puts(bio_err, "0x");
for (j = 0; j < num; j++)
@@ -1002,8 +1052,8 @@ static char *hexencode(const unsigned char *data, size_t len)
int ilen = (int) outlen;
if (outlen < len || ilen < 0 || outlen != (size_t)ilen) {
BIO_printf(bio_err, "%s: %"BIO_PRI64"u-byte buffer too large to hexencode\n",
opt_getprog(), (uint64_t)len);
BIO_printf(bio_err, "%s: %zu-byte buffer too large to hexencode\n",
opt_getprog(), len);
exit(1);
}
cp = out = app_malloc(ilen, "TLSA hex data buffer");
@@ -1068,7 +1118,6 @@ void print_ssl_summary(SSL *s)
{
const SSL_CIPHER *c;
X509 *peer;
/* const char *pnam = SSL_is_server(s) ? "client" : "server"; */
BIO_printf(bio_err, "Protocol version: %s\n", SSL_get_version(s));
print_raw_cipherlist(s);
@@ -1076,23 +1125,26 @@ void print_ssl_summary(SSL *s)
BIO_printf(bio_err, "Ciphersuite: %s\n", SSL_CIPHER_get_name(c));
do_print_sigalgs(bio_err, s, 0);
peer = SSL_get_peer_certificate(s);
if (peer) {
if (peer != NULL) {
int nid;
BIO_puts(bio_err, "Peer certificate: ");
X509_NAME_print_ex(bio_err, X509_get_subject_name(peer),
0, XN_FLAG_ONELINE);
0, get_nameopt());
BIO_puts(bio_err, "\n");
if (SSL_get_peer_signature_nid(s, &nid))
BIO_printf(bio_err, "Hash used: %s\n", OBJ_nid2sn(nid));
if (SSL_get_peer_signature_type_nid(s, &nid))
BIO_printf(bio_err, "Signature type: %s\n", get_sigtype(nid));
print_verify_detail(s, bio_err);
} else
} else {
BIO_puts(bio_err, "No peer certificate\n");
}
X509_free(peer);
#ifndef OPENSSL_NO_EC
ssl_print_point_formats(bio_err, s);
if (SSL_is_server(s))
ssl_print_curves(bio_err, s, 1);
ssl_print_groups(bio_err, s, 1);
else
ssl_print_tmp_key(bio_err, s);
#else
@@ -1111,7 +1163,7 @@ int config_ctx(SSL_CONF_CTX *cctx, STACK_OF(OPENSSL_STRING) *str,
const char *flag = sk_OPENSSL_STRING_value(str, i);
const char *arg = sk_OPENSSL_STRING_value(str, i + 1);
if (SSL_CONF_cmd(cctx, flag, arg) <= 0) {
if (arg)
if (arg != NULL)
BIO_printf(bio_err, "Error with command: \"%s %s\"\n",
flag, arg);
else
@@ -1245,7 +1297,7 @@ static int security_callback_debug(const SSL *s, const SSL_CTX *ctx,
cert_md = 1;
break;
}
if (nm)
if (nm != NULL)
BIO_printf(sdb->out, "%s=", nm);
switch (op & SSL_SECOP_OTHER_TYPE) {
@@ -1333,3 +1385,68 @@ void ssl_ctx_security_debug(SSL_CTX *ctx, int verbose)
SSL_CTX_set_security_callback(ctx, security_callback_debug);
SSL_CTX_set0_security_ex_data(ctx, &sdb);
}
static void keylog_callback(const SSL *ssl, const char *line)
{
if (bio_keylog == NULL) {
BIO_printf(bio_err, "Keylog callback is invoked without valid file!\n");
return;
}
/*
* There might be concurrent writers to the keylog file, so we must ensure
* that the given line is written at once.
*/
BIO_printf(bio_keylog, "%s\n", line);
(void)BIO_flush(bio_keylog);
}
int set_keylog_file(SSL_CTX *ctx, const char *keylog_file)
{
/* Close any open files */
BIO_free_all(bio_keylog);
bio_keylog = NULL;
if (ctx == NULL || keylog_file == NULL) {
/* Keylogging is disabled, OK. */
return 0;
}
/*
* Append rather than write in order to allow concurrent modification.
* Furthermore, this preserves existing keylog files which is useful when
* the tool is run multiple times.
*/
bio_keylog = BIO_new_file(keylog_file, "a");
if (bio_keylog == NULL) {
BIO_printf(bio_err, "Error writing keylog file %s\n", keylog_file);
return 1;
}
/* Write a header for seekable, empty files (this excludes pipes). */
if (BIO_tell(bio_keylog) == 0) {
BIO_puts(bio_keylog,
"# SSL/TLS secrets log file, generated by OpenSSL\n");
(void)BIO_flush(bio_keylog);
}
SSL_CTX_set_keylog_callback(ctx, keylog_callback);
return 0;
}
void print_ca_names(BIO *bio, SSL *s)
{
const char *cs = SSL_is_server(s) ? "server" : "client";
const STACK_OF(X509_NAME) *sk = SSL_get0_peer_CA_list(s);
int i;
if (sk == NULL || sk_X509_NAME_num(sk) == 0) {
BIO_printf(bio, "---\nNo %s certificate CA names sent\n", cs);
return;
}
BIO_printf(bio, "---\nAcceptable %s certificate CA names\n",cs);
for (i = 0; i < sk_X509_NAME_num(sk); i++) {
X509_NAME_print_ex(bio, sk_X509_NAME_value(sk, i), 0, get_nameopt());
BIO_write(bio, "\n", 1);
}
}
+874 -198
View File
@@ -1,5 +1,6 @@
/*
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2005 Nokia. 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
@@ -7,33 +8,7 @@
* https://www.openssl.org/source/license.html
*/
/* ====================================================================
* Copyright 2005 Nokia. All rights reserved.
*
* The portions of the attached software ("Contribution") is developed by
* Nokia Corporation and is licensed pursuant to the OpenSSL open source
* license.
*
* The Contribution, originally written by Mika Kousa and Pasi Eronen of
* Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
* support (see RFC 4279) to OpenSSL.
*
* No patent licenses or other rights except those expressly stated in
* the OpenSSL open source license shall be deemed granted or received
* expressly, by implication, estoppel, or otherwise.
*
* No assurances are provided by Nokia that the Contribution does not
* infringe the patent or other intellectual property rights of any third
* party or that the license provides you with all the necessary rights
* to make use of the Contribution.
*
* THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
* ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
* SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
* OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
* OTHERWISE.
*/
#include "e_os.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
@@ -54,8 +29,8 @@
typedef unsigned int u_int;
#endif
#define USE_SOCKETS
#include "apps.h"
#include "progs.h"
#include <openssl/x509.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
@@ -72,6 +47,7 @@ typedef unsigned int u_int;
#endif
#include "s_apps.h"
#include "timeouts.h"
#include "internal/sockets.h"
#if defined(__has_feature)
# if __has_feature(memory_sanitizer)
@@ -90,11 +66,14 @@ static char *keymatexportlabel = NULL;
static int keymatexportlen = 20;
static BIO *bio_c_out = NULL;
static int c_quiet = 0;
static char *sess_out = NULL;
static SSL_SESSION *psksess = NULL;
static void print_stuff(BIO *berr, SSL *con, int full);
#ifndef OPENSSL_NO_OCSP
static int ocsp_resp_cb(SSL *s, void *arg);
#endif
static int ldap_ExtendedResponse_parse(const char *buf, long rem);
static int saved_errno;
@@ -132,13 +111,10 @@ static void do_ssl_shutdown(SSL *ssl)
} while (ret < 0);
}
#ifndef OPENSSL_NO_PSK
/* Default PSK identity and key */
static char *psk_identity = "Client_identity";
/*
* char *psk_key=NULL; by default PSK is not used
*/
#ifndef OPENSSL_NO_PSK
static unsigned int psk_client_cb(SSL *ssl, const char *hint, char *identity,
unsigned int max_identity_len,
unsigned char *psk,
@@ -155,8 +131,9 @@ static unsigned int psk_client_cb(SSL *ssl, const char *hint, char *identity,
if (c_debug)
BIO_printf(bio_c_out,
"NULL received PSK identity hint, continuing anyway\n");
} else if (c_debug)
} else if (c_debug) {
BIO_printf(bio_c_out, "Received PSK identity hint '%s'\n", hint);
}
/*
* lookup PSK identity and PSK key based on the given identity hint here
@@ -197,6 +174,76 @@ static unsigned int psk_client_cb(SSL *ssl, const char *hint, char *identity,
}
#endif
const unsigned char tls13_aes128gcmsha256_id[] = { 0x13, 0x01 };
const unsigned char tls13_aes256gcmsha384_id[] = { 0x13, 0x02 };
static int psk_use_session_cb(SSL *s, const EVP_MD *md,
const unsigned char **id, size_t *idlen,
SSL_SESSION **sess)
{
SSL_SESSION *usesess = NULL;
const SSL_CIPHER *cipher = NULL;
if (psksess != NULL) {
SSL_SESSION_up_ref(psksess);
usesess = psksess;
} else {
long key_len;
unsigned char *key = OPENSSL_hexstr2buf(psk_key, &key_len);
if (key == NULL) {
BIO_printf(bio_err, "Could not convert PSK key '%s' to buffer\n",
psk_key);
return 0;
}
if (key_len == EVP_MD_size(EVP_sha256()))
cipher = SSL_CIPHER_find(s, tls13_aes128gcmsha256_id);
else if (key_len == EVP_MD_size(EVP_sha384()))
cipher = SSL_CIPHER_find(s, tls13_aes256gcmsha384_id);
if (cipher == NULL) {
/* Doesn't look like a suitable TLSv1.3 key. Ignore it */
OPENSSL_free(key);
*id = NULL;
*idlen = 0;
*sess = NULL;
return 1;
}
usesess = SSL_SESSION_new();
if (usesess == NULL
|| !SSL_SESSION_set1_master_key(usesess, key, key_len)
|| !SSL_SESSION_set_cipher(usesess, cipher)
|| !SSL_SESSION_set_protocol_version(usesess, TLS1_3_VERSION)) {
OPENSSL_free(key);
goto err;
}
OPENSSL_free(key);
}
cipher = SSL_SESSION_get0_cipher(usesess);
if (cipher == NULL)
goto err;
if (md != NULL && SSL_CIPHER_get_handshake_digest(cipher) != md) {
/* PSK not usable, ignore it */
*id = NULL;
*idlen = 0;
*sess = NULL;
SSL_SESSION_free(usesess);
} else {
*sess = usesess;
*id = (unsigned char *)psk_identity;
*idlen = strlen(psk_identity);
}
return 1;
err:
SSL_SESSION_free(usesess);
return 0;
}
/* This is a context that we pass to callbacks */
typedef struct tlsextctx_st {
BIO *biodebug;
@@ -371,10 +418,11 @@ static int serverinfo_cli_parse_cb(SSL *s, unsigned int ext_type,
unsigned char ext_buf[4 + 65536];
/* Reconstruct the type/len fields prior to extension data */
ext_buf[0] = ext_type >> 8;
ext_buf[1] = ext_type & 0xFF;
ext_buf[2] = inlen >> 8;
ext_buf[3] = inlen & 0xFF;
inlen &= 0xffff; /* for formal memcmpy correctness */
ext_buf[0] = (unsigned char)(ext_type >> 8);
ext_buf[1] = (unsigned char)(ext_type);
ext_buf[2] = (unsigned char)(inlen >> 8);
ext_buf[3] = (unsigned char)(inlen);
memcpy(ext_buf + 4, in, inlen);
BIO_snprintf(pem_name, sizeof(pem_name), "SERVERINFO FOR EXTENSION %d",
@@ -522,32 +570,30 @@ static int tlsa_import_rrset(SSL *con, STACK_OF(OPENSSL_STRING) *rrset)
typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_4, OPT_6, OPT_HOST, OPT_PORT, OPT_CONNECT, OPT_UNIX,
OPT_XMPPHOST, OPT_VERIFY,
OPT_4, OPT_6, OPT_HOST, OPT_PORT, OPT_CONNECT, OPT_BIND, OPT_UNIX,
OPT_XMPPHOST, OPT_VERIFY, OPT_NAMEOPT,
OPT_CERT, OPT_CRL, OPT_CRL_DOWNLOAD, OPT_SESS_OUT, OPT_SESS_IN,
OPT_CERTFORM, OPT_CRLFORM, OPT_VERIFY_RET_ERROR, OPT_VERIFY_QUIET,
OPT_BRIEF, OPT_PREXIT, OPT_CRLF, OPT_QUIET, OPT_NBIO,
OPT_SSL_CLIENT_ENGINE, OPT_RAND, OPT_IGN_EOF, OPT_NO_IGN_EOF,
OPT_SSL_CLIENT_ENGINE, OPT_IGN_EOF, OPT_NO_IGN_EOF,
OPT_DEBUG, OPT_TLSEXTDEBUG, OPT_STATUS, OPT_WDEBUG,
OPT_MSG, OPT_MSGFILE, OPT_ENGINE, OPT_TRACE, OPT_SECURITY_DEBUG,
OPT_SECURITY_DEBUG_VERBOSE, OPT_SHOWCERTS, OPT_NBIO_TEST, OPT_STATE,
#ifndef OPENSSL_NO_PSK
OPT_PSK_IDENTITY, OPT_PSK,
#endif
OPT_PSK_IDENTITY, OPT_PSK, OPT_PSK_SESS,
#ifndef OPENSSL_NO_SRP
OPT_SRPUSER, OPT_SRPPASS, OPT_SRP_STRENGTH, OPT_SRP_LATEUSER,
OPT_SRP_MOREGROUPS,
#endif
OPT_SSL3, OPT_SSL_CONFIG,
OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1,
OPT_DTLS1_2, OPT_TIMEOUT, OPT_MTU, OPT_KEYFORM, OPT_PASS,
OPT_CERT_CHAIN, OPT_CAPATH, OPT_NOCAPATH, OPT_CHAINCAPATH,
OPT_VERIFYCAPATH,
OPT_TLS1_3, OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1,
OPT_DTLS1_2, OPT_SCTP, OPT_TIMEOUT, OPT_MTU, OPT_KEYFORM, OPT_PASS,
OPT_CERT_CHAIN, OPT_CAPATH, OPT_NOCAPATH, OPT_CHAINCAPATH, OPT_VERIFYCAPATH,
OPT_KEY, OPT_RECONNECT, OPT_BUILD_CHAIN, OPT_CAFILE, OPT_NOCAFILE,
OPT_CHAINCAFILE, OPT_VERIFYCAFILE, OPT_NEXTPROTONEG, OPT_ALPN,
OPT_SERVERINFO, OPT_STARTTLS, OPT_SERVERNAME,
OPT_USE_SRTP, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN, OPT_SMTPHOST,
OPT_ASYNC, OPT_SPLIT_SEND_FRAG, OPT_MAX_PIPELINES, OPT_READ_BUF,
OPT_SERVERINFO, OPT_STARTTLS, OPT_SERVERNAME, OPT_NOSERVERNAME, OPT_ASYNC,
OPT_USE_SRTP, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN, OPT_PROTOHOST,
OPT_MAXFRAGLEN, OPT_MAX_SEND_FRAG, OPT_SPLIT_SEND_FRAG, OPT_MAX_PIPELINES,
OPT_READ_BUF, OPT_KEYLOG_FILE, OPT_EARLY_DATA, OPT_REQCAFILE,
OPT_V_ENUM,
OPT_X_ENUM,
OPT_S_ENUM,
@@ -555,15 +601,18 @@ typedef enum OPTION_choice {
#ifndef OPENSSL_NO_CT
OPT_CT, OPT_NOCT, OPT_CTLOG_FILE,
#endif
OPT_DANE_TLSA_RRDATA, OPT_DANE_EE_NO_NAME
OPT_DANE_TLSA_RRDATA, OPT_DANE_EE_NO_NAME,
OPT_FORCE_PHA,
OPT_R_ENUM
} OPTION_CHOICE;
OPTIONS s_client_options[] = {
const OPTIONS s_client_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"host", OPT_HOST, 's', "Use -connect instead"},
{"port", OPT_PORT, 'p', "Use -connect instead"},
{"connect", OPT_CONNECT, 's',
"TCP/IP where to connect (default is :" PORT ")"},
{"bind", OPT_BIND, 's', "bind local address for connection"},
{"proxy", OPT_PROXY, 's',
"Connect to via specified proxy to the real server"},
#ifdef AF_UNIX
@@ -577,6 +626,7 @@ OPTIONS s_client_options[] = {
{"cert", OPT_CERT, '<', "Certificate file to use, PEM format assumed"},
{"certform", OPT_CERTFORM, 'F',
"Certificate format (PEM or DER) PEM default"},
{"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"},
{"key", OPT_KEY, 's', "Private key file to use, if not in -cert file"},
{"keyform", OPT_KEYFORM, 'E', "Key format (PEM, DER or engine) PEM default"},
{"pass", OPT_PASS, 's', "Private key file pass phrase source"},
@@ -586,6 +636,8 @@ OPTIONS s_client_options[] = {
"Do not load the default certificates file"},
{"no-CApath", OPT_NOCAPATH, '-',
"Do not load certificates from the default certificates directory"},
{"requestCAfile", OPT_REQCAFILE, '<',
"PEM format file of CA names to send to the server"},
{"dane_tlsa_domain", OPT_DANE_TLSA_DOMAIN, 's', "DANE TLSA base domain"},
{"dane_tlsa_rrdata", OPT_DANE_TLSA_RRDATA, 's',
"DANE TLSA rrdata presentation form"},
@@ -607,9 +659,8 @@ OPTIONS s_client_options[] = {
{"starttls", OPT_STARTTLS, 's',
"Use the appropriate STARTTLS command before starting TLS"},
{"xmpphost", OPT_XMPPHOST, 's',
"Host to use with \"-starttls xmpp[-server]\""},
{"rand", OPT_RAND, 's',
"Load the file(s) into the random number generator"},
"Alias of -name option for \"-starttls xmpp[-server]\""},
OPT_R_OPTIONS,
{"sess_out", OPT_SESS_OUT, '>', "File to write SSL session to"},
{"sess_in", OPT_SESS_IN, '<', "File to read SSL session from"},
{"use_srtp", OPT_USE_SRTP, 's',
@@ -618,8 +669,11 @@ OPTIONS s_client_options[] = {
"Export keying material using label"},
{"keymatexportlen", OPT_KEYMATEXPORTLEN, 'p',
"Export len bytes of keying material (default 20)"},
{"maxfraglen", OPT_MAXFRAGLEN, 'p',
"Enable Maximum Fragment Length Negotiation (len values: 512, 1024, 2048 and 4096)"},
{"fallback_scsv", OPT_FALLBACKSCSV, '-', "Send the fallback SCSV"},
{"name", OPT_SMTPHOST, 's', "Hostname to use for \"-starttls smtp\""},
{"name", OPT_PROTOHOST, 's',
"Hostname to use for \"-starttls lmtp\", \"-starttls smtp\" or \"-starttls xmpp[-server]\""},
{"CRL", OPT_CRL, '<', "CRL file to use"},
{"crl_download", OPT_CRL_DOWNLOAD, '-', "Download CRL from distribution points"},
{"CRLform", OPT_CRLFORM, 'F', "CRL format (PEM or DER) PEM is default"},
@@ -647,7 +701,9 @@ OPTIONS s_client_options[] = {
"CA file for certificate verification (PEM format)"},
{"nocommands", OPT_NOCMDS, '-', "Do not use interactive command letters"},
{"servername", OPT_SERVERNAME, 's',
"Set TLS extension servername in ClientHello"},
"Set TLS extension servername (SNI) in ClientHello (default)"},
{"noservername", OPT_NOSERVERNAME, '-',
"Do not send the server name (SNI) extension in the ClientHello"},
{"tlsextdebug", OPT_TLSEXTDEBUG, '-',
"Hex dump of all TLS extensions received"},
#ifndef OPENSSL_NO_OCSP
@@ -659,11 +715,12 @@ OPTIONS s_client_options[] = {
"Enable ALPN extension, considering named protocols supported (comma-separated list)"},
{"async", OPT_ASYNC, '-', "Support asynchronous operation"},
{"ssl_config", OPT_SSL_CONFIG, 's', "Use specified configuration file"},
{"split_send_frag", OPT_SPLIT_SEND_FRAG, 'n',
{"max_send_frag", OPT_MAX_SEND_FRAG, 'p', "Maximum Size of send frames "},
{"split_send_frag", OPT_SPLIT_SEND_FRAG, 'p',
"Size used to split data for encrypt pipelines"},
{"max_pipelines", OPT_MAX_PIPELINES, 'n',
{"max_pipelines", OPT_MAX_PIPELINES, 'p',
"Maximum number of encrypt/decrypt pipelines to be used"},
{"read_buf", OPT_READ_BUF, 'n',
{"read_buf", OPT_READ_BUF, 'p',
"Default read buffer size to be used for connections"},
OPT_S_OPTIONS,
OPT_V_OPTIONS,
@@ -680,6 +737,9 @@ OPTIONS s_client_options[] = {
#ifndef OPENSSL_NO_TLS1_2
{"tls1_2", OPT_TLS1_2, '-', "Just use TLSv1.2"},
#endif
#ifndef OPENSSL_NO_TLS1_3
{"tls1_3", OPT_TLS1_3, '-', "Just use TLSv1.3"},
#endif
#ifndef OPENSSL_NO_DTLS
{"dtls", OPT_DTLS, '-', "Use any version of DTLS"},
{"timeout", OPT_TIMEOUT, '-',
@@ -692,6 +752,9 @@ OPTIONS s_client_options[] = {
#ifndef OPENSSL_NO_DTLS1_2
{"dtls1_2", OPT_DTLS1_2, '-', "Just use DTLSv1.2"},
#endif
#ifndef OPENSSL_NO_SCTP
{"sctp", OPT_SCTP, '-', "Use SCTP"},
#endif
#ifndef OPENSSL_NO_SSL_TRACE
{"trace", OPT_TRACE, '-', "Show trace output of protocol messages"},
#endif
@@ -699,10 +762,9 @@ OPTIONS s_client_options[] = {
{"wdebug", OPT_WDEBUG, '-', "WATT-32 tcp debugging"},
#endif
{"nbio", OPT_NBIO, '-', "Use non-blocking IO"},
#ifndef OPENSSL_NO_PSK
{"psk_identity", OPT_PSK_IDENTITY, 's', "PSK identity"},
{"psk", OPT_PSK, 's', "PSK in hex (without 0x)"},
#endif
{"psk_session", OPT_PSK_SESS, '<', "File to read PSK SSL session from"},
#ifndef OPENSSL_NO_SRP
{"srpuser", OPT_SRPUSER, 's', "SRP authentication for 'user'"},
{"srppass", OPT_SRPPASS, 's', "Password for 'user'"},
@@ -726,6 +788,9 @@ OPTIONS s_client_options[] = {
{"noct", OPT_NOCT, '-', "Do not request or parse SCTs (default)"},
{"ctlogfile", OPT_CTLOG_FILE, '<', "CT log list CONF file"},
#endif
{"keylogfile", OPT_KEYLOG_FILE, '>', "Write TLS secrets to file"},
{"early_data", OPT_EARLY_DATA, '<', "File to send as early data"},
{"force_pha", OPT_FORCE_PHA, '-', "Force-enable post-handshake-authentication"},
{NULL, OPT_EOF, 0x00, NULL}
};
@@ -739,7 +804,13 @@ typedef enum PROTOCOL_choice {
PROTO_XMPP,
PROTO_XMPP_SERVER,
PROTO_CONNECT,
PROTO_IRC
PROTO_IRC,
PROTO_MYSQL,
PROTO_POSTGRES,
PROTO_LMTP,
PROTO_NNTP,
PROTO_SIEVE,
PROTO_LDAP
} PROTOCOL_CHOICE;
static const OPT_PAIR services[] = {
@@ -751,6 +822,12 @@ static const OPT_PAIR services[] = {
{"xmpp-server", PROTO_XMPP_SERVER},
{"telnet", PROTO_TELNET},
{"irc", PROTO_IRC},
{"mysql", PROTO_MYSQL},
{"postgres", PROTO_POSTGRES},
{"lmtp", PROTO_LMTP},
{"nntp", PROTO_NNTP},
{"sieve", PROTO_SIEVE},
{"ldap", PROTO_LDAP},
{NULL, 0}
};
@@ -760,7 +837,7 @@ static const OPT_PAIR services[] = {
#define IS_PROT_FLAG(o) \
(o == OPT_SSL3 || o == OPT_TLS1 || o == OPT_TLS1_1 || o == OPT_TLS1_2 \
|| o == OPT_DTLS || o == OPT_DTLS1 || o == OPT_DTLS1_2)
|| o == OPT_TLS1_3 || o == OPT_DTLS || o == OPT_DTLS1 || o == OPT_DTLS1_2)
/* Free |*dest| and optionally set it to a copy of |source|. */
static void freeandcopy(char **dest, const char *source)
@@ -771,6 +848,24 @@ static void freeandcopy(char **dest, const char *source)
*dest = OPENSSL_strdup(source);
}
static int new_session_cb(SSL *S, SSL_SESSION *sess)
{
BIO *stmp = BIO_new_file(sess_out, "w");
if (stmp == NULL) {
BIO_printf(bio_err, "Error writing session file %s\n", sess_out);
} else {
PEM_write_bio_SSL_SESSION(stmp, sess);
BIO_free(stmp);
}
/*
* We always return a "fail" response so that the session gets freed again
* because we haven't used the reference.
*/
return 0;
}
int s_client_main(int argc, char **argv)
{
BIO *sbio;
@@ -790,15 +885,15 @@ int s_client_main(int argc, char **argv)
const SSL_METHOD *meth = TLS_client_method();
const char *CApath = NULL, *CAfile = NULL;
char *cbuf = NULL, *sbuf = NULL;
char *mbuf = NULL, *proxystr = NULL, *connectstr = NULL;
char *mbuf = NULL, *proxystr = NULL, *connectstr = NULL, *bindstr = NULL;
char *cert_file = NULL, *key_file = NULL, *chain_file = NULL;
char *chCApath = NULL, *chCAfile = NULL, *host = NULL;
char *port = OPENSSL_strdup(PORT);
char *inrand = NULL;
char *bindhost = NULL, *bindport = NULL;
char *passarg = NULL, *pass = NULL, *vfyCApath = NULL, *vfyCAfile = NULL;
char *sess_in = NULL, *sess_out = NULL, *crl_file = NULL, *p;
char *xmpphost = NULL;
const char *ehlo = "mail.example.com";
char *ReqCAfile = NULL;
char *sess_in = NULL, *crl_file = NULL, *p;
const char *protohost = NULL;
struct timeval timeout, *timeoutp;
fd_set readfds, writefds;
int noCApath = 0, noCAfile = 0;
@@ -809,7 +904,7 @@ int s_client_main(int argc, char **argv)
int reconnect = 0, verify = SSL_VERIFY_NONE, vpmtouched = 0;
int ret = 1, in_init = 1, i, nbio_test = 0, s = -1, k, width, state = 0;
int sbuf_len, sbuf_off, cmdletters = 1;
int socket_family = AF_UNSPEC, socket_type = SOCK_STREAM;
int socket_family = AF_UNSPEC, socket_type = SOCK_STREAM, protocol = 0;
int starttls_proto = PROTO_OFF, crl_format = FORMAT_PEM, crl_download = 0;
int write_tty, read_tty, write_ssl, read_ssl, tty_on, ssl_pending;
#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS)
@@ -817,7 +912,6 @@ int s_client_main(int argc, char **argv)
#endif
int read_buf_len = 0;
int fallback_scsv = 0;
long randamt = 0;
OPTION_CHOICE o;
#ifndef OPENSSL_NO_DTLS
int enable_timeouts = 0;
@@ -830,7 +924,8 @@ int s_client_main(int argc, char **argv)
#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
struct timeval tv;
#endif
char *servername = NULL;
const char *servername = NULL;
int noservername = 0;
const char *alpn_in = NULL;
tlsextctx tlsextcbp = { NULL, 0 };
const char *ssl_config = NULL;
@@ -851,16 +946,23 @@ int s_client_main(int argc, char **argv)
#endif
int min_version = 0, max_version = 0, prot_opt = 0, no_prot_opt = 0;
int async = 0;
unsigned int split_send_fragment = 0;
unsigned int max_pipelines = 0;
unsigned int max_send_fragment = 0;
unsigned int split_send_fragment = 0, max_pipelines = 0;
enum { use_inet, use_unix, use_unknown } connect_type = use_unknown;
int count4or6 = 0;
uint8_t maxfraglen = 0;
int c_nbio = 0, c_msg = 0, c_ign_eof = 0, c_brief = 0;
int c_tlsextdebug = 0;
#ifndef OPENSSL_NO_OCSP
int c_status_req = 0;
#endif
BIO *bio_c_msg = NULL;
const char *keylog_file = NULL, *early_data_file = NULL;
#ifndef OPENSSL_NO_DTLS
int isdtls = 0;
#endif
char *psksessf = NULL;
int force_pha = 0;
FD_ZERO(&readfds);
FD_ZERO(&writefds);
@@ -953,6 +1055,9 @@ int s_client_main(int argc, char **argv)
connect_type = use_inet;
freeandcopy(&connectstr, opt_arg());
break;
case OPT_BIND:
freeandcopy(&bindstr, opt_arg());
break;
case OPT_PROXY:
proxystr = opt_arg();
starttls_proto = PROTO_CONNECT;
@@ -965,10 +1070,9 @@ int s_client_main(int argc, char **argv)
break;
#endif
case OPT_XMPPHOST:
xmpphost = opt_arg();
break;
case OPT_SMTPHOST:
ehlo = opt_arg();
/* fall through, since this is an alias */
case OPT_PROTOHOST:
protohost = opt_arg();
break;
case OPT_VERIFY:
verify = SSL_VERIFY_PEER;
@@ -979,6 +1083,10 @@ int s_client_main(int argc, char **argv)
case OPT_CERT:
cert_file = opt_arg();
break;
case OPT_NAMEOPT:
if (!set_nameopt(opt_arg()))
goto end;
break;
case OPT_CRL:
crl_file = opt_arg();
break;
@@ -1054,8 +1162,9 @@ int s_client_main(int argc, char **argv)
}
#endif
break;
case OPT_RAND:
inrand = opt_arg();
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
case OPT_IGN_EOF:
c_ign_eof = 1;
@@ -1105,7 +1214,6 @@ int s_client_main(int argc, char **argv)
case OPT_STATE:
state = 1;
break;
#ifndef OPENSSL_NO_PSK
case OPT_PSK_IDENTITY:
psk_identity = opt_arg();
break;
@@ -1117,7 +1225,9 @@ int s_client_main(int argc, char **argv)
goto end;
}
break;
#endif
case OPT_PSK_SESS:
psksessf = opt_arg();
break;
#ifndef OPENSSL_NO_SRP
case OPT_SRPUSER:
srp_arg.srplogin = opt_arg();
@@ -1154,6 +1264,10 @@ int s_client_main(int argc, char **argv)
min_version = SSL3_VERSION;
max_version = SSL3_VERSION;
break;
case OPT_TLS1_3:
min_version = TLS1_3_VERSION;
max_version = TLS1_3_VERSION;
break;
case OPT_TLS1_2:
min_version = TLS1_2_VERSION;
max_version = TLS1_2_VERSION;
@@ -1170,6 +1284,7 @@ int s_client_main(int argc, char **argv)
#ifndef OPENSSL_NO_DTLS
meth = DTLS_client_method();
socket_type = SOCK_DGRAM;
isdtls = 1;
#endif
break;
case OPT_DTLS1:
@@ -1178,6 +1293,7 @@ int s_client_main(int argc, char **argv)
min_version = DTLS1_VERSION;
max_version = DTLS1_VERSION;
socket_type = SOCK_DGRAM;
isdtls = 1;
#endif
break;
case OPT_DTLS1_2:
@@ -1186,6 +1302,12 @@ int s_client_main(int argc, char **argv)
min_version = DTLS1_2_VERSION;
max_version = DTLS1_2_VERSION;
socket_type = SOCK_DGRAM;
isdtls = 1;
#endif
break;
case OPT_SCTP:
#ifndef OPENSSL_NO_SCTP
protocol = IPPROTO_SCTP;
#endif
break;
case OPT_TIMEOUT:
@@ -1232,6 +1354,9 @@ int s_client_main(int argc, char **argv)
case OPT_BUILD_CHAIN:
build_chain = 1;
break;
case OPT_REQCAFILE:
ReqCAfile = opt_arg();
break;
case OPT_CAFILE:
CAfile = opt_arg();
break;
@@ -1297,6 +1422,9 @@ int s_client_main(int argc, char **argv)
case OPT_SERVERNAME:
servername = opt_arg();
break;
case OPT_NOSERVERNAME:
noservername = 1;
break;
case OPT_USE_SRTP:
srtp_profiles = opt_arg();
break;
@@ -1309,15 +1437,33 @@ int s_client_main(int argc, char **argv)
case OPT_ASYNC:
async = 1;
break;
case OPT_MAXFRAGLEN:
len = atoi(opt_arg());
switch (len) {
case 512:
maxfraglen = TLSEXT_max_fragment_length_512;
break;
case 1024:
maxfraglen = TLSEXT_max_fragment_length_1024;
break;
case 2048:
maxfraglen = TLSEXT_max_fragment_length_2048;
break;
case 4096:
maxfraglen = TLSEXT_max_fragment_length_4096;
break;
default:
BIO_printf(bio_err,
"%s: Max Fragment Len %u is out of permitted values",
prog, len);
goto opthelp;
}
break;
case OPT_MAX_SEND_FRAG:
max_send_fragment = atoi(opt_arg());
break;
case OPT_SPLIT_SEND_FRAG:
split_send_fragment = atoi(opt_arg());
if (split_send_fragment == 0) {
/*
* Not allowed - set to a deliberately bad value so we get an
* error message below
*/
split_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH + 1;
}
break;
case OPT_MAX_PIPELINES:
max_pipelines = atoi(opt_arg());
@@ -1325,21 +1471,64 @@ int s_client_main(int argc, char **argv)
case OPT_READ_BUF:
read_buf_len = atoi(opt_arg());
break;
case OPT_KEYLOG_FILE:
keylog_file = opt_arg();
break;
case OPT_EARLY_DATA:
early_data_file = opt_arg();
break;
case OPT_FORCE_PHA:
force_pha = 1;
break;
}
}
if (count4or6 >= 2) {
BIO_printf(bio_err, "%s: Can't use both -4 and -6\n", prog);
goto opthelp;
}
if (noservername) {
if (servername != NULL) {
BIO_printf(bio_err,
"%s: Can't use -servername and -noservername together\n",
prog);
goto opthelp;
}
if (dane_tlsa_domain != NULL) {
BIO_printf(bio_err,
"%s: Can't use -dane_tlsa_domain and -noservername together\n",
prog);
goto opthelp;
}
}
argc = opt_num_rest();
if (argc != 0)
if (argc == 1) {
/* If there's a positional argument, it's the equivalent of
* OPT_CONNECT.
* Don't allow -connect and a separate argument.
*/
if (connectstr != NULL) {
BIO_printf(bio_err,
"%s: must not provide both -connect option and target parameter\n",
prog);
goto opthelp;
}
connect_type = use_inet;
freeandcopy(&connectstr, *opt_rest());
} else if (argc != 0) {
goto opthelp;
}
if (proxystr) {
#ifndef OPENSSL_NO_NEXTPROTONEG
if (min_version == TLS1_3_VERSION && next_proto_neg_in != NULL) {
BIO_printf(bio_err, "Cannot supply -nextprotoneg with TLSv1.3\n");
goto opthelp;
}
#endif
if (proxystr != NULL) {
int res;
char *tmp_host = host, *tmp_port = port;
if (connectstr == NULL) {
BIO_printf(bio_err, "%s: -proxy requires use of -connect\n", prog);
BIO_printf(bio_err, "%s: -proxy requires use of -connect or target parameter\n", prog);
goto opthelp;
}
res = BIO_parse_hostserv(proxystr, &host, &port, BIO_PARSE_PRIO_HOST);
@@ -1364,7 +1553,19 @@ int s_client_main(int argc, char **argv)
OPENSSL_free(tmp_port);
if (!res) {
BIO_printf(bio_err,
"%s: -connect argument malformed or ambiguous\n",
"%s: -connect argument or target parameter malformed or ambiguous\n",
prog);
goto end;
}
}
if (bindstr != NULL) {
int res;
res = BIO_parse_hostserv(bindstr, &bindhost, &bindport,
BIO_PARSE_PRIO_HOST);
if (!res) {
BIO_printf(bio_err,
"%s: -bind argument parameter malformed or ambiguous\n",
prog);
goto end;
}
@@ -1378,15 +1579,16 @@ int s_client_main(int argc, char **argv)
}
#endif
if (split_send_fragment > SSL3_RT_MAX_PLAIN_LENGTH) {
BIO_printf(bio_err, "Bad split send fragment size\n");
goto end;
}
if (max_pipelines > SSL_MAX_PIPELINES) {
BIO_printf(bio_err, "Bad max pipelines value\n");
goto end;
#ifndef OPENSSL_NO_SCTP
if (protocol == IPPROTO_SCTP) {
if (socket_type != SOCK_DGRAM) {
BIO_printf(bio_err, "Can't use -sctp without DTLS\n");
goto end;
}
/* SCTP is unusual. It uses DTLS over a SOCK_STREAM protocol */
socket_type = SOCK_STREAM;
}
#endif
#if !defined(OPENSSL_NO_NEXTPROTONEG)
next_proto.status = -1;
@@ -1409,7 +1611,7 @@ int s_client_main(int argc, char **argv)
if (key_file == NULL)
key_file = cert_file;
if (key_file) {
if (key_file != NULL) {
key = load_key(key_file, key_format, 0, pass, e,
"client certificate private key file");
if (key == NULL) {
@@ -1418,7 +1620,7 @@ int s_client_main(int argc, char **argv)
}
}
if (cert_file) {
if (cert_file != NULL) {
cert = load_cert(cert_file, cert_format, "client certificate file");
if (cert == NULL) {
ERR_print_errors(bio_err);
@@ -1426,13 +1628,13 @@ int s_client_main(int argc, char **argv)
}
}
if (chain_file) {
if (chain_file != NULL) {
if (!load_certs(chain_file, &chain, FORMAT_PEM, NULL,
"client certificate chain"))
goto end;
}
if (crl_file) {
if (crl_file != NULL) {
X509_CRL *crl;
crl = load_crl(crl_file, crl_format);
if (crl == NULL) {
@@ -1452,20 +1654,10 @@ int s_client_main(int argc, char **argv)
if (!load_excert(&exc))
goto end;
if (!app_RAND_load_file(NULL, 1) && inrand == NULL
&& !RAND_status()) {
BIO_printf(bio_err,
"warning, not much extra random data, consider using the -rand option\n");
}
if (inrand != NULL) {
randamt = app_RAND_load_files(inrand);
BIO_printf(bio_err, "%ld semi-random bytes loaded\n", randamt);
}
if (bio_c_out == NULL) {
if (c_quiet && !c_debug) {
bio_c_out = BIO_new(BIO_s_null());
if (c_msg && !bio_c_msg)
if (c_msg && bio_c_msg == NULL)
bio_c_msg = dup_bio_out(FORMAT_TEXT);
} else if (bio_c_out == NULL)
bio_c_out = dup_bio_out(FORMAT_TEXT);
@@ -1486,10 +1678,7 @@ int s_client_main(int argc, char **argv)
if (sdebug)
ssl_ctx_security_debug(ctx, sdebug);
if (!config_ctx(cctx, ssl_args, ctx))
goto end;
if (ssl_config) {
if (ssl_config != NULL) {
if (SSL_CTX_config(ctx, ssl_config) == 0) {
BIO_printf(bio_err, "Error using configuration \"%s\"\n",
ssl_config);
@@ -1498,11 +1687,9 @@ int s_client_main(int argc, char **argv)
}
}
if (min_version != 0
&& SSL_CTX_set_min_proto_version(ctx, min_version) == 0)
if (SSL_CTX_set_min_proto_version(ctx, min_version) == 0)
goto end;
if (max_version != 0
&& SSL_CTX_set_max_proto_version(ctx, max_version) == 0)
if (SSL_CTX_set_max_proto_version(ctx, max_version) == 0)
goto end;
if (vpmtouched && !SSL_CTX_set1_param(ctx, vpm)) {
@@ -1514,23 +1701,60 @@ int s_client_main(int argc, char **argv)
if (async) {
SSL_CTX_set_mode(ctx, SSL_MODE_ASYNC);
}
if (split_send_fragment > 0) {
SSL_CTX_set_split_send_fragment(ctx, split_send_fragment);
if (max_send_fragment > 0
&& !SSL_CTX_set_max_send_fragment(ctx, max_send_fragment)) {
BIO_printf(bio_err, "%s: Max send fragment size %u is out of permitted range\n",
prog, max_send_fragment);
goto end;
}
if (max_pipelines > 0) {
SSL_CTX_set_max_pipelines(ctx, max_pipelines);
if (split_send_fragment > 0
&& !SSL_CTX_set_split_send_fragment(ctx, split_send_fragment)) {
BIO_printf(bio_err, "%s: Split send fragment size %u is out of permitted range\n",
prog, split_send_fragment);
goto end;
}
if (max_pipelines > 0
&& !SSL_CTX_set_max_pipelines(ctx, max_pipelines)) {
BIO_printf(bio_err, "%s: Max pipelines %u is out of permitted range\n",
prog, max_pipelines);
goto end;
}
if (read_buf_len > 0) {
SSL_CTX_set_default_read_buffer_len(ctx, read_buf_len);
}
if (maxfraglen > 0
&& !SSL_CTX_set_tlsext_max_fragment_length(ctx, maxfraglen)) {
BIO_printf(bio_err,
"%s: Max Fragment Length code %u is out of permitted values"
"\n", prog, maxfraglen);
goto end;
}
if (!config_ctx(cctx, ssl_args, ctx))
goto end;
if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile,
crls, crl_download)) {
BIO_printf(bio_err, "Error loading store locations\n");
ERR_print_errors(bio_err);
goto end;
}
if (ReqCAfile != NULL) {
STACK_OF(X509_NAME) *nm = sk_X509_NAME_new_null();
if (nm == NULL || !SSL_add_file_cert_subjects_to_stack(nm, ReqCAfile)) {
sk_X509_NAME_pop_free(nm, X509_NAME_free);
BIO_printf(bio_err, "Error loading CA names\n");
ERR_print_errors(bio_err);
goto end;
}
SSL_CTX_set0_CA_list(ctx, nm);
}
#ifndef OPENSSL_NO_ENGINE
if (ssl_client_engine) {
if (!SSL_CTX_set_client_cert_engine(ctx, ssl_client_engine)) {
@@ -1550,6 +1774,25 @@ int s_client_main(int argc, char **argv)
SSL_CTX_set_psk_client_callback(ctx, psk_client_cb);
}
#endif
if (psksessf != NULL) {
BIO *stmp = BIO_new_file(psksessf, "r");
if (stmp == NULL) {
BIO_printf(bio_err, "Can't open PSK session file %s\n", psksessf);
ERR_print_errors(bio_err);
goto end;
}
psksess = PEM_read_bio_SSL_SESSION(stmp, NULL, 0, NULL);
BIO_free(stmp);
if (psksess == NULL) {
BIO_printf(bio_err, "Can't read PSK session file %s\n", psksessf);
ERR_print_errors(bio_err);
goto end;
}
}
if (psk_key != NULL || psksess != NULL)
SSL_CTX_set_psk_use_session_callback(ctx, psk_use_session_cb);
#ifndef OPENSSL_NO_SRTP
if (srtp_profiles != NULL) {
/* Returns 0 on success! */
@@ -1561,11 +1804,11 @@ int s_client_main(int argc, char **argv)
}
#endif
if (exc)
if (exc != NULL)
ssl_ctx_set_excert(ctx, exc);
#if !defined(OPENSSL_NO_NEXTPROTONEG)
if (next_proto.data)
if (next_proto.data != NULL)
SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &next_proto);
#endif
if (alpn_in) {
@@ -1634,7 +1877,7 @@ int s_client_main(int argc, char **argv)
if (!set_cert_key_stuff(ctx, cert, key, chain, build_chain))
goto end;
if (servername != NULL) {
if (!noservername) {
tlsextcbp.biodebug = bio_err;
SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp);
@@ -1666,18 +1909,38 @@ int s_client_main(int argc, char **argv)
}
}
/*
* In TLSv1.3 NewSessionTicket messages arrive after the handshake and can
* come at any time. Therefore we use a callback to write out the session
* when we know about it. This approach works for < TLSv1.3 as well.
*/
if (sess_out != NULL) {
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_CLIENT
| SSL_SESS_CACHE_NO_INTERNAL_STORE);
SSL_CTX_sess_set_new_cb(ctx, new_session_cb);
}
if (set_keylog_file(ctx, keylog_file))
goto end;
con = SSL_new(ctx);
if (sess_in) {
if (con == NULL)
goto end;
if (force_pha)
SSL_force_post_handshake_auth(con);
if (sess_in != NULL) {
SSL_SESSION *sess;
BIO *stmp = BIO_new_file(sess_in, "r");
if (!stmp) {
if (stmp == NULL) {
BIO_printf(bio_err, "Can't open session file %s\n", sess_in);
ERR_print_errors(bio_err);
goto end;
}
sess = PEM_read_bio_SSL_SESSION(stmp, NULL, 0, NULL);
BIO_free(stmp);
if (!sess) {
if (sess == NULL) {
BIO_printf(bio_err, "Can't open session file %s\n", sess_in);
ERR_print_errors(bio_err);
goto end;
@@ -1687,13 +1950,16 @@ int s_client_main(int argc, char **argv)
ERR_print_errors(bio_err);
goto end;
}
SSL_SESSION_free(sess);
}
if (fallback_scsv)
SSL_set_mode(con, SSL_MODE_SEND_FALLBACK_SCSV);
if (servername != NULL) {
if (!noservername && (servername != NULL || dane_tlsa_domain == NULL)) {
if (servername == NULL)
servername = (host == NULL) ? "localhost" : host;
if (!SSL_set_tlsext_host_name(con, servername)) {
BIO_printf(bio_err, "Unable to set TLS servername extension.\n");
ERR_print_errors(bio_err);
@@ -1727,7 +1993,8 @@ int s_client_main(int argc, char **argv)
}
re_start:
if (init_client(&s, host, port, socket_family, socket_type) == 0) {
if (init_client(&s, host, port, bindhost, bindport, socket_family,
socket_type, protocol) == 0) {
BIO_printf(bio_err, "connect:errno=%d\n", get_last_socket_error());
BIO_closesocket(s);
goto end;
@@ -1742,10 +2009,16 @@ int s_client_main(int argc, char **argv)
BIO_printf(bio_c_out, "Turned on non blocking io\n");
}
#ifndef OPENSSL_NO_DTLS
if (socket_type == SOCK_DGRAM) {
if (isdtls) {
union BIO_sock_info_u peer_info;
sbio = BIO_new_dgram(s, BIO_NOCLOSE);
#ifndef OPENSSL_NO_SCTP
if (protocol == IPPROTO_SCTP)
sbio = BIO_new_dgram_sctp(s, BIO_NOCLOSE);
else
#endif
sbio = BIO_new_dgram(s, BIO_NOCLOSE);
if ((peer_info.addr = BIO_ADDR_new()) == NULL) {
BIO_printf(bio_err, "memory allocation failure\n");
BIO_closesocket(s);
@@ -1786,9 +2059,10 @@ int s_client_main(int argc, char **argv)
BIO_free(sbio);
goto shut;
}
} else
} else {
/* want to do MTU discovery */
BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);
}
} else
#endif /* OPENSSL_NO_DTLS */
sbio = BIO_new_socket(s, BIO_NOCLOSE);
@@ -1849,6 +2123,7 @@ int s_client_main(int argc, char **argv)
switch ((PROTOCOL_CHOICE) starttls_proto) {
case PROTO_OFF:
break;
case PROTO_LMTP:
case PROTO_SMTP:
{
/*
@@ -1861,27 +2136,34 @@ int s_client_main(int argc, char **argv)
*/
int foundit = 0;
BIO *fbio = BIO_new(BIO_f_buffer());
BIO_push(fbio, sbio);
/* wait for multi-line response to end from SMTP */
/* Wait for multi-line response to end from LMTP or SMTP */
do {
mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
}
while (mbuf_len > 3 && mbuf[3] == '-');
BIO_printf(fbio, "EHLO %s\r\n", ehlo);
} while (mbuf_len > 3 && mbuf[3] == '-');
if (protohost == NULL)
protohost = "mail.example.com";
if (starttls_proto == (int)PROTO_LMTP)
BIO_printf(fbio, "LHLO %s\r\n", protohost);
else
BIO_printf(fbio, "EHLO %s\r\n", protohost);
(void)BIO_flush(fbio);
/* wait for multi-line response to end EHLO SMTP response */
/*
* Wait for multi-line response to end LHLO LMTP or EHLO SMTP
* response.
*/
do {
mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
if (strstr(mbuf, "STARTTLS"))
foundit = 1;
}
while (mbuf_len > 3 && mbuf[3] == '-');
} while (mbuf_len > 3 && mbuf[3] == '-');
(void)BIO_flush(fbio);
BIO_pop(fbio);
BIO_free(fbio);
if (!foundit)
BIO_printf(bio_err,
"didn't find starttls in server response,"
"Didn't find STARTTLS in server response,"
" trying anyway...\n");
BIO_printf(sbio, "STARTTLS\r\n");
BIO_read(sbio, sbuf, BUFSIZZ);
@@ -1902,6 +2184,7 @@ int s_client_main(int argc, char **argv)
{
int foundit = 0;
BIO *fbio = BIO_new(BIO_f_buffer());
BIO_push(fbio, sbio);
BIO_gets(fbio, mbuf, BUFSIZZ);
/* STARTTLS command requires CAPABILITY... */
@@ -1919,7 +2202,7 @@ int s_client_main(int argc, char **argv)
BIO_free(fbio);
if (!foundit)
BIO_printf(bio_err,
"didn't find STARTTLS in server response,"
"Didn't find STARTTLS in server response,"
" trying anyway...\n");
BIO_printf(sbio, ". STARTTLS\r\n");
BIO_read(sbio, sbuf, BUFSIZZ);
@@ -1928,6 +2211,7 @@ int s_client_main(int argc, char **argv)
case PROTO_FTP:
{
BIO *fbio = BIO_new(BIO_f_buffer());
BIO_push(fbio, sbio);
/* wait for multi-line response to end from FTP */
do {
@@ -1949,9 +2233,13 @@ int s_client_main(int argc, char **argv)
"xmlns:stream='http://etherx.jabber.org/streams' "
"xmlns='jabber:%s' to='%s' version='1.0'>",
starttls_proto == PROTO_XMPP ? "client" : "server",
xmpphost ? xmpphost : host);
protohost ? protohost : host);
seen = BIO_read(sbio, mbuf, BUFSIZZ);
mbuf[seen] = 0;
if (seen < 0) {
BIO_printf(bio_err, "BIO_read failed\n");
goto end;
}
mbuf[seen] = '\0';
while (!strstr
(mbuf, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'")
&& !strstr(mbuf,
@@ -1962,15 +2250,19 @@ int s_client_main(int argc, char **argv)
if (seen <= 0)
goto shut;
mbuf[seen] = 0;
mbuf[seen] = '\0';
}
BIO_printf(sbio,
"<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
seen = BIO_read(sbio, sbuf, BUFSIZZ);
sbuf[seen] = 0;
if (seen < 0) {
BIO_printf(bio_err, "BIO_read failed\n");
goto shut;
}
sbuf[seen] = '\0';
if (!strstr(sbuf, "<proceed"))
goto shut;
mbuf[0] = 0;
mbuf[0] = '\0';
}
break;
case PROTO_TELNET:
@@ -2022,6 +2314,15 @@ int s_client_main(int argc, char **argv)
* HTTP/d.d ddd Reason text\r\n
*/
mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
if (mbuf_len < (int)strlen("HTTP/1.0 200")) {
BIO_printf(bio_err,
"%s: HTTP CONNECT failed, insufficient response "
"from proxy (got %d octets)\n", prog, mbuf_len);
(void)BIO_flush(fbio);
BIO_pop(fbio);
BIO_free(fbio);
goto shut;
}
if (mbuf[8] != ' ') {
BIO_printf(bio_err,
"%s: HTTP CONNECT failed, incorrect response "
@@ -2108,6 +2409,296 @@ int s_client_main(int argc, char **argv)
goto shut;
}
}
break;
case PROTO_MYSQL:
{
/* SSL request packet */
static const unsigned char ssl_req[] = {
/* payload_length, sequence_id */
0x20, 0x00, 0x00, 0x01,
/* payload */
/* capability flags, CLIENT_SSL always set */
0x85, 0xae, 0x7f, 0x00,
/* max-packet size */
0x00, 0x00, 0x00, 0x01,
/* character set */
0x21,
/* string[23] reserved (all [0]) */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
int bytes = 0;
int ssl_flg = 0x800;
int pos;
const unsigned char *packet = (const unsigned char *)sbuf;
/* Receiving Initial Handshake packet. */
bytes = BIO_read(sbio, (void *)packet, BUFSIZZ);
if (bytes < 0) {
BIO_printf(bio_err, "BIO_read failed\n");
goto shut;
/* Packet length[3], Packet number[1] + minimum payload[17] */
} else if (bytes < 21) {
BIO_printf(bio_err, "MySQL packet too short.\n");
goto shut;
} else if (bytes != (4 + packet[0] +
(packet[1] << 8) +
(packet[2] << 16))) {
BIO_printf(bio_err, "MySQL packet length does not match.\n");
goto shut;
/* protocol version[1] */
} else if (packet[4] != 0xA) {
BIO_printf(bio_err,
"Only MySQL protocol version 10 is supported.\n");
goto shut;
}
pos = 5;
/* server version[string+NULL] */
for (;;) {
if (pos >= bytes) {
BIO_printf(bio_err, "Cannot confirm server version. ");
goto shut;
} else if (packet[pos++] == '\0') {
break;
}
}
/* make sure we have at least 15 bytes left in the packet */
if (pos + 15 > bytes) {
BIO_printf(bio_err,
"MySQL server handshake packet is broken.\n");
goto shut;
}
pos += 12; /* skip over conn id[4] + SALT[8] */
if (packet[pos++] != '\0') { /* verify filler */
BIO_printf(bio_err,
"MySQL packet is broken.\n");
goto shut;
}
/* capability flags[2] */
if (!((packet[pos] + (packet[pos + 1] << 8)) & ssl_flg)) {
BIO_printf(bio_err, "MySQL server does not support SSL.\n");
goto shut;
}
/* Sending SSL Handshake packet. */
BIO_write(sbio, ssl_req, sizeof(ssl_req));
(void)BIO_flush(sbio);
}
break;
case PROTO_POSTGRES:
{
static const unsigned char ssl_request[] = {
/* Length SSLRequest */
0, 0, 0, 8, 4, 210, 22, 47
};
int bytes;
/* Send SSLRequest packet */
BIO_write(sbio, ssl_request, 8);
(void)BIO_flush(sbio);
/* Reply will be a single S if SSL is enabled */
bytes = BIO_read(sbio, sbuf, BUFSIZZ);
if (bytes != 1 || sbuf[0] != 'S')
goto shut;
}
break;
case PROTO_NNTP:
{
int foundit = 0;
BIO *fbio = BIO_new(BIO_f_buffer());
BIO_push(fbio, sbio);
BIO_gets(fbio, mbuf, BUFSIZZ);
/* STARTTLS command requires CAPABILITIES... */
BIO_printf(fbio, "CAPABILITIES\r\n");
(void)BIO_flush(fbio);
/* wait for multi-line CAPABILITIES response */
do {
mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
if (strstr(mbuf, "STARTTLS"))
foundit = 1;
} while (mbuf_len > 1 && mbuf[0] != '.');
(void)BIO_flush(fbio);
BIO_pop(fbio);
BIO_free(fbio);
if (!foundit)
BIO_printf(bio_err,
"Didn't find STARTTLS in server response,"
" trying anyway...\n");
BIO_printf(sbio, "STARTTLS\r\n");
mbuf_len = BIO_read(sbio, mbuf, BUFSIZZ);
if (mbuf_len < 0) {
BIO_printf(bio_err, "BIO_read failed\n");
goto end;
}
mbuf[mbuf_len] = '\0';
if (strstr(mbuf, "382") == NULL) {
BIO_printf(bio_err, "STARTTLS failed: %s", mbuf);
goto shut;
}
}
break;
case PROTO_SIEVE:
{
int foundit = 0;
BIO *fbio = BIO_new(BIO_f_buffer());
BIO_push(fbio, sbio);
/* wait for multi-line response to end from Sieve */
do {
mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ);
/*
* According to RFC 5804 § 1.7, capability
* is case-insensitive, make it uppercase
*/
if (mbuf_len > 1 && mbuf[0] == '"') {
make_uppercase(mbuf);
if (strncmp(mbuf, "\"STARTTLS\"", 10) == 0)
foundit = 1;
}
} while (mbuf_len > 1 && mbuf[0] == '"');
(void)BIO_flush(fbio);
BIO_pop(fbio);
BIO_free(fbio);
if (!foundit)
BIO_printf(bio_err,
"Didn't find STARTTLS in server response,"
" trying anyway...\n");
BIO_printf(sbio, "STARTTLS\r\n");
mbuf_len = BIO_read(sbio, mbuf, BUFSIZZ);
if (mbuf_len < 0) {
BIO_printf(bio_err, "BIO_read failed\n");
goto end;
}
mbuf[mbuf_len] = '\0';
if (mbuf_len < 2) {
BIO_printf(bio_err, "STARTTLS failed: %s", mbuf);
goto shut;
}
/*
* According to RFC 5804 § 2.2, response codes are case-
* insensitive, make it uppercase but preserve the response.
*/
strncpy(sbuf, mbuf, 2);
make_uppercase(sbuf);
if (strncmp(sbuf, "OK", 2) != 0) {
BIO_printf(bio_err, "STARTTLS not supported: %s", mbuf);
goto shut;
}
}
break;
case PROTO_LDAP:
{
/* StartTLS Operation according to RFC 4511 */
static char ldap_tls_genconf[] = "asn1=SEQUENCE:LDAPMessage\n"
"[LDAPMessage]\n"
"messageID=INTEGER:1\n"
"extendedReq=EXPLICIT:23A,IMPLICIT:0C,"
"FORMAT:ASCII,OCT:1.3.6.1.4.1.1466.20037\n";
long errline = -1;
char *genstr = NULL;
int result = -1;
ASN1_TYPE *atyp = NULL;
BIO *ldapbio = BIO_new(BIO_s_mem());
CONF *cnf = NCONF_new(NULL);
if (cnf == NULL) {
BIO_free(ldapbio);
goto end;
}
BIO_puts(ldapbio, ldap_tls_genconf);
if (NCONF_load_bio(cnf, ldapbio, &errline) <= 0) {
BIO_free(ldapbio);
NCONF_free(cnf);
if (errline <= 0) {
BIO_printf(bio_err, "NCONF_load_bio failed\n");
goto end;
} else {
BIO_printf(bio_err, "Error on line %ld\n", errline);
goto end;
}
}
BIO_free(ldapbio);
genstr = NCONF_get_string(cnf, "default", "asn1");
if (genstr == NULL) {
NCONF_free(cnf);
BIO_printf(bio_err, "NCONF_get_string failed\n");
goto end;
}
atyp = ASN1_generate_nconf(genstr, cnf);
if (atyp == NULL) {
NCONF_free(cnf);
BIO_printf(bio_err, "ASN1_generate_nconf failed\n");
goto end;
}
NCONF_free(cnf);
/* Send SSLRequest packet */
BIO_write(sbio, atyp->value.sequence->data,
atyp->value.sequence->length);
(void)BIO_flush(sbio);
ASN1_TYPE_free(atyp);
mbuf_len = BIO_read(sbio, mbuf, BUFSIZZ);
if (mbuf_len < 0) {
BIO_printf(bio_err, "BIO_read failed\n");
goto end;
}
result = ldap_ExtendedResponse_parse(mbuf, mbuf_len);
if (result < 0) {
BIO_printf(bio_err, "ldap_ExtendedResponse_parse failed\n");
goto shut;
} else if (result > 0) {
BIO_printf(bio_err, "STARTTLS failed, LDAP Result Code: %i\n",
result);
goto shut;
}
mbuf_len = 0;
}
break;
}
if (early_data_file != NULL
&& ((SSL_get0_session(con) != NULL
&& SSL_SESSION_get_max_early_data(SSL_get0_session(con)) > 0)
|| (psksess != NULL
&& SSL_SESSION_get_max_early_data(psksess) > 0))) {
BIO *edfile = BIO_new_file(early_data_file, "r");
size_t readbytes, writtenbytes;
int finish = 0;
if (edfile == NULL) {
BIO_printf(bio_err, "Cannot open early data file\n");
goto shut;
}
while (!finish) {
if (!BIO_read_ex(edfile, cbuf, BUFSIZZ, &readbytes))
finish = 1;
while (!SSL_write_early_data(con, cbuf, readbytes, &writtenbytes)) {
switch (SSL_get_error(con, 0)) {
case SSL_ERROR_WANT_WRITE:
case SSL_ERROR_WANT_ASYNC:
case SSL_ERROR_WANT_READ:
/* Just keep trying - busy waiting */
continue;
default:
BIO_printf(bio_err, "Error writing early data\n");
BIO_free(edfile);
ERR_print_errors(bio_err);
goto shut;
}
}
}
BIO_free(edfile);
}
for (;;) {
@@ -2120,7 +2711,8 @@ int s_client_main(int argc, char **argv)
else
timeoutp = NULL;
if (SSL_in_init(con) && !SSL_total_renegotiations(con)) {
if (!SSL_is_init_finished(con) && SSL_total_renegotiations(con) == 0
&& SSL_get_key_update_type(con) == SSL_KEY_UPDATE_NONE) {
in_init = 1;
tty_on = 0;
} else {
@@ -2128,15 +2720,6 @@ int s_client_main(int argc, char **argv)
if (in_init) {
in_init = 0;
if (sess_out) {
BIO *stmp = BIO_new_file(sess_out, "w");
if (stmp) {
PEM_write_bio_SSL_SESSION(stmp, SSL_get_session(con));
BIO_free(stmp);
} else
BIO_printf(bio_err, "Error writing session file %s\n",
sess_out);
}
if (c_brief) {
BIO_puts(bio_err, "CONNECTION ESTABLISHED\n");
print_ssl_summary(con);
@@ -2231,7 +2814,6 @@ int s_client_main(int argc, char **argv)
BIO_printf(bio_err, "bad select %d\n",
get_last_socket_error());
goto shut;
/* goto end; */
}
}
@@ -2322,10 +2904,9 @@ int s_client_main(int argc, char **argv)
BIO_printf(bio_c_out, "DONE\n");
ret = 0;
goto shut;
/* goto end; */
}
sbuf_len -= i;;
sbuf_len -= i;
sbuf_off += i;
if (sbuf_len <= 0) {
read_ssl = 1;
@@ -2392,7 +2973,6 @@ int s_client_main(int argc, char **argv)
case SSL_ERROR_SSL:
ERR_print_errors(bio_err);
goto shut;
/* break; */
}
}
/* OPENSSL_SYS_MSDOS includes OPENSSL_SYS_WINDOWS */
@@ -2438,6 +3018,15 @@ int s_client_main(int argc, char **argv)
SSL_renegotiate(con);
cbuf_len = 0;
}
if (!c_ign_eof && (cbuf[0] == 'K' || cbuf[0] == 'k' )
&& cmdletters) {
BIO_printf(bio_err, "KEYUPDATE\n");
SSL_key_update(con,
cbuf[0] == 'K' ? SSL_KEY_UPDATE_REQUESTED
: SSL_KEY_UPDATE_NOT_REQUESTED);
cbuf_len = 0;
}
#ifndef OPENSSL_NO_HEARTBEATS
else if ((!c_ign_eof) && (cbuf[0] == 'B' && cmdletters)) {
BIO_printf(bio_err, "HEARTBEATING\n");
@@ -2495,10 +3084,12 @@ int s_client_main(int argc, char **argv)
print_stuff(bio_c_out, con, 1);
SSL_free(con);
}
SSL_SESSION_free(psksess);
#if !defined(OPENSSL_NO_NEXTPROTONEG)
OPENSSL_free(next_proto.data);
#endif
SSL_CTX_free(ctx);
set_keylog_file(NULL, NULL);
X509_free(cert);
sk_X509_CRL_pop_free(crls, X509_CRL_free);
EVP_PKEY_free(key);
@@ -2508,6 +3099,7 @@ int s_client_main(int argc, char **argv)
OPENSSL_free(srp_arg.srppassin);
#endif
OPENSSL_free(connectstr);
OPENSSL_free(bindstr);
OPENSSL_free(host);
OPENSSL_free(port);
X509_VERIFY_PARAM_free(vpm);
@@ -2523,17 +3115,14 @@ int s_client_main(int argc, char **argv)
bio_c_out = NULL;
BIO_free(bio_c_msg);
bio_c_msg = NULL;
return (ret);
return ret;
}
static void print_stuff(BIO *bio, SSL *s, int full)
{
X509 *peer = NULL;
char buf[BUFSIZ];
STACK_OF(X509) *sk;
STACK_OF(X509_NAME) *sk2;
const SSL_CIPHER *c;
X509_NAME *xn;
int i;
#ifndef OPENSSL_NO_COMP
const COMP_METHOD *comp, *expansion;
@@ -2552,12 +3141,12 @@ static void print_stuff(BIO *bio, SSL *s, int full)
BIO_printf(bio, "---\nCertificate chain\n");
for (i = 0; i < sk_X509_num(sk); i++) {
X509_NAME_oneline(X509_get_subject_name(sk_X509_value(sk, i)),
buf, sizeof(buf));
BIO_printf(bio, "%2d s:%s\n", i, buf);
X509_NAME_oneline(X509_get_issuer_name(sk_X509_value(sk, i)),
buf, sizeof(buf));
BIO_printf(bio, " i:%s\n", buf);
BIO_printf(bio, "%2d s:", i);
X509_NAME_print_ex(bio, X509_get_subject_name(sk_X509_value(sk, i)), 0, get_nameopt());
BIO_puts(bio, "\n");
BIO_printf(bio, " i:");
X509_NAME_print_ex(bio, X509_get_issuer_name(sk_X509_value(sk, i)), 0, get_nameopt());
BIO_puts(bio, "\n");
if (c_showcerts)
PEM_write_bio_X509(bio, sk_X509_value(sk, i));
}
@@ -2571,25 +3160,11 @@ static void print_stuff(BIO *bio, SSL *s, int full)
/* Redundant if we showed the whole chain */
if (!(c_showcerts && got_a_chain))
PEM_write_bio_X509(bio, peer);
X509_NAME_oneline(X509_get_subject_name(peer), buf, sizeof(buf));
BIO_printf(bio, "subject=%s\n", buf);
X509_NAME_oneline(X509_get_issuer_name(peer), buf, sizeof(buf));
BIO_printf(bio, "issuer=%s\n", buf);
} else
BIO_printf(bio, "no peer certificate available\n");
sk2 = SSL_get_client_CA_list(s);
if ((sk2 != NULL) && (sk_X509_NAME_num(sk2) > 0)) {
BIO_printf(bio, "---\nAcceptable client certificate CA names\n");
for (i = 0; i < sk_X509_NAME_num(sk2); i++) {
xn = sk_X509_NAME_value(sk2, i);
X509_NAME_oneline(xn, buf, sizeof(buf));
BIO_write(bio, buf, strlen(buf));
BIO_write(bio, "\n", 1);
}
dump_cert_text(bio, peer);
} else {
BIO_printf(bio, "---\nNo client certificate CA names sent\n");
BIO_printf(bio, "no peer certificate available\n");
}
print_ca_names(bio, s);
ssl_print_sigalgs(bio, s);
ssl_print_tmp_key(bio, s);
@@ -2628,8 +3203,8 @@ static void print_stuff(BIO *bio, SSL *s, int full)
#endif
BIO_printf(bio,
"---\nSSL handshake has read %"BIO_PRI64"u"
" bytes and written %"BIO_PRI64"u bytes\n",
"---\nSSL handshake has read %ju bytes "
"and written %ju bytes\n",
BIO_number_read(SSL_get_rbio(s)),
BIO_number_written(SSL_get_wbio(s)));
}
@@ -2705,6 +3280,23 @@ static void print_stuff(BIO *bio, SSL *s, int full)
}
#endif
if (SSL_version(s) == TLS1_3_VERSION) {
switch (SSL_get_early_data_status(s)) {
case SSL_EARLY_DATA_NOT_SENT:
BIO_printf(bio, "Early data was not sent\n");
break;
case SSL_EARLY_DATA_REJECTED:
BIO_printf(bio, "Early data was rejected\n");
break;
case SSL_EARLY_DATA_ACCEPTED:
BIO_printf(bio, "Early data was accepted\n");
break;
}
}
SSL_SESSION_print(bio, SSL_get_session(s));
if (SSL_get_session(s) != NULL && keymatexportlabel != NULL) {
BIO_printf(bio, "Keying material exporter:\n");
@@ -2739,12 +3331,12 @@ static int ocsp_resp_cb(SSL *s, void *arg)
OCSP_RESPONSE *rsp;
len = SSL_get_tlsext_status_ocsp_resp(s, &p);
BIO_puts(arg, "OCSP response: ");
if (!p) {
if (p == NULL) {
BIO_puts(arg, "no response sent\n");
return 1;
}
rsp = d2i_OCSP_RESPONSE(NULL, &p, len);
if (!rsp) {
if (rsp == NULL) {
BIO_puts(arg, "response parse error\n");
BIO_dump_indent(arg, (char *)p, len, 4);
return 0;
@@ -2757,4 +3349,88 @@ static int ocsp_resp_cb(SSL *s, void *arg)
}
# endif
static int ldap_ExtendedResponse_parse(const char *buf, long rem)
{
const unsigned char *cur, *end;
long len;
int tag, xclass, inf, ret = -1;
cur = (const unsigned char *)buf;
end = cur + rem;
/*
* From RFC 4511:
*
* LDAPMessage ::= SEQUENCE {
* messageID MessageID,
* protocolOp CHOICE {
* ...
* extendedResp ExtendedResponse,
* ... },
* controls [0] Controls OPTIONAL }
*
* ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
* COMPONENTS OF LDAPResult,
* responseName [10] LDAPOID OPTIONAL,
* responseValue [11] OCTET STRING OPTIONAL }
*
* LDAPResult ::= SEQUENCE {
* resultCode ENUMERATED {
* success (0),
* ...
* other (80),
* ... },
* matchedDN LDAPDN,
* diagnosticMessage LDAPString,
* referral [3] Referral OPTIONAL }
*/
/* pull SEQUENCE */
inf = ASN1_get_object(&cur, &len, &tag, &xclass, rem);
if (inf != V_ASN1_CONSTRUCTED || tag != V_ASN1_SEQUENCE ||
(rem = end - cur, len > rem)) {
BIO_printf(bio_err, "Unexpected LDAP response\n");
goto end;
}
rem = len; /* ensure that we don't overstep the SEQUENCE */
/* pull MessageID */
inf = ASN1_get_object(&cur, &len, &tag, &xclass, rem);
if (inf != V_ASN1_UNIVERSAL || tag != V_ASN1_INTEGER ||
(rem = end - cur, len > rem)) {
BIO_printf(bio_err, "No MessageID\n");
goto end;
}
cur += len; /* shall we check for MessageId match or just skip? */
/* pull [APPLICATION 24] */
rem = end - cur;
inf = ASN1_get_object(&cur, &len, &tag, &xclass, rem);
if (inf != V_ASN1_CONSTRUCTED || xclass != V_ASN1_APPLICATION ||
tag != 24) {
BIO_printf(bio_err, "Not ExtendedResponse\n");
goto end;
}
/* pull resultCode */
rem = end - cur;
inf = ASN1_get_object(&cur, &len, &tag, &xclass, rem);
if (inf != V_ASN1_UNIVERSAL || tag != V_ASN1_ENUMERATED || len == 0 ||
(rem = end - cur, len > rem)) {
BIO_printf(bio_err, "Not LDAPResult\n");
goto end;
}
/* len should always be one, but just in case... */
for (ret = 0, inf = 0; inf < len; inf++) {
ret <<= 8;
ret |= cur[inf];
}
/* There is more data, but we don't care... */
end:
return ret;
}
#endif /* OPENSSL_NO_SOCK */
+574 -289
View File
@@ -1,5 +1,7 @@
/*
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
* Copyright 2005 Nokia. 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
@@ -7,38 +9,6 @@
* https://www.openssl.org/source/license.html
*/
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
* ECC cipher suite support in OpenSSL originally developed by
* SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
*/
/* ====================================================================
* Copyright 2005 Nokia. All rights reserved.
*
* The portions of the attached software ("Contribution") is developed by
* Nokia Corporation and is licensed pursuant to the OpenSSL open source
* license.
*
* The Contribution, originally written by Mika Kousa and Pasi Eronen of
* Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
* support (see RFC 4279) to OpenSSL.
*
* No patent licenses or other rights except those expressly stated in
* the OpenSSL open source license shall be deemed granted or received
* expressly, by implication, estoppel, or otherwise.
*
* No assurances are provided by Nokia that the Contribution does not
* infringe the patent or other intellectual property rights of any third
* party or that the license provides you with all the necessary rights
* to make use of the Contribution.
*
* THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
* ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
* SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
* OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
* OTHERWISE.
*/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
@@ -65,10 +35,9 @@
typedef unsigned int u_int;
#endif
#include <openssl/lhash.h>
#include <openssl/bn.h>
#define USE_SOCKETS
#include "apps.h"
#include "progs.h"
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
@@ -89,21 +58,23 @@ typedef unsigned int u_int;
#ifdef CHARSET_EBCDIC
#include <openssl/ebcdic.h>
#endif
#include "internal/sockets.h"
static int not_resumable_sess_cb(SSL *s, int is_forward_secure);
static int sv_body(int s, int stype, unsigned char *context);
static int www_body(int s, int stype, unsigned char *context);
static int rev_body(int s, int stype, unsigned char *context);
static int sv_body(int s, int stype, int prot, unsigned char *context);
static int www_body(int s, int stype, int prot, unsigned char *context);
static int rev_body(int s, int stype, int prot, unsigned char *context);
static void close_accept_socket(void);
static int init_ssl_connection(SSL *s);
static void print_stats(BIO *bp, SSL_CTX *ctx);
static int generate_session_id(const SSL *ssl, unsigned char *id,
static int generate_session_id(SSL *ssl, unsigned char *id,
unsigned int *id_len);
static void init_session_cache_ctx(SSL_CTX *sctx);
static void free_sessions(void);
#ifndef OPENSSL_NO_DH
static DH *load_dh_param(const char *dhfile);
#endif
static void print_connection_info(SSL *con);
static const int bufsize = 16 * 1024;
static int accept_socket = -1;
@@ -144,11 +115,15 @@ static long socket_mtu;
* code.
*/
static int dtlslisten = 0;
static int stateless = 0;
#ifndef OPENSSL_NO_PSK
static const char psk_identity[] = "Client_identity";
static int early_data = 0;
static SSL_SESSION *psksess = NULL;
static char *psk_identity = "Client_identity";
char *psk_key = NULL; /* by default PSK is not used */
#ifndef OPENSSL_NO_PSK
static unsigned int psk_server_cb(SSL *ssl, const char *identity,
unsigned char *psk,
unsigned int max_psk_len)
@@ -158,7 +133,7 @@ static unsigned int psk_server_cb(SSL *ssl, const char *identity,
if (s_debug)
BIO_printf(bio_s_out, "psk_server_cb\n");
if (!identity) {
if (identity == NULL) {
BIO_printf(bio_err, "Error: client did not send PSK identity\n");
goto out_err;
}
@@ -168,12 +143,12 @@ static unsigned int psk_server_cb(SSL *ssl, const char *identity,
/* here we could lookup the given identity e.g. from a database */
if (strcmp(identity, psk_identity) != 0) {
BIO_printf(bio_s_out, "PSK error: client identity not found"
BIO_printf(bio_s_out, "PSK warning: client identity not what we expected"
" (got '%s' expected '%s')\n", identity, psk_identity);
goto out_err;
}
if (s_debug)
} else {
if (s_debug)
BIO_printf(bio_s_out, "PSK client identity found\n");
}
/* convert the PSK key to binary */
key = OPENSSL_hexstr2buf(psk_key, &key_len);
@@ -205,6 +180,59 @@ static unsigned int psk_server_cb(SSL *ssl, const char *identity,
}
#endif
#define TLS13_AES_128_GCM_SHA256_BYTES ((const unsigned char *)"\x13\x01")
#define TLS13_AES_256_GCM_SHA384_BYTES ((const unsigned char *)"\x13\x02")
static int psk_find_session_cb(SSL *ssl, const unsigned char *identity,
size_t identity_len, SSL_SESSION **sess)
{
SSL_SESSION *tmpsess = NULL;
unsigned char *key;
long key_len;
const SSL_CIPHER *cipher = NULL;
if (strlen(psk_identity) != identity_len
|| memcmp(psk_identity, identity, identity_len) != 0)
return 0;
if (psksess != NULL) {
SSL_SESSION_up_ref(psksess);
*sess = psksess;
return 1;
}
key = OPENSSL_hexstr2buf(psk_key, &key_len);
if (key == NULL) {
BIO_printf(bio_err, "Could not convert PSK key '%s' to buffer\n",
psk_key);
return 0;
}
if (key_len == EVP_MD_size(EVP_sha256()))
cipher = SSL_CIPHER_find(ssl, tls13_aes128gcmsha256_id);
else if (key_len == EVP_MD_size(EVP_sha384()))
cipher = SSL_CIPHER_find(ssl, tls13_aes256gcmsha384_id);
if (cipher == NULL) {
/* Doesn't look like a suitable TLSv1.3 key. Ignore it */
OPENSSL_free(key);
return 0;
}
tmpsess = SSL_SESSION_new();
if (tmpsess == NULL
|| !SSL_SESSION_set1_master_key(tmpsess, key, key_len)
|| !SSL_SESSION_set_cipher(tmpsess, cipher)
|| !SSL_SESSION_set_protocol_version(tmpsess, SSL_version(ssl))) {
OPENSSL_free(key);
return 0;
}
OPENSSL_free(key);
*sess = tmpsess;
return 1;
}
#ifndef OPENSSL_NO_SRP
/* This is a context that we pass to callbacks */
typedef struct srpsrvparm_st {
@@ -229,7 +257,7 @@ static int ssl_srp_server_param_cb(SSL *s, int *ad, void *arg)
if (p->login == NULL && p->user == NULL) {
p->login = SSL_get_srp_username(s);
BIO_printf(bio_err, "SRP username = \"%s\"\n", p->login);
return (-1);
return -1;
}
if (p->user == NULL) {
@@ -329,9 +357,9 @@ static int ebcdic_read(BIO *b, char *out, int outl)
BIO *next = BIO_next(b);
if (out == NULL || outl == 0)
return (0);
return 0;
if (next == NULL)
return (0);
return 0;
ret = BIO_read(next, out, outl);
if (ret > 0)
@@ -347,7 +375,7 @@ static int ebcdic_write(BIO *b, const char *in, int inl)
int num;
if ((in == NULL) || (inl <= 0))
return (0);
return 0;
if (next == NULL)
return 0;
@@ -370,7 +398,7 @@ static int ebcdic_write(BIO *b, const char *in, int inl)
ret = BIO_write(next, wbuf->buff, inl);
return (ret);
return ret;
}
static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr)
@@ -379,7 +407,7 @@ static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr)
BIO *next = BIO_next(b);
if (next == NULL)
return (0);
return 0;
switch (cmd) {
case BIO_CTRL_DUP:
ret = 0L;
@@ -388,7 +416,7 @@ static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr)
ret = BIO_ctrl(next, cmd, num, ptr);
break;
}
return (ret);
return ret;
}
static int ebcdic_gets(BIO *bp, char *buf, int size)
@@ -432,17 +460,25 @@ static int ssl_servername_cb(SSL *s, int *ad, void *arg)
{
tlsextctx *p = (tlsextctx *) arg;
const char *servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
if (servername && p->biodebug)
BIO_printf(p->biodebug, "Hostname in TLS extension: \"%s\"\n",
servername);
if (!p->servername)
if (servername != NULL && p->biodebug != NULL) {
const char *cp = servername;
unsigned char uc;
BIO_printf(p->biodebug, "Hostname in TLS extension: \"");
while ((uc = *cp++) != 0)
BIO_printf(p->biodebug,
isascii(uc) && isprint(uc) ? "%c" : "\\x%02x", uc);
BIO_printf(p->biodebug, "\"\n");
}
if (p->servername == NULL)
return SSL_TLSEXT_ERR_NOACK;
if (servername) {
if (servername != NULL) {
if (strcasecmp(servername, p->servername))
return p->extension_error;
if (ctx2) {
if (ctx2 != NULL) {
BIO_printf(p->biodebug, "Switching server context.\n");
SSL_set_SSL_CTX(s, ctx2);
}
@@ -452,49 +488,45 @@ static int ssl_servername_cb(SSL *s, int *ad, void *arg)
/* Structure passed to cert status callback */
typedef struct tlsextstatusctx_st {
int timeout;
/* File to load OCSP Response from (or NULL if no file) */
char *respin;
/* Default responder to use */
char *host, *path, *port;
int use_ssl;
int timeout;
int verbose;
} tlsextstatusctx;
static tlsextstatusctx tlscstatp = { NULL, NULL, NULL, 0, -1, 0 };
static tlsextstatusctx tlscstatp = { -1 };
#ifndef OPENSSL_NO_OCSP
/*
* Certificate Status callback. This is called when a client includes a
* certificate status request extension. This is a simplified version. It
* examines certificates each time and makes one OCSP responder query for
* each request. A full version would store details such as the OCSP
* certificate IDs and minimise the number of OCSP responses by caching them
* until they were considered "expired".
*/
static int cert_status_cb(SSL *s, void *arg)
/*
* Helper function to get an OCSP_RESPONSE from a responder. This is a
* simplified version. It examines certificates each time and makes one OCSP
* responder query for each request. A full version would store details such as
* the OCSP certificate IDs and minimise the number of OCSP responses by caching
* them until they were considered "expired".
*/
static int get_ocsp_resp_from_responder(SSL *s, tlsextstatusctx *srctx,
OCSP_RESPONSE **resp)
{
tlsextstatusctx *srctx = arg;
char *host = NULL, *port = NULL, *path = NULL;
int use_ssl;
unsigned char *rspder = NULL;
int rspderlen;
STACK_OF(OPENSSL_STRING) *aia = NULL;
X509 *x = NULL;
X509_STORE_CTX *inctx = NULL;
X509_OBJECT *obj;
OCSP_REQUEST *req = NULL;
OCSP_RESPONSE *resp = NULL;
OCSP_CERTID *id = NULL;
STACK_OF(X509_EXTENSION) *exts;
int ret = SSL_TLSEXT_ERR_NOACK;
int i;
if (srctx->verbose)
BIO_puts(bio_err, "cert_status: callback called\n");
/* Build up OCSP query from server certificate */
x = SSL_get_certificate(s);
aia = X509_get1_ocsp(x);
if (aia) {
if (aia != NULL) {
if (!OCSP_parse_url(sk_OPENSSL_STRING_value(aia, 0),
&host, &port, &path, &use_ssl)) {
BIO_puts(bio_err, "cert_status: can't parse AIA URL\n");
@@ -504,7 +536,7 @@ static int cert_status_cb(SSL *s, void *arg)
BIO_printf(bio_err, "cert_status: AIA URL: %s\n",
sk_OPENSSL_STRING_value(aia, 0));
} else {
if (!srctx->host) {
if (srctx->host == NULL) {
BIO_puts(bio_err,
"cert_status: no AIA and no default responder URL\n");
goto done;
@@ -530,7 +562,7 @@ static int cert_status_cb(SSL *s, void *arg)
}
id = OCSP_cert_to_id(NULL, x, X509_OBJECT_get0_X509(obj));
X509_OBJECT_free(obj);
if (!id)
if (id == NULL)
goto err;
req = OCSP_REQUEST_new();
if (req == NULL)
@@ -545,29 +577,24 @@ static int cert_status_cb(SSL *s, void *arg)
if (!OCSP_REQUEST_add_ext(req, ext, -1))
goto err;
}
resp = process_responder(req, host, path, port, use_ssl, NULL,
*resp = process_responder(req, host, path, port, use_ssl, NULL,
srctx->timeout);
if (!resp) {
if (*resp == NULL) {
BIO_puts(bio_err, "cert_status: error querying responder\n");
goto done;
}
rspderlen = i2d_OCSP_RESPONSE(resp, &rspder);
if (rspderlen <= 0)
goto err;
SSL_set_tlsext_status_ocsp_resp(s, rspder, rspderlen);
if (srctx->verbose) {
BIO_puts(bio_err, "cert_status: ocsp response sent:\n");
OCSP_RESPONSE_print(bio_err, resp, 2);
}
ret = SSL_TLSEXT_ERR_OK;
goto done;
err:
ret = SSL_TLSEXT_ERR_ALERT_FATAL;
done:
if (ret != SSL_TLSEXT_ERR_OK)
ERR_print_errors(bio_err);
if (aia) {
/*
* If we parsed aia we need to free; otherwise they were copied and we
* don't
*/
if (aia != NULL) {
OPENSSL_free(host);
OPENSSL_free(path);
OPENSSL_free(port);
@@ -575,10 +602,64 @@ static int cert_status_cb(SSL *s, void *arg)
}
OCSP_CERTID_free(id);
OCSP_REQUEST_free(req);
OCSP_RESPONSE_free(resp);
X509_STORE_CTX_free(inctx);
return ret;
}
/*
* Certificate Status callback. This is called when a client includes a
* certificate status request extension. The response is either obtained from a
* file, or from an OCSP responder.
*/
static int cert_status_cb(SSL *s, void *arg)
{
tlsextstatusctx *srctx = arg;
OCSP_RESPONSE *resp = NULL;
unsigned char *rspder = NULL;
int rspderlen;
int ret = SSL_TLSEXT_ERR_ALERT_FATAL;
if (srctx->verbose)
BIO_puts(bio_err, "cert_status: callback called\n");
if (srctx->respin != NULL) {
BIO *derbio = bio_open_default(srctx->respin, 'r', FORMAT_ASN1);
if (derbio == NULL) {
BIO_puts(bio_err, "cert_status: Cannot open OCSP response file\n");
goto err;
}
resp = d2i_OCSP_RESPONSE_bio(derbio, NULL);
BIO_free(derbio);
if (resp == NULL) {
BIO_puts(bio_err, "cert_status: Error reading OCSP response\n");
goto err;
}
} else {
ret = get_ocsp_resp_from_responder(s, srctx, &resp);
if (ret != SSL_TLSEXT_ERR_OK)
goto err;
}
rspderlen = i2d_OCSP_RESPONSE(resp, &rspder);
if (rspderlen <= 0)
goto err;
SSL_set_tlsext_status_ocsp_resp(s, rspder, rspderlen);
if (srctx->verbose) {
BIO_puts(bio_err, "cert_status: ocsp response sent:\n");
OCSP_RESPONSE_print(bio_err, resp, 2);
}
ret = SSL_TLSEXT_ERR_OK;
err:
if (ret != SSL_TLSEXT_ERR_OK)
ERR_print_errors(bio_err);
OCSP_RESPONSE_free(resp);
return ret;
}
#endif
#ifndef OPENSSL_NO_NEXTPROTONEG
@@ -655,7 +736,7 @@ static char *srtp_profiles = NULL;
typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_ENGINE,
OPT_4, OPT_6, OPT_ACCEPT, OPT_PORT, OPT_UNIX, OPT_UNLINK, OPT_NACCEPT,
OPT_VERIFY, OPT_UPPER_V_VERIFY, OPT_CONTEXT, OPT_CERT, OPT_CRL,
OPT_VERIFY, OPT_NAMEOPT, OPT_UPPER_V_VERIFY, OPT_CONTEXT, OPT_CERT, OPT_CRL,
OPT_CRL_DOWNLOAD, OPT_SERVERINFO, OPT_CERTFORM, OPT_KEY, OPT_KEYFORM,
OPT_PASS, OPT_CERT_CHAIN, OPT_DHPARAM, OPT_DCERTFORM, OPT_DCERT,
OPT_DKEYFORM, OPT_DPASS, OPT_DKEY, OPT_DCERT_CHAIN, OPT_NOCERT,
@@ -664,23 +745,26 @@ typedef enum OPTION_choice {
OPT_BUILD_CHAIN, OPT_CAFILE, OPT_NOCAFILE, OPT_CHAINCAFILE,
OPT_VERIFYCAFILE, OPT_NBIO, OPT_NBIO_TEST, OPT_IGN_EOF, OPT_NO_IGN_EOF,
OPT_DEBUG, OPT_TLSEXTDEBUG, OPT_STATUS, OPT_STATUS_VERBOSE,
OPT_STATUS_TIMEOUT, OPT_STATUS_URL, OPT_MSG, OPT_MSGFILE, OPT_TRACE,
OPT_SECURITY_DEBUG, OPT_SECURITY_DEBUG_VERBOSE, OPT_STATE, OPT_CRLF,
OPT_QUIET, OPT_BRIEF, OPT_NO_DHE,
OPT_NO_RESUME_EPHEMERAL, OPT_PSK_HINT, OPT_PSK, OPT_SRPVFILE,
OPT_SRPUSERSEED, OPT_REV, OPT_WWW, OPT_UPPER_WWW, OPT_HTTP, OPT_ASYNC,
OPT_SSL_CONFIG, OPT_SPLIT_SEND_FRAG, OPT_MAX_PIPELINES, OPT_READ_BUF,
OPT_SSL3, OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1,
OPT_DTLS1_2, OPT_TIMEOUT, OPT_MTU, OPT_LISTEN,
OPT_ID_PREFIX, OPT_RAND, OPT_SERVERNAME, OPT_SERVERNAME_FATAL,
OPT_STATUS_TIMEOUT, OPT_STATUS_URL, OPT_STATUS_FILE, OPT_MSG, OPT_MSGFILE,
OPT_TRACE, OPT_SECURITY_DEBUG, OPT_SECURITY_DEBUG_VERBOSE, OPT_STATE,
OPT_CRLF, OPT_QUIET, OPT_BRIEF, OPT_NO_DHE,
OPT_NO_RESUME_EPHEMERAL, OPT_PSK_IDENTITY, OPT_PSK_HINT, OPT_PSK,
OPT_PSK_SESS, OPT_SRPVFILE, OPT_SRPUSERSEED, OPT_REV, OPT_WWW,
OPT_UPPER_WWW, OPT_HTTP, OPT_ASYNC, OPT_SSL_CONFIG,
OPT_MAX_SEND_FRAG, OPT_SPLIT_SEND_FRAG, OPT_MAX_PIPELINES, OPT_READ_BUF,
OPT_SSL3, OPT_TLS1_3, OPT_TLS1_2, OPT_TLS1_1, OPT_TLS1, OPT_DTLS, OPT_DTLS1,
OPT_DTLS1_2, OPT_SCTP, OPT_TIMEOUT, OPT_MTU, OPT_LISTEN, OPT_STATELESS,
OPT_ID_PREFIX, OPT_SERVERNAME, OPT_SERVERNAME_FATAL,
OPT_CERT2, OPT_KEY2, OPT_NEXTPROTONEG, OPT_ALPN,
OPT_SRTP_PROFILES, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN,
OPT_KEYLOG_FILE, OPT_MAX_EARLY, OPT_EARLY_DATA,
OPT_R_ENUM,
OPT_S_ENUM,
OPT_V_ENUM,
OPT_X_ENUM
} OPTION_CHOICE;
OPTIONS s_server_options[] = {
const OPTIONS s_server_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"port", OPT_PORT, 'p',
"TCP/IP port to listen on for connections (default is " PORT ")"},
@@ -699,6 +783,7 @@ OPTIONS s_server_options[] = {
{"Verify", OPT_UPPER_V_VERIFY, 'n',
"Turn on peer certificate verification, must have a cert"},
{"cert", OPT_CERT, '<', "Certificate file to use; default is " TEST_CERT},
{"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"},
{"naccept", OPT_NACCEPT, 'p', "Terminate after #num connections"},
{"serverinfo", OPT_SERVERINFO, 's',
"PEM serverinfo file for certificate"},
@@ -751,8 +836,7 @@ OPTIONS s_server_options[] = {
{"HTTP", OPT_HTTP, '-', "Like -WWW but ./path includes HTTP headers"},
{"id_prefix", OPT_ID_PREFIX, 's',
"Generate SSL/TLS session IDs prefixed by arg"},
{"rand", OPT_RAND, 's',
"Load the file(s) into the random number generator"},
OPT_R_OPTIONS,
{"keymatexport", OPT_KEYMATEXPORT, 's',
"Export keying material using label"},
{"keymatexportlen", OPT_KEYMATEXPORTLEN, 'p',
@@ -790,6 +874,8 @@ OPTIONS s_server_options[] = {
{"status_timeout", OPT_STATUS_TIMEOUT, 'n',
"Status request responder timeout"},
{"status_url", OPT_STATUS_URL, 's', "Status request fallback URL"},
{"status_file", OPT_STATUS_FILE, '<',
"File containing DER encoded OCSP Response"},
#endif
#ifndef OPENSSL_NO_SSL_TRACE
{"trace", OPT_TRACE, '-', "trace protocol messages"},
@@ -805,20 +891,23 @@ OPTIONS s_server_options[] = {
{"async", OPT_ASYNC, '-', "Operate in asynchronous mode"},
{"ssl_config", OPT_SSL_CONFIG, 's',
"Configure SSL_CTX using the configuration 'val'"},
{"split_send_frag", OPT_SPLIT_SEND_FRAG, 'n',
{"max_send_frag", OPT_MAX_SEND_FRAG, 'p', "Maximum Size of send frames "},
{"split_send_frag", OPT_SPLIT_SEND_FRAG, 'p',
"Size used to split data for encrypt pipelines"},
{"max_pipelines", OPT_MAX_PIPELINES, 'n',
{"max_pipelines", OPT_MAX_PIPELINES, 'p',
"Maximum number of encrypt/decrypt pipelines to be used"},
{"read_buf", OPT_READ_BUF, 'n',
{"read_buf", OPT_READ_BUF, 'p',
"Default read buffer size to be used for connections"},
OPT_S_OPTIONS,
OPT_V_OPTIONS,
OPT_X_OPTIONS,
{"nbio", OPT_NBIO, '-', "Use non-blocking IO"},
{"psk_identity", OPT_PSK_IDENTITY, 's', "PSK identity to expect"},
#ifndef OPENSSL_NO_PSK
{"psk_hint", OPT_PSK_HINT, 's', "PSK identity hint to use"},
{"psk", OPT_PSK, 's', "PSK in hex (without 0x)"},
#endif
{"psk", OPT_PSK, 's', "PSK in hex (without 0x)"},
{"psk_session", OPT_PSK_SESS, '<', "File to read PSK SSL session from"},
#ifndef OPENSSL_NO_SRP
{"srpvfile", OPT_SRPVFILE, '<', "The verifier file for SRP"},
{"srpuserseed", OPT_SRPUSERSEED, 's',
@@ -836,6 +925,9 @@ OPTIONS s_server_options[] = {
#ifndef OPENSSL_NO_TLS1_2
{"tls1_2", OPT_TLS1_2, '-', "just talk TLSv1.2"},
#endif
#ifndef OPENSSL_NO_TLS1_3
{"tls1_3", OPT_TLS1_3, '-', "just talk TLSv1.3"},
#endif
#ifndef OPENSSL_NO_DTLS
{"dtls", OPT_DTLS, '-', "Use any DTLS version"},
{"timeout", OPT_TIMEOUT, '-', "Enable timeouts"},
@@ -843,12 +935,16 @@ OPTIONS s_server_options[] = {
{"listen", OPT_LISTEN, '-',
"Listen for a DTLS ClientHello with a cookie and then connect"},
#endif
{"stateless", OPT_STATELESS, '-', "Require TLSv1.3 cookies"},
#ifndef OPENSSL_NO_DTLS1
{"dtls1", OPT_DTLS1, '-', "Just talk DTLSv1"},
#endif
#ifndef OPENSSL_NO_DTLS1_2
{"dtls1_2", OPT_DTLS1_2, '-', "Just talk DTLSv1.2"},
#endif
#ifndef OPENSSL_NO_SCTP
{"sctp", OPT_SCTP, '-', "Use SCTP"},
#endif
#ifndef OPENSSL_NO_DH
{"no_dhe", OPT_NO_DHE, '-', "Disable ephemeral DH"},
#endif
@@ -865,12 +961,16 @@ OPTIONS s_server_options[] = {
#ifndef OPENSSL_NO_ENGINE
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
#endif
{"keylogfile", OPT_KEYLOG_FILE, '>', "Write TLS secrets to file"},
{"max_early_data", OPT_MAX_EARLY, 'n',
"The maximum number of bytes of early data"},
{"early_data", OPT_EARLY_DATA, '-', "Attempt to read early data"},
{NULL, OPT_EOF, 0, NULL}
};
#define IS_PROT_FLAG(o) \
(o == OPT_SSL3 || o == OPT_TLS1 || o == OPT_TLS1_1 || o == OPT_TLS1_2 \
|| o == OPT_DTLS || o == OPT_DTLS1 || o == OPT_DTLS1_2)
|| o == OPT_TLS1_3 || o == OPT_DTLS || o == OPT_DTLS1 || o == OPT_DTLS1_2)
int s_server_main(int argc, char *argv[])
{
@@ -885,7 +985,7 @@ int s_server_main(int argc, char *argv[])
X509 *s_cert = NULL, *s_dcert = NULL;
X509_VERIFY_PARAM *vpm = NULL;
const char *CApath = NULL, *CAfile = NULL, *chCApath = NULL, *chCAfile = NULL;
char *dpassarg = NULL, *dpass = NULL, *inrand = NULL;
char *dpassarg = NULL, *dpass = NULL;
char *passarg = NULL, *pass = NULL, *vfyCApath = NULL, *vfyCAfile = NULL;
char *crl_file = NULL, *prog;
#ifdef AF_UNIX
@@ -902,7 +1002,7 @@ int s_server_main(int argc, char *argv[])
int s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM;
int s_dcert_format = FORMAT_PEM, s_dkey_format = FORMAT_PEM;
int rev = 0, naccept = -1, sdebug = 0;
int socket_family = AF_UNSPEC, socket_type = SOCK_STREAM;
int socket_family = AF_UNSPEC, socket_type = SOCK_STREAM, protocol = 0;
int state = 0, crl_format = FORMAT_PEM, crl_download = 0;
char *host = NULL;
char *port = BUF_strdup(PORT);
@@ -922,8 +1022,8 @@ int s_server_main(int argc, char *argv[])
#ifndef OPENSSL_NO_PSK
/* by default do not send a PSK identity hint */
char *psk_identity_hint = NULL;
char *p;
#endif
char *p;
#ifndef OPENSSL_NO_SRP
char *srpuserseed = NULL;
char *srp_verifier_file = NULL;
@@ -938,8 +1038,12 @@ int s_server_main(int argc, char *argv[])
int s_tlsextstatus = 0;
#endif
int no_resume_ephemeral = 0;
unsigned int max_send_fragment = 0;
unsigned int split_send_fragment = 0, max_pipelines = 0;
const char *s_serverinfo_file = NULL;
const char *keylog_file = NULL;
int max_early_data = -1;
char *psksessf = NULL;
/* Init of few remaining global variables */
local_argc = argc;
@@ -1076,6 +1180,10 @@ int s_server_main(int argc, char *argv[])
case OPT_CERT:
s_cert_file = opt_arg();
break;
case OPT_NAMEOPT:
if (!set_nameopt(opt_arg()))
goto end;
break;
case OPT_CRL:
crl_file = opt_arg();
break;
@@ -1236,6 +1344,12 @@ int s_server_main(int argc, char *argv[])
BIO_printf(bio_err, "Error parsing URL\n");
goto end;
}
#endif
break;
case OPT_STATUS_FILE:
#ifndef OPENSSL_NO_OCSP
s_tlsextstatus = 1;
tlscstatp.respin = opt_arg();
#endif
break;
case OPT_MSG:
@@ -1275,20 +1389,24 @@ int s_server_main(int argc, char *argv[])
case OPT_NO_RESUME_EPHEMERAL:
no_resume_ephemeral = 1;
break;
case OPT_PSK_IDENTITY:
psk_identity = opt_arg();
break;
case OPT_PSK_HINT:
#ifndef OPENSSL_NO_PSK
psk_identity_hint = opt_arg();
#endif
break;
case OPT_PSK:
#ifndef OPENSSL_NO_PSK
for (p = psk_key = opt_arg(); *p; p++) {
if (isxdigit(_UC(*p)))
continue;
BIO_printf(bio_err, "Not a hex number '%s'\n", *argv);
goto end;
}
#endif
break;
case OPT_PSK_SESS:
psksessf = opt_arg();
break;
case OPT_SRPVFILE:
#ifndef OPENSSL_NO_SRP
@@ -1323,6 +1441,10 @@ int s_server_main(int argc, char *argv[])
min_version = SSL3_VERSION;
max_version = SSL3_VERSION;
break;
case OPT_TLS1_3:
min_version = TLS1_3_VERSION;
max_version = TLS1_3_VERSION;
break;
case OPT_TLS1_2:
min_version = TLS1_2_VERSION;
max_version = TLS1_2_VERSION;
@@ -1355,6 +1477,11 @@ int s_server_main(int argc, char *argv[])
min_version = DTLS1_2_VERSION;
max_version = DTLS1_2_VERSION;
socket_type = SOCK_DGRAM;
#endif
break;
case OPT_SCTP:
#ifndef OPENSSL_NO_SCTP
protocol = IPPROTO_SCTP;
#endif
break;
case OPT_TIMEOUT:
@@ -1372,14 +1499,18 @@ int s_server_main(int argc, char *argv[])
dtlslisten = 1;
#endif
break;
case OPT_STATELESS:
stateless = 1;
break;
case OPT_ID_PREFIX:
session_id_prefix = opt_arg();
break;
case OPT_ENGINE:
engine = setup_engine(opt_arg(), 1);
break;
case OPT_RAND:
inrand = opt_arg();
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
case OPT_SERVERNAME:
tlsextcbp.servername = opt_arg();
@@ -1415,15 +1546,11 @@ int s_server_main(int argc, char *argv[])
case OPT_ASYNC:
async = 1;
break;
case OPT_MAX_SEND_FRAG:
max_send_fragment = atoi(opt_arg());
break;
case OPT_SPLIT_SEND_FRAG:
split_send_fragment = atoi(opt_arg());
if (split_send_fragment == 0) {
/*
* Not allowed - set to a deliberately bad value so we get an
* error message below
*/
split_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH + 1;
}
break;
case OPT_MAX_PIPELINES:
max_pipelines = atoi(opt_arg());
@@ -1431,12 +1558,30 @@ int s_server_main(int argc, char *argv[])
case OPT_READ_BUF:
read_buf_len = atoi(opt_arg());
break;
case OPT_KEYLOG_FILE:
keylog_file = opt_arg();
break;
case OPT_MAX_EARLY:
max_early_data = atoi(opt_arg());
if (max_early_data < 0) {
BIO_printf(bio_err, "Invalid value for max_early_data\n");
goto end;
}
break;
case OPT_EARLY_DATA:
early_data = 1;
break;
}
}
argc = opt_num_rest();
argv = opt_rest();
#ifndef OPENSSL_NO_NEXTPROTONEG
if (min_version == TLS1_3_VERSION && next_proto_neg_in != NULL) {
BIO_printf(bio_err, "Cannot supply -nextprotoneg with TLSv1.3\n");
goto opthelp;
}
#endif
#ifndef OPENSSL_NO_DTLS
if (www && socket_type == SOCK_DGRAM) {
BIO_printf(bio_err, "Can't use -HTTP, -www or -WWW with DTLS\n");
@@ -1449,6 +1594,11 @@ int s_server_main(int argc, char *argv[])
}
#endif
if (stateless && socket_type != SOCK_STREAM) {
BIO_printf(bio_err, "Can only use --stateless with TLS\n");
goto end;
}
#ifdef AF_UNIX
if (socket_family == AF_UNIX && socket_type != SOCK_STREAM) {
BIO_printf(bio_err,
@@ -1457,15 +1607,16 @@ int s_server_main(int argc, char *argv[])
}
#endif
if (split_send_fragment > SSL3_RT_MAX_PLAIN_LENGTH) {
BIO_printf(bio_err, "Bad split send fragment size\n");
goto end;
}
if (max_pipelines > SSL_MAX_PIPELINES) {
BIO_printf(bio_err, "Bad max pipelines value\n");
goto end;
#ifndef OPENSSL_NO_SCTP
if (protocol == IPPROTO_SCTP) {
if (socket_type != SOCK_DGRAM) {
BIO_printf(bio_err, "Can't use -sctp without DTLS\n");
goto end;
}
/* SCTP is unusual. It uses DTLS over a SOCK_STREAM protocol */
socket_type = SOCK_STREAM;
}
#endif
if (!app_passwd(passarg, dpassarg, &pass, &dpass)) {
BIO_printf(bio_err, "Error getting password\n");
@@ -1484,7 +1635,7 @@ int s_server_main(int argc, char *argv[])
if (nocert == 0) {
s_key = load_key(s_key_file, s_key_format, 0, pass, engine,
"server certificate private key file");
if (!s_key) {
if (s_key == NULL) {
ERR_print_errors(bio_err);
goto end;
}
@@ -1492,20 +1643,20 @@ int s_server_main(int argc, char *argv[])
s_cert = load_cert(s_cert_file, s_cert_format,
"server certificate file");
if (!s_cert) {
if (s_cert == NULL) {
ERR_print_errors(bio_err);
goto end;
}
if (s_chain_file) {
if (s_chain_file != NULL) {
if (!load_certs(s_chain_file, &s_chain, FORMAT_PEM, NULL,
"server certificate chain"))
goto end;
}
if (tlsextcbp.servername) {
if (tlsextcbp.servername != NULL) {
s_key2 = load_key(s_key_file2, s_key_format, 0, pass, engine,
"second server certificate private key file");
if (!s_key2) {
if (s_key2 == NULL) {
ERR_print_errors(bio_err);
goto end;
}
@@ -1513,7 +1664,7 @@ int s_server_main(int argc, char *argv[])
s_cert2 = load_cert(s_cert_file2, s_cert_format,
"second server certificate file");
if (!s_cert2) {
if (s_cert2 == NULL) {
ERR_print_errors(bio_err);
goto end;
}
@@ -1533,16 +1684,16 @@ int s_server_main(int argc, char *argv[])
goto end;
}
if (crl_file) {
if (crl_file != NULL) {
X509_CRL *crl;
crl = load_crl(crl_file, crl_format);
if (!crl) {
if (crl == NULL) {
BIO_puts(bio_err, "Error loading CRL\n");
ERR_print_errors(bio_err);
goto end;
}
crls = sk_X509_CRL_new_null();
if (!crls || !sk_X509_CRL_push(crls, crl)) {
if (crls == NULL || !sk_X509_CRL_push(crls, crl)) {
BIO_puts(bio_err, "Error adding CRL\n");
ERR_print_errors(bio_err);
X509_CRL_free(crl);
@@ -1550,14 +1701,14 @@ int s_server_main(int argc, char *argv[])
}
}
if (s_dcert_file) {
if (s_dcert_file != NULL) {
if (s_dkey_file == NULL)
s_dkey_file = s_dcert_file;
s_dkey = load_key(s_dkey_file, s_dkey_format,
0, dpass, engine, "second certificate private key file");
if (!s_dkey) {
if (s_dkey == NULL) {
ERR_print_errors(bio_err);
goto end;
}
@@ -1565,11 +1716,11 @@ int s_server_main(int argc, char *argv[])
s_dcert = load_cert(s_dcert_file, s_dcert_format,
"second server certificate file");
if (!s_dcert) {
if (s_dcert == NULL) {
ERR_print_errors(bio_err);
goto end;
}
if (s_dchain_file) {
if (s_dchain_file != NULL) {
if (!load_certs(s_dchain_file, &s_dchain, FORMAT_PEM, NULL,
"second server certificate chain"))
goto end;
@@ -1577,19 +1728,10 @@ int s_server_main(int argc, char *argv[])
}
if (!app_RAND_load_file(NULL, 1) && inrand == NULL
&& !RAND_status()) {
BIO_printf(bio_err,
"warning, not much extra random data, consider using the -rand option\n");
}
if (inrand != NULL)
BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
app_RAND_load_files(inrand));
if (bio_s_out == NULL) {
if (s_quiet && !s_debug) {
bio_s_out = BIO_new(BIO_s_null());
if (s_msg && !bio_s_msg)
if (s_msg && bio_s_msg == NULL)
bio_s_msg = dup_bio_out(FORMAT_TEXT);
} else {
if (bio_s_out == NULL)
@@ -1615,10 +1757,6 @@ int s_server_main(int argc, char *argv[])
}
if (sdebug)
ssl_ctx_security_debug(ctx, sdebug);
if (!config_ctx(cctx, ssl_args, ctx))
goto end;
if (ssl_config) {
if (SSL_CTX_config(ctx, ssl_config) == 0) {
BIO_printf(bio_err, "Error using configuration \"%s\"\n",
@@ -1627,11 +1765,9 @@ int s_server_main(int argc, char *argv[])
goto end;
}
}
if (min_version != 0
&& SSL_CTX_set_min_proto_version(ctx, min_version) == 0)
if (SSL_CTX_set_min_proto_version(ctx, min_version) == 0)
goto end;
if (max_version != 0
&& SSL_CTX_set_max_proto_version(ctx, max_version) == 0)
if (SSL_CTX_set_max_proto_version(ctx, max_version) == 0)
goto end;
if (session_id_prefix) {
@@ -1646,7 +1782,7 @@ int s_server_main(int argc, char *argv[])
BIO_printf(bio_err, "id_prefix '%s' set.\n", session_id_prefix);
}
SSL_CTX_set_quiet_shutdown(ctx, 1);
if (exc)
if (exc != NULL)
ssl_ctx_set_excert(ctx, exc);
if (state)
@@ -1661,11 +1797,25 @@ int s_server_main(int argc, char *argv[])
if (async) {
SSL_CTX_set_mode(ctx, SSL_MODE_ASYNC);
}
if (split_send_fragment > 0) {
SSL_CTX_set_split_send_fragment(ctx, split_send_fragment);
if (max_send_fragment > 0
&& !SSL_CTX_set_max_send_fragment(ctx, max_send_fragment)) {
BIO_printf(bio_err, "%s: Max send fragment size %u is out of permitted range\n",
prog, max_send_fragment);
goto end;
}
if (max_pipelines > 0) {
SSL_CTX_set_max_pipelines(ctx, max_pipelines);
if (split_send_fragment > 0
&& !SSL_CTX_set_split_send_fragment(ctx, split_send_fragment)) {
BIO_printf(bio_err, "%s: Split send fragment size %u is out of permitted range\n",
prog, split_send_fragment);
goto end;
}
if (max_pipelines > 0
&& !SSL_CTX_set_max_pipelines(ctx, max_pipelines)) {
BIO_printf(bio_err, "%s: Max pipelines %u is out of permitted range\n",
prog, max_pipelines);
goto end;
}
if (read_buf_len > 0) {
@@ -1693,6 +1843,8 @@ int s_server_main(int argc, char *argv[])
}
ssl_ctx_add_crls(ctx, crls, 0);
if (!config_ctx(cctx, ssl_args, ctx))
goto end;
if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile,
crls, crl_download)) {
@@ -1709,7 +1861,7 @@ int s_server_main(int argc, char *argv[])
}
}
if (ctx2) {
if (ctx2 != NULL) {
BIO_printf(bio_s_out, "Setting secondary ctx parameters\n");
if (sdebug)
@@ -1727,7 +1879,7 @@ int s_server_main(int argc, char *argv[])
BIO_printf(bio_err, "id_prefix '%s' set.\n", session_id_prefix);
}
SSL_CTX_set_quiet_shutdown(ctx2, 1);
if (exc)
if (exc != NULL)
ssl_ctx_set_excert(ctx2, exc);
if (state)
@@ -1770,9 +1922,9 @@ int s_server_main(int argc, char *argv[])
if (!no_dhe) {
DH *dh = NULL;
if (dhfile)
if (dhfile != NULL)
dh = load_dh_param(dhfile);
else if (s_cert_file)
else if (s_cert_file != NULL)
dh = load_dh_param(s_cert_file);
if (dh != NULL) {
@@ -1782,16 +1934,16 @@ int s_server_main(int argc, char *argv[])
}
(void)BIO_flush(bio_s_out);
if (dh == NULL)
if (dh == NULL) {
SSL_CTX_set_dh_auto(ctx, 1);
else if (!SSL_CTX_set_tmp_dh(ctx, dh)) {
} else if (!SSL_CTX_set_tmp_dh(ctx, dh)) {
BIO_puts(bio_err, "Error setting temp DH parameters\n");
ERR_print_errors(bio_err);
DH_free(dh);
goto end;
}
if (ctx2) {
if (ctx2 != NULL) {
if (!dhfile) {
DH *dh2 = load_dh_param(s_cert_file2);
if (dh2 != NULL) {
@@ -1802,9 +1954,9 @@ int s_server_main(int argc, char *argv[])
dh = dh2;
}
}
if (dh == NULL)
if (dh == NULL) {
SSL_CTX_set_dh_auto(ctx2, 1);
else if (!SSL_CTX_set_tmp_dh(ctx2, dh)) {
} else if (!SSL_CTX_set_tmp_dh(ctx2, dh)) {
BIO_puts(bio_err, "Error setting temp DH parameters\n");
ERR_print_errors(bio_err);
DH_free(dh);
@@ -1824,7 +1976,8 @@ int s_server_main(int argc, char *argv[])
goto end;
}
if (ctx2 && !set_cert_key_stuff(ctx2, s_cert2, s_key2, NULL, build_chain))
if (ctx2 != NULL
&& !set_cert_key_stuff(ctx2, s_cert2, s_key2, NULL, build_chain))
goto end;
if (s_dcert != NULL) {
@@ -1836,7 +1989,7 @@ int s_server_main(int argc, char *argv[])
SSL_CTX_set_not_resumable_session_callback(ctx,
not_resumable_sess_cb);
if (ctx2)
if (ctx2 != NULL)
SSL_CTX_set_not_resumable_session_callback(ctx2,
not_resumable_sess_cb);
}
@@ -1853,6 +2006,26 @@ int s_server_main(int argc, char *argv[])
goto end;
}
#endif
if (psksessf != NULL) {
BIO *stmp = BIO_new_file(psksessf, "r");
if (stmp == NULL) {
BIO_printf(bio_err, "Can't open PSK session file %s\n", psksessf);
ERR_print_errors(bio_err);
goto end;
}
psksess = PEM_read_bio_SSL_SESSION(stmp, NULL, 0, NULL);
BIO_free(stmp);
if (psksess == NULL) {
BIO_printf(bio_err, "Can't read PSK session file %s\n", psksessf);
ERR_print_errors(bio_err);
goto end;
}
}
if (psk_key != NULL || psksess != NULL)
SSL_CTX_set_psk_find_session_callback(ctx, psk_find_session_cb);
SSL_CTX_set_verify(ctx, s_server_verify, verify_callback);
if (!SSL_CTX_set_session_id_context(ctx,
@@ -1867,7 +2040,7 @@ int s_server_main(int argc, char *argv[])
SSL_CTX_set_cookie_generate_cb(ctx, generate_cookie_callback);
SSL_CTX_set_cookie_verify_cb(ctx, verify_cookie_callback);
if (ctx2) {
if (ctx2 != NULL) {
SSL_CTX_set_verify(ctx2, s_server_verify, verify_callback);
if (!SSL_CTX_set_session_id_context(ctx2,
(void *)&s_server_session_id_context,
@@ -1917,6 +2090,11 @@ int s_server_main(int argc, char *argv[])
}
}
#endif
if (set_keylog_file(ctx, keylog_file))
goto end;
if (max_early_data >= 0)
SSL_CTX_set_max_early_data(ctx, max_early_data);
BIO_printf(bio_s_out, "ACCEPT\n");
(void)BIO_flush(bio_s_out);
@@ -1931,12 +2109,14 @@ int s_server_main(int argc, char *argv[])
&& unlink_unix_path)
unlink(host);
#endif
do_server(&accept_socket, host, port, socket_family, socket_type,
do_server(&accept_socket, host, port, socket_family, socket_type, protocol,
server_cb, context, naccept);
print_stats(bio_s_out, ctx);
ret = 0;
end:
SSL_CTX_free(ctx);
SSL_SESSION_free(psksess);
set_keylog_file(NULL, NULL);
X509_free(s_cert);
sk_X509_CRL_pop_free(crls, X509_CRL_free);
X509_free(s_dcert);
@@ -1971,7 +2151,7 @@ int s_server_main(int argc, char *argv[])
#ifdef CHARSET_EBCDIC
BIO_meth_free(methods_ebcdic);
#endif
return (ret);
return ret;
}
static void print_stats(BIO *bio, SSL_CTX *ssl_ctx)
@@ -2002,7 +2182,7 @@ static void print_stats(BIO *bio, SSL_CTX *ssl_ctx)
SSL_CTX_sess_get_cache_size(ssl_ctx));
}
static int sv_body(int s, int stype, unsigned char *context)
static int sv_body(int s, int stype, int prot, unsigned char *context)
{
char *buf = NULL;
fd_set readfds;
@@ -2016,6 +2196,13 @@ static int sv_body(int s, int stype, unsigned char *context)
struct timeval tv;
#else
struct timeval *timeoutp;
#endif
#ifndef OPENSSL_NO_DTLS
# ifndef OPENSSL_NO_SCTP
int isdtls = (stype == SOCK_DGRAM || prot == IPPROTO_SCTP);
# else
int isdtls = (stype == SOCK_DGRAM);
# endif
#endif
buf = app_malloc(bufsize, "server buffer");
@@ -2026,31 +2213,38 @@ static int sv_body(int s, int stype, unsigned char *context)
BIO_printf(bio_err, "Turned on non blocking io\n");
}
con = SSL_new(ctx);
if (con == NULL) {
con = SSL_new(ctx);
if (s_tlsextdebug) {
SSL_set_tlsext_debug_callback(con, tlsext_cb);
SSL_set_tlsext_debug_arg(con, bio_s_out);
}
if (context
&& !SSL_set_session_id_context(con,
context, strlen((char *)context))) {
BIO_printf(bio_err, "Error setting session id context\n");
ret = -1;
goto err;
}
ret = -1;
goto err;
}
if (s_tlsextdebug) {
SSL_set_tlsext_debug_callback(con, tlsext_cb);
SSL_set_tlsext_debug_arg(con, bio_s_out);
}
if (context != NULL
&& !SSL_set_session_id_context(con, context,
strlen((char *)context))) {
BIO_printf(bio_err, "Error setting session id context\n");
ret = -1;
goto err;
}
if (!SSL_clear(con)) {
BIO_printf(bio_err, "Error clearing SSL connection\n");
ret = -1;
goto err;
}
#ifndef OPENSSL_NO_DTLS
if (stype == SOCK_DGRAM) {
sbio = BIO_new_dgram(s, BIO_NOCLOSE);
if (isdtls) {
# ifndef OPENSSL_NO_SCTP
if (prot == IPPROTO_SCTP)
sbio = BIO_new_dgram_sctp(s, BIO_NOCLOSE);
else
# endif
sbio = BIO_new_dgram(s, BIO_NOCLOSE);
if (enable_timeouts) {
timeout.tv_sec = 0;
@@ -2081,12 +2275,21 @@ static int sv_body(int s, int stype, unsigned char *context)
/* want to do MTU discovery */
BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);
/* turn on cookie exchange */
SSL_set_options(con, SSL_OP_COOKIE_EXCHANGE);
# ifndef OPENSSL_NO_SCTP
if (prot != IPPROTO_SCTP)
# endif
/* Turn on cookie exchange. Not necessary for SCTP */
SSL_set_options(con, SSL_OP_COOKIE_EXCHANGE);
} else
#endif
sbio = BIO_new_socket(s, BIO_NOCLOSE);
if (sbio == NULL) {
BIO_printf(bio_err, "Unable to create BIO\n");
ERR_print_errors(bio_err);
goto err;
}
if (s_nbio_test) {
BIO *test;
@@ -2117,6 +2320,49 @@ static int sv_body(int s, int stype, unsigned char *context)
SSL_set_tlsext_debug_arg(con, bio_s_out);
}
if (early_data) {
int write_header = 1, edret = SSL_READ_EARLY_DATA_ERROR;
size_t readbytes;
while (edret != SSL_READ_EARLY_DATA_FINISH) {
for (;;) {
edret = SSL_read_early_data(con, buf, bufsize, &readbytes);
if (edret != SSL_READ_EARLY_DATA_ERROR)
break;
switch (SSL_get_error(con, 0)) {
case SSL_ERROR_WANT_WRITE:
case SSL_ERROR_WANT_ASYNC:
case SSL_ERROR_WANT_READ:
/* Just keep trying - busy waiting */
continue;
default:
BIO_printf(bio_err, "Error reading early data\n");
ERR_print_errors(bio_err);
goto err;
}
}
if (readbytes > 0) {
if (write_header) {
BIO_printf(bio_s_out, "Early data received:\n");
write_header = 0;
}
raw_write_stdout(buf, (unsigned int)readbytes);
(void)BIO_flush(bio_s_out);
}
}
if (write_header) {
if (SSL_get_early_data_status(con) == SSL_EARLY_DATA_NOT_SENT)
BIO_printf(bio_s_out, "No early data received\n");
else
BIO_printf(bio_s_out, "Early data was rejected\n");
} else {
BIO_printf(bio_s_out, "\nEnd of early data\n");
}
if (SSL_is_init_finished(con))
print_connection_info(con);
}
if (fileno_stdin() > s)
width = fileno_stdin() + 1;
else
@@ -2197,8 +2443,9 @@ static int sv_body(int s, int stype, unsigned char *context)
}
}
assert(lf_num == 0);
} else
} else {
i = raw_read_stdin(buf, bufsize);
}
if (!s_quiet && !s_brief) {
if ((i <= 0) || (buf[0] == 'Q')) {
@@ -2233,9 +2480,6 @@ static int sv_body(int s, int stype, unsigned char *context)
printf("SSL_do_handshake -> %d\n", i);
i = 0; /* 13; */
continue;
/*
* strcpy(buf,"server side RE-NEGOTIATE\n");
*/
}
if ((buf[0] == 'R') && ((buf[1] == '\n') || (buf[1] == '\r'))) {
SSL_set_verify(con,
@@ -2246,10 +2490,29 @@ static int sv_body(int s, int stype, unsigned char *context)
printf("SSL_do_handshake -> %d\n", i);
i = 0; /* 13; */
continue;
/*
* strcpy(buf,"server side RE-NEGOTIATE asking for client
* cert\n");
*/
}
if ((buf[0] == 'K' || buf[0] == 'k')
&& ((buf[1] == '\n') || (buf[1] == '\r'))) {
SSL_key_update(con, buf[0] == 'K' ?
SSL_KEY_UPDATE_REQUESTED
: SSL_KEY_UPDATE_NOT_REQUESTED);
i = SSL_do_handshake(con);
printf("SSL_do_handshake -> %d\n", i);
i = 0;
continue;
}
if (buf[0] == 'c' && ((buf[1] == '\n') || (buf[1] == '\r'))) {
SSL_set_verify(con, SSL_VERIFY_PEER, NULL);
i = SSL_verify_client_post_handshake(con);
if (i == 0) {
printf("Failed to initiate request\n");
ERR_print_errors(bio_err);
} else {
i = SSL_do_handshake(con);
printf("SSL_do_handshake -> %d\n", i);
i = 0;
}
continue;
}
if (buf[0] == 'P') {
static const char *str = "Lets print some clear text\n";
@@ -2414,7 +2677,7 @@ static int sv_body(int s, int stype, unsigned char *context)
if (ret >= 0)
BIO_printf(bio_s_out, "ACCEPT\n");
(void)BIO_flush(bio_s_out);
return (ret);
return ret;
}
static void close_accept_socket(void)
@@ -2425,97 +2688,105 @@ static void close_accept_socket(void)
}
}
static int is_retryable(SSL *con, int i)
{
int err = SSL_get_error(con, i);
/* If it's not a fatal error, it must be retryable */
return (err != SSL_ERROR_SSL)
&& (err != SSL_ERROR_SYSCALL)
&& (err != SSL_ERROR_ZERO_RETURN);
}
static int init_ssl_connection(SSL *con)
{
int i;
const char *str;
X509 *peer;
long verify_err;
char buf[BUFSIZ];
#if !defined(OPENSSL_NO_NEXTPROTONEG)
const unsigned char *next_proto_neg;
unsigned next_proto_neg_len;
#endif
unsigned char *exportedkeymat;
int retry = 0;
#ifndef OPENSSL_NO_DTLS
if (dtlslisten) {
if (dtlslisten || stateless) {
BIO_ADDR *client = NULL;
if ((client = BIO_ADDR_new()) == NULL) {
BIO_printf(bio_err, "ERROR - memory\n");
return 0;
if (dtlslisten) {
if ((client = BIO_ADDR_new()) == NULL) {
BIO_printf(bio_err, "ERROR - memory\n");
return 0;
}
i = DTLSv1_listen(con, client);
} else {
i = SSL_stateless(con);
}
i = DTLSv1_listen(con, client);
if (i > 0) {
BIO *wbio;
int fd = -1;
wbio = SSL_get_wbio(con);
if (wbio) {
BIO_get_fd(wbio, &fd);
}
if (dtlslisten) {
wbio = SSL_get_wbio(con);
if (wbio) {
BIO_get_fd(wbio, &fd);
}
if (!wbio || BIO_connect(fd, client, 0) == 0) {
BIO_printf(bio_err, "ERROR - unable to connect\n");
if (!wbio || BIO_connect(fd, client, 0) == 0) {
BIO_printf(bio_err, "ERROR - unable to connect\n");
BIO_ADDR_free(client);
return 0;
}
BIO_ADDR_free(client);
return 0;
dtlslisten = 0;
} else {
stateless = 0;
}
BIO_ADDR_free(client);
dtlslisten = 0;
i = SSL_accept(con);
} else {
BIO_ADDR_free(client);
}
} else
#endif
} else {
do {
i = SSL_accept(con);
do {
i = SSL_accept(con);
if (i <= 0)
retry = BIO_sock_should_retry(i);
if (i <= 0)
retry = is_retryable(con, i);
#ifdef CERT_CB_TEST_RETRY
{
while (i <= 0
&& SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP
&& SSL_get_state(con) == TLS_ST_SR_CLNT_HELLO) {
BIO_printf(bio_err,
"LOOKUP from certificate callback during accept\n");
i = SSL_accept(con);
if (i <= 0)
retry = BIO_sock_should_retry(i);
{
while (i <= 0
&& SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP
&& SSL_get_state(con) == TLS_ST_SR_CLNT_HELLO) {
BIO_printf(bio_err,
"LOOKUP from certificate callback during accept\n");
i = SSL_accept(con);
if (i <= 0)
retry = is_retryable(con, i);
}
}
}
#endif
#ifndef OPENSSL_NO_SRP
while (i <= 0
&& SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP) {
BIO_printf(bio_s_out, "LOOKUP during accept %s\n",
srp_callback_parm.login);
SRP_user_pwd_free(srp_callback_parm.user);
srp_callback_parm.user =
SRP_VBASE_get1_by_user(srp_callback_parm.vb,
srp_callback_parm.login);
if (srp_callback_parm.user)
BIO_printf(bio_s_out, "LOOKUP done %s\n",
srp_callback_parm.user->info);
else
BIO_printf(bio_s_out, "LOOKUP not successful\n");
i = SSL_accept(con);
if (i <= 0)
retry = BIO_sock_should_retry(i);
}
while (i <= 0
&& SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP) {
BIO_printf(bio_s_out, "LOOKUP during accept %s\n",
srp_callback_parm.login);
SRP_user_pwd_free(srp_callback_parm.user);
srp_callback_parm.user =
SRP_VBASE_get1_by_user(srp_callback_parm.vb,
srp_callback_parm.login);
if (srp_callback_parm.user)
BIO_printf(bio_s_out, "LOOKUP done %s\n",
srp_callback_parm.user->info);
else
BIO_printf(bio_s_out, "LOOKUP not successful\n");
i = SSL_accept(con);
if (i <= 0)
retry = is_retryable(con, i);
}
#endif
} while (i < 0 && SSL_waiting_for_async(con));
} while (i < 0 && SSL_waiting_for_async(con));
}
if (i <= 0) {
if ((dtlslisten && i == 0)
|| (!dtlslisten && retry)) {
if (((dtlslisten || stateless) && i == 0)
|| (!dtlslisten && !stateless && retry)) {
BIO_printf(bio_s_out, "DELAY\n");
return (1);
return 1;
}
BIO_printf(bio_err, "ERROR\n");
@@ -2527,9 +2798,25 @@ static int init_ssl_connection(SSL *con)
}
/* Always print any error messages */
ERR_print_errors(bio_err);
return (0);
return 0;
}
print_connection_info(con);
return 1;
}
static void print_connection_info(SSL *con)
{
const char *str;
X509 *peer;
char buf[BUFSIZ];
#if !defined(OPENSSL_NO_NEXTPROTONEG)
const unsigned char *next_proto_neg;
unsigned next_proto_neg_len;
#endif
unsigned char *exportedkeymat;
int i;
if (s_brief)
print_ssl_summary(con);
@@ -2539,10 +2826,7 @@ static int init_ssl_connection(SSL *con)
if (peer != NULL) {
BIO_printf(bio_s_out, "Client certificate\n");
PEM_write_bio_X509(bio_s_out, peer);
X509_NAME_oneline(X509_get_subject_name(peer), buf, sizeof(buf));
BIO_printf(bio_s_out, "subject=%s\n", buf);
X509_NAME_oneline(X509_get_issuer_name(peer), buf, sizeof(buf));
BIO_printf(bio_s_out, "issuer=%s\n", buf);
dump_cert_text(bio_s_out, peer);
X509_free(peer);
peer = NULL;
}
@@ -2553,8 +2837,9 @@ static int init_ssl_connection(SSL *con)
ssl_print_sigalgs(bio_s_out, con);
#ifndef OPENSSL_NO_EC
ssl_print_point_formats(bio_s_out, con);
ssl_print_curves(bio_s_out, con, 0);
ssl_print_groups(bio_s_out, con, 0);
#endif
print_ca_names(bio_s_out, con);
BIO_printf(bio_s_out, "CIPHER is %s\n", (str != NULL) ? str : "(NONE)");
#if !defined(OPENSSL_NO_NEXTPROTONEG)
@@ -2603,7 +2888,6 @@ static int init_ssl_connection(SSL *con)
}
(void)BIO_flush(bio_s_out);
return (1);
}
#ifndef OPENSSL_NO_DH
@@ -2617,11 +2901,11 @@ static DH *load_dh_param(const char *dhfile)
ret = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
err:
BIO_free(bio);
return (ret);
return ret;
}
#endif
static int www_body(int s, int stype, unsigned char *context)
static int www_body(int s, int stype, int prot, unsigned char *context)
{
char *buf = NULL;
int ret = 1;
@@ -2663,7 +2947,7 @@ static int www_body(int s, int stype, unsigned char *context)
SSL_set_tlsext_debug_arg(con, bio_s_out);
}
if (context
if (context != NULL
&& !SSL_set_session_id_context(con, context,
strlen((char *)context)))
goto err;
@@ -2843,8 +3127,9 @@ static int www_body(int s, int stype, unsigned char *context)
}
ssl_print_sigalgs(io, con);
#ifndef OPENSSL_NO_EC
ssl_print_curves(io, con, 0);
ssl_print_groups(io, con, 0);
#endif
print_ca_names(io, con);
BIO_printf(io, (SSL_session_reused(con)
? "---\nReused, " : "---\nNew, "));
c = SSL_get_current_cipher(con);
@@ -3004,10 +3289,10 @@ static int www_body(int s, int stype, unsigned char *context)
BIO_printf(bio_s_out, "ACCEPT\n");
OPENSSL_free(buf);
BIO_free_all(io);
return (ret);
return ret;
}
static int rev_body(int s, int stype, unsigned char *context)
static int rev_body(int s, int stype, int prot, unsigned char *context)
{
char *buf = NULL;
int i;
@@ -3032,7 +3317,7 @@ static int rev_body(int s, int stype, unsigned char *context)
SSL_set_tlsext_debug_callback(con, tlsext_cb);
SSL_set_tlsext_debug_arg(con, bio_s_out);
}
if (context
if (context != NULL
&& !SSL_set_session_id_context(con, context,
strlen((char *)context))) {
ERR_print_errors(bio_err);
@@ -3157,11 +3442,11 @@ static int rev_body(int s, int stype, unsigned char *context)
OPENSSL_free(buf);
BIO_free_all(io);
return (ret);
return ret;
}
#define MAX_SESSION_ID_ATTEMPTS 10
static int generate_session_id(const SSL *ssl, unsigned char *id,
static int generate_session_id(SSL *ssl, unsigned char *id,
unsigned int *id_len)
{
unsigned int count = 0;
+117 -13
View File
@@ -28,22 +28,27 @@ typedef unsigned int u_int;
#ifndef OPENSSL_NO_SOCK
# define USE_SOCKETS
# include "apps.h"
# undef USE_SOCKETS
# include "s_apps.h"
# include "internal/sockets.h"
# include <openssl/bio.h>
# include <openssl/err.h>
/* Keep track of our peer's address for the cookie callback */
BIO_ADDR *ourpeer = NULL;
/*
* init_client - helper routine to set up socket communication
* @sock: pointer to storage of resulting socket.
* @host: the host name or path (for AF_UNIX) to connect to.
* @port: the port to connect to (ignored for AF_UNIX).
* @bindhost: source host or path (for AF_UNIX).
* @bindport: source port (ignored for AF_UNIX).
* @family: desired socket family, may be AF_INET, AF_INET6, AF_UNIX or
* AF_UNSPEC
* @type: socket type, must be SOCK_STREAM or SOCK_DGRAM
* @protocol: socket protocol, e.g. IPPROTO_TCP or IPPROTO_UDP (or 0 for any)
*
* This will create a socket and use it to connect to a host:port, or if
* family == AF_UNIX, to the path found in host.
@@ -55,21 +60,35 @@ typedef unsigned int u_int;
* Returns 1 on success, 0 on failure.
*/
int init_client(int *sock, const char *host, const char *port,
int family, int type)
const char *bindhost, const char *bindport,
int family, int type, int protocol)
{
BIO_ADDRINFO *res = NULL;
BIO_ADDRINFO *bindaddr = NULL;
const BIO_ADDRINFO *ai = NULL;
const BIO_ADDRINFO *bi = NULL;
int found = 0;
int ret;
if (!BIO_sock_init())
if (BIO_sock_init() != 1)
return 0;
ret = BIO_lookup(host, port, BIO_LOOKUP_CLIENT, family, type, &res);
ret = BIO_lookup_ex(host, port, BIO_LOOKUP_CLIENT, family, type, protocol,
&res);
if (ret == 0) {
ERR_print_errors(bio_err);
return 0;
}
if (bindhost != NULL || bindport != NULL) {
ret = BIO_lookup_ex(bindhost, bindport, BIO_LOOKUP_CLIENT,
family, type, protocol, &bindaddr);
if (ret == 0) {
ERR_print_errors (bio_err);
goto out;
}
}
ret = 0;
for (ai = res; ai != NULL; ai = BIO_ADDRINFO_next(ai)) {
/* Admittedly, these checks are quite paranoid, we should not get
@@ -77,7 +96,19 @@ int init_client(int *sock, const char *host, const char *port,
* asked for. */
OPENSSL_assert((family == AF_UNSPEC
|| family == BIO_ADDRINFO_family(ai))
&& (type == 0 || type == BIO_ADDRINFO_socktype(ai)));
&& (type == 0 || type == BIO_ADDRINFO_socktype(ai))
&& (protocol == 0
|| protocol == BIO_ADDRINFO_protocol(ai)));
if (bindaddr != NULL) {
for (bi = bindaddr; bi != NULL; bi = BIO_ADDRINFO_next(bi)) {
if (BIO_ADDRINFO_family(bi) == BIO_ADDRINFO_family(ai))
break;
}
if (bi == NULL)
continue;
++found;
}
*sock = BIO_socket(BIO_ADDRINFO_family(ai), BIO_ADDRINFO_socktype(ai),
BIO_ADDRINFO_protocol(ai), 0);
@@ -87,6 +118,34 @@ int init_client(int *sock, const char *host, const char *port,
*/
continue;
}
if (bi != NULL) {
if (!BIO_bind(*sock, BIO_ADDRINFO_address(bi),
BIO_SOCK_REUSEADDR)) {
BIO_closesocket(*sock);
*sock = INVALID_SOCKET;
break;
}
}
#ifndef OPENSSL_NO_SCTP
if (protocol == IPPROTO_SCTP) {
/*
* For SCTP we have to set various options on the socket prior to
* connecting. This is done automatically by BIO_new_dgram_sctp().
* We don't actually need the created BIO though so we free it again
* immediately.
*/
BIO *tmpbio = BIO_new_dgram_sctp(*sock, BIO_NOCLOSE);
if (tmpbio == NULL) {
ERR_print_errors(bio_err);
return 0;
}
BIO_free(tmpbio);
}
#endif
if (!BIO_connect(*sock, BIO_ADDRINFO_address(ai), 0)) {
BIO_closesocket(*sock);
*sock = INVALID_SOCKET;
@@ -98,12 +157,27 @@ int init_client(int *sock, const char *host, const char *port,
}
if (*sock == INVALID_SOCKET) {
if (bindaddr != NULL && !found) {
BIO_printf(bio_err, "Can't bind %saddress for %s%s%s\n",
BIO_ADDRINFO_family(res) == AF_INET6 ? "IPv6 " :
BIO_ADDRINFO_family(res) == AF_INET ? "IPv4 " :
BIO_ADDRINFO_family(res) == AF_UNIX ? "unix " : "",
bindhost != NULL ? bindhost : "",
bindport != NULL ? ":" : "",
bindport != NULL ? bindport : "");
ERR_clear_error();
ret = 0;
}
ERR_print_errors(bio_err);
} else {
/* Remove any stale errors from previous connection attempts */
ERR_clear_error();
ret = 1;
}
out:
if (bindaddr != NULL) {
BIO_ADDRINFO_free (bindaddr);
}
BIO_ADDRINFO_free(res);
return ret;
}
@@ -129,7 +203,7 @@ int init_client(int *sock, const char *host, const char *port,
* 0 on failure, something other on success.
*/
int do_server(int *accept_sock, const char *host, const char *port,
int family, int type, do_server_cb cb,
int family, int type, int protocol, do_server_cb cb,
unsigned char *context, int naccept)
{
int asock = 0;
@@ -142,10 +216,11 @@ int do_server(int *accept_sock, const char *host, const char *port,
int sock_options = BIO_SOCK_REUSEADDR;
int ret = 0;
if (!BIO_sock_init())
if (BIO_sock_init() != 1)
return 0;
if (!BIO_lookup(host, port, BIO_LOOKUP_SERVER, family, type, &res)) {
if (!BIO_lookup_ex(host, port, BIO_LOOKUP_SERVER, family, type, protocol,
&res)) {
ERR_print_errors(bio_err);
return 0;
}
@@ -153,7 +228,8 @@ int do_server(int *accept_sock, const char *host, const char *port,
/* Admittedly, these checks are quite paranoid, we should not get
* anything in the BIO_ADDRINFO chain that we haven't asked for */
OPENSSL_assert((family == AF_UNSPEC || family == BIO_ADDRINFO_family(res))
&& (type == 0 || type == BIO_ADDRINFO_socktype(res)));
&& (type == 0 || type == BIO_ADDRINFO_socktype(res))
&& (protocol == 0 || protocol == BIO_ADDRINFO_protocol(res)));
sock_family = BIO_ADDRINFO_family(res);
sock_type = BIO_ADDRINFO_socktype(res);
@@ -185,6 +261,25 @@ int do_server(int *accept_sock, const char *host, const char *port,
goto end;
}
#ifndef OPENSSL_NO_SCTP
if (protocol == IPPROTO_SCTP) {
/*
* For SCTP we have to set various options on the socket prior to
* accepting. This is done automatically by BIO_new_dgram_sctp().
* We don't actually need the created BIO though so we free it again
* immediately.
*/
BIO *tmpbio = BIO_new_dgram_sctp(asock, BIO_NOCLOSE);
if (tmpbio == NULL) {
BIO_closesocket(asock);
ERR_print_errors(bio_err);
goto end;
}
BIO_free(tmpbio);
}
#endif
BIO_ADDRINFO_free(res);
res = NULL;
@@ -192,15 +287,22 @@ int do_server(int *accept_sock, const char *host, const char *port,
*accept_sock = asock;
for (;;) {
if (type == SOCK_STREAM) {
BIO_ADDR_free(ourpeer);
ourpeer = BIO_ADDR_new();
if (ourpeer == NULL) {
BIO_closesocket(asock);
ERR_print_errors(bio_err);
goto end;
}
do {
sock = BIO_accept_ex(asock, NULL, 0);
sock = BIO_accept_ex(asock, ourpeer, 0);
} while (sock < 0 && BIO_sock_should_retry(sock));
if (sock < 0) {
ERR_print_errors(bio_err);
BIO_closesocket(asock);
break;
}
i = (*cb)(sock, type, context);
i = (*cb)(sock, type, protocol, context);
/*
* Give the socket time to send its last data before we close it.
@@ -228,7 +330,7 @@ int do_server(int *accept_sock, const char *host, const char *port,
shutdown(sock, 1); /* SHUT_WR */
BIO_closesocket(sock);
} else {
i = (*cb)(asock, type, context);
i = (*cb)(asock, type, protocol, context);
}
if (naccept != -1)
@@ -244,6 +346,8 @@ int do_server(int *accept_sock, const char *host, const char *port,
if (family == AF_UNIX)
unlink(host);
# endif
BIO_ADDR_free(ourpeer);
ourpeer = NULL;
return ret;
}
+94 -41
View File
@@ -7,6 +7,8 @@
* https://www.openssl.org/source/license.html
*/
#define NO_SHUTDOWN
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -15,8 +17,8 @@
#ifndef OPENSSL_NO_SOCK
#define USE_SOCKETS
#include "apps.h"
#include "progs.h"
#include <openssl/x509.h>
#include <openssl/ssl.h>
#include <openssl/pem.h>
@@ -26,29 +28,50 @@
# include OPENSSL_UNISTD
#endif
#undef ioctl
#define ioctl ioctlsocket
#define SSL_CONNECT_NAME "localhost:4433"
/* no default cert. */
/*
* #define TEST_CERT "client.pem"
*/
#undef min
#undef max
#define min(a,b) (((a) < (b)) ? (a) : (b))
#define max(a,b) (((a) > (b)) ? (a) : (b))
#undef SECONDS
#define SECONDS 30
#define SECONDSSTR "30"
static SSL *doConnection(SSL *scon, const char *host, SSL_CTX *ctx);
/*
* Define a HTTP get command globally.
* Also define the size of the command, this is two bytes less than
* the size of the string because the %s is replaced by the URL.
*/
static const char fmt_http_get_cmd[] = "GET %s HTTP/1.0\r\n\r\n";
static const size_t fmt_http_get_cmd_size = sizeof(fmt_http_get_cmd) - 2;
typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_CONNECT, OPT_CIPHER, OPT_CERT, OPT_KEY, OPT_CAPATH,
OPT_CONNECT, OPT_CIPHER, OPT_CERT, OPT_NAMEOPT, OPT_KEY, OPT_CAPATH,
OPT_CAFILE, OPT_NOCAPATH, OPT_NOCAFILE, OPT_NEW, OPT_REUSE, OPT_BUGS,
OPT_VERIFY, OPT_TIME, OPT_SSL3,
OPT_WWW
} OPTION_CHOICE;
OPTIONS s_time_options[] = {
const OPTIONS s_time_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"connect", OPT_CONNECT, 's',
"Where to connect as post:port (default is " SSL_CONNECT_NAME ")"},
{"cipher", OPT_CIPHER, 's', "Cipher to use, see 'openssl ciphers'"},
{"cert", OPT_CERT, '<', "Cert file to use, PEM format assumed"},
{"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"},
{"key", OPT_KEY, '<', "File with key, PEM; default is -cert file"},
{"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"},
{"cafile", OPT_CAFILE, '<', "PEM format file of CA's"},
@@ -125,6 +148,10 @@ int s_time_main(int argc, char **argv)
case OPT_CERT:
certfile = opt_arg();
break;
case OPT_NAMEOPT:
if (!set_nameopt(opt_arg()))
goto end;
break;
case OPT_KEY:
keyfile = opt_arg();
break;
@@ -152,7 +179,7 @@ int s_time_main(int argc, char **argv)
break;
case OPT_WWW:
www_path = opt_arg();
buf_size = strlen(www_path) + sizeof(fmt_http_get_cmd) - 2; /* 2 is for %s */
buf_size = strlen(www_path) + fmt_http_get_cmd_size;
if (buf_size > sizeof(buf)) {
BIO_printf(bio_err, "%s: -www option is too long\n", prog);
goto end;
@@ -169,20 +196,21 @@ int s_time_main(int argc, char **argv)
if (cipher == NULL)
cipher = getenv("SSL_CIPHER");
if (cipher == NULL)
if (cipher == NULL) {
BIO_printf(bio_err, "No CIPHER specified\n");
goto end;
}
if ((ctx = SSL_CTX_new(meth)) == NULL)
goto end;
SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
SSL_CTX_set_quiet_shutdown(ctx, 1);
if (SSL_CTX_set_max_proto_version(ctx, max_version) == 0)
goto end;
if (st_bugs)
SSL_CTX_set_options(ctx, SSL_OP_ALL);
if (cipher != NULL && !SSL_CTX_set_cipher_list(ctx, cipher))
if (!SSL_CTX_set_cipher_list(ctx, cipher))
goto end;
if (!set_cert_stuff(ctx, certfile, keyfile))
goto end;
@@ -208,20 +236,26 @@ int s_time_main(int argc, char **argv)
goto end;
if (www_path != NULL) {
buf_len = BIO_snprintf(buf, sizeof(buf),
fmt_http_get_cmd, www_path);
if (SSL_write(scon, buf, buf_len) <= 0)
buf_len = BIO_snprintf(buf, sizeof(buf), fmt_http_get_cmd,
www_path);
if (buf_len <= 0 || SSL_write(scon, buf, buf_len) <= 0)
goto end;
while ((i = SSL_read(scon, buf, sizeof(buf))) > 0)
bytes_read += i;
while ((i = SSL_read(scon, buf, sizeof(buf))) > 0 ||
SSL_get_error(scon, i) == SSL_ERROR_WANT_READ ||
SSL_get_error(scon, i) == SSL_ERROR_WANT_WRITE)
if (i > 0) bytes_read += i;
}
#ifdef NO_SHUTDOWN
SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
#else
SSL_shutdown(scon);
#endif
BIO_closesocket(SSL_get_fd(scon));
nConn += 1;
if (SSL_session_reused(scon))
if (SSL_session_reused(scon)) {
ver = 'r';
else {
} else {
ver = SSL_version(scon);
if (ver == TLS1_VERSION)
ver = 't';
@@ -262,14 +296,19 @@ int s_time_main(int argc, char **argv)
}
if (www_path != NULL) {
buf_len = BIO_snprintf(buf, sizeof(buf),
fmt_http_get_cmd, www_path);
if (SSL_write(scon, buf, buf_len) <= 0)
buf_len = BIO_snprintf(buf, sizeof(buf), fmt_http_get_cmd, www_path);
if (buf_len <= 0 || SSL_write(scon, buf, buf_len) <= 0)
goto end;
while ((i = SSL_read(scon, buf, sizeof(buf))) > 0)
while ((i = SSL_read(scon, buf, sizeof(buf))) > 0 ||
SSL_get_error(scon, i) == SSL_ERROR_WANT_READ ||
SSL_get_error(scon, i) == SSL_ERROR_WANT_WRITE)
continue;
}
#ifdef NO_SHUTDOWN
SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
#else
SSL_shutdown(scon);
#endif
BIO_closesocket(SSL_get_fd(scon));
nConn = 0;
@@ -288,21 +327,27 @@ int s_time_main(int argc, char **argv)
if ((doConnection(scon, host, ctx)) == NULL)
goto end;
if (www_path) {
BIO_snprintf(buf, sizeof(buf), "GET %s HTTP/1.0\r\n\r\n",
www_path);
if (SSL_write(scon, buf, strlen(buf)) <= 0)
if (www_path != NULL) {
buf_len = BIO_snprintf(buf, sizeof(buf), fmt_http_get_cmd,
www_path);
if (buf_len <= 0 || SSL_write(scon, buf, buf_len) <= 0)
goto end;
while ((i = SSL_read(scon, buf, sizeof(buf))) > 0)
bytes_read += i;
while ((i = SSL_read(scon, buf, sizeof(buf))) > 0 ||
SSL_get_error(scon, i) == SSL_ERROR_WANT_READ ||
SSL_get_error(scon, i) == SSL_ERROR_WANT_WRITE)
if (i > 0) bytes_read += i;
}
#ifdef NO_SHUTDOWN
SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
#else
SSL_shutdown(scon);
#endif
BIO_closesocket(SSL_get_fd(scon));
nConn += 1;
if (SSL_session_reused(scon))
if (SSL_session_reused(scon)) {
ver = 'r';
else {
} else {
ver = SSL_version(scon);
if (ver == TLS1_VERSION)
ver = 't';
@@ -328,7 +373,7 @@ int s_time_main(int argc, char **argv)
end:
SSL_free(scon);
SSL_CTX_free(ctx);
return (ret);
return ret;
}
/*-
@@ -338,13 +383,13 @@ static SSL *doConnection(SSL *scon, const char *host, SSL_CTX *ctx)
{
BIO *conn;
SSL *serverCon;
int i;
int width, i;
fd_set readfds;
if ((conn = BIO_new(BIO_s_connect())) == NULL)
return NULL;
BIO_set_conn_hostname(conn, host);
BIO_set_conn_mode(conn, BIO_SOCK_NODELAY);
if (scon == NULL)
serverCon = SSL_new(ctx);
@@ -356,7 +401,26 @@ static SSL *doConnection(SSL *scon, const char *host, SSL_CTX *ctx)
SSL_set_bio(serverCon, conn, conn);
/* ok, lets connect */
i = SSL_connect(serverCon);
for (;;) {
i = SSL_connect(serverCon);
if (BIO_sock_should_retry(i)) {
BIO_printf(bio_err, "DELAY\n");
i = SSL_get_fd(serverCon);
width = i + 1;
FD_ZERO(&readfds);
openssl_fdset(i, &readfds);
/*
* Note: under VMS with SOCKETSHR the 2nd parameter is currently
* of type (int *) whereas under other systems it is (void *) if
* you don't have a cast it will choke the compiler: if you do
* have a cast then you can either go for (int *) or (void *).
*/
select(width, (void *)&readfds, NULL, NULL, NULL);
continue;
}
break;
}
if (i <= 0) {
BIO_printf(bio_err, "ERROR\n");
if (verify_args.error != X509_V_OK)
@@ -369,17 +433,6 @@ static SSL *doConnection(SSL *scon, const char *host, SSL_CTX *ctx)
return NULL;
}
#if defined(SOL_SOCKET) && defined(SO_LINGER)
{
struct linger no_linger;
no_linger.l_onoff = 1;
no_linger.l_linger = 0;
(void) setsockopt(SSL_get_fd(serverCon), SOL_SOCKET, SO_LINGER,
(char*)&no_linger, sizeof(no_linger));
}
#endif
return serverCon;
}
#endif /* OPENSSL_NO_SOCK */
+14 -13
View File
@@ -1,5 +1,5 @@
/*
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2018 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
@@ -11,6 +11,7 @@
#include <stdlib.h>
#include <string.h>
#include "apps.h"
#include "progs.h"
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/x509.h>
@@ -23,7 +24,7 @@ typedef enum OPTION_choice {
OPT_TEXT, OPT_CERT, OPT_NOOUT, OPT_CONTEXT
} OPTION_CHOICE;
OPTIONS sess_id_options[] = {
const OPTIONS sess_id_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"inform", OPT_INFORM, 'F', "Input format - default PEM (DER or PEM)"},
{"outform", OPT_OUTFORM, 'f',
@@ -100,14 +101,14 @@ int sess_id_main(int argc, char **argv)
}
peer = SSL_SESSION_get0_peer(x);
if (context) {
if (context != NULL) {
size_t ctx_len = strlen(context);
if (ctx_len > SSL_MAX_SID_CTX_LENGTH) {
BIO_printf(bio_err, "Context too long\n");
goto end;
}
if (!SSL_SESSION_set1_id_context(x, (unsigned char *)context,
ctx_len)) {
ctx_len)) {
BIO_printf(bio_err, "Error setting id context\n");
goto end;
}
@@ -131,13 +132,13 @@ int sess_id_main(int argc, char **argv)
}
if (!noout && !cert) {
if (outformat == FORMAT_ASN1)
if (outformat == FORMAT_ASN1) {
i = i2d_SSL_SESSION_bio(out, x);
else if (outformat == FORMAT_PEM)
} else if (outformat == FORMAT_PEM) {
i = PEM_write_bio_SSL_SESSION(out, x);
else if (outformat == FORMAT_NSS)
} else if (outformat == FORMAT_NSS) {
i = SSL_SESSION_print_keylog(out, x);
else {
} else {
BIO_printf(bio_err, "bad output format specified for outfile\n");
goto end;
}
@@ -146,11 +147,11 @@ int sess_id_main(int argc, char **argv)
goto end;
}
} else if (!noout && (peer != NULL)) { /* just print the certificate */
if (outformat == FORMAT_ASN1)
if (outformat == FORMAT_ASN1) {
i = (int)i2d_X509_bio(out, peer);
else if (outformat == FORMAT_PEM)
} else if (outformat == FORMAT_PEM) {
i = PEM_write_bio_X509(out, peer);
else {
} else {
BIO_printf(bio_err, "bad output format specified for outfile\n");
goto end;
}
@@ -163,7 +164,7 @@ int sess_id_main(int argc, char **argv)
end:
BIO_free_all(out);
SSL_SESSION_free(x);
return (ret);
return ret;
}
static SSL_SESSION *load_sess_id(char *infile, int format)
@@ -186,5 +187,5 @@ static SSL_SESSION *load_sess_id(char *infile, int format)
end:
BIO_free(in);
return (x);
return x;
}
+57 -66
View File
@@ -1,5 +1,5 @@
/*
* Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1999-2018 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
@@ -12,6 +12,7 @@
#include <stdio.h>
#include <string.h>
#include "apps.h"
#include "progs.h"
#include <openssl/crypto.h>
#include <openssl/pem.h>
#include <openssl/err.h>
@@ -37,15 +38,16 @@ typedef enum OPTION_choice {
OPT_PK7OUT, OPT_TEXT, OPT_NOINTERN, OPT_NOVERIFY, OPT_NOCHAIN,
OPT_NOCERTS, OPT_NOATTR, OPT_NODETACH, OPT_NOSMIMECAP,
OPT_BINARY, OPT_NOSIGS, OPT_STREAM, OPT_INDEF, OPT_NOINDEF,
OPT_CRLFEOL, OPT_RAND, OPT_ENGINE, OPT_PASSIN,
OPT_CRLFEOL, OPT_ENGINE, OPT_PASSIN,
OPT_TO, OPT_FROM, OPT_SUBJECT, OPT_SIGNER, OPT_RECIP, OPT_MD,
OPT_CIPHER, OPT_INKEY, OPT_KEYFORM, OPT_CERTFILE, OPT_CAFILE,
OPT_R_ENUM,
OPT_V_ENUM,
OPT_CAPATH, OPT_NOCAFILE, OPT_NOCAPATH, OPT_IN, OPT_INFORM, OPT_OUT,
OPT_OUTFORM, OPT_CONTENT
} OPTION_CHOICE;
OPTIONS smime_options[] = {
const OPTIONS smime_options[] = {
{OPT_HELP_STR, 1, '-', "Usage: %s [options] cert.pem...\n"},
{OPT_HELP_STR, 1, '-',
" cert.pem... recipient certs for encryption\n"},
@@ -89,15 +91,14 @@ OPTIONS smime_options[] = {
{"no-CApath", OPT_NOCAPATH, '-',
"Do not load certificates from the default certificates directory"},
{"resign", OPT_RESIGN, '-', "Resign a signed message"},
{"nochain", OPT_NOCHAIN, '-',
{"nochain", OPT_NOCHAIN, '-',
"set PKCS7_NOCHAIN so certificates contained in the message are not used as untrusted CAs" },
{"nosmimecap", OPT_NOSMIMECAP, '-', "Omit the SMIMECapabilities attribute"},
{"stream", OPT_STREAM, '-', "Enable CMS streaming" },
{"indef", OPT_INDEF, '-', "Same as -stream" },
{"noindef", OPT_NOINDEF, '-', "Disable CMS streaming"},
{"crlfeol", OPT_CRLFEOL, '-', "Use CRLF as EOL termination instead of CR only"},
{"rand", OPT_RAND, 's',
"Load the file(s) into the random number generator"},
OPT_R_OPTIONS,
{"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
{"md", OPT_MD, 's', "Digest algorithm to use when signing or resigning"},
{"", OPT_CIPHER, '-', "Any supported cipher"},
@@ -121,15 +122,12 @@ int smime_main(int argc, char **argv)
const EVP_CIPHER *cipher = NULL;
const EVP_MD *sign_md = NULL;
const char *CAfile = NULL, *CApath = NULL, *prog = NULL;
char *certfile = NULL, *keyfile = NULL, *contfile = NULL, *inrand = NULL;
char *infile = NULL, *outfile = NULL, *signerfile = NULL, *recipfile =
NULL;
char *passinarg = NULL, *passin = NULL, *to = NULL, *from =
NULL, *subject = NULL;
char *certfile = NULL, *keyfile = NULL, *contfile = NULL;
char *infile = NULL, *outfile = NULL, *signerfile = NULL, *recipfile = NULL;
char *passinarg = NULL, *passin = NULL, *to = NULL, *from = NULL, *subject = NULL;
OPTION_CHOICE o;
int noCApath = 0, noCAfile = 0;
int flags = PKCS7_DETACHED, operation = 0, ret = 0, need_rand = 0, indef =
0;
int flags = PKCS7_DETACHED, operation = 0, ret = 0, indef = 0;
int informat = FORMAT_SMIME, outformat = FORMAT_SMIME, keyform =
FORMAT_PEM;
int vpmtouched = 0, rv = 0;
@@ -224,9 +222,9 @@ int smime_main(int argc, char **argv)
flags |= PKCS7_CRLFEOL;
mime_eol = "\r\n";
break;
case OPT_RAND:
inrand = opt_arg();
need_rand = 1;
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
case OPT_ENGINE:
e = setup_engine(opt_arg(), 0);
@@ -245,7 +243,7 @@ int smime_main(int argc, char **argv)
break;
case OPT_SIGNER:
/* If previous -signer argument add signer to list */
if (signerfile) {
if (signerfile != NULL) {
if (sksigners == NULL
&& (sksigners = sk_OPENSSL_STRING_new_null()) == NULL)
goto end;
@@ -273,7 +271,7 @@ int smime_main(int argc, char **argv)
break;
case OPT_INKEY:
/* If previous -inkey argument add signer to list */
if (keyfile) {
if (keyfile != NULL) {
if (signerfile == NULL) {
BIO_printf(bio_err,
"%s: Must have -signer before -inkey\n", prog);
@@ -323,7 +321,7 @@ int smime_main(int argc, char **argv)
argc = opt_num_rest();
argv = opt_rest();
if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners)) {
if (!(operation & SMIME_SIGNERS) && (skkeys != NULL || sksigners != NULL)) {
BIO_puts(bio_err, "Multiple signers or keys not allowed\n");
goto opthelp;
}
@@ -334,8 +332,8 @@ int smime_main(int argc, char **argv)
BIO_puts(bio_err, "Illegal -inkey without -signer\n");
goto opthelp;
}
if (signerfile) {
if (!sksigners
if (signerfile != NULL) {
if (sksigners == NULL
&& (sksigners = sk_OPENSSL_STRING_new_null()) == NULL)
goto end;
sk_OPENSSL_STRING_push(sksigners, signerfile);
@@ -345,15 +343,14 @@ int smime_main(int argc, char **argv)
keyfile = signerfile;
sk_OPENSSL_STRING_push(skkeys, keyfile);
}
if (!sksigners) {
if (sksigners == NULL) {
BIO_printf(bio_err, "No signer certificate specified\n");
goto opthelp;
}
signerfile = NULL;
keyfile = NULL;
need_rand = 1;
} else if (operation == SMIME_DECRYPT) {
if (!recipfile && !keyfile) {
if (recipfile == NULL && keyfile == NULL) {
BIO_printf(bio_err,
"No recipient certificate or key specified\n");
goto opthelp;
@@ -363,22 +360,15 @@ int smime_main(int argc, char **argv)
BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n");
goto opthelp;
}
need_rand = 1;
} else if (!operation)
} else if (!operation) {
goto opthelp;
}
if (!app_passwd(passinarg, NULL, &passin, NULL)) {
BIO_printf(bio_err, "Error getting password\n");
goto end;
}
if (need_rand) {
app_RAND_load_file(NULL, (inrand != NULL));
if (inrand != NULL)
BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
app_RAND_load_files(inrand));
}
ret = 2;
if (!(operation & SMIME_SIGNERS))
@@ -395,7 +385,7 @@ int smime_main(int argc, char **argv)
}
if (operation == SMIME_ENCRYPT) {
if (!cipher) {
if (cipher == NULL) {
#ifndef OPENSSL_NO_DES
cipher = EVP_des_ede3_cbc();
#else
@@ -404,9 +394,9 @@ int smime_main(int argc, char **argv)
#endif
}
encerts = sk_X509_new_null();
if (!encerts)
if (encerts == NULL)
goto end;
while (*argv) {
while (*argv != NULL) {
cert = load_cert(*argv, FORMAT_PEM,
"recipient certificate file");
if (cert == NULL)
@@ -417,7 +407,7 @@ int smime_main(int argc, char **argv)
}
}
if (certfile) {
if (certfile != NULL) {
if (!load_certs(certfile, &other, FORMAT_PEM, NULL,
"certificate file")) {
ERR_print_errors(bio_err);
@@ -425,7 +415,7 @@ int smime_main(int argc, char **argv)
}
}
if (recipfile && (operation == SMIME_DECRYPT)) {
if (recipfile != NULL && (operation == SMIME_DECRYPT)) {
if ((recip = load_cert(recipfile, FORMAT_PEM,
"recipient certificate file")) == NULL) {
ERR_print_errors(bio_err);
@@ -434,17 +424,18 @@ int smime_main(int argc, char **argv)
}
if (operation == SMIME_DECRYPT) {
if (!keyfile)
if (keyfile == NULL)
keyfile = recipfile;
} else if (operation == SMIME_SIGN) {
if (!keyfile)
if (keyfile == NULL)
keyfile = signerfile;
} else
} else {
keyfile = NULL;
}
if (keyfile) {
if (keyfile != NULL) {
key = load_key(keyfile, keyform, 0, passin, e, "signing key file");
if (!key)
if (key == NULL)
goto end;
}
@@ -453,22 +444,22 @@ int smime_main(int argc, char **argv)
goto end;
if (operation & SMIME_IP) {
if (informat == FORMAT_SMIME)
if (informat == FORMAT_SMIME) {
p7 = SMIME_read_PKCS7(in, &indata);
else if (informat == FORMAT_PEM)
} else if (informat == FORMAT_PEM) {
p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL);
else if (informat == FORMAT_ASN1)
} else if (informat == FORMAT_ASN1) {
p7 = d2i_PKCS7_bio(in, NULL);
else {
} else {
BIO_printf(bio_err, "Bad input format for PKCS#7 file\n");
goto end;
}
if (!p7) {
if (p7 == NULL) {
BIO_printf(bio_err, "Error reading S/MIME message\n");
goto end;
}
if (contfile) {
if (contfile != NULL) {
BIO_free(indata);
if ((indata = BIO_new_file(contfile, "rb")) == NULL) {
BIO_printf(bio_err, "Can't read content file %s\n", contfile);
@@ -505,11 +496,12 @@ int smime_main(int argc, char **argv)
if (flags & PKCS7_DETACHED) {
if (outformat == FORMAT_SMIME)
flags |= PKCS7_STREAM;
} else if (indef)
} else if (indef) {
flags |= PKCS7_STREAM;
}
flags |= PKCS7_PARTIAL;
p7 = PKCS7_sign(NULL, NULL, other, in, flags);
if (!p7)
if (p7 == NULL)
goto end;
if (flags & PKCS7_NOCERTS) {
for (i = 0; i < sk_X509_num(other); i++) {
@@ -517,17 +509,18 @@ int smime_main(int argc, char **argv)
PKCS7_add_certificate(p7, x);
}
}
} else
} else {
flags |= PKCS7_REUSE_DIGEST;
}
for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++) {
signerfile = sk_OPENSSL_STRING_value(sksigners, i);
keyfile = sk_OPENSSL_STRING_value(skkeys, i);
signer = load_cert(signerfile, FORMAT_PEM,
"signer certificate");
if (!signer)
if (signer == NULL)
goto end;
key = load_key(keyfile, keyform, 0, passin, e, "signing key file");
if (!key)
if (key == NULL)
goto end;
if (!PKCS7_sign_add_signer(p7, signer, key, sign_md, flags))
goto end;
@@ -543,7 +536,7 @@ int smime_main(int argc, char **argv)
}
}
if (!p7) {
if (p7 == NULL) {
BIO_printf(bio_err, "Error creating PKCS#7 structure\n");
goto end;
}
@@ -569,9 +562,9 @@ int smime_main(int argc, char **argv)
goto end;
}
sk_X509_free(signers);
} else if (operation == SMIME_PK7OUT)
} else if (operation == SMIME_PK7OUT) {
PEM_write_bio_PKCS7(out, p7);
else {
} else {
if (to)
BIO_printf(out, "To: %s%s", to, mime_eol);
if (from)
@@ -583,11 +576,11 @@ int smime_main(int argc, char **argv)
rv = SMIME_write_PKCS7(out, p7, indata, flags);
else
rv = SMIME_write_PKCS7(out, p7, in, flags);
} else if (outformat == FORMAT_PEM)
} else if (outformat == FORMAT_PEM) {
rv = PEM_write_bio_PKCS7_stream(out, p7, in, flags);
else if (outformat == FORMAT_ASN1)
} else if (outformat == FORMAT_ASN1) {
rv = i2d_PKCS7_bio_stream(out, p7, in, flags);
else {
} else {
BIO_printf(bio_err, "Bad output format for PKCS#7 file\n");
goto end;
}
@@ -599,8 +592,6 @@ int smime_main(int argc, char **argv)
}
ret = 0;
end:
if (need_rand)
app_RAND_write_file(NULL);
if (ret)
ERR_print_errors(bio_err);
sk_X509_pop_free(encerts, X509_free);
@@ -619,17 +610,18 @@ int smime_main(int argc, char **argv)
BIO_free(indata);
BIO_free_all(out);
OPENSSL_free(passin);
return (ret);
return ret;
}
static int save_certs(char *signerfile, STACK_OF(X509) *signers)
{
int i;
BIO *tmp;
if (!signerfile)
if (signerfile == NULL)
return 1;
tmp = BIO_new_file(signerfile, "w");
if (!tmp)
if (tmp == NULL)
return 0;
for (i = 0; i < sk_X509_num(signers); i++)
PEM_write_bio_X509(tmp, sk_X509_value(signers, i));
@@ -652,5 +644,4 @@ static int smime_cb(int ok, X509_STORE_CTX *ctx)
policies_print(ctx);
return ok;
}
+607 -398
View File
@@ -1,5 +1,6 @@
/*
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2002, Oracle and/or its affiliates. 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
@@ -7,23 +8,8 @@
* https://www.openssl.org/source/license.html
*/
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
*
* Portions of the attached software ("Contribution") are developed by
* SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
*
* The Contribution is licensed pursuant to the OpenSSL open source
* license provided above.
*
* The ECDH and ECDSA speed test software is originally written by
* Sumit Gupta of Sun Microsystems Laboratories.
*
*/
#undef SECONDS
#define SECONDS 3
#define PRIME_SECONDS 10
#define RSA_SECONDS 10
#define DSA_SECONDS 10
#define ECDSA_SECONDS 10
@@ -34,6 +20,7 @@
#include <string.h>
#include <math.h>
#include "apps.h"
#include "progs.h"
#include <openssl/crypto.h>
#include <openssl/rand.h>
#include <openssl/err.h>
@@ -125,13 +112,9 @@
# define NO_FORK
#endif
#undef BUFSIZE
#define BUFSIZE (1024*16+1)
#define MAX_MISALIGNMENT 63
#define ALGOR_NUM 30
#define SIZE_NUM 6
#define PRIME_NUM 3
#define ALGOR_NUM 31
#define RSA_NUM 7
#define DSA_NUM 3
@@ -139,14 +122,19 @@
#define MAX_ECDH_SIZE 256
#define MISALIGN 64
typedef struct openssl_speed_sec_st {
int sym;
int rsa;
int dsa;
int ecdsa;
int ecdh;
} openssl_speed_sec_t;
static volatile int run = 0;
static int mr = 0;
static int usertime = 1;
typedef void *(*kdf_fn) (
const void *in, size_t inlen, void *out, size_t *xoutlen);
typedef struct loopargs_st {
ASYNC_JOB *inprogress_job;
ASYNC_WAIT_CTX *wait_ctx;
@@ -154,6 +142,7 @@ typedef struct loopargs_st {
unsigned char *buf2;
unsigned char *buf_malloc;
unsigned char *buf2_malloc;
unsigned char *key;
unsigned int siglen;
#ifndef OPENSSL_NO_RSA
RSA *rsa_key[RSA_NUM];
@@ -163,12 +152,10 @@ typedef struct loopargs_st {
#endif
#ifndef OPENSSL_NO_EC
EC_KEY *ecdsa[EC_NUM];
EC_KEY *ecdh_a[EC_NUM];
EC_KEY *ecdh_b[EC_NUM];
EVP_PKEY_CTX *ecdh_ctx[EC_NUM];
unsigned char *secret_a;
unsigned char *secret_b;
size_t outlen;
kdf_fn kdf;
size_t outlen[EC_NUM];
#endif
EVP_CIPHER_CTX *ctx;
HMAC_CTX *hctx;
@@ -212,7 +199,9 @@ static int AES_cbc_256_encrypt_loop(void *args);
static int AES_ige_192_encrypt_loop(void *args);
static int AES_ige_256_encrypt_loop(void *args);
static int CRYPTO_gcm128_aad_loop(void *args);
static int RAND_bytes_loop(void *args);
static int EVP_Update_loop(void *args);
static int EVP_Update_loop_ccm(void *args);
static int EVP_Digest_loop(void *args);
#ifndef OPENSSL_NO_RSA
static int RSA_sign_loop(void *args);
@@ -225,19 +214,26 @@ static int DSA_verify_loop(void *args);
#ifndef OPENSSL_NO_EC
static int ECDSA_sign_loop(void *args);
static int ECDSA_verify_loop(void *args);
static int ECDH_compute_key_loop(void *args);
#endif
static int run_benchmark(int async_jobs, int (*loop_function)(void *), loopargs_t *loopargs);
static int run_benchmark(int async_jobs, int (*loop_function) (void *),
loopargs_t * loopargs);
static double Time_F(int s);
static void print_message(const char *s, long num, int length);
static void print_message(const char *s, long num, int length, int tm);
static void pkey_print_message(const char *str, const char *str2,
long num, int bits, int sec);
static void print_result(int alg, int run_no, int count, double time_used);
#ifndef NO_FORK
static int do_multi(int multi);
static int do_multi(int multi, int size_num);
#endif
static const int lengths_list[] = {
16, 64, 256, 1024, 8 * 1024, 16 * 1024
};
static int lengths_single = 0;
static const int *lengths = lengths_list;
static const char *names[ALGOR_NUM] = {
"md2", "mdc2", "md4", "md5", "hmac(md5)", "sha1", "rmd160", "rc4",
"des cbc", "des ede3", "idea cbc", "seed cbc",
@@ -245,14 +241,11 @@ static const char *names[ALGOR_NUM] = {
"aes-128 cbc", "aes-192 cbc", "aes-256 cbc",
"camellia-128 cbc", "camellia-192 cbc", "camellia-256 cbc",
"evp", "sha256", "sha512", "whirlpool",
"aes-128 ige", "aes-192 ige", "aes-256 ige", "ghash"
"aes-128 ige", "aes-192 ige", "aes-256 ige", "ghash",
"rand"
};
static double results[ALGOR_NUM][SIZE_NUM];
static const int lengths[SIZE_NUM] = {
16, 64, 256, 1024, 8 * 1024, 16 * 1024
};
static double results[ALGOR_NUM][OSSL_NELEM(lengths_list)];
#ifndef OPENSSL_NO_RSA
static double rsa_results[RSA_NUM][2];
@@ -265,11 +258,6 @@ static double ecdsa_results[EC_NUM][2];
static double ecdh_results[EC_NUM][1];
#endif
#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_EC)
static const char rnd_seed[] =
"string to make the random number generator think it has entropy";
#endif
#ifdef SIGALRM
# if defined(__STDC__) || defined(sgi) || defined(_AIX)
# define SIGRETTYPE void
@@ -346,7 +334,8 @@ static double Time_F(int s)
}
#endif
static void multiblock_speed(const EVP_CIPHER *evp_cipher);
static void multiblock_speed(const EVP_CIPHER *evp_cipher,
const openssl_speed_sec_t *seconds);
static int found(const char *name, const OPT_PAIR *pairs, int *result)
{
@@ -361,10 +350,11 @@ static int found(const char *name, const OPT_PAIR *pairs, int *result)
typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_ELAPSED, OPT_EVP, OPT_DECRYPT, OPT_ENGINE, OPT_MULTI,
OPT_MR, OPT_MB, OPT_MISALIGN, OPT_ASYNCJOBS
OPT_MR, OPT_MB, OPT_MISALIGN, OPT_ASYNCJOBS, OPT_R_ENUM,
OPT_PRIMES, OPT_SECONDS, OPT_BYTES
} OPTION_CHOICE;
OPTIONS speed_options[] = {
const OPTIONS speed_options[] = {
{OPT_HELP_STR, 1, '-', "Usage: %s [options] ciphers...\n"},
{OPT_HELP_STR, 1, '-', "Valid options are:\n"},
{"help", OPT_HELP, '-', "Display this summary"},
@@ -384,9 +374,15 @@ OPTIONS speed_options[] = {
{"async_jobs", OPT_ASYNCJOBS, 'p',
"Enable async mode and start pnum jobs"},
#endif
OPT_R_OPTIONS,
#ifndef OPENSSL_NO_ENGINE
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
#endif
{"primes", OPT_PRIMES, 'p', "Specify number of primes (for RSA only)"},
{"seconds", OPT_SECONDS, 'p',
"Run benchmarks for pnum seconds"},
{"bytes", OPT_BYTES, 'p',
"Run cipher, digest and rand benchmarks on pnum bytes"},
{NULL},
};
@@ -420,6 +416,7 @@ OPTIONS speed_options[] = {
#define D_IGE_192_AES 27
#define D_IGE_256_AES 28
#define D_GHASH 29
#define D_RAND 30
static OPT_PAIR doit_choices[] = {
#ifndef OPENSSL_NO_MD2
{"md2", D_MD2},
@@ -485,6 +482,7 @@ static OPT_PAIR doit_choices[] = {
{"cast5", D_CBC_CAST},
#endif
{"ghash", D_GHASH},
{"rand", D_RAND},
{NULL}
};
@@ -584,24 +582,24 @@ static OPT_PAIR ecdh_choices[] = {
#else
# define COND(unused_cond) (run && count<0x7fffffff)
# define COUNT(d) (count)
#endif /* SIGALRM */
#endif /* SIGALRM */
static int testnum;
/* Nb of iterations to do per algorithm and key-size */
static long c[ALGOR_NUM][SIZE_NUM];
static long c[ALGOR_NUM][OSSL_NELEM(lengths_list)];
#ifndef OPENSSL_NO_MD2
static int EVP_Digest_MD2_loop(void *args)
{
loopargs_t *tempargs = *(loopargs_t **)args;
loopargs_t *tempargs = *(loopargs_t **) args;
unsigned char *buf = tempargs->buf;
unsigned char md2[MD2_DIGEST_LENGTH];
int count;
for (count = 0; COND(c[D_MD2][testnum]); count++) {
if (!EVP_Digest(buf, (size_t)lengths[testnum], md2, NULL, EVP_md2(),
NULL))
NULL))
return -1;
}
return count;
@@ -611,14 +609,14 @@ static int EVP_Digest_MD2_loop(void *args)
#ifndef OPENSSL_NO_MDC2
static int EVP_Digest_MDC2_loop(void *args)
{
loopargs_t *tempargs = *(loopargs_t **)args;
loopargs_t *tempargs = *(loopargs_t **) args;
unsigned char *buf = tempargs->buf;
unsigned char mdc2[MDC2_DIGEST_LENGTH];
int count;
for (count = 0; COND(c[D_MDC2][testnum]); count++) {
if (!EVP_Digest(buf, (size_t)lengths[testnum], mdc2, NULL, EVP_mdc2(),
NULL))
NULL))
return -1;
}
return count;
@@ -628,14 +626,14 @@ static int EVP_Digest_MDC2_loop(void *args)
#ifndef OPENSSL_NO_MD4
static int EVP_Digest_MD4_loop(void *args)
{
loopargs_t *tempargs = *(loopargs_t **)args;
loopargs_t *tempargs = *(loopargs_t **) args;
unsigned char *buf = tempargs->buf;
unsigned char md4[MD4_DIGEST_LENGTH];
int count;
for (count = 0; COND(c[D_MD4][testnum]); count++) {
if (!EVP_Digest(buf, (size_t)lengths[testnum], md4, NULL, EVP_md4(),
NULL))
NULL))
return -1;
}
return count;
@@ -645,7 +643,7 @@ static int EVP_Digest_MD4_loop(void *args)
#ifndef OPENSSL_NO_MD5
static int MD5_loop(void *args)
{
loopargs_t *tempargs = *(loopargs_t **)args;
loopargs_t *tempargs = *(loopargs_t **) args;
unsigned char *buf = tempargs->buf;
unsigned char md5[MD5_DIGEST_LENGTH];
int count;
@@ -656,7 +654,7 @@ static int MD5_loop(void *args)
static int HMAC_loop(void *args)
{
loopargs_t *tempargs = *(loopargs_t **)args;
loopargs_t *tempargs = *(loopargs_t **) args;
unsigned char *buf = tempargs->buf;
HMAC_CTX *hctx = tempargs->hctx;
unsigned char hmac[MD5_DIGEST_LENGTH];
@@ -673,7 +671,7 @@ static int HMAC_loop(void *args)
static int SHA1_loop(void *args)
{
loopargs_t *tempargs = *(loopargs_t **)args;
loopargs_t *tempargs = *(loopargs_t **) args;
unsigned char *buf = tempargs->buf;
unsigned char sha[SHA_DIGEST_LENGTH];
int count;
@@ -684,7 +682,7 @@ static int SHA1_loop(void *args)
static int SHA256_loop(void *args)
{
loopargs_t *tempargs = *(loopargs_t **)args;
loopargs_t *tempargs = *(loopargs_t **) args;
unsigned char *buf = tempargs->buf;
unsigned char sha256[SHA256_DIGEST_LENGTH];
int count;
@@ -695,7 +693,7 @@ static int SHA256_loop(void *args)
static int SHA512_loop(void *args)
{
loopargs_t *tempargs = *(loopargs_t **)args;
loopargs_t *tempargs = *(loopargs_t **) args;
unsigned char *buf = tempargs->buf;
unsigned char sha512[SHA512_DIGEST_LENGTH];
int count;
@@ -707,7 +705,7 @@ static int SHA512_loop(void *args)
#ifndef OPENSSL_NO_WHIRLPOOL
static int WHIRLPOOL_loop(void *args)
{
loopargs_t *tempargs = *(loopargs_t **)args;
loopargs_t *tempargs = *(loopargs_t **) args;
unsigned char *buf = tempargs->buf;
unsigned char whirlpool[WHIRLPOOL_DIGEST_LENGTH];
int count;
@@ -720,13 +718,13 @@ static int WHIRLPOOL_loop(void *args)
#ifndef OPENSSL_NO_RMD160
static int EVP_Digest_RMD160_loop(void *args)
{
loopargs_t *tempargs = *(loopargs_t **)args;
loopargs_t *tempargs = *(loopargs_t **) args;
unsigned char *buf = tempargs->buf;
unsigned char rmd160[RIPEMD160_DIGEST_LENGTH];
int count;
for (count = 0; COND(c[D_RMD160][testnum]); count++) {
if (!EVP_Digest(buf, (size_t)lengths[testnum], &(rmd160[0]),
NULL, EVP_ripemd160(), NULL))
NULL, EVP_ripemd160(), NULL))
return -1;
}
return count;
@@ -737,7 +735,7 @@ static int EVP_Digest_RMD160_loop(void *args)
static RC4_KEY rc4_ks;
static int RC4_loop(void *args)
{
loopargs_t *tempargs = *(loopargs_t **)args;
loopargs_t *tempargs = *(loopargs_t **) args;
unsigned char *buf = tempargs->buf;
int count;
for (count = 0; COND(c[D_RC4][testnum]); count++)
@@ -753,24 +751,23 @@ static DES_key_schedule sch2;
static DES_key_schedule sch3;
static int DES_ncbc_encrypt_loop(void *args)
{
loopargs_t *tempargs = *(loopargs_t **)args;
loopargs_t *tempargs = *(loopargs_t **) args;
unsigned char *buf = tempargs->buf;
int count;
for (count = 0; COND(c[D_CBC_DES][testnum]); count++)
DES_ncbc_encrypt(buf, buf, lengths[testnum], &sch,
&DES_iv, DES_ENCRYPT);
&DES_iv, DES_ENCRYPT);
return count;
}
static int DES_ede3_cbc_encrypt_loop(void *args)
{
loopargs_t *tempargs = *(loopargs_t **)args;
loopargs_t *tempargs = *(loopargs_t **) args;
unsigned char *buf = tempargs->buf;
int count;
for (count = 0; COND(c[D_EDE3_DES][testnum]); count++)
DES_ede3_cbc_encrypt(buf, buf, lengths[testnum],
&sch, &sch2, &sch3,
&DES_iv, DES_ENCRYPT);
&sch, &sch2, &sch3, &DES_iv, DES_ENCRYPT);
return count;
}
#endif
@@ -781,82 +778,76 @@ static unsigned char iv[2 * MAX_BLOCK_SIZE / 8];
static AES_KEY aes_ks1, aes_ks2, aes_ks3;
static int AES_cbc_128_encrypt_loop(void *args)
{
loopargs_t *tempargs = *(loopargs_t **)args;
loopargs_t *tempargs = *(loopargs_t **) args;
unsigned char *buf = tempargs->buf;
int count;
for (count = 0; COND(c[D_CBC_128_AES][testnum]); count++)
AES_cbc_encrypt(buf, buf,
(size_t)lengths[testnum], &aes_ks1,
iv, AES_ENCRYPT);
(size_t)lengths[testnum], &aes_ks1, iv, AES_ENCRYPT);
return count;
}
static int AES_cbc_192_encrypt_loop(void *args)
{
loopargs_t *tempargs = *(loopargs_t **)args;
loopargs_t *tempargs = *(loopargs_t **) args;
unsigned char *buf = tempargs->buf;
int count;
for (count = 0; COND(c[D_CBC_192_AES][testnum]); count++)
AES_cbc_encrypt(buf, buf,
(size_t)lengths[testnum], &aes_ks2,
iv, AES_ENCRYPT);
(size_t)lengths[testnum], &aes_ks2, iv, AES_ENCRYPT);
return count;
}
static int AES_cbc_256_encrypt_loop(void *args)
{
loopargs_t *tempargs = *(loopargs_t **)args;
loopargs_t *tempargs = *(loopargs_t **) args;
unsigned char *buf = tempargs->buf;
int count;
for (count = 0; COND(c[D_CBC_256_AES][testnum]); count++)
AES_cbc_encrypt(buf, buf,
(size_t)lengths[testnum], &aes_ks3,
iv, AES_ENCRYPT);
(size_t)lengths[testnum], &aes_ks3, iv, AES_ENCRYPT);
return count;
}
static int AES_ige_128_encrypt_loop(void *args)
{
loopargs_t *tempargs = *(loopargs_t **)args;
loopargs_t *tempargs = *(loopargs_t **) args;
unsigned char *buf = tempargs->buf;
unsigned char *buf2 = tempargs->buf2;
int count;
for (count = 0; COND(c[D_IGE_128_AES][testnum]); count++)
AES_ige_encrypt(buf, buf2,
(size_t)lengths[testnum], &aes_ks1,
iv, AES_ENCRYPT);
(size_t)lengths[testnum], &aes_ks1, iv, AES_ENCRYPT);
return count;
}
static int AES_ige_192_encrypt_loop(void *args)
{
loopargs_t *tempargs = *(loopargs_t **)args;
loopargs_t *tempargs = *(loopargs_t **) args;
unsigned char *buf = tempargs->buf;
unsigned char *buf2 = tempargs->buf2;
int count;
for (count = 0; COND(c[D_IGE_192_AES][testnum]); count++)
AES_ige_encrypt(buf, buf2,
(size_t)lengths[testnum], &aes_ks2,
iv, AES_ENCRYPT);
(size_t)lengths[testnum], &aes_ks2, iv, AES_ENCRYPT);
return count;
}
static int AES_ige_256_encrypt_loop(void *args)
{
loopargs_t *tempargs = *(loopargs_t **)args;
loopargs_t *tempargs = *(loopargs_t **) args;
unsigned char *buf = tempargs->buf;
unsigned char *buf2 = tempargs->buf2;
int count;
for (count = 0; COND(c[D_IGE_256_AES][testnum]); count++)
AES_ige_encrypt(buf, buf2,
(size_t)lengths[testnum], &aes_ks3,
iv, AES_ENCRYPT);
(size_t)lengths[testnum], &aes_ks3, iv, AES_ENCRYPT);
return count;
}
static int CRYPTO_gcm128_aad_loop(void *args)
{
loopargs_t *tempargs = *(loopargs_t **)args;
loopargs_t *tempargs = *(loopargs_t **) args;
unsigned char *buf = tempargs->buf;
GCM128_CONTEXT *gcm_ctx = tempargs->gcm_ctx;
int count;
@@ -865,34 +856,85 @@ static int CRYPTO_gcm128_aad_loop(void *args)
return count;
}
static int RAND_bytes_loop(void *args)
{
loopargs_t *tempargs = *(loopargs_t **) args;
unsigned char *buf = tempargs->buf;
int count;
for (count = 0; COND(c[D_RAND][testnum]); count++)
RAND_bytes(buf, lengths[testnum]);
return count;
}
static long save_count = 0;
static int decrypt = 0;
static int EVP_Update_loop(void *args)
{
loopargs_t *tempargs = *(loopargs_t **)args;
loopargs_t *tempargs = *(loopargs_t **) args;
unsigned char *buf = tempargs->buf;
EVP_CIPHER_CTX *ctx = tempargs->ctx;
int outl, count;
int outl, count, rc;
#ifndef SIGALRM
int nb_iter = save_count * 4 * lengths[0] / lengths[testnum];
#endif
if (decrypt)
for (count = 0; COND(nb_iter); count++)
EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
else
for (count = 0; COND(nb_iter); count++)
EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
if (decrypt) {
for (count = 0; COND(nb_iter); count++) {
rc = EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
if (rc != 1)
EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, -1);
}
} else {
for (count = 0; COND(nb_iter); count++) {
rc = EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
if (rc != 1)
EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, -1);
}
}
if (decrypt)
EVP_DecryptFinal_ex(ctx, buf, &outl);
else
EVP_EncryptFinal_ex(ctx, buf, &outl);
return count;
}
/*
* CCM does not support streaming. For the purpose of performance measurement,
* each message is encrypted using the same (key,iv)-pair. Do not use this
* code in your application.
*/
static int EVP_Update_loop_ccm(void *args)
{
loopargs_t *tempargs = *(loopargs_t **) args;
unsigned char *buf = tempargs->buf;
EVP_CIPHER_CTX *ctx = tempargs->ctx;
int outl, count;
unsigned char tag[12];
#ifndef SIGALRM
int nb_iter = save_count * 4 * lengths[0] / lengths[testnum];
#endif
if (decrypt) {
for (count = 0; COND(nb_iter); count++) {
EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv);
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, sizeof(tag), tag);
EVP_DecryptUpdate(ctx, NULL, &outl, NULL, lengths[testnum]);
EVP_DecryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
EVP_DecryptFinal_ex(ctx, buf, &outl);
}
} else {
for (count = 0; COND(nb_iter); count++) {
EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv);
EVP_EncryptUpdate(ctx, NULL, &outl, NULL, lengths[testnum]);
EVP_EncryptUpdate(ctx, buf, &outl, buf, lengths[testnum]);
EVP_EncryptFinal_ex(ctx, buf, &outl);
}
}
return count;
}
static const EVP_MD *evp_md = NULL;
static int EVP_Digest_loop(void *args)
{
loopargs_t *tempargs = *(loopargs_t **)args;
loopargs_t *tempargs = *(loopargs_t **) args;
unsigned char *buf = tempargs->buf;
unsigned char md[EVP_MAX_MD_SIZE];
int count;
@@ -912,7 +954,7 @@ static long rsa_c[RSA_NUM][2]; /* # RSA iteration test */
static int RSA_sign_loop(void *args)
{
loopargs_t *tempargs = *(loopargs_t **)args;
loopargs_t *tempargs = *(loopargs_t **) args;
unsigned char *buf = tempargs->buf;
unsigned char *buf2 = tempargs->buf2;
unsigned int *rsa_num = &tempargs->siglen;
@@ -932,14 +974,15 @@ static int RSA_sign_loop(void *args)
static int RSA_verify_loop(void *args)
{
loopargs_t *tempargs = *(loopargs_t **)args;
loopargs_t *tempargs = *(loopargs_t **) args;
unsigned char *buf = tempargs->buf;
unsigned char *buf2 = tempargs->buf2;
unsigned int rsa_num = tempargs->siglen;
RSA **rsa_key = tempargs->rsa_key;
int ret, count;
for (count = 0; COND(rsa_c[testnum][1]); count++) {
ret = RSA_verify(NID_md5_sha1, buf, 36, buf2, rsa_num, rsa_key[testnum]);
ret =
RSA_verify(NID_md5_sha1, buf, 36, buf2, rsa_num, rsa_key[testnum]);
if (ret <= 0) {
BIO_printf(bio_err, "RSA verify failure\n");
ERR_print_errors(bio_err);
@@ -955,7 +998,7 @@ static int RSA_verify_loop(void *args)
static long dsa_c[DSA_NUM][2];
static int DSA_sign_loop(void *args)
{
loopargs_t *tempargs = *(loopargs_t **)args;
loopargs_t *tempargs = *(loopargs_t **) args;
unsigned char *buf = tempargs->buf;
unsigned char *buf2 = tempargs->buf2;
DSA **dsa_key = tempargs->dsa_key;
@@ -975,7 +1018,7 @@ static int DSA_sign_loop(void *args)
static int DSA_verify_loop(void *args)
{
loopargs_t *tempargs = *(loopargs_t **)args;
loopargs_t *tempargs = *(loopargs_t **) args;
unsigned char *buf = tempargs->buf;
unsigned char *buf2 = tempargs->buf2;
DSA **dsa_key = tempargs->dsa_key;
@@ -998,15 +1041,14 @@ static int DSA_verify_loop(void *args)
static long ecdsa_c[EC_NUM][2];
static int ECDSA_sign_loop(void *args)
{
loopargs_t *tempargs = *(loopargs_t **)args;
loopargs_t *tempargs = *(loopargs_t **) args;
unsigned char *buf = tempargs->buf;
EC_KEY **ecdsa = tempargs->ecdsa;
unsigned char *ecdsasig = tempargs->buf2;
unsigned int *ecdsasiglen = &tempargs->siglen;
int ret, count;
for (count = 0; COND(ecdsa_c[testnum][0]); count++) {
ret = ECDSA_sign(0, buf, 20,
ecdsasig, ecdsasiglen, ecdsa[testnum]);
ret = ECDSA_sign(0, buf, 20, ecdsasig, ecdsasiglen, ecdsa[testnum]);
if (ret == 0) {
BIO_printf(bio_err, "ECDSA sign failure\n");
ERR_print_errors(bio_err);
@@ -1019,15 +1061,14 @@ static int ECDSA_sign_loop(void *args)
static int ECDSA_verify_loop(void *args)
{
loopargs_t *tempargs = *(loopargs_t **)args;
loopargs_t *tempargs = *(loopargs_t **) args;
unsigned char *buf = tempargs->buf;
EC_KEY **ecdsa = tempargs->ecdsa;
unsigned char *ecdsasig = tempargs->buf2;
unsigned int ecdsasiglen = tempargs->siglen;
int ret, count;
for (count = 0; COND(ecdsa_c[testnum][1]); count++) {
ret = ECDSA_verify(0, buf, 20, ecdsasig, ecdsasiglen,
ecdsa[testnum]);
ret = ECDSA_verify(0, buf, 20, ecdsasig, ecdsasiglen, ecdsa[testnum]);
if (ret != 1) {
BIO_printf(bio_err, "ECDSA verify failure\n");
ERR_print_errors(bio_err);
@@ -1041,37 +1082,24 @@ static int ECDSA_verify_loop(void *args)
/* ******************************************************************** */
static long ecdh_c[EC_NUM][1];
static int ECDH_compute_key_loop(void *args)
static int ECDH_EVP_derive_key_loop(void *args)
{
loopargs_t *tempargs = *(loopargs_t **)args;
EC_KEY **ecdh_a = tempargs->ecdh_a;
EC_KEY **ecdh_b = tempargs->ecdh_b;
unsigned char *secret_a = tempargs->secret_a;
loopargs_t *tempargs = *(loopargs_t **) args;
EVP_PKEY_CTX *ctx = tempargs->ecdh_ctx[testnum];
unsigned char *derived_secret = tempargs->secret_a;
int count;
size_t outlen = tempargs->outlen;
kdf_fn kdf = tempargs->kdf;
size_t *outlen = &(tempargs->outlen[testnum]);
for (count = 0; COND(ecdh_c[testnum][0]); count++)
EVP_PKEY_derive(ctx, derived_secret, outlen);
for (count = 0; COND(ecdh_c[testnum][0]); count++) {
ECDH_compute_key(secret_a, outlen,
EC_KEY_get0_public_key(ecdh_b[testnum]),
ecdh_a[testnum], kdf);
}
return count;
}
static const size_t KDF1_SHA1_len = 20;
static void *KDF1_SHA1(const void *in, size_t inlen, void *out,
size_t *outlen)
{
if (*outlen < SHA_DIGEST_LENGTH)
return NULL;
*outlen = SHA_DIGEST_LENGTH;
return SHA1(in, inlen, out);
}
#endif /* OPENSSL_NO_EC */
static int run_benchmark(int async_jobs,
int (*loop_function)(void *), loopargs_t *loopargs)
int (*loop_function) (void *), loopargs_t * loopargs)
{
int job_op_count = 0;
int total_op_count = 0;
@@ -1127,14 +1155,16 @@ static int run_benchmark(int async_jobs,
if (loopargs[i].inprogress_job == NULL)
continue;
if (!ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, NULL, &num_job_fds)
|| num_job_fds > 1) {
if (!ASYNC_WAIT_CTX_get_all_fds
(loopargs[i].wait_ctx, NULL, &num_job_fds)
|| num_job_fds > 1) {
BIO_printf(bio_err, "Too many fds in ASYNC_WAIT_CTX\n");
ERR_print_errors(bio_err);
error = 1;
break;
}
ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, &job_fd, &num_job_fds);
ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, &job_fd,
&num_job_fds);
FD_SET(job_fd, &waitfdset);
if (job_fd > max_fd)
max_fd = job_fd;
@@ -1142,9 +1172,9 @@ static int run_benchmark(int async_jobs,
if (max_fd >= (OSSL_ASYNC_FD)FD_SETSIZE) {
BIO_printf(bio_err,
"Error: max_fd (%d) must be smaller than FD_SETSIZE (%d). "
"Decrease the value of async_jobs\n",
max_fd, FD_SETSIZE);
"Error: max_fd (%d) must be smaller than FD_SETSIZE (%d). "
"Decrease the value of async_jobs\n",
max_fd, FD_SETSIZE);
ERR_print_errors(bio_err);
error = 1;
break;
@@ -1169,14 +1199,16 @@ static int run_benchmark(int async_jobs,
if (loopargs[i].inprogress_job == NULL)
continue;
if (!ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, NULL, &num_job_fds)
|| num_job_fds > 1) {
if (!ASYNC_WAIT_CTX_get_all_fds
(loopargs[i].wait_ctx, NULL, &num_job_fds)
|| num_job_fds > 1) {
BIO_printf(bio_err, "Too many fds in ASYNC_WAIT_CTX\n");
ERR_print_errors(bio_err);
error = 1;
break;
}
ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, &job_fd, &num_job_fds);
ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, &job_fd,
&num_job_fds);
#if defined(OPENSSL_SYS_UNIX)
if (num_job_fds == 1 && !FD_ISSET(job_fd, &waitfdset))
@@ -1188,9 +1220,10 @@ static int run_benchmark(int async_jobs,
continue;
#endif
ret = ASYNC_start_job(&loopargs[i].inprogress_job,
loopargs[i].wait_ctx, &job_op_count, loop_function,
(void *)(loopargs + i), sizeof(loopargs_t));
ret = ASYNC_start_job(&loopargs[i].inprogress_job,
loopargs[i].wait_ctx, &job_op_count,
loop_function, (void *)(loopargs + i),
sizeof(loopargs_t));
switch (ret) {
case ASYNC_PAUSE:
break;
@@ -1221,6 +1254,7 @@ static int run_benchmark(int async_jobs,
int speed_main(int argc, char **argv)
{
ENGINE *e = NULL;
int (*loopfunc)(void *args);
loopargs_t *loopargs = NULL;
int async_init = 0;
int loopargs_len = 0;
@@ -1233,6 +1267,9 @@ int speed_main(int argc, char **argv)
int doit[ALGOR_NUM] = { 0 };
int ret = 1, i, k, misalign = 0;
long count = 0;
int size_num = OSSL_NELEM(lengths_list);
int keylen;
int buflen;
#ifndef NO_FORK
int multi = 0;
#endif
@@ -1241,7 +1278,9 @@ int speed_main(int argc, char **argv)
|| !defined(OPENSSL_NO_EC)
long rsa_count = 1;
#endif
#ifndef OPENSSL_NO_EC
size_t loop;
#endif
/* What follows are the buffers and key material. */
#ifndef OPENSSL_NO_RC5
@@ -1316,6 +1355,7 @@ int speed_main(int argc, char **argv)
sizeof(test15360)
};
int rsa_doit[RSA_NUM] = { 0 };
int primes = RSA_DEFAULT_PRIME_NUM;
#endif
#ifndef OPENSSL_NO_DSA
static const unsigned int dsa_bits[DSA_NUM] = { 512, 1024, 2048 };
@@ -1357,13 +1397,16 @@ int speed_main(int argc, char **argv)
163, 233, 283,
409, 571, 163,
233, 283, 409,
571, 253 /* X25519 */
571, 253 /* X25519 */
};
int ecdsa_doit[EC_NUM] = { 0 };
int ecdh_doit[EC_NUM] = { 0 };
#endif /* ndef OPENSSL_NO_EC */
openssl_speed_sec_t seconds = { SECONDS, RSA_SECONDS, DSA_SECONDS,
ECDSA_SECONDS, ECDH_SECONDS };
prog = opt_init(argc, argv, speed_options);
while ((o = opt_next()) != OPT_EOF) {
switch (o) {
@@ -1446,13 +1489,30 @@ int speed_main(int argc, char **argv)
goto end;
#endif
break;
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
case OPT_PRIMES:
if (!opt_int(opt_arg(), &primes))
goto end;
break;
case OPT_SECONDS:
seconds.sym = seconds.rsa = seconds.dsa = seconds.ecdsa
= seconds.ecdh = atoi(opt_arg());
break;
case OPT_BYTES:
lengths_single = atoi(opt_arg());
lengths = &lengths_single;
size_num = 1;
break;
}
}
argc = opt_num_rest();
argv = opt_rest();
/* Remaining arguments are algorithms. */
for ( ; *argv; argv++) {
for (; *argv; argv++) {
if (found(*argv, doit_choices, &i)) {
doit[i] = 1;
continue;
@@ -1494,14 +1554,12 @@ int speed_main(int argc, char **argv)
}
#endif
if (strcmp(*argv, "aes") == 0) {
doit[D_CBC_128_AES] = doit[D_CBC_192_AES] =
doit[D_CBC_256_AES] = 1;
doit[D_CBC_128_AES] = doit[D_CBC_192_AES] = doit[D_CBC_256_AES] = 1;
continue;
}
#ifndef OPENSSL_NO_CAMELLIA
if (strcmp(*argv, "camellia") == 0) {
doit[D_CBC_128_CML] = doit[D_CBC_192_CML] =
doit[D_CBC_256_CML] = 1;
doit[D_CBC_128_CML] = doit[D_CBC_192_CML] = doit[D_CBC_256_CML] = 1;
continue;
}
#endif
@@ -1539,7 +1597,8 @@ int speed_main(int argc, char **argv)
}
loopargs_len = (async_jobs == 0 ? 1 : async_jobs);
loopargs = app_malloc(loopargs_len * sizeof(loopargs_t), "array of loopargs");
loopargs =
app_malloc(loopargs_len * sizeof(loopargs_t), "array of loopargs");
memset(loopargs, 0, loopargs_len * sizeof(loopargs_t));
for (i = 0; i < loopargs_len; i++) {
@@ -1551,8 +1610,12 @@ int speed_main(int argc, char **argv)
}
}
loopargs[i].buf_malloc = app_malloc((int)BUFSIZE + MAX_MISALIGNMENT + 1, "input buffer");
loopargs[i].buf2_malloc = app_malloc((int)BUFSIZE + MAX_MISALIGNMENT + 1, "input buffer");
buflen = lengths[size_num - 1] + MAX_MISALIGNMENT + 1;
loopargs[i].buf_malloc = app_malloc(buflen, "input buffer");
loopargs[i].buf2_malloc = app_malloc(buflen, "input buffer");
memset(loopargs[i].buf_malloc, 0, buflen);
memset(loopargs[i].buf2_malloc, 0, buflen);
/* Align the start of buffers on a 64 byte boundary */
loopargs[i].buf = loopargs[i].buf_malloc + misalign;
loopargs[i].buf2 = loopargs[i].buf2_malloc + misalign;
@@ -1563,7 +1626,7 @@ int speed_main(int argc, char **argv)
}
#ifndef NO_FORK
if (multi && do_multi(multi))
if (multi && do_multi(multi, size_num))
goto show_res;
#endif
@@ -1601,14 +1664,19 @@ int speed_main(int argc, char **argv)
#ifndef OPENSSL_NO_RSA
for (i = 0; i < loopargs_len; i++) {
if (primes > RSA_DEFAULT_PRIME_NUM) {
/* for multi-prime RSA, skip this */
break;
}
for (k = 0; k < RSA_NUM; k++) {
const unsigned char *p;
p = rsa_data[k];
loopargs[i].rsa_key[k] = d2i_RSAPrivateKey(NULL, &p, rsa_data_length[k]);
loopargs[i].rsa_key[k] =
d2i_RSAPrivateKey(NULL, &p, rsa_data_length[k]);
if (loopargs[i].rsa_key[k] == NULL) {
BIO_printf(bio_err, "internal error loading RSA key number %d\n",
k);
BIO_printf(bio_err,
"internal error loading RSA key number %d\n", k);
goto end;
}
}
@@ -1616,9 +1684,9 @@ int speed_main(int argc, char **argv)
#endif
#ifndef OPENSSL_NO_DSA
for (i = 0; i < loopargs_len; i++) {
loopargs[i].dsa_key[0] = get_dsa512();
loopargs[i].dsa_key[1] = get_dsa1024();
loopargs[i].dsa_key[2] = get_dsa2048();
loopargs[i].dsa_key[0] = get_dsa(512);
loopargs[i].dsa_key[1] = get_dsa(1024);
loopargs[i].dsa_key[2] = get_dsa(2048);
}
#endif
#ifndef OPENSSL_NO_DES
@@ -1698,8 +1766,9 @@ int speed_main(int argc, char **argv)
c[D_IGE_192_AES][0] = count;
c[D_IGE_256_AES][0] = count;
c[D_GHASH][0] = count;
c[D_RAND][0] = count;
for (i = 1; i < SIZE_NUM; i++) {
for (i = 1; i < size_num; i++) {
long l0, l1;
l0 = (long)lengths[0];
@@ -1716,6 +1785,7 @@ int speed_main(int argc, char **argv)
c[D_SHA512][i] = c[D_SHA512][0] * 4 * l0 / l1;
c[D_WHIRLPOOL][i] = c[D_WHIRLPOOL][0] * 4 * l0 / l1;
c[D_GHASH][i] = c[D_GHASH][0] * 4 * l0 / l1;
c[D_RAND][i] = c[D_RAND][0] * 4 * l0 / l1;
l0 = (long)lengths[i - 1];
@@ -1749,7 +1819,7 @@ int speed_main(int argc, char **argv)
rsa_doit[i] = 0;
else {
if (rsa_c[i][0] == 0) {
rsa_c[i][0] = 1; /* Set minimum iteration Nb to 1. */
rsa_c[i][0] = 1; /* Set minimum iteration Nb to 1. */
rsa_c[i][1] = 20;
}
}
@@ -1766,7 +1836,7 @@ int speed_main(int argc, char **argv)
dsa_doit[i] = 0;
else {
if (dsa_c[i][0] == 0) {
dsa_c[i][0] = 1; /* Set minimum iteration Nb to 1. */
dsa_c[i][0] = 1; /* Set minimum iteration Nb to 1. */
dsa_c[i][1] = 1;
}
}
@@ -1855,17 +1925,18 @@ int speed_main(int argc, char **argv)
# else
/* not worth fixing */
# error "You cannot disable DES on systems without SIGALRM."
# endif /* OPENSSL_NO_DES */
# endif /* OPENSSL_NO_DES */
#else
# ifndef _WIN32
signal(SIGALRM, sig_done);
# endif
#endif /* SIGALRM */
#endif /* SIGALRM */
#ifndef OPENSSL_NO_MD2
if (doit[D_MD2]) {
for (testnum = 0; testnum < SIZE_NUM; testnum++) {
print_message(names[D_MD2], c[D_MD2][testnum], lengths[testnum]);
for (testnum = 0; testnum < size_num; testnum++) {
print_message(names[D_MD2], c[D_MD2][testnum], lengths[testnum],
seconds.sym);
Time_F(START);
count = run_benchmark(async_jobs, EVP_Digest_MD2_loop, loopargs);
d = Time_F(STOP);
@@ -1875,8 +1946,9 @@ int speed_main(int argc, char **argv)
#endif
#ifndef OPENSSL_NO_MDC2
if (doit[D_MDC2]) {
for (testnum = 0; testnum < SIZE_NUM; testnum++) {
print_message(names[D_MDC2], c[D_MDC2][testnum], lengths[testnum]);
for (testnum = 0; testnum < size_num; testnum++) {
print_message(names[D_MDC2], c[D_MDC2][testnum], lengths[testnum],
seconds.sym);
Time_F(START);
count = run_benchmark(async_jobs, EVP_Digest_MDC2_loop, loopargs);
d = Time_F(STOP);
@@ -1887,8 +1959,9 @@ int speed_main(int argc, char **argv)
#ifndef OPENSSL_NO_MD4
if (doit[D_MD4]) {
for (testnum = 0; testnum < SIZE_NUM; testnum++) {
print_message(names[D_MD4], c[D_MD4][testnum], lengths[testnum]);
for (testnum = 0; testnum < size_num; testnum++) {
print_message(names[D_MD4], c[D_MD4][testnum], lengths[testnum],
seconds.sym);
Time_F(START);
count = run_benchmark(async_jobs, EVP_Digest_MD4_loop, loopargs);
d = Time_F(STOP);
@@ -1899,8 +1972,9 @@ int speed_main(int argc, char **argv)
#ifndef OPENSSL_NO_MD5
if (doit[D_MD5]) {
for (testnum = 0; testnum < SIZE_NUM; testnum++) {
print_message(names[D_MD5], c[D_MD5][testnum], lengths[testnum]);
for (testnum = 0; testnum < size_num; testnum++) {
print_message(names[D_MD5], c[D_MD5][testnum], lengths[testnum],
seconds.sym);
Time_F(START);
count = run_benchmark(async_jobs, MD5_loop, loopargs);
d = Time_F(STOP);
@@ -1921,8 +1995,9 @@ int speed_main(int argc, char **argv)
HMAC_Init_ex(loopargs[i].hctx, hmac_key, len, EVP_md5(), NULL);
}
for (testnum = 0; testnum < SIZE_NUM; testnum++) {
print_message(names[D_HMAC], c[D_HMAC][testnum], lengths[testnum]);
for (testnum = 0; testnum < size_num; testnum++) {
print_message(names[D_HMAC], c[D_HMAC][testnum], lengths[testnum],
seconds.sym);
Time_F(START);
count = run_benchmark(async_jobs, HMAC_loop, loopargs);
d = Time_F(STOP);
@@ -1934,8 +2009,9 @@ int speed_main(int argc, char **argv)
}
#endif
if (doit[D_SHA1]) {
for (testnum = 0; testnum < SIZE_NUM; testnum++) {
print_message(names[D_SHA1], c[D_SHA1][testnum], lengths[testnum]);
for (testnum = 0; testnum < size_num; testnum++) {
print_message(names[D_SHA1], c[D_SHA1][testnum], lengths[testnum],
seconds.sym);
Time_F(START);
count = run_benchmark(async_jobs, SHA1_loop, loopargs);
d = Time_F(STOP);
@@ -1943,8 +2019,9 @@ int speed_main(int argc, char **argv)
}
}
if (doit[D_SHA256]) {
for (testnum = 0; testnum < SIZE_NUM; testnum++) {
print_message(names[D_SHA256], c[D_SHA256][testnum], lengths[testnum]);
for (testnum = 0; testnum < size_num; testnum++) {
print_message(names[D_SHA256], c[D_SHA256][testnum],
lengths[testnum], seconds.sym);
Time_F(START);
count = run_benchmark(async_jobs, SHA256_loop, loopargs);
d = Time_F(STOP);
@@ -1952,19 +2029,20 @@ int speed_main(int argc, char **argv)
}
}
if (doit[D_SHA512]) {
for (testnum = 0; testnum < SIZE_NUM; testnum++) {
print_message(names[D_SHA512], c[D_SHA512][testnum], lengths[testnum]);
for (testnum = 0; testnum < size_num; testnum++) {
print_message(names[D_SHA512], c[D_SHA512][testnum],
lengths[testnum], seconds.sym);
Time_F(START);
count = run_benchmark(async_jobs, SHA512_loop, loopargs);
d = Time_F(STOP);
print_result(D_SHA512, testnum, count, d);
}
}
#ifndef OPENSSL_NO_WHIRLPOOL
if (doit[D_WHIRLPOOL]) {
for (testnum = 0; testnum < SIZE_NUM; testnum++) {
print_message(names[D_WHIRLPOOL], c[D_WHIRLPOOL][testnum], lengths[testnum]);
for (testnum = 0; testnum < size_num; testnum++) {
print_message(names[D_WHIRLPOOL], c[D_WHIRLPOOL][testnum],
lengths[testnum], seconds.sym);
Time_F(START);
count = run_benchmark(async_jobs, WHIRLPOOL_loop, loopargs);
d = Time_F(STOP);
@@ -1975,8 +2053,9 @@ int speed_main(int argc, char **argv)
#ifndef OPENSSL_NO_RMD160
if (doit[D_RMD160]) {
for (testnum = 0; testnum < SIZE_NUM; testnum++) {
print_message(names[D_RMD160], c[D_RMD160][testnum], lengths[testnum]);
for (testnum = 0; testnum < size_num; testnum++) {
print_message(names[D_RMD160], c[D_RMD160][testnum],
lengths[testnum], seconds.sym);
Time_F(START);
count = run_benchmark(async_jobs, EVP_Digest_RMD160_loop, loopargs);
d = Time_F(STOP);
@@ -1986,8 +2065,9 @@ int speed_main(int argc, char **argv)
#endif
#ifndef OPENSSL_NO_RC4
if (doit[D_RC4]) {
for (testnum = 0; testnum < SIZE_NUM; testnum++) {
print_message(names[D_RC4], c[D_RC4][testnum], lengths[testnum]);
for (testnum = 0; testnum < size_num; testnum++) {
print_message(names[D_RC4], c[D_RC4][testnum], lengths[testnum],
seconds.sym);
Time_F(START);
count = run_benchmark(async_jobs, RC4_loop, loopargs);
d = Time_F(STOP);
@@ -1997,8 +2077,9 @@ int speed_main(int argc, char **argv)
#endif
#ifndef OPENSSL_NO_DES
if (doit[D_CBC_DES]) {
for (testnum = 0; testnum < SIZE_NUM; testnum++) {
print_message(names[D_CBC_DES], c[D_CBC_DES][testnum], lengths[testnum]);
for (testnum = 0; testnum < size_num; testnum++) {
print_message(names[D_CBC_DES], c[D_CBC_DES][testnum],
lengths[testnum], seconds.sym);
Time_F(START);
count = run_benchmark(async_jobs, DES_ncbc_encrypt_loop, loopargs);
d = Time_F(STOP);
@@ -2007,10 +2088,12 @@ int speed_main(int argc, char **argv)
}
if (doit[D_EDE3_DES]) {
for (testnum = 0; testnum < SIZE_NUM; testnum++) {
print_message(names[D_EDE3_DES], c[D_EDE3_DES][testnum], lengths[testnum]);
for (testnum = 0; testnum < size_num; testnum++) {
print_message(names[D_EDE3_DES], c[D_EDE3_DES][testnum],
lengths[testnum], seconds.sym);
Time_F(START);
count = run_benchmark(async_jobs, DES_ede3_cbc_encrypt_loop, loopargs);
count =
run_benchmark(async_jobs, DES_ede3_cbc_encrypt_loop, loopargs);
d = Time_F(STOP);
print_result(D_EDE3_DES, testnum, count, d);
}
@@ -2018,74 +2101,83 @@ int speed_main(int argc, char **argv)
#endif
if (doit[D_CBC_128_AES]) {
for (testnum = 0; testnum < SIZE_NUM; testnum++) {
for (testnum = 0; testnum < size_num; testnum++) {
print_message(names[D_CBC_128_AES], c[D_CBC_128_AES][testnum],
lengths[testnum]);
lengths[testnum], seconds.sym);
Time_F(START);
count = run_benchmark(async_jobs, AES_cbc_128_encrypt_loop, loopargs);
count =
run_benchmark(async_jobs, AES_cbc_128_encrypt_loop, loopargs);
d = Time_F(STOP);
print_result(D_CBC_128_AES, testnum, count, d);
}
}
if (doit[D_CBC_192_AES]) {
for (testnum = 0; testnum < SIZE_NUM; testnum++) {
for (testnum = 0; testnum < size_num; testnum++) {
print_message(names[D_CBC_192_AES], c[D_CBC_192_AES][testnum],
lengths[testnum]);
lengths[testnum], seconds.sym);
Time_F(START);
count = run_benchmark(async_jobs, AES_cbc_192_encrypt_loop, loopargs);
count =
run_benchmark(async_jobs, AES_cbc_192_encrypt_loop, loopargs);
d = Time_F(STOP);
print_result(D_CBC_192_AES, testnum, count, d);
}
}
if (doit[D_CBC_256_AES]) {
for (testnum = 0; testnum < SIZE_NUM; testnum++) {
for (testnum = 0; testnum < size_num; testnum++) {
print_message(names[D_CBC_256_AES], c[D_CBC_256_AES][testnum],
lengths[testnum]);
lengths[testnum], seconds.sym);
Time_F(START);
count = run_benchmark(async_jobs, AES_cbc_256_encrypt_loop, loopargs);
count =
run_benchmark(async_jobs, AES_cbc_256_encrypt_loop, loopargs);
d = Time_F(STOP);
print_result(D_CBC_256_AES, testnum, count, d);
}
}
if (doit[D_IGE_128_AES]) {
for (testnum = 0; testnum < SIZE_NUM; testnum++) {
for (testnum = 0; testnum < size_num; testnum++) {
print_message(names[D_IGE_128_AES], c[D_IGE_128_AES][testnum],
lengths[testnum]);
lengths[testnum], seconds.sym);
Time_F(START);
count = run_benchmark(async_jobs, AES_ige_128_encrypt_loop, loopargs);
count =
run_benchmark(async_jobs, AES_ige_128_encrypt_loop, loopargs);
d = Time_F(STOP);
print_result(D_IGE_128_AES, testnum, count, d);
}
}
if (doit[D_IGE_192_AES]) {
for (testnum = 0; testnum < SIZE_NUM; testnum++) {
for (testnum = 0; testnum < size_num; testnum++) {
print_message(names[D_IGE_192_AES], c[D_IGE_192_AES][testnum],
lengths[testnum]);
lengths[testnum], seconds.sym);
Time_F(START);
count = run_benchmark(async_jobs, AES_ige_192_encrypt_loop, loopargs);
count =
run_benchmark(async_jobs, AES_ige_192_encrypt_loop, loopargs);
d = Time_F(STOP);
print_result(D_IGE_192_AES, testnum, count, d);
}
}
if (doit[D_IGE_256_AES]) {
for (testnum = 0; testnum < SIZE_NUM; testnum++) {
for (testnum = 0; testnum < size_num; testnum++) {
print_message(names[D_IGE_256_AES], c[D_IGE_256_AES][testnum],
lengths[testnum]);
lengths[testnum], seconds.sym);
Time_F(START);
count = run_benchmark(async_jobs, AES_ige_256_encrypt_loop, loopargs);
count =
run_benchmark(async_jobs, AES_ige_256_encrypt_loop, loopargs);
d = Time_F(STOP);
print_result(D_IGE_256_AES, testnum, count, d);
}
}
if (doit[D_GHASH]) {
for (i = 0; i < loopargs_len; i++) {
loopargs[i].gcm_ctx = CRYPTO_gcm128_new(&aes_ks1, (block128_f) AES_encrypt);
CRYPTO_gcm128_setiv(loopargs[i].gcm_ctx, (unsigned char *)"0123456789ab", 12);
loopargs[i].gcm_ctx =
CRYPTO_gcm128_new(&aes_ks1, (block128_f) AES_encrypt);
CRYPTO_gcm128_setiv(loopargs[i].gcm_ctx,
(unsigned char *)"0123456789ab", 12);
}
for (testnum = 0; testnum < SIZE_NUM; testnum++) {
print_message(names[D_GHASH], c[D_GHASH][testnum], lengths[testnum]);
for (testnum = 0; testnum < size_num; testnum++) {
print_message(names[D_GHASH], c[D_GHASH][testnum],
lengths[testnum], seconds.sym);
Time_F(START);
count = run_benchmark(async_jobs, CRYPTO_gcm128_aad_loop, loopargs);
d = Time_F(STOP);
@@ -2094,7 +2186,6 @@ int speed_main(int argc, char **argv)
for (i = 0; i < loopargs_len; i++)
CRYPTO_gcm128_release(loopargs[i].gcm_ctx);
}
#ifndef OPENSSL_NO_CAMELLIA
if (doit[D_CBC_128_CML]) {
if (async_jobs > 0) {
@@ -2102,9 +2193,9 @@ int speed_main(int argc, char **argv)
names[D_CBC_128_CML]);
doit[D_CBC_128_CML] = 0;
}
for (testnum = 0; testnum < SIZE_NUM && async_init == 0; testnum++) {
for (testnum = 0; testnum < size_num && async_init == 0; testnum++) {
print_message(names[D_CBC_128_CML], c[D_CBC_128_CML][testnum],
lengths[testnum]);
lengths[testnum], seconds.sym);
Time_F(START);
for (count = 0, run = 1; COND(c[D_CBC_128_CML][testnum]); count++)
Camellia_cbc_encrypt(loopargs[0].buf, loopargs[0].buf,
@@ -2120,9 +2211,9 @@ int speed_main(int argc, char **argv)
names[D_CBC_192_CML]);
doit[D_CBC_192_CML] = 0;
}
for (testnum = 0; testnum < SIZE_NUM && async_init == 0; testnum++) {
for (testnum = 0; testnum < size_num && async_init == 0; testnum++) {
print_message(names[D_CBC_192_CML], c[D_CBC_192_CML][testnum],
lengths[testnum]);
lengths[testnum], seconds.sym);
if (async_jobs > 0) {
BIO_printf(bio_err, "Async mode is not supported, exiting...");
exit(1);
@@ -2142,9 +2233,9 @@ int speed_main(int argc, char **argv)
names[D_CBC_256_CML]);
doit[D_CBC_256_CML] = 0;
}
for (testnum = 0; testnum < SIZE_NUM && async_init == 0; testnum++) {
for (testnum = 0; testnum < size_num && async_init == 0; testnum++) {
print_message(names[D_CBC_256_CML], c[D_CBC_256_CML][testnum],
lengths[testnum]);
lengths[testnum], seconds.sym);
Time_F(START);
for (count = 0, run = 1; COND(c[D_CBC_256_CML][testnum]); count++)
Camellia_cbc_encrypt(loopargs[0].buf, loopargs[0].buf,
@@ -2162,8 +2253,9 @@ int speed_main(int argc, char **argv)
names[D_CBC_IDEA]);
doit[D_CBC_IDEA] = 0;
}
for (testnum = 0; testnum < SIZE_NUM && async_init == 0; testnum++) {
print_message(names[D_CBC_IDEA], c[D_CBC_IDEA][testnum], lengths[testnum]);
for (testnum = 0; testnum < size_num && async_init == 0; testnum++) {
print_message(names[D_CBC_IDEA], c[D_CBC_IDEA][testnum],
lengths[testnum], seconds.sym);
Time_F(START);
for (count = 0, run = 1; COND(c[D_CBC_IDEA][testnum]); count++)
IDEA_cbc_encrypt(loopargs[0].buf, loopargs[0].buf,
@@ -2181,8 +2273,9 @@ int speed_main(int argc, char **argv)
names[D_CBC_SEED]);
doit[D_CBC_SEED] = 0;
}
for (testnum = 0; testnum < SIZE_NUM && async_init == 0; testnum++) {
print_message(names[D_CBC_SEED], c[D_CBC_SEED][testnum], lengths[testnum]);
for (testnum = 0; testnum < size_num && async_init == 0; testnum++) {
print_message(names[D_CBC_SEED], c[D_CBC_SEED][testnum],
lengths[testnum], seconds.sym);
Time_F(START);
for (count = 0, run = 1; COND(c[D_CBC_SEED][testnum]); count++)
SEED_cbc_encrypt(loopargs[0].buf, loopargs[0].buf,
@@ -2199,8 +2292,9 @@ int speed_main(int argc, char **argv)
names[D_CBC_RC2]);
doit[D_CBC_RC2] = 0;
}
for (testnum = 0; testnum < SIZE_NUM && async_init == 0; testnum++) {
print_message(names[D_CBC_RC2], c[D_CBC_RC2][testnum], lengths[testnum]);
for (testnum = 0; testnum < size_num && async_init == 0; testnum++) {
print_message(names[D_CBC_RC2], c[D_CBC_RC2][testnum],
lengths[testnum], seconds.sym);
if (async_jobs > 0) {
BIO_printf(bio_err, "Async mode is not supported, exiting...");
exit(1);
@@ -2222,8 +2316,9 @@ int speed_main(int argc, char **argv)
names[D_CBC_RC5]);
doit[D_CBC_RC5] = 0;
}
for (testnum = 0; testnum < SIZE_NUM && async_init == 0; testnum++) {
print_message(names[D_CBC_RC5], c[D_CBC_RC5][testnum], lengths[testnum]);
for (testnum = 0; testnum < size_num && async_init == 0; testnum++) {
print_message(names[D_CBC_RC5], c[D_CBC_RC5][testnum],
lengths[testnum], seconds.sym);
if (async_jobs > 0) {
BIO_printf(bio_err, "Async mode is not supported, exiting...");
exit(1);
@@ -2245,8 +2340,9 @@ int speed_main(int argc, char **argv)
names[D_CBC_BF]);
doit[D_CBC_BF] = 0;
}
for (testnum = 0; testnum < SIZE_NUM && async_init == 0; testnum++) {
print_message(names[D_CBC_BF], c[D_CBC_BF][testnum], lengths[testnum]);
for (testnum = 0; testnum < size_num && async_init == 0; testnum++) {
print_message(names[D_CBC_BF], c[D_CBC_BF][testnum],
lengths[testnum], seconds.sym);
Time_F(START);
for (count = 0, run = 1; COND(c[D_CBC_BF][testnum]); count++)
BF_cbc_encrypt(loopargs[0].buf, loopargs[0].buf,
@@ -2264,8 +2360,9 @@ int speed_main(int argc, char **argv)
names[D_CBC_CAST]);
doit[D_CBC_CAST] = 0;
}
for (testnum = 0; testnum < SIZE_NUM && async_init == 0; testnum++) {
print_message(names[D_CBC_CAST], c[D_CBC_CAST][testnum], lengths[testnum]);
for (testnum = 0; testnum < size_num && async_init == 0; testnum++) {
print_message(names[D_CBC_CAST], c[D_CBC_CAST][testnum],
lengths[testnum], seconds.sym);
Time_F(START);
for (count = 0, run = 1; COND(c[D_CBC_CAST][testnum]); count++)
CAST_cbc_encrypt(loopargs[0].buf, loopargs[0].buf,
@@ -2276,6 +2373,16 @@ int speed_main(int argc, char **argv)
}
}
#endif
if (doit[D_RAND]) {
for (testnum = 0; testnum < size_num; testnum++) {
print_message(names[D_RAND], c[D_RAND][testnum], lengths[testnum],
seconds.sym);
Time_F(START);
count = run_benchmark(async_jobs, RAND_bytes_loop, loopargs);
d = Time_F(STOP);
print_result(D_RAND, testnum, count, d);
}
}
if (doit[D_EVP]) {
if (multiblock && evp_cipher) {
@@ -2290,11 +2397,11 @@ int speed_main(int argc, char **argv)
BIO_printf(bio_err, "Async mode is not supported, exiting...");
exit(1);
}
multiblock_speed(evp_cipher);
multiblock_speed(evp_cipher, &seconds);
ret = 0;
goto end;
}
for (testnum = 0; testnum < SIZE_NUM; testnum++) {
for (testnum = 0; testnum < size_num; testnum++) {
if (evp_cipher) {
names[D_EVP] = OBJ_nid2ln(EVP_CIPHER_nid(evp_cipher));
@@ -2302,19 +2409,33 @@ int speed_main(int argc, char **argv)
* -O3 -fschedule-insns messes up an optimization here!
* names[D_EVP] somehow becomes NULL
*/
print_message(names[D_EVP], save_count, lengths[testnum]);
print_message(names[D_EVP], save_count, lengths[testnum],
seconds.sym);
for (k = 0; k < loopargs_len; k++) {
loopargs[k].ctx = EVP_CIPHER_CTX_new();
if (decrypt)
EVP_DecryptInit_ex(loopargs[k].ctx, evp_cipher, NULL, key16, iv);
else
EVP_EncryptInit_ex(loopargs[k].ctx, evp_cipher, NULL, key16, iv);
EVP_CipherInit_ex(loopargs[k].ctx, evp_cipher, NULL, NULL,
iv, decrypt ? 0 : 1);
EVP_CIPHER_CTX_set_padding(loopargs[k].ctx, 0);
keylen = EVP_CIPHER_CTX_key_length(loopargs[k].ctx);
loopargs[k].key = app_malloc(keylen, "evp_cipher key");
EVP_CIPHER_CTX_rand_key(loopargs[k].ctx, loopargs[k].key);
EVP_CipherInit_ex(loopargs[k].ctx, NULL, NULL,
loopargs[k].key, NULL, -1);
OPENSSL_clear_free(loopargs[k].key, keylen);
}
switch (EVP_CIPHER_mode(evp_cipher)) {
case EVP_CIPH_CCM_MODE:
loopfunc = EVP_Update_loop_ccm;
break;
default:
loopfunc = EVP_Update_loop;
}
Time_F(START);
count = run_benchmark(async_jobs, EVP_Update_loop, loopargs);
count = run_benchmark(async_jobs, loopfunc, loopargs);
d = Time_F(STOP);
for (k = 0; k < loopargs_len; k++) {
EVP_CIPHER_CTX_free(loopargs[k].ctx);
@@ -2322,7 +2443,8 @@ int speed_main(int argc, char **argv)
}
if (evp_md) {
names[D_EVP] = OBJ_nid2ln(EVP_MD_type(evp_md));
print_message(names[D_EVP], save_count, lengths[testnum]);
print_message(names[D_EVP], save_count, lengths[testnum],
seconds.sym);
Time_F(START);
count = run_benchmark(async_jobs, EVP_Digest_loop, loopargs);
d = Time_F(STOP);
@@ -2340,6 +2462,34 @@ int speed_main(int argc, char **argv)
if (!rsa_doit[testnum])
continue;
for (i = 0; i < loopargs_len; i++) {
if (primes > 2) {
/* we haven't set keys yet, generate multi-prime RSA keys */
BIGNUM *bn = BN_new();
if (bn == NULL)
goto end;
if (!BN_set_word(bn, RSA_F4)) {
BN_free(bn);
goto end;
}
BIO_printf(bio_err, "Generate multi-prime RSA key for %s\n",
rsa_choices[testnum].name);
loopargs[i].rsa_key[testnum] = RSA_new();
if (loopargs[i].rsa_key[testnum] == NULL) {
BN_free(bn);
goto end;
}
if (!RSA_generate_multi_prime_key(loopargs[i].rsa_key[testnum],
rsa_bits[testnum],
primes, bn, NULL)) {
BN_free(bn);
goto end;
}
BN_free(bn);
}
st = RSA_sign(NID_md5_sha1, loopargs[i].buf, 36, loopargs[i].buf2,
&loopargs[i].siglen, loopargs[i].rsa_key[testnum]);
if (st == 0)
@@ -2352,7 +2502,8 @@ int speed_main(int argc, char **argv)
rsa_count = 1;
} else {
pkey_print_message("private", "rsa",
rsa_c[testnum][0], rsa_bits[testnum], RSA_SECONDS);
rsa_c[testnum][0], rsa_bits[testnum],
seconds.rsa);
/* RSA_blinding_on(rsa_key[testnum],NULL); */
Time_F(START);
count = run_benchmark(async_jobs, RSA_sign_loop, loopargs);
@@ -2361,7 +2512,7 @@ int speed_main(int argc, char **argv)
mr ? "+R1:%ld:%d:%.2f\n"
: "%ld %d bit private RSA's in %.2fs\n",
count, rsa_bits[testnum], d);
rsa_results[testnum][0] = d / (double)count;
rsa_results[testnum][0] = (double)count / d;
rsa_count = count;
}
@@ -2378,7 +2529,8 @@ int speed_main(int argc, char **argv)
rsa_doit[testnum] = 0;
} else {
pkey_print_message("public", "rsa",
rsa_c[testnum][1], rsa_bits[testnum], RSA_SECONDS);
rsa_c[testnum][1], rsa_bits[testnum],
seconds.rsa);
Time_F(START);
count = run_benchmark(async_jobs, RSA_verify_loop, loopargs);
d = Time_F(STOP);
@@ -2386,7 +2538,7 @@ int speed_main(int argc, char **argv)
mr ? "+R2:%ld:%d:%.2f\n"
: "%ld %d bit public RSA's in %.2fs\n",
count, rsa_bits[testnum], d);
rsa_results[testnum][1] = d / (double)count;
rsa_results[testnum][1] = (double)count / d;
}
if (rsa_count <= 1) {
@@ -2401,9 +2553,6 @@ int speed_main(int argc, char **argv)
RAND_bytes(loopargs[i].buf, 36);
#ifndef OPENSSL_NO_DSA
if (RAND_status() != 1) {
RAND_seed(rnd_seed, sizeof(rnd_seed));
}
for (testnum = 0; testnum < DSA_NUM; testnum++) {
int st = 0;
if (!dsa_doit[testnum])
@@ -2424,7 +2573,8 @@ int speed_main(int argc, char **argv)
rsa_count = 1;
} else {
pkey_print_message("sign", "dsa",
dsa_c[testnum][0], dsa_bits[testnum], DSA_SECONDS);
dsa_c[testnum][0], dsa_bits[testnum],
seconds.dsa);
Time_F(START);
count = run_benchmark(async_jobs, DSA_sign_loop, loopargs);
d = Time_F(STOP);
@@ -2432,7 +2582,7 @@ int speed_main(int argc, char **argv)
mr ? "+R3:%ld:%d:%.2f\n"
: "%ld %d bit DSA signs in %.2fs\n",
count, dsa_bits[testnum], d);
dsa_results[testnum][0] = d / (double)count;
dsa_results[testnum][0] = (double)count / d;
rsa_count = count;
}
@@ -2449,7 +2599,8 @@ int speed_main(int argc, char **argv)
dsa_doit[testnum] = 0;
} else {
pkey_print_message("verify", "dsa",
dsa_c[testnum][1], dsa_bits[testnum], DSA_SECONDS);
dsa_c[testnum][1], dsa_bits[testnum],
seconds.dsa);
Time_F(START);
count = run_benchmark(async_jobs, DSA_verify_loop, loopargs);
d = Time_F(STOP);
@@ -2457,7 +2608,7 @@ int speed_main(int argc, char **argv)
mr ? "+R4:%ld:%d:%.2f\n"
: "%ld %d bit DSA verify in %.2fs\n",
count, dsa_bits[testnum], d);
dsa_results[testnum][1] = d / (double)count;
dsa_results[testnum][1] = (double)count / d;
}
if (rsa_count <= 1) {
@@ -2469,16 +2620,14 @@ int speed_main(int argc, char **argv)
#endif /* OPENSSL_NO_DSA */
#ifndef OPENSSL_NO_EC
if (RAND_status() != 1) {
RAND_seed(rnd_seed, sizeof(rnd_seed));
}
for (testnum = 0; testnum < EC_NUM; testnum++) {
int st = 1;
if (!ecdsa_doit[testnum])
continue; /* Ignore Curve */
for (i = 0; i < loopargs_len; i++) {
loopargs[i].ecdsa[testnum] = EC_KEY_new_by_curve_name(test_curves[testnum]);
loopargs[i].ecdsa[testnum] =
EC_KEY_new_by_curve_name(test_curves[testnum]);
if (loopargs[i].ecdsa[testnum] == NULL) {
st = 0;
break;
@@ -2494,7 +2643,8 @@ int speed_main(int argc, char **argv)
/* Perform ECDSA signature test */
EC_KEY_generate_key(loopargs[i].ecdsa[testnum]);
st = ECDSA_sign(0, loopargs[i].buf, 20, loopargs[i].buf2,
&loopargs[i].siglen, loopargs[i].ecdsa[testnum]);
&loopargs[i].siglen,
loopargs[i].ecdsa[testnum]);
if (st == 0)
break;
}
@@ -2506,7 +2656,8 @@ int speed_main(int argc, char **argv)
} else {
pkey_print_message("sign", "ecdsa",
ecdsa_c[testnum][0],
test_curves_bits[testnum], ECDSA_SECONDS);
test_curves_bits[testnum],
seconds.ecdsa);
Time_F(START);
count = run_benchmark(async_jobs, ECDSA_sign_loop, loopargs);
d = Time_F(STOP);
@@ -2515,14 +2666,15 @@ int speed_main(int argc, char **argv)
mr ? "+R5:%ld:%d:%.2f\n" :
"%ld %d bit ECDSA signs in %.2fs \n",
count, test_curves_bits[testnum], d);
ecdsa_results[testnum][0] = d / (double)count;
ecdsa_results[testnum][0] = (double)count / d;
rsa_count = count;
}
/* Perform ECDSA verification test */
for (i = 0; i < loopargs_len; i++) {
st = ECDSA_verify(0, loopargs[i].buf, 20, loopargs[i].buf2,
loopargs[i].siglen, loopargs[i].ecdsa[testnum]);
loopargs[i].siglen,
loopargs[i].ecdsa[testnum]);
if (st != 1)
break;
}
@@ -2534,7 +2686,8 @@ int speed_main(int argc, char **argv)
} else {
pkey_print_message("verify", "ecdsa",
ecdsa_c[testnum][1],
test_curves_bits[testnum], ECDSA_SECONDS);
test_curves_bits[testnum],
seconds.ecdsa);
Time_F(START);
count = run_benchmark(async_jobs, ECDSA_verify_loop, loopargs);
d = Time_F(STOP);
@@ -2542,7 +2695,7 @@ int speed_main(int argc, char **argv)
mr ? "+R6:%ld:%d:%.2f\n"
: "%ld %d bit ECDSA verify in %.2fs\n",
count, test_curves_bits[testnum], d);
ecdsa_results[testnum][1] = d / (double)count;
ecdsa_results[testnum][1] = (double)count / d;
}
if (rsa_count <= 1) {
@@ -2553,93 +2706,159 @@ int speed_main(int argc, char **argv)
}
}
if (RAND_status() != 1) {
RAND_seed(rnd_seed, sizeof(rnd_seed));
}
for (testnum = 0; testnum < EC_NUM; testnum++) {
int ecdh_checks = 1;
if (!ecdh_doit[testnum])
continue;
for (i = 0; i < loopargs_len; i++) {
loopargs[i].ecdh_a[testnum] = EC_KEY_new_by_curve_name(test_curves[testnum]);
loopargs[i].ecdh_b[testnum] = EC_KEY_new_by_curve_name(test_curves[testnum]);
if (loopargs[i].ecdh_a[testnum] == NULL ||
loopargs[i].ecdh_b[testnum] == NULL) {
EVP_PKEY_CTX *kctx = NULL;
EVP_PKEY_CTX *test_ctx = NULL;
EVP_PKEY_CTX *ctx = NULL;
EVP_PKEY *key_A = NULL;
EVP_PKEY *key_B = NULL;
size_t outlen;
size_t test_outlen;
/* Ensure that the error queue is empty */
if (ERR_peek_error()) {
BIO_printf(bio_err,
"WARNING: the error queue contains previous unhandled errors.\n");
ERR_print_errors(bio_err);
}
/* Let's try to create a ctx directly from the NID: this works for
* curves like Curve25519 that are not implemented through the low
* level EC interface.
* If this fails we try creating a EVP_PKEY_EC generic param ctx,
* then we set the curve by NID before deriving the actual keygen
* ctx for that specific curve. */
kctx = EVP_PKEY_CTX_new_id(test_curves[testnum], NULL); /* keygen ctx from NID */
if (!kctx) {
EVP_PKEY_CTX *pctx = NULL;
EVP_PKEY *params = NULL;
/* If we reach this code EVP_PKEY_CTX_new_id() failed and a
* "int_ctx_new:unsupported algorithm" error was added to the
* error queue.
* We remove it from the error queue as we are handling it. */
unsigned long error = ERR_peek_error(); /* peek the latest error in the queue */
if (error == ERR_peek_last_error() && /* oldest and latest errors match */
/* check that the error origin matches */
ERR_GET_LIB(error) == ERR_LIB_EVP &&
ERR_GET_FUNC(error) == EVP_F_INT_CTX_NEW &&
ERR_GET_REASON(error) == EVP_R_UNSUPPORTED_ALGORITHM)
ERR_get_error(); /* pop error from queue */
if (ERR_peek_error()) {
BIO_printf(bio_err,
"Unhandled error in the error queue during ECDH init.\n");
ERR_print_errors(bio_err);
rsa_count = 1;
break;
}
if ( /* Create the context for parameter generation */
!(pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)) ||
/* Initialise the parameter generation */
!EVP_PKEY_paramgen_init(pctx) ||
/* Set the curve by NID */
!EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx,
test_curves
[testnum]) ||
/* Create the parameter object params */
!EVP_PKEY_paramgen(pctx, &params)) {
ecdh_checks = 0;
BIO_printf(bio_err, "ECDH EC params init failure.\n");
ERR_print_errors(bio_err);
rsa_count = 1;
break;
}
/* Create the context for the key generation */
kctx = EVP_PKEY_CTX_new(params, NULL);
EVP_PKEY_free(params);
params = NULL;
EVP_PKEY_CTX_free(pctx);
pctx = NULL;
}
if (kctx == NULL || /* keygen ctx is not null */
!EVP_PKEY_keygen_init(kctx) /* init keygen ctx */ ) {
ecdh_checks = 0;
BIO_printf(bio_err, "ECDH keygen failure.\n");
ERR_print_errors(bio_err);
rsa_count = 1;
break;
}
if (!EVP_PKEY_keygen(kctx, &key_A) || /* generate secret key A */
!EVP_PKEY_keygen(kctx, &key_B) || /* generate secret key B */
!(ctx = EVP_PKEY_CTX_new(key_A, NULL)) || /* derivation ctx from skeyA */
!EVP_PKEY_derive_init(ctx) || /* init derivation ctx */
!EVP_PKEY_derive_set_peer(ctx, key_B) || /* set peer pubkey in ctx */
!EVP_PKEY_derive(ctx, NULL, &outlen) || /* determine max length */
outlen == 0 || /* ensure outlen is a valid size */
outlen > MAX_ECDH_SIZE /* avoid buffer overflow */ ) {
ecdh_checks = 0;
BIO_printf(bio_err, "ECDH key generation failure.\n");
ERR_print_errors(bio_err);
rsa_count = 1;
break;
}
/* Here we perform a test run, comparing the output of a*B and b*A;
* we try this here and assume that further EVP_PKEY_derive calls
* never fail, so we can skip checks in the actually benchmarked
* code, for maximum performance. */
if (!(test_ctx = EVP_PKEY_CTX_new(key_B, NULL)) || /* test ctx from skeyB */
!EVP_PKEY_derive_init(test_ctx) || /* init derivation test_ctx */
!EVP_PKEY_derive_set_peer(test_ctx, key_A) || /* set peer pubkey in test_ctx */
!EVP_PKEY_derive(test_ctx, NULL, &test_outlen) || /* determine max length */
!EVP_PKEY_derive(ctx, loopargs[i].secret_a, &outlen) || /* compute a*B */
!EVP_PKEY_derive(test_ctx, loopargs[i].secret_b, &test_outlen) || /* compute b*A */
test_outlen != outlen /* compare output length */ ) {
ecdh_checks = 0;
BIO_printf(bio_err, "ECDH computation failure.\n");
ERR_print_errors(bio_err);
rsa_count = 1;
break;
}
/* Compare the computation results: CRYPTO_memcmp() returns 0 if equal */
if (CRYPTO_memcmp(loopargs[i].secret_a,
loopargs[i].secret_b, outlen)) {
ecdh_checks = 0;
BIO_printf(bio_err, "ECDH computations don't match.\n");
ERR_print_errors(bio_err);
rsa_count = 1;
break;
}
loopargs[i].ecdh_ctx[testnum] = ctx;
loopargs[i].outlen[testnum] = outlen;
EVP_PKEY_free(key_A);
EVP_PKEY_free(key_B);
EVP_PKEY_CTX_free(kctx);
kctx = NULL;
EVP_PKEY_CTX_free(test_ctx);
test_ctx = NULL;
}
if (ecdh_checks == 0) {
BIO_printf(bio_err, "ECDH failure.\n");
ERR_print_errors(bio_err);
rsa_count = 1;
} else {
for (i = 0; i < loopargs_len; i++) {
/* generate two ECDH key pairs */
if (!EC_KEY_generate_key(loopargs[i].ecdh_a[testnum]) ||
!EC_KEY_generate_key(loopargs[i].ecdh_b[testnum])) {
BIO_printf(bio_err, "ECDH key generation failure.\n");
ERR_print_errors(bio_err);
ecdh_checks = 0;
rsa_count = 1;
} else {
int secret_size_a, secret_size_b;
/*
* If field size is not more than 24 octets, then use SHA-1
* hash of result; otherwise, use result (see section 4.8 of
* draft-ietf-tls-ecc-03.txt).
*/
int field_size = EC_GROUP_get_degree(
EC_KEY_get0_group(loopargs[i].ecdh_a[testnum]));
if (field_size <= 24 * 8) { /* 192 bits */
loopargs[i].outlen = KDF1_SHA1_len;
loopargs[i].kdf = KDF1_SHA1;
} else {
loopargs[i].outlen = (field_size + 7) / 8;
loopargs[i].kdf = NULL;
}
secret_size_a =
ECDH_compute_key(loopargs[i].secret_a, loopargs[i].outlen,
EC_KEY_get0_public_key(loopargs[i].ecdh_b[testnum]),
loopargs[i].ecdh_a[testnum], loopargs[i].kdf);
secret_size_b =
ECDH_compute_key(loopargs[i].secret_b, loopargs[i].outlen,
EC_KEY_get0_public_key(loopargs[i].ecdh_a[testnum]),
loopargs[i].ecdh_b[testnum], loopargs[i].kdf);
if (secret_size_a != secret_size_b)
ecdh_checks = 0;
else
ecdh_checks = 1;
for (k = 0; k < secret_size_a && ecdh_checks == 1; k++) {
if (loopargs[i].secret_a[k] != loopargs[i].secret_b[k])
ecdh_checks = 0;
}
if (ecdh_checks == 0) {
BIO_printf(bio_err, "ECDH computations don't match.\n");
ERR_print_errors(bio_err);
rsa_count = 1;
break;
}
}
}
if (ecdh_checks != 0) {
pkey_print_message("", "ecdh",
ecdh_c[testnum][0],
test_curves_bits[testnum], ECDH_SECONDS);
Time_F(START);
count = run_benchmark(async_jobs, ECDH_compute_key_loop, loopargs);
d = Time_F(STOP);
BIO_printf(bio_err,
mr ? "+R7:%ld:%d:%.2f\n" :
"%ld %d-bit ECDH ops in %.2fs\n", count,
test_curves_bits[testnum], d);
ecdh_results[testnum][0] = d / (double)count;
rsa_count = count;
}
if (ecdh_checks != 0) {
pkey_print_message("", "ecdh",
ecdh_c[testnum][0],
test_curves_bits[testnum],
seconds.ecdh);
Time_F(START);
count =
run_benchmark(async_jobs, ECDH_EVP_derive_key_loop, loopargs);
d = Time_F(STOP);
BIO_printf(bio_err,
mr ? "+R7:%ld:%d:%.2f\n" :
"%ld %d-bit ECDH ops in %.2fs\n", count,
test_curves_bits[testnum], d);
ecdh_results[testnum][0] = (double)count / d;
rsa_count = count;
}
if (rsa_count <= 1) {
@@ -2684,7 +2903,7 @@ int speed_main(int argc, char **argv)
("The 'numbers' are in 1000s of bytes per second processed.\n");
printf("type ");
}
for (testnum = 0; testnum < SIZE_NUM; testnum++)
for (testnum = 0; testnum < size_num; testnum++)
printf(mr ? ":%d" : "%7d bytes", lengths[testnum]);
printf("\n");
}
@@ -2696,7 +2915,7 @@ int speed_main(int argc, char **argv)
printf("+F:%d:%s", k, names[k]);
else
printf("%-13s", names[k]);
for (testnum = 0; testnum < SIZE_NUM; testnum++) {
for (testnum = 0; testnum < size_num; testnum++) {
if (results[k][testnum] > 10000 && !mr)
printf(" %11.2fk", results[k][testnum] / 1e3);
else
@@ -2718,8 +2937,8 @@ int speed_main(int argc, char **argv)
k, rsa_bits[k], rsa_results[k][0], rsa_results[k][1]);
else
printf("rsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
rsa_bits[k], rsa_results[k][0], rsa_results[k][1],
1.0 / rsa_results[k][0], 1.0 / rsa_results[k][1]);
rsa_bits[k], 1.0 / rsa_results[k][0], 1.0 / rsa_results[k][1],
rsa_results[k][0], rsa_results[k][1]);
}
#endif
#ifndef OPENSSL_NO_DSA
@@ -2736,8 +2955,8 @@ int speed_main(int argc, char **argv)
k, dsa_bits[k], dsa_results[k][0], dsa_results[k][1]);
else
printf("dsa %4u bits %8.6fs %8.6fs %8.1f %8.1f\n",
dsa_bits[k], dsa_results[k][0], dsa_results[k][1],
1.0 / dsa_results[k][0], 1.0 / dsa_results[k][1]);
dsa_bits[k], 1.0 / dsa_results[k][0], 1.0 / dsa_results[k][1],
dsa_results[k][0], dsa_results[k][1]);
}
#endif
#ifndef OPENSSL_NO_EC
@@ -2758,8 +2977,8 @@ int speed_main(int argc, char **argv)
printf("%4u bit ecdsa (%s) %8.4fs %8.4fs %8.1f %8.1f\n",
test_curves_bits[k],
test_curves_names[k],
ecdsa_results[k][0], ecdsa_results[k][1],
1.0 / ecdsa_results[k][0], 1.0 / ecdsa_results[k][1]);
1.0 / ecdsa_results[k][0], 1.0 / ecdsa_results[k][1],
ecdsa_results[k][0], ecdsa_results[k][1]);
}
testnum = 1;
@@ -2779,7 +2998,7 @@ int speed_main(int argc, char **argv)
printf("%4u bit ecdh (%s) %8.4fs %8.1f\n",
test_curves_bits[k],
test_curves_names[k],
ecdh_results[k][0], 1.0 / ecdh_results[k][0]);
1.0 / ecdh_results[k][0], ecdh_results[k][0]);
}
#endif
@@ -2802,8 +3021,7 @@ int speed_main(int argc, char **argv)
#ifndef OPENSSL_NO_EC
for (k = 0; k < EC_NUM; k++) {
EC_KEY_free(loopargs[i].ecdsa[k]);
EC_KEY_free(loopargs[i].ecdh_a[k]);
EC_KEY_free(loopargs[i].ecdh_b[k]);
EVP_PKEY_CTX_free(loopargs[i].ecdh_ctx[k]);
}
OPENSSL_free(loopargs[i].secret_a);
OPENSSL_free(loopargs[i].secret_b);
@@ -2820,17 +3038,17 @@ int speed_main(int argc, char **argv)
}
OPENSSL_free(loopargs);
release_engine(e);
return (ret);
return ret;
}
static void print_message(const char *s, long num, int length)
static void print_message(const char *s, long num, int length, int tm)
{
#ifdef SIGALRM
BIO_printf(bio_err,
mr ? "+DT:%s:%d:%d\n"
: "Doing %s for %ds on %d size blocks: ", s, SECONDS, length);
: "Doing %s for %ds on %d size blocks: ", s, tm, length);
(void)BIO_flush(bio_err);
alarm(SECONDS);
alarm(tm);
#else
BIO_printf(bio_err,
mr ? "+DN:%s:%ld:%d\n"
@@ -2897,7 +3115,7 @@ static char *sstrsep(char **string, const char *delim)
return token;
}
static int do_multi(int multi)
static int do_multi(int multi, int size_num)
{
int n;
int fd[2];
@@ -2943,8 +3161,9 @@ static int do_multi(int multi)
if (p)
*p = '\0';
if (buf[0] != '+') {
BIO_printf(bio_err, "Don't understand line '%s' from child %d\n",
buf, n);
BIO_printf(bio_err,
"Don't understand line '%s' from child %d\n", buf,
n);
continue;
}
printf("Got: %s from %d\n", buf, n);
@@ -2955,7 +3174,7 @@ static int do_multi(int multi)
p = buf + 3;
alg = atoi(sstrsep(&p, sep));
sstrsep(&p, sep);
for (j = 0; j < SIZE_NUM; ++j)
for (j = 0; j < size_num; ++j)
results[alg][j] += atof(sstrsep(&p, sep));
} else if (strncmp(buf, "+F2:", 4) == 0) {
int k;
@@ -2966,16 +3185,10 @@ static int do_multi(int multi)
sstrsep(&p, sep);
d = atof(sstrsep(&p, sep));
if (n)
rsa_results[k][0] = 1 / (1 / rsa_results[k][0] + 1 / d);
else
rsa_results[k][0] = d;
rsa_results[k][0] += d;
d = atof(sstrsep(&p, sep));
if (n)
rsa_results[k][1] = 1 / (1 / rsa_results[k][1] + 1 / d);
else
rsa_results[k][1] = d;
rsa_results[k][1] += d;
}
# ifndef OPENSSL_NO_DSA
else if (strncmp(buf, "+F3:", 4) == 0) {
@@ -2987,16 +3200,10 @@ static int do_multi(int multi)
sstrsep(&p, sep);
d = atof(sstrsep(&p, sep));
if (n)
dsa_results[k][0] = 1 / (1 / dsa_results[k][0] + 1 / d);
else
dsa_results[k][0] = d;
dsa_results[k][0] += d;
d = atof(sstrsep(&p, sep));
if (n)
dsa_results[k][1] = 1 / (1 / dsa_results[k][1] + 1 / d);
else
dsa_results[k][1] = d;
dsa_results[k][1] += d;
}
# endif
# ifndef OPENSSL_NO_EC
@@ -3009,18 +3216,10 @@ static int do_multi(int multi)
sstrsep(&p, sep);
d = atof(sstrsep(&p, sep));
if (n)
ecdsa_results[k][0] =
1 / (1 / ecdsa_results[k][0] + 1 / d);
else
ecdsa_results[k][0] = d;
ecdsa_results[k][0] += d;
d = atof(sstrsep(&p, sep));
if (n)
ecdsa_results[k][1] =
1 / (1 / ecdsa_results[k][1] + 1 / d);
else
ecdsa_results[k][1] = d;
ecdsa_results[k][1] += d;
} else if (strncmp(buf, "+F5:", 4) == 0) {
int k;
double d;
@@ -3030,18 +3229,15 @@ static int do_multi(int multi)
sstrsep(&p, sep);
d = atof(sstrsep(&p, sep));
if (n)
ecdh_results[k][0] = 1 / (1 / ecdh_results[k][0] + 1 / d);
else
ecdh_results[k][0] = d;
ecdh_results[k][0] += d;
}
# endif
else if (strncmp(buf, "+H:", 3) == 0) {
;
} else
BIO_printf(bio_err, "Unknown type '%s' from child %d\n", buf, n);
BIO_printf(bio_err, "Unknown type '%s' from child %d\n", buf,
n);
}
fclose(f);
@@ -3051,26 +3247,39 @@ static int do_multi(int multi)
}
#endif
static void multiblock_speed(const EVP_CIPHER *evp_cipher)
static void multiblock_speed(const EVP_CIPHER *evp_cipher,
const openssl_speed_sec_t *seconds)
{
static int mblengths[] =
static const int mblengths_list[] =
{ 8 * 1024, 2 * 8 * 1024, 4 * 8 * 1024, 8 * 8 * 1024, 8 * 16 * 1024 };
int j, count, num = OSSL_NELEM(mblengths);
const int *mblengths = mblengths_list;
int j, count, keylen, num = OSSL_NELEM(mblengths_list);
const char *alg_name;
unsigned char *inp, *out, no_key[32], no_iv[16];
unsigned char *inp, *out, *key, no_key[32], no_iv[16];
EVP_CIPHER_CTX *ctx;
double d = 0.0;
if (lengths_single) {
mblengths = &lengths_single;
num = 1;
}
inp = app_malloc(mblengths[num - 1], "multiblock input buffer");
out = app_malloc(mblengths[num - 1] + 1024, "multiblock output buffer");
ctx = EVP_CIPHER_CTX_new();
EVP_EncryptInit_ex(ctx, evp_cipher, NULL, no_key, no_iv);
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_MAC_KEY, sizeof(no_key),
no_key);
EVP_EncryptInit_ex(ctx, evp_cipher, NULL, NULL, no_iv);
keylen = EVP_CIPHER_CTX_key_length(ctx);
key = app_malloc(keylen, "evp_cipher key");
EVP_CIPHER_CTX_rand_key(ctx, key);
EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL);
OPENSSL_clear_free(key, keylen);
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_MAC_KEY, sizeof(no_key), no_key);
alg_name = OBJ_nid2ln(EVP_CIPHER_nid(evp_cipher));
for (j = 0; j < num; j++) {
print_message(alg_name, 0, mblengths[j]);
print_message(alg_name, 0, mblengths[j], seconds->sym);
Time_F(START);
for (count = 0, run = 1; run && count < 0x7fffffff; count++) {
unsigned char aad[EVP_AEAD_TLS1_AAD_LEN];
@@ -3103,8 +3312,8 @@ static void multiblock_speed(const EVP_CIPHER *evp_cipher)
RAND_bytes(out, 16);
len += 16;
aad[11] = len >> 8;
aad[12] = len;
aad[11] = (unsigned char)(len >> 8);
aad[12] = (unsigned char)(len);
pad = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD,
EVP_AEAD_TLS1_AAD_LEN, aad);
EVP_Cipher(ctx, out, inp, len + pad);
+12 -6
View File
@@ -1,5 +1,5 @@
/*
* Copyright 1999-2017 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1999-2018 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
@@ -12,11 +12,11 @@
#include <string.h>
#include <time.h>
#include "apps.h"
#include "progs.h"
#include <openssl/bio.h>
#include <openssl/conf.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/lhash.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
@@ -24,14 +24,15 @@ typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_NOOUT, OPT_PUBKEY, OPT_VERIFY, OPT_IN, OPT_OUT,
OPT_ENGINE, OPT_KEY, OPT_CHALLENGE, OPT_PASSIN, OPT_SPKAC,
OPT_SPKSECT
OPT_SPKSECT, OPT_KEYFORM
} OPTION_CHOICE;
OPTIONS spkac_options[] = {
const OPTIONS spkac_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"in", OPT_IN, '<', "Input file"},
{"out", OPT_OUT, '>', "Output file"},
{"key", OPT_KEY, '<', "Create SPKAC using private key"},
{"keyform", OPT_KEYFORM, 'f', "Private key file format - default PEM (PEM, DER, or ENGINE)"},
{"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
{"challenge", OPT_CHALLENGE, 's', "Challenge string"},
{"spkac", OPT_SPKAC, 's', "Alternative SPKAC name"},
@@ -58,6 +59,7 @@ int spkac_main(int argc, char **argv)
char *spkstr = NULL, *prog;
const char *spkac = "SPKAC", *spksect = "default";
int i, ret = 1, verify = 0, noout = 0, pubkey = 0;
int keyformat = FORMAT_PEM;
OPTION_CHOICE o;
prog = opt_init(argc, argv, spkac_options);
@@ -93,6 +95,10 @@ int spkac_main(int argc, char **argv)
case OPT_KEY:
keyfile = opt_arg();
break;
case OPT_KEYFORM:
if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyformat))
goto opthelp;
break;
case OPT_CHALLENGE:
challenge = opt_arg();
break;
@@ -118,7 +124,7 @@ int spkac_main(int argc, char **argv)
if (keyfile != NULL) {
pkey = load_key(strcmp(keyfile, "-") ? keyfile : NULL,
FORMAT_PEM, 1, passin, e, "private key");
keyformat, 1, passin, e, "private key");
if (pkey == NULL)
goto end;
spki = NETSCAPE_SPKI_new();
@@ -192,5 +198,5 @@ int spkac_main(int argc, char **argv)
EVP_PKEY_free(pkey);
release_engine(e);
OPENSSL_free(passin);
return (ret);
return ret;
}
+21 -25
View File
@@ -22,11 +22,11 @@ NON_EMPTY_TRANSLATION_UNIT
# include <openssl/buffer.h>
# include <openssl/srp.h>
# include "apps.h"
# include "progs.h"
# define BASE_SECTION "srp"
# define CONFIG_FILE "openssl.cnf"
# define ENV_RANDFILE "RANDFILE"
# define ENV_DATABASE "srpvfile"
# define ENV_DEFAULT_SRP "default_srp"
@@ -139,8 +139,8 @@ static char *srp_verify_user(const char *user, const char *srp_verifier,
BIO_printf(bio_err, "Pass %s\n", password);
OPENSSL_assert(srp_usersalt != NULL);
if (!(gNid = SRP_create_verifier(user, password, &srp_usersalt,
&verifier, N, g)) ) {
if ((gNid = SRP_create_verifier(user, password, &srp_usersalt,
&verifier, N, g)) == NULL) {
BIO_printf(bio_err, "Internal error validating SRP verifier\n");
} else {
if (strcmp(verifier, srp_verifier))
@@ -170,8 +170,8 @@ static char *srp_create_user(char *user, char **srp_verifier,
if (verbose)
BIO_printf(bio_err, "Creating\n user=\"%s\"\n g=\"%s\"\n N=\"%s\"\n",
user, g, N);
if (!(gNid = SRP_create_verifier(user, password, &salt,
srp_verifier, N, g)) ) {
if ((gNid = SRP_create_verifier(user, password, &salt,
srp_verifier, N, g)) == NULL) {
BIO_printf(bio_err, "Internal error creating SRP verifier\n");
} else {
*srp_usersalt = salt;
@@ -189,10 +189,10 @@ typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_VERBOSE, OPT_CONFIG, OPT_NAME, OPT_SRPVFILE, OPT_ADD,
OPT_DELETE, OPT_MODIFY, OPT_LIST, OPT_GN, OPT_USERINFO,
OPT_PASSIN, OPT_PASSOUT, OPT_ENGINE
OPT_PASSIN, OPT_PASSOUT, OPT_ENGINE, OPT_R_ENUM
} OPTION_CHOICE;
OPTIONS srp_options[] = {
const OPTIONS srp_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"verbose", OPT_VERBOSE, '-', "Talk a lot while doing things"},
{"config", OPT_CONFIG, '<', "A config file"},
@@ -207,6 +207,7 @@ OPTIONS srp_options[] = {
{"userinfo", OPT_USERINFO, 's', "Additional info to be set for user"},
{"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
{"passout", OPT_PASSOUT, 's', "Output file pass phrase source"},
OPT_R_OPTIONS,
# ifndef OPENSSL_NO_ENGINE
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
# endif
@@ -222,7 +223,7 @@ int srp_main(int argc, char **argv)
int doupdatedb = 0, mode = OPT_ERR;
char *user = NULL, *passinarg = NULL, *passoutarg = NULL;
char *passin = NULL, *passout = NULL, *gN = NULL, *userinfo = NULL;
char *randfile = NULL, *section = NULL;
char *section = NULL;
char **gNrow = NULL, *configfile = NULL;
char *srpvfile = NULL, **pp, *prog;
OPTION_CHOICE o;
@@ -278,12 +279,16 @@ int srp_main(int argc, char **argv)
case OPT_ENGINE:
e = setup_engine(opt_arg(), 0);
break;
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
}
}
argc = opt_num_rest();
argv = opt_rest();
if (srpvfile && configfile) {
if (srpvfile != NULL && configfile != NULL) {
BIO_printf(bio_err,
"-srpvfile and -configfile cannot be specified together.\n");
goto end;
@@ -300,7 +305,7 @@ int srp_main(int argc, char **argv)
}
user = *argv++;
}
if ((passinarg || passoutarg) && argc != 1) {
if ((passinarg != NULL || passoutarg != NULL) && argc != 1) {
BIO_printf(bio_err,
"-passin, -passout arguments only valid with one user.\n");
goto opthelp;
@@ -311,8 +316,8 @@ int srp_main(int argc, char **argv)
goto end;
}
if (!srpvfile) {
if (!configfile)
if (srpvfile == NULL) {
if (configfile == NULL)
configfile = default_config_file;
if (verbose)
@@ -336,8 +341,7 @@ int srp_main(int argc, char **argv)
goto end;
}
if (randfile == NULL)
randfile = NCONF_get_string(conf, BASE_SECTION, "RANDFILE");
app_RAND_load_conf(conf, BASE_SECTION);
if (verbose)
BIO_printf(bio_err,
@@ -348,10 +352,6 @@ int srp_main(int argc, char **argv)
if (srpvfile == NULL)
goto end;
}
if (randfile == NULL)
ERR_clear_error();
else
app_RAND_load_file(randfile, 0);
if (verbose)
BIO_printf(bio_err, "Trying to read SRP verifier file \"%s\"\n",
@@ -397,17 +397,15 @@ int srp_main(int argc, char **argv)
if (user != NULL && verbose > 1)
BIO_printf(bio_err, "Processing user \"%s\"\n", user);
if ((userindex = get_index(db, user, 'U')) >= 0) {
if ((userindex = get_index(db, user, 'U')) >= 0)
print_user(db, userindex, (verbose > 0) || mode == OPT_LIST);
}
if (mode == OPT_LIST) {
if (user == NULL) {
BIO_printf(bio_err, "List all users\n");
for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) {
for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++)
print_user(db, i, 1);
}
} else if (userindex < 0) {
BIO_printf(bio_err,
"user \"%s\" does not exist, ignored. t\n", user);
@@ -603,11 +601,9 @@ int srp_main(int argc, char **argv)
OPENSSL_free(passout);
if (ret)
ERR_print_errors(bio_err);
if (randfile)
app_RAND_write_file(randfile);
NCONF_free(conf);
free_index(db);
release_engine(e);
return (ret);
return ret;
}
#endif
+471
View File
@@ -0,0 +1,471 @@
/*
* Copyright 2016-2018 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
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include <openssl/opensslconf.h>
#include "apps.h"
#include "progs.h"
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/store.h>
static int process(const char *uri, const UI_METHOD *uimeth, PW_CB_DATA *uidata,
int expected, int criterion, OSSL_STORE_SEARCH *search,
int text, int noout, int recursive, int indent, BIO *out,
const char *prog);
typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_ENGINE, OPT_OUT, OPT_PASSIN,
OPT_NOOUT, OPT_TEXT, OPT_RECURSIVE,
OPT_SEARCHFOR_CERTS, OPT_SEARCHFOR_KEYS, OPT_SEARCHFOR_CRLS,
OPT_CRITERION_SUBJECT, OPT_CRITERION_ISSUER, OPT_CRITERION_SERIAL,
OPT_CRITERION_FINGERPRINT, OPT_CRITERION_ALIAS,
OPT_MD
} OPTION_CHOICE;
const OPTIONS storeutl_options[] = {
{OPT_HELP_STR, 1, '-', "Usage: %s [options] uri\nValid options are:\n"},
{"help", OPT_HELP, '-', "Display this summary"},
{"out", OPT_OUT, '>', "Output file - default stdout"},
{"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
{"text", OPT_TEXT, '-', "Print a text form of the objects"},
{"noout", OPT_NOOUT, '-', "No PEM output, just status"},
{"certs", OPT_SEARCHFOR_CERTS, '-', "Search for certificates only"},
{"keys", OPT_SEARCHFOR_KEYS, '-', "Search for keys only"},
{"crls", OPT_SEARCHFOR_CRLS, '-', "Search for CRLs only"},
{"subject", OPT_CRITERION_SUBJECT, 's', "Search by subject"},
{"issuer", OPT_CRITERION_ISSUER, 's', "Search by issuer and serial, issuer name"},
{"serial", OPT_CRITERION_SERIAL, 's', "Search by issuer and serial, serial number"},
{"fingerprint", OPT_CRITERION_FINGERPRINT, 's', "Search by public key fingerprint, given in hex"},
{"alias", OPT_CRITERION_ALIAS, 's', "Search by alias"},
{"", OPT_MD, '-', "Any supported digest"},
#ifndef OPENSSL_NO_ENGINE
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
#endif
{"r", OPT_RECURSIVE, '-', "Recurse through names"},
{NULL}
};
int storeutl_main(int argc, char *argv[])
{
int ret = 1, noout = 0, text = 0, recursive = 0;
char *outfile = NULL, *passin = NULL, *passinarg = NULL;
BIO *out = NULL;
ENGINE *e = NULL;
OPTION_CHOICE o;
char *prog = opt_init(argc, argv, storeutl_options);
PW_CB_DATA pw_cb_data;
int expected = 0;
int criterion = 0;
X509_NAME *subject = NULL, *issuer = NULL;
ASN1_INTEGER *serial = NULL;
unsigned char *fingerprint = NULL;
size_t fingerprintlen = 0;
char *alias = NULL;
OSSL_STORE_SEARCH *search = NULL;
const EVP_MD *digest = NULL;
while ((o = opt_next()) != OPT_EOF) {
switch (o) {
case OPT_EOF:
case OPT_ERR:
opthelp:
BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
goto end;
case OPT_HELP:
opt_help(storeutl_options);
ret = 0;
goto end;
case OPT_OUT:
outfile = opt_arg();
break;
case OPT_PASSIN:
passinarg = opt_arg();
break;
case OPT_NOOUT:
noout = 1;
break;
case OPT_TEXT:
text = 1;
break;
case OPT_RECURSIVE:
recursive = 1;
break;
case OPT_SEARCHFOR_CERTS:
case OPT_SEARCHFOR_KEYS:
case OPT_SEARCHFOR_CRLS:
if (expected != 0) {
BIO_printf(bio_err, "%s: only one search type can be given.\n",
prog);
goto end;
}
{
static const struct {
enum OPTION_choice choice;
int type;
} map[] = {
{OPT_SEARCHFOR_CERTS, OSSL_STORE_INFO_CERT},
{OPT_SEARCHFOR_KEYS, OSSL_STORE_INFO_PKEY},
{OPT_SEARCHFOR_CRLS, OSSL_STORE_INFO_CRL},
};
size_t i;
for (i = 0; i < OSSL_NELEM(map); i++) {
if (o == map[i].choice) {
expected = map[i].type;
break;
}
}
/*
* If expected wasn't set at this point, it means the map
* isn't syncronised with the possible options leading here.
*/
OPENSSL_assert(expected != 0);
}
break;
case OPT_CRITERION_SUBJECT:
if (criterion != 0) {
BIO_printf(bio_err, "%s: criterion already given.\n",
prog);
goto end;
}
criterion = OSSL_STORE_SEARCH_BY_NAME;
if (subject != NULL) {
BIO_printf(bio_err, "%s: subject already given.\n",
prog);
goto end;
}
if ((subject = parse_name(opt_arg(), MBSTRING_UTF8, 1)) == NULL) {
BIO_printf(bio_err, "%s: can't parse subject argument.\n",
prog);
goto end;
}
break;
case OPT_CRITERION_ISSUER:
if (criterion != 0
|| (criterion == OSSL_STORE_SEARCH_BY_ISSUER_SERIAL
&& issuer != NULL)) {
BIO_printf(bio_err, "%s: criterion already given.\n",
prog);
goto end;
}
criterion = OSSL_STORE_SEARCH_BY_ISSUER_SERIAL;
if (issuer != NULL) {
BIO_printf(bio_err, "%s: issuer already given.\n",
prog);
goto end;
}
if ((issuer = parse_name(opt_arg(), MBSTRING_UTF8, 1)) == NULL) {
BIO_printf(bio_err, "%s: can't parse issuer argument.\n",
prog);
goto end;
}
break;
case OPT_CRITERION_SERIAL:
if (criterion != 0
|| (criterion == OSSL_STORE_SEARCH_BY_ISSUER_SERIAL
&& serial != NULL)) {
BIO_printf(bio_err, "%s: criterion already given.\n",
prog);
goto end;
}
criterion = OSSL_STORE_SEARCH_BY_ISSUER_SERIAL;
if (serial != NULL) {
BIO_printf(bio_err, "%s: serial number already given.\n",
prog);
goto end;
}
if ((serial = s2i_ASN1_INTEGER(NULL, opt_arg())) == NULL) {
BIO_printf(bio_err, "%s: can't parse serial number argument.\n",
prog);
goto end;
}
break;
case OPT_CRITERION_FINGERPRINT:
if (criterion != 0
|| (criterion == OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT
&& fingerprint != NULL)) {
BIO_printf(bio_err, "%s: criterion already given.\n",
prog);
goto end;
}
criterion = OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT;
if (fingerprint != NULL) {
BIO_printf(bio_err, "%s: fingerprint already given.\n",
prog);
goto end;
}
{
long tmplen = 0;
if ((fingerprint = OPENSSL_hexstr2buf(opt_arg(), &tmplen))
== NULL) {
BIO_printf(bio_err,
"%s: can't parse fingerprint argument.\n",
prog);
goto end;
}
fingerprintlen = (size_t)tmplen;
}
break;
case OPT_CRITERION_ALIAS:
if (criterion != 0) {
BIO_printf(bio_err, "%s: criterion already given.\n",
prog);
goto end;
}
criterion = OSSL_STORE_SEARCH_BY_ALIAS;
if (alias != NULL) {
BIO_printf(bio_err, "%s: alias already given.\n",
prog);
goto end;
}
if ((alias = OPENSSL_strdup(opt_arg())) == NULL) {
BIO_printf(bio_err, "%s: can't parse alias argument.\n",
prog);
goto end;
}
break;
case OPT_ENGINE:
e = setup_engine(opt_arg(), 0);
break;
case OPT_MD:
if (!opt_md(opt_unknown(), &digest))
goto opthelp;
}
}
argc = opt_num_rest();
argv = opt_rest();
if (argc == 0) {
BIO_printf(bio_err, "%s: No URI given, nothing to do...\n", prog);
goto opthelp;
}
if (argc > 1) {
BIO_printf(bio_err, "%s: Unknown extra parameters after URI\n", prog);
goto opthelp;
}
if (criterion != 0) {
switch (criterion) {
case OSSL_STORE_SEARCH_BY_NAME:
if ((search = OSSL_STORE_SEARCH_by_name(subject)) == NULL) {
ERR_print_errors(bio_err);
goto end;
}
break;
case OSSL_STORE_SEARCH_BY_ISSUER_SERIAL:
if (issuer == NULL || serial == NULL) {
BIO_printf(bio_err,
"%s: both -issuer and -serial must be given.\n",
prog);
goto end;
}
if ((search = OSSL_STORE_SEARCH_by_issuer_serial(issuer, serial))
== NULL) {
ERR_print_errors(bio_err);
goto end;
}
break;
case OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT:
if ((search = OSSL_STORE_SEARCH_by_key_fingerprint(digest,
fingerprint,
fingerprintlen))
== NULL) {
ERR_print_errors(bio_err);
goto end;
}
break;
case OSSL_STORE_SEARCH_BY_ALIAS:
if ((search = OSSL_STORE_SEARCH_by_alias(alias)) == NULL) {
ERR_print_errors(bio_err);
goto end;
}
break;
}
}
if (!app_passwd(passinarg, NULL, &passin, NULL)) {
BIO_printf(bio_err, "Error getting passwords\n");
goto end;
}
pw_cb_data.password = passin;
pw_cb_data.prompt_info = argv[0];
out = bio_open_default(outfile, 'w', FORMAT_TEXT);
if (out == NULL)
goto end;
ret = process(argv[0], get_ui_method(), &pw_cb_data,
expected, criterion, search,
text, noout, recursive, 0, out, prog);
end:
OPENSSL_free(alias);
ASN1_INTEGER_free(serial);
X509_NAME_free(subject);
X509_NAME_free(issuer);
OSSL_STORE_SEARCH_free(search);
BIO_free_all(out);
OPENSSL_free(passin);
release_engine(e);
return ret;
}
static int indent_printf(int indent, BIO *bio, const char *format, ...)
{
va_list args;
int ret;
va_start(args, format);
ret = BIO_printf(bio, "%*s", indent, "") + BIO_vprintf(bio, format, args);
va_end(args);
return ret;
}
static int process(const char *uri, const UI_METHOD *uimeth, PW_CB_DATA *uidata,
int expected, int criterion, OSSL_STORE_SEARCH *search,
int text, int noout, int recursive, int indent, BIO *out,
const char *prog)
{
OSSL_STORE_CTX *store_ctx = NULL;
int ret = 1, items = 0;
if ((store_ctx = OSSL_STORE_open(uri, uimeth, uidata, NULL, NULL))
== NULL) {
BIO_printf(bio_err, "Couldn't open file or uri %s\n", uri);
ERR_print_errors(bio_err);
return ret;
}
if (expected != 0) {
if (!OSSL_STORE_expect(store_ctx, expected)) {
ERR_print_errors(bio_err);
goto end2;
}
}
if (criterion != 0) {
if (!OSSL_STORE_supports_search(store_ctx, criterion)) {
BIO_printf(bio_err,
"%s: the store scheme doesn't support the given search criteria.\n",
prog);
goto end2;
}
if (!OSSL_STORE_find(store_ctx, search)) {
ERR_print_errors(bio_err);
goto end2;
}
}
/* From here on, we count errors, and we'll return the count at the end */
ret = 0;
for (;;) {
OSSL_STORE_INFO *info = OSSL_STORE_load(store_ctx);
int type = info == NULL ? 0 : OSSL_STORE_INFO_get_type(info);
const char *infostr =
info == NULL ? NULL : OSSL_STORE_INFO_type_string(type);
if (info == NULL) {
if (OSSL_STORE_eof(store_ctx))
break;
if (OSSL_STORE_error(store_ctx)) {
if (recursive)
ERR_clear_error();
else
ERR_print_errors(bio_err);
ret++;
continue;
}
BIO_printf(bio_err,
"ERROR: OSSL_STORE_load() returned NULL without "
"eof or error indications\n");
BIO_printf(bio_err, " This is an error in the loader\n");
ERR_print_errors(bio_err);
ret++;
break;
}
if (type == OSSL_STORE_INFO_NAME) {
const char *name = OSSL_STORE_INFO_get0_NAME(info);
const char *desc = OSSL_STORE_INFO_get0_NAME_description(info);
indent_printf(indent, bio_out, "%d: %s: %s\n", items, infostr,
name);
if (desc != NULL)
indent_printf(indent, bio_out, "%s\n", desc);
} else {
indent_printf(indent, bio_out, "%d: %s\n", items, infostr);
}
/*
* Unfortunately, PEM_X509_INFO_write_bio() is sorely lacking in
* functionality, so we must figure out how exactly to write things
* ourselves...
*/
switch (type) {
case OSSL_STORE_INFO_NAME:
if (recursive) {
const char *suburi = OSSL_STORE_INFO_get0_NAME(info);
ret += process(suburi, uimeth, uidata,
expected, criterion, search,
text, noout, recursive, indent + 2, out, prog);
}
break;
case OSSL_STORE_INFO_PARAMS:
if (text)
EVP_PKEY_print_params(out, OSSL_STORE_INFO_get0_PARAMS(info),
0, NULL);
if (!noout)
PEM_write_bio_Parameters(out,
OSSL_STORE_INFO_get0_PARAMS(info));
break;
case OSSL_STORE_INFO_PKEY:
if (text)
EVP_PKEY_print_private(out, OSSL_STORE_INFO_get0_PKEY(info),
0, NULL);
if (!noout)
PEM_write_bio_PrivateKey(out, OSSL_STORE_INFO_get0_PKEY(info),
NULL, NULL, 0, NULL, NULL);
break;
case OSSL_STORE_INFO_CERT:
if (text)
X509_print(out, OSSL_STORE_INFO_get0_CERT(info));
if (!noout)
PEM_write_bio_X509(out, OSSL_STORE_INFO_get0_CERT(info));
break;
case OSSL_STORE_INFO_CRL:
if (text)
X509_CRL_print(out, OSSL_STORE_INFO_get0_CRL(info));
if (!noout)
PEM_write_bio_X509_CRL(out, OSSL_STORE_INFO_get0_CRL(info));
break;
default:
BIO_printf(bio_err, "!!! Unknown code\n");
ret++;
break;
}
items++;
OSSL_STORE_INFO_free(info);
}
indent_printf(indent, out, "Total found: %d\n", items);
end2:
if (!OSSL_STORE_close(store_ctx)) {
ERR_print_errors(bio_err);
ret++;
}
return ret;
}
+52 -82
View File
@@ -1,5 +1,5 @@
/*
* Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1998-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
@@ -8,9 +8,7 @@
*/
/* used by speed.c */
DSA *get_dsa512(void);
DSA *get_dsa1024(void);
DSA *get_dsa2048(void);
DSA *get_dsa(int);
static unsigned char dsa512_priv[] = {
0x65, 0xe5, 0xc7, 0x38, 0x60, 0x24, 0xb5, 0x89, 0xd4, 0x9c, 0xeb, 0x4c,
@@ -49,40 +47,6 @@ static unsigned char dsa512_g[] = {
0xA2, 0x03, 0x9D, 0x20,
};
DSA *get_dsa512()
{
DSA *dsa;
BIGNUM *priv_key, *pub_key, *p, *q, *g;
if ((dsa = DSA_new()) == NULL)
return (NULL);
priv_key = BN_bin2bn(dsa512_priv, sizeof(dsa512_priv), NULL);
pub_key = BN_bin2bn(dsa512_pub, sizeof(dsa512_pub), NULL);
p = BN_bin2bn(dsa512_p, sizeof(dsa512_p), NULL);
q = BN_bin2bn(dsa512_q, sizeof(dsa512_q), NULL);
g = BN_bin2bn(dsa512_g, sizeof(dsa512_g), NULL);
if ((priv_key == NULL) || (pub_key == NULL) || (p == NULL) || (q == NULL)
|| (g == NULL)) {
goto err;
}
if (!DSA_set0_pqg(dsa, p, q, g))
goto err;
p = q = g = NULL;
if (!DSA_set0_key(dsa, pub_key, priv_key))
goto err;
return dsa;
err:
DSA_free(dsa);
BN_free(priv_key);
BN_free(pub_key);
BN_free(p);
BN_free(q);
BN_free(g);
return NULL;
}
static unsigned char dsa1024_priv[] = {
0x7d, 0x21, 0xda, 0xbb, 0x62, 0x15, 0x47, 0x36, 0x07, 0x67, 0x12, 0xe8,
0x8c, 0xaa, 0x1c, 0xcd, 0x38, 0x12, 0x61, 0x18,
@@ -135,40 +99,6 @@ static unsigned char dsa1024_g[] = {
0x6A, 0x7E, 0xD8, 0x32, 0xED, 0x0E, 0x02, 0xB8,
};
DSA *get_dsa1024()
{
DSA *dsa;
BIGNUM *priv_key, *pub_key, *p, *q, *g;
if ((dsa = DSA_new()) == NULL)
return (NULL);
priv_key = BN_bin2bn(dsa1024_priv, sizeof(dsa1024_priv), NULL);
pub_key = BN_bin2bn(dsa1024_pub, sizeof(dsa1024_pub), NULL);
p = BN_bin2bn(dsa1024_p, sizeof(dsa1024_p), NULL);
q = BN_bin2bn(dsa1024_q, sizeof(dsa1024_q), NULL);
g = BN_bin2bn(dsa1024_g, sizeof(dsa1024_g), NULL);
if ((priv_key == NULL) || (pub_key == NULL) || (p == NULL) || (q == NULL)
|| (g == NULL)) {
goto err;
}
if (!DSA_set0_pqg(dsa, p, q, g))
goto err;
p = q = g = NULL;
if (!DSA_set0_key(dsa, pub_key, priv_key))
goto err;
return dsa;
err:
DSA_free(dsa);
BN_free(priv_key);
BN_free(pub_key);
BN_free(p);
BN_free(q);
BN_free(g);
return NULL;
}
static unsigned char dsa2048_priv[] = {
0x32, 0x67, 0x92, 0xf6, 0xc4, 0xe2, 0xe2, 0xe8, 0xa0, 0x8b, 0x6b, 0x45,
0x0c, 0x8a, 0x76, 0xb0, 0xee, 0xcf, 0x91, 0xa7,
@@ -254,25 +184,66 @@ static unsigned char dsa2048_g[] = {
0xF8, 0xB2, 0xE5, 0x38,
};
DSA *get_dsa2048()
typedef struct testdsa_st {
unsigned char *priv;
unsigned char *pub;
unsigned char *p;
unsigned char *g;
unsigned char *q;
int priv_l;
int pub_l;
int p_l;
int g_l;
int q_l;
} testdsa;
#define set_dsa_ptr(st, bits) \
do { \
st.priv = dsa##bits##_priv; \
st.pub = dsa##bits##_pub; \
st.p = dsa##bits##_p; \
st.g = dsa##bits##_g; \
st.q = dsa##bits##_q; \
st.priv_l = sizeof(dsa##bits##_priv); \
st.pub_l = sizeof(dsa##bits##_pub); \
st.p_l = sizeof(dsa##bits##_p); \
st.g_l = sizeof(dsa##bits##_g); \
st.q_l = sizeof(dsa##bits##_q); \
} while (0)
DSA *get_dsa(int dsa_bits)
{
DSA *dsa;
BIGNUM *priv_key, *pub_key, *p, *q, *g;
testdsa dsa_t;
switch (dsa_bits) {
case 512:
set_dsa_ptr(dsa_t, 512);
break;
case 1024:
set_dsa_ptr(dsa_t, 1024);
break;
case 2048:
set_dsa_ptr(dsa_t, 2048);
break;
default:
return NULL;
}
if ((dsa = DSA_new()) == NULL)
return (NULL);
priv_key = BN_bin2bn(dsa2048_priv, sizeof(dsa2048_priv), NULL);
pub_key = BN_bin2bn(dsa2048_pub, sizeof(dsa2048_pub), NULL);
p = BN_bin2bn(dsa2048_p, sizeof(dsa2048_p), NULL);
q = BN_bin2bn(dsa2048_q, sizeof(dsa2048_q), NULL);
g = BN_bin2bn(dsa2048_g, sizeof(dsa2048_g), NULL);
return NULL;
priv_key = BN_bin2bn(dsa_t.priv, dsa_t.priv_l, NULL);
pub_key = BN_bin2bn(dsa_t.pub, dsa_t.pub_l, NULL);
p = BN_bin2bn(dsa_t.p, dsa_t.p_l, NULL);
q = BN_bin2bn(dsa_t.q, dsa_t.q_l, NULL);
g = BN_bin2bn(dsa_t.g, dsa_t.g_l, NULL);
if ((priv_key == NULL) || (pub_key == NULL) || (p == NULL) || (q == NULL)
|| (g == NULL)) {
|| (g == NULL)) {
goto err;
}
if (!DSA_set0_pqg(dsa, p, q, g))
goto err;
p = q = g = NULL;
if (!DSA_set0_key(dsa, pub_key, priv_key))
goto err;
@@ -287,4 +258,3 @@ DSA *get_dsa2048()
BN_free(g);
return NULL;
}
+26 -35
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2006-2018 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
@@ -15,6 +15,7 @@ NON_EMPTY_TRANSLATION_UNIT
# include <stdlib.h>
# include <string.h>
# include "apps.h"
# include "progs.h"
# include <openssl/bio.h>
# include <openssl/err.h>
# include <openssl/pem.h>
@@ -79,22 +80,21 @@ static int verify_cb(int ok, X509_STORE_CTX *ctx);
typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_ENGINE, OPT_CONFIG, OPT_SECTION, OPT_QUERY, OPT_DATA,
OPT_DIGEST, OPT_RAND, OPT_TSPOLICY, OPT_NO_NONCE, OPT_CERT,
OPT_DIGEST, OPT_TSPOLICY, OPT_NO_NONCE, OPT_CERT,
OPT_IN, OPT_TOKEN_IN, OPT_OUT, OPT_TOKEN_OUT, OPT_TEXT,
OPT_REPLY, OPT_QUERYFILE, OPT_PASSIN, OPT_INKEY, OPT_SIGNER,
OPT_CHAIN, OPT_VERIFY, OPT_CAPATH, OPT_CAFILE, OPT_UNTRUSTED,
OPT_MD, OPT_V_ENUM
OPT_MD, OPT_V_ENUM, OPT_R_ENUM
} OPTION_CHOICE;
OPTIONS ts_options[] = {
const OPTIONS ts_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"config", OPT_CONFIG, '<', "Configuration file"},
{"section", OPT_SECTION, 's', "Section to use within config file"},
{"query", OPT_QUERY, '-', "Generate a TS query"},
{"data", OPT_DATA, '<', "File to hash"},
{"digest", OPT_DIGEST, 's', "Digest (as a hex string)"},
{"rand", OPT_RAND, 's',
"Load the file(s) into the random number generator"},
OPT_R_OPTIONS,
{"tspolicy", OPT_TSPOLICY, 's', "Policy OID to use"},
{"no_nonce", OPT_NO_NONCE, '-', "Do not include a nonce"},
{"cert", OPT_CERT, '-', "Put cert request into query"},
@@ -158,7 +158,7 @@ int ts_main(int argc, char **argv)
const char *section = NULL;
char **helpp;
char *password = NULL;
char *data = NULL, *digest = NULL, *rnd = NULL, *policy = NULL;
char *data = NULL, *digest = NULL, *policy = NULL;
char *in = NULL, *out = NULL, *queryfile = NULL, *passin = NULL;
char *inkey = NULL, *signer = NULL, *chain = NULL, *CApath = NULL;
const EVP_MD *md = NULL;
@@ -207,8 +207,9 @@ int ts_main(int argc, char **argv)
case OPT_DIGEST:
digest = opt_arg();
break;
case OPT_RAND:
rnd = opt_arg();
case OPT_R_CASES:
if (!opt_rand(o))
goto end;
break;
case OPT_TSPOLICY:
policy = opt_arg();
@@ -275,16 +276,6 @@ int ts_main(int argc, char **argv)
if (mode == OPT_ERR || opt_num_rest() != 0)
goto opthelp;
/* Seed the random number generator if it is going to be used. */
if (mode == OPT_QUERY && !no_nonce) {
if (!app_RAND_load_file(NULL, 1) && rnd == NULL)
BIO_printf(bio_err, "warning, not much extra random "
"data, consider using the -rand option\n");
if (rnd != NULL)
BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
app_RAND_load_files(rnd));
}
if (mode == OPT_REPLY && passin &&
!app_passwd(passin, NULL, &password, NULL)) {
BIO_printf(bio_err, "Error getting password.\n");
@@ -296,19 +287,14 @@ int ts_main(int argc, char **argv)
goto end;
/* Check parameter consistency and execute the appropriate function. */
switch (mode) {
default:
case OPT_ERR:
goto opthelp;
case OPT_QUERY:
if (mode == OPT_QUERY) {
if (vpmtouched)
goto opthelp;
if ((data != NULL) && (digest != NULL))
goto opthelp;
ret = !query_command(data, digest, md, policy, no_nonce, cert,
in, out, text);
break;
case OPT_REPLY:
} else if (mode == OPT_REPLY) {
if (vpmtouched)
goto opthelp;
if ((in != NULL) && (queryfile != NULL))
@@ -320,21 +306,22 @@ int ts_main(int argc, char **argv)
ret = !reply_command(conf, section, engine, queryfile,
password, inkey, md, signer, chain, policy,
in, token_in, out, token_out, text);
break;
case OPT_VERIFY:
} else if (mode == OPT_VERIFY) {
if ((in == NULL) || !EXACTLY_ONE(queryfile, data, digest))
goto opthelp;
ret = !verify_command(data, digest, queryfile, in, token_in,
CApath, CAfile, untrusted,
vpmtouched ? vpm : NULL);
} else {
goto opthelp;
}
end:
X509_VERIFY_PARAM_free(vpm);
app_RAND_write_file(NULL);
NCONF_free(conf);
OPENSSL_free(password);
return (ret);
return ret;
}
/*
@@ -501,7 +488,7 @@ static int create_digest(BIO *input, const char *digest, const EVP_MD *md,
if (md_value_len < 0)
return 0;
if (input) {
if (input != NULL) {
unsigned char buffer[4096];
int length;
@@ -593,7 +580,7 @@ static int reply_command(CONF *conf, const char *section, const char *engine,
} else {
response = create_response(conf, section, engine, queryfile,
passin, inkey, md, signer, chain, policy);
if (response)
if (response != NULL)
BIO_printf(bio_err, "Response has been generated.\n");
else
BIO_printf(bio_err, "Response is not generated.\n");
@@ -712,6 +699,8 @@ static TS_RESP *create_response(CONF *conf, const char *section, const char *eng
goto end;
}
if (!TS_CONF_set_ess_cert_id_digest(conf, section, resp_ctx))
goto end;
if (!TS_CONF_set_def_policy(conf, section, policy, resp_ctx))
goto end;
if (!TS_CONF_set_policies(conf, section, resp_ctx))
@@ -747,13 +736,14 @@ static ASN1_INTEGER *serial_cb(TS_RESP_CTX *ctx, void *data)
const char *serial_file = (const char *)data;
ASN1_INTEGER *serial = next_serial(serial_file);
if (!serial) {
if (serial == NULL) {
TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION,
"Error during serial number "
"generation.");
TS_RESP_CTX_add_failure_info(ctx, TS_INFO_ADD_INFO_NOT_AVAILABLE);
} else
} else {
save_ts_serial(serial_file, serial);
}
return serial;
}
@@ -916,8 +906,9 @@ static TS_VERIFY_CTX *create_verify_ctx(const char *data, const char *digest,
goto err;
if ((ctx = TS_REQ_to_TS_VERIFY_CTX(request, NULL)) == NULL)
goto err;
} else
} else {
return NULL;
}
/* Add the signature verification flag and arguments. */
TS_VERIFY_CTX_add_flags(ctx, f | TS_VFY_SIGNATURE);
+1 -1
View File
@@ -1,6 +1,6 @@
#!{- $config{hashbangperl} -}
# Copyright (c) 2002 The OpenTSA Project. All rights reserved.
# Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
# Copyright (c) 2002 The OpenTSA Project. 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
+15 -9
View File
@@ -1,5 +1,5 @@
/*
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2018 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
@@ -11,6 +11,7 @@
#include <stdlib.h>
#include <string.h>
#include "apps.h"
#include "progs.h"
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/x509.h>
@@ -27,11 +28,11 @@ typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_ENGINE, OPT_CAPATH, OPT_CAFILE, OPT_NOCAPATH, OPT_NOCAFILE,
OPT_UNTRUSTED, OPT_TRUSTED, OPT_CRLFILE, OPT_CRL_DOWNLOAD, OPT_SHOW_CHAIN,
OPT_V_ENUM,
OPT_V_ENUM, OPT_NAMEOPT,
OPT_VERBOSE
} OPTION_CHOICE;
OPTIONS verify_options[] = {
const OPTIONS verify_options[] = {
{OPT_HELP_STR, 1, '-', "Usage: %s [options] cert.pem...\n"},
{OPT_HELP_STR, 1, '-', "Valid options are:\n"},
{"help", OPT_HELP, '-', "Display this summary"},
@@ -51,6 +52,7 @@ OPTIONS verify_options[] = {
"Attempt to download CRL information for this certificate"},
{"show_chain", OPT_SHOW_CHAIN, '-',
"Display information about the certificate chain"},
{"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"},
OPT_V_OPTIONS,
#ifndef OPENSSL_NO_ENGINE
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
@@ -149,6 +151,10 @@ int verify_main(int argc, char **argv)
case OPT_SHOW_CHAIN:
show_chain = 1;
break;
case OPT_NAMEOPT:
if (!set_nameopt(opt_arg()))
goto end;
break;
case OPT_VERBOSE:
v_verbose = 1;
break;
@@ -223,9 +229,9 @@ static int check(X509_STORE *ctx, const char *file,
(file == NULL) ? "stdin" : file);
goto end;
}
if (tchain)
if (tchain != NULL)
X509_STORE_CTX_set0_trusted_stack(csc, tchain);
if (crls)
if (crls != NULL)
X509_STORE_CTX_set0_crls(csc, crls);
i = X509_verify_cert(csc);
if (i > 0 && X509_STORE_CTX_get_error(csc) == X509_V_OK) {
@@ -242,7 +248,7 @@ static int check(X509_STORE *ctx, const char *file,
printf("depth=%d: ", j);
X509_NAME_print_ex_fp(stdout,
X509_get_subject_name(cert),
0, XN_FLAG_ONELINE);
0, get_nameopt());
if (j < num_untrusted)
printf(" (untrusted)");
printf("\n");
@@ -268,10 +274,10 @@ static int cb(int ok, X509_STORE_CTX *ctx)
X509 *current_cert = X509_STORE_CTX_get_current_cert(ctx);
if (!ok) {
if (current_cert) {
if (current_cert != NULL) {
X509_NAME_print_ex(bio_err,
X509_get_subject_name(current_cert),
0, XN_FLAG_ONELINE);
0, get_nameopt());
BIO_printf(bio_err, "\n");
}
BIO_printf(bio_err, "%serror %d at %d depth lookup: %s\n",
@@ -308,5 +314,5 @@ static int cb(int ok, X509_STORE_CTX *ctx)
policies_print(ctx);
if (!v_verbose)
ERR_clear_error();
return (ok);
return ok;
}
+56 -8
View File
@@ -11,6 +11,7 @@
#include <stdlib.h>
#include <string.h>
#include "apps.h"
#include "progs.h"
#include <openssl/evp.h>
#include <openssl/crypto.h>
#include <openssl/bn.h>
@@ -32,10 +33,10 @@
typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_B, OPT_D, OPT_E, OPT_F, OPT_O, OPT_P, OPT_V, OPT_A
OPT_B, OPT_D, OPT_E, OPT_F, OPT_O, OPT_P, OPT_V, OPT_A, OPT_R
} OPTION_CHOICE;
OPTIONS version_options[] = {
const OPTIONS version_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"a", OPT_A, '-', "Show all data"},
{"b", OPT_B, '-', "Show build date"},
@@ -44,13 +45,24 @@ OPTIONS version_options[] = {
{"f", OPT_F, '-', "Show compiler flags used"},
{"o", OPT_O, '-', "Show some internal datatype options"},
{"p", OPT_P, '-', "Show target build platform"},
{"r", OPT_R, '-', "Show random seeding options"},
{"v", OPT_V, '-', "Show library version"},
{NULL}
};
#if defined(OPENSSL_RAND_SEED_DEVRANDOM) || defined(OPENSSL_RAND_SEED_EGD)
static void printlist(const char *prefix, const char **dev)
{
printf("%s (", prefix);
for ( ; *dev != NULL; dev++)
printf(" \"%s\"", *dev);
printf(" )");
}
#endif
int version_main(int argc, char **argv)
{
int ret = 1, dirty = 0;
int ret = 1, dirty = 0, seed = 0;
int cflags = 0, version = 0, date = 0, options = 0, platform = 0, dir = 0;
int engdir = 0;
char *prog;
@@ -86,11 +98,14 @@ opthelp:
case OPT_P:
dirty = platform = 1;
break;
case OPT_R:
dirty = seed = 1;
break;
case OPT_V:
dirty = version = 1;
break;
case OPT_A:
options = cflags = version = date = platform = dir = engdir = 1;
seed = cflags = version = date = platform = dir = engdir = 1;
break;
}
}
@@ -102,12 +117,11 @@ opthelp:
version = 1;
if (version) {
if (OpenSSL_version_num() == OPENSSL_VERSION_NUMBER) {
if (OpenSSL_version_num() == OPENSSL_VERSION_NUMBER)
printf("%s\n", OpenSSL_version(OPENSSL_VERSION));
} else {
else
printf("%s (Library: %s)\n",
OPENSSL_VERSION_TEXT, OpenSSL_version(OPENSSL_VERSION));
}
}
if (date)
printf("%s\n", OpenSSL_version(OPENSSL_BUILT_ON));
@@ -139,7 +153,41 @@ opthelp:
printf("%s\n", OpenSSL_version(OPENSSL_DIR));
if (engdir)
printf("%s\n", OpenSSL_version(OPENSSL_ENGINES_DIR));
if (seed) {
printf("Seeding source:");
#ifdef OPENSSL_RAND_SEED_RTDSC
printf(" rtdsc");
#endif
#ifdef OPENSSL_RAND_SEED_RDCPU
printf(" rdrand ( rdseed rdrand )");
#endif
#ifdef OPENSSL_RAND_SEED_LIBRANDOM
printf(" C-library-random");
#endif
#ifdef OPENSSL_RAND_SEED_GETRANDOM
printf(" getrandom-syscall");
#endif
#ifdef OPENSSL_RAND_SEED_DEVRANDOM
{
static const char *dev[] = { DEVRANDOM, NULL };
printlist(" random-device", dev);
}
#endif
#ifdef OPENSSL_RAND_SEED_EGD
{
static const char *dev[] = { DEVRANDOM_EGD, NULL };
printlist(" EGD", dev);
}
#endif
#ifdef OPENSSL_RAND_SEED_NONE
printf(" none");
#endif
#ifdef OPENSSL_RAND_SEED_OS
printf(" os-specific");
#endif
printf("\n");
}
ret = 0;
end:
return (ret);
return ret;
}
+18 -17
View File
@@ -1,4 +1,5 @@
/*
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2016 VMS Software, Inc. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
@@ -183,7 +184,7 @@ int TerminalSocket (int FunctionCode, int *ReturnSocket)
close (TerminalSocketPair[0]);
if (TerminalSocketPair[1])
close (TerminalSocketPair[1]);
return (TERM_SOCK_FAILURE);
return TERM_SOCK_FAILURE;
}
/*
@@ -196,7 +197,7 @@ int TerminalSocket (int FunctionCode, int *ReturnSocket)
LogMessage ("TerminalSocket: SYS$ASSIGN () - %08X", status);
close (TerminalSocketPair[0]);
close (TerminalSocketPair[1]);
return (TERM_SOCK_FAILURE);
return TERM_SOCK_FAILURE;
}
/*
@@ -215,7 +216,7 @@ int TerminalSocket (int FunctionCode, int *ReturnSocket)
LogMessage ("TerminalSocket: SYS$QIO () - %08X", status);
close (TerminalSocketPair[0]);
close (TerminalSocketPair[1]);
return (TERM_SOCK_FAILURE);
return TERM_SOCK_FAILURE;
}
/*
@@ -233,7 +234,7 @@ int TerminalSocket (int FunctionCode, int *ReturnSocket)
LogMessage ("TerminalSocket: SYS$CANCEL () - %08X", status);
close (TerminalSocketPair[0]);
close (TerminalSocketPair[1]);
return (TERM_SOCK_FAILURE);
return TERM_SOCK_FAILURE;
}
/*
@@ -244,7 +245,7 @@ int TerminalSocket (int FunctionCode, int *ReturnSocket)
LogMessage ("TerminalSocket: SYS$DASSGN () - %08X", status);
close (TerminalSocketPair[0]);
close (TerminalSocketPair[1]);
return (TERM_SOCK_FAILURE);
return TERM_SOCK_FAILURE;
}
/*
@@ -264,14 +265,14 @@ int TerminalSocket (int FunctionCode, int *ReturnSocket)
** Invalid function code
*/
LogMessage ("TerminalSocket: Invalid Function Code - %d", FunctionCode);
return (TERM_SOCK_FAILURE);
return TERM_SOCK_FAILURE;
break;
}
/*
** Return success
*/
return (TERM_SOCK_SUCCESS);
return TERM_SOCK_SUCCESS;
}
@@ -311,7 +312,7 @@ static int CreateSocketPair (int SocketFamily,
SockDesc1 = socket (SocketFamily, SocketType, 0);
if (SockDesc1 < 0) {
LogMessage ("CreateSocketPair: socket () - %d", errno);
return (-1);
return -1;
}
/*
@@ -330,7 +331,7 @@ static int CreateSocketPair (int SocketFamily,
if (status < 0) {
LogMessage ("CreateSocketPair: bind () - %d", errno);
close (SockDesc1);
return (-1);
return -1;
}
/*
@@ -340,7 +341,7 @@ static int CreateSocketPair (int SocketFamily,
if (status < 0) {
LogMessage ("CreateSocketPair: getsockname () - %d", errno);
close (SockDesc1);
return (-1);
return -1;
} else
LocalHostPort = sin.sin_port;
@@ -359,7 +360,7 @@ static int CreateSocketPair (int SocketFamily,
if (! (status & 1)) {
LogMessage ("CreateSocketPair: SYS$BINTIM () - %08X", status);
close (SockDesc1);
return (-1);
return -1;
}
/*
@@ -370,7 +371,7 @@ static int CreateSocketPair (int SocketFamily,
if (! (status & 1)) {
LogMessage ("CreateSocketPair: SYS$ASSIGN () - %08X", status);
close (SockDesc1);
return (-1);
return -1;
}
/*
@@ -392,7 +393,7 @@ static int CreateSocketPair (int SocketFamily,
LogMessage ("CreateSocketPair: SYS$QIO () - %08X", status);
close (SockDesc1);
sys$dassgn (TcpDeviceChan);
return (-1);
return -1;
}
/*
@@ -428,7 +429,7 @@ static int CreateSocketPair (int SocketFamily,
close (SockDesc1);
close (SockDesc2);
sys$dassgn (TcpDeviceChan);
return (-1);
return -1;
}
/*
@@ -447,7 +448,7 @@ static int CreateSocketPair (int SocketFamily,
close (SockDesc1);
close (SockDesc2);
sys$dassgn (TcpDeviceChan);
return (-1);
return -1;
}
/*
@@ -467,7 +468,7 @@ static int CreateSocketPair (int SocketFamily,
close (SockDesc1);
close (SockDesc2);
sys$dassgn (TcpDeviceChan);
return (-1);
return -1;
}
/*
@@ -513,7 +514,7 @@ static int TerminalDeviceAst (int astparm)
strcat (TerminalDeviceBuff, "\n");
/*
** Send the data read from the terminal device throught the socket pair
** Send the data read from the terminal device through the socket pair
*/
send (TerminalSocketPair[0], TerminalDeviceBuff,
TerminalDeviceIosb.iosb$w_bcnt + 1, 0);
+1
View File
@@ -1,4 +1,5 @@
/*
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2016 VMS Software, Inc. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
+1 -1
View File
@@ -302,6 +302,6 @@ void win32_utf8argv(int *argc, char **argv[])
return;
}
#else
void win32_utf8argv(int &argc, char **argv[])
void win32_utf8argv(int *argc, char **argv[])
{ return; }
#endif
+182 -83
View File
@@ -11,6 +11,7 @@
#include <stdlib.h>
#include <string.h>
#include "apps.h"
#include "progs.h"
#include <openssl/bio.h>
#include <openssl/asn1.h>
#include <openssl/err.h>
@@ -33,13 +34,16 @@
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);
static int print_x509v3_exts(BIO *bio, X509 *x, const char *exts);
typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
@@ -56,10 +60,11 @@ 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, OPT_EXT
} OPTION_CHOICE;
OPTIONS x509_options[] = {
const OPTIONS x509_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"inform", OPT_INFORM, 'f',
"Input format - default PEM (one of DER, NET or PEM)"},
@@ -114,8 +119,10 @@ OPTIONS x509_options[] = {
{"CAserial", OPT_CASERIAL, 's', "Serial file"},
{"set_serial", OPT_SET_SERIAL, 's', "Serial number to use"},
{"text", OPT_TEXT, '-', "Print the certificate in text form"},
{"ext", OPT_EXT, 's', "Print various X509V3 extensions"},
{"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"},
@@ -140,6 +147,7 @@ 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}
};
@@ -157,23 +165,23 @@ int x509_main(int argc, char **argv)
X509_STORE *ctx = NULL;
const EVP_MD *digest = NULL;
char *CAkeyfile = NULL, *CAserial = NULL, *fkeyfile = NULL, *alias = NULL;
char *checkhost = NULL, *checkemail = NULL, *checkip = NULL;
char *checkhost = NULL, *checkemail = NULL, *checkip = NULL, *exts = NULL;
char *extsect = NULL, *extfile = NULL, *passin = NULL, *passinarg = NULL;
char *infile = NULL, *outfile = NULL, *keyfile = NULL, *CAfile = NULL;
char buf[256], *prog;
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 ocsp_uri = 0, trustout = 0, clrtrust = 0, clrreject = 0, aliasout = 0;
int ret = 1, i, num = 0, badsig = 0, clrext = 0, nocert = 0;
int text = 0, serial = 0, subject = 0, issuer = 0, startdate = 0;
int text = 0, serial = 0, subject = 0, issuer = 0, startdate = 0, ext = 0;
int enddate = 0;
time_t checkoffset = 0;
unsigned long nmflag = 0, certflag = 0;
char nmflag_set = 0;
unsigned long certflag = 0;
int preserve_dates = 0;
OPTION_CHOICE o;
ENGINE *e = NULL;
#ifndef OPENSSL_NO_MD5
@@ -224,7 +232,7 @@ int x509_main(int argc, char **argv)
outfile = opt_arg();
break;
case OPT_REQ:
reqfile = need_rand = 1;
reqfile = 1;
break;
case OPT_SIGOPT:
@@ -234,6 +242,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:
@@ -242,18 +252,20 @@ int x509_main(int argc, char **argv)
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();
@@ -308,8 +320,7 @@ int x509_main(int argc, char **argv)
goto opthelp;
break;
case OPT_NAMEOPT:
nmflag_set = 1;
if (!set_name_ex(&nmflag, opt_arg()))
if (!set_nameopt(opt_arg()))
goto opthelp;
break;
case OPT_ENGINE:
@@ -369,6 +380,10 @@ int x509_main(int argc, char **argv)
case OPT_NOOUT:
noout = ++num;
break;
case OPT_EXT:
ext = ++num;
exts = opt_arg();
break;
case OPT_NOCERT:
nocert = 1;
break;
@@ -435,6 +450,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;
@@ -447,11 +467,9 @@ int x509_main(int argc, char **argv)
goto opthelp;
}
if (!nmflag_set)
nmflag = XN_FLAG_ONELINE;
if (need_rand)
app_RAND_load_file(NULL, 0);
out = bio_open_default(outfile, 'w', outformat);
if (out == NULL)
goto end;
if (!app_passwd(passinarg, NULL, &passin, NULL)) {
BIO_printf(bio_err, "Error getting password\n");
@@ -463,7 +481,7 @@ int x509_main(int argc, char **argv)
goto end;
}
if (fkeyfile) {
if (fkeyfile != NULL) {
fkey = load_pubkey(fkeyfile, keyformat, 0, NULL, e, "Forced key");
if (fkey == NULL)
goto end;
@@ -477,13 +495,13 @@ int x509_main(int argc, char **argv)
goto end;
}
if (extfile) {
if (extfile != NULL) {
X509V3_CTX ctx2;
if ((extconf = app_load_config(extfile)) == NULL)
goto end;
if (!extsect) {
if (extsect == NULL) {
extsect = NCONF_get_string(extconf, "default", "extensions");
if (!extsect) {
if (extsect == NULL) {
ERR_clear_error();
extsect = "default";
}
@@ -531,11 +549,12 @@ int x509_main(int argc, char **argv)
BIO_printf(bio_err,
"Signature did not match the certificate request\n");
goto end;
} else
} else {
BIO_printf(bio_err, "Signature ok\n");
}
print_name(bio_err, "subject=", X509_REQ_get_subject_name(req),
nmflag);
get_nameopt());
if ((x = X509_new()) == NULL)
goto end;
@@ -548,8 +567,9 @@ int x509_main(int argc, char **argv)
goto end;
ASN1_INTEGER_free(sno);
sno = NULL;
} else if (!X509_set_serialNumber(x, sno))
} else if (!X509_set_serialNumber(x, sno)) {
goto end;
}
if (!X509_set_issuer_name(x, X509_REQ_get_subject_name(req)))
goto end;
@@ -558,14 +578,15 @@ int x509_main(int argc, char **argv)
if (!set_cert_times(x, NULL, NULL, days))
goto end;
if (fkey)
if (fkey != NULL) {
X509_set_pubkey(x, fkey);
else {
} else {
pkey = X509_REQ_get0_pubkey(req);
X509_set_pubkey(x, pkey);
}
} else
} else {
x = load_cert(infile, informat, "Certificate");
}
if (x == NULL)
goto end;
@@ -575,13 +596,11 @@ int x509_main(int argc, char **argv)
goto end;
}
out = bio_open_default(outfile, 'w', outformat);
if (out == NULL)
goto end;
if (!noout || text || next_serial)
if (!noout || text || next_serial) {
OBJ_create("2.99999.3", "SET.ex3", "SET x509v3 extension 3");
}
if (alias)
X509_alias_set1(x, (unsigned char *)alias, -1);
@@ -590,7 +609,7 @@ int x509_main(int argc, char **argv)
if (clrreject)
X509_reject_clear(x);
if (trust) {
if (trust != NULL) {
for (i = 0; i < sk_ASN1_OBJECT_num(trust); i++) {
objtmp = sk_ASN1_OBJECT_value(trust, i);
X509_add1_trust_object(x, objtmp);
@@ -598,7 +617,7 @@ int x509_main(int argc, char **argv)
objtmp = NULL;
}
if (reject) {
if (reject != NULL) {
for (i = 0; i < sk_ASN1_OBJECT_num(reject); i++) {
objtmp = sk_ASN1_OBJECT_value(reject, i);
X509_add1_reject_object(x, objtmp);
@@ -616,10 +635,10 @@ int x509_main(int argc, char **argv)
if (num) {
for (i = 1; i <= num; i++) {
if (issuer == i) {
print_name(out, "issuer=", X509_get_issuer_name(x), nmflag);
print_name(out, "issuer=", X509_get_issuer_name(x), get_nameopt());
} else if (subject == i) {
print_name(out, "subject=",
X509_get_subject_name(x), nmflag);
X509_get_subject_name(x), get_nameopt());
} else if (serial == i) {
BIO_printf(out, "serial=");
i2a_ASN1_INTEGER(out, X509_get_serialNumber(x));
@@ -724,13 +743,10 @@ int x509_main(int argc, char **argv)
char *m;
int len;
X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof(buf));
BIO_printf(out, "/*\n"
" * Subject: %s\n", buf);
X509_NAME_oneline(X509_get_issuer_name(x), buf, sizeof(buf));
BIO_printf(out, " * Issuer: %s\n"
" */\n", buf);
print_name(out, "/*\n"
" * Subject: ", X509_get_subject_name(x), get_nameopt());
print_name(out, " * Issuer: ", X509_get_issuer_name(x), get_nameopt());
BIO_puts(out, " */\n");
len = i2d_X509(x, NULL);
m = app_malloc(len, "x509 name buffer");
@@ -745,7 +761,7 @@ int x509_main(int argc, char **argv)
print_array(out, "the_certificate", len, (unsigned char *)m);
OPENSSL_free(m);
} else if (text == i) {
X509_print_ex(out, x, nmflag, certflag);
X509_print_ex(out, x, get_nameopt(), certflag);
} else if (startdate == i) {
BIO_puts(out, "notBefore=");
ASN1_TIME_print(out, X509_get0_notBefore(x));
@@ -760,7 +776,7 @@ int x509_main(int argc, char **argv)
unsigned char md[EVP_MAX_MD_SIZE];
const EVP_MD *fdig = digest;
if (!fdig)
if (fdig == NULL)
fdig = EVP_sha1();
if (!X509_digest(x, fdig, md, &n)) {
@@ -785,8 +801,7 @@ int x509_main(int argc, char **argv)
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");
@@ -797,11 +812,10 @@ int x509_main(int argc, char **argv)
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;
@@ -826,12 +840,14 @@ int x509_main(int argc, char **argv)
goto end;
}
if (!noout) {
X509_REQ_print(out, rq);
X509_REQ_print_ex(out, rq, get_nameopt(), X509_FLAG_COMPAT);
PEM_write_bio_X509_REQ(out, rq);
}
noout = 1;
} else if (ocspid == i) {
X509_ocspid_print(out, x);
} else if (ext == i) {
print_x509v3_exts(out, x, exts);
}
}
}
@@ -856,9 +872,9 @@ int x509_main(int argc, char **argv)
goto end;
}
if (outformat == FORMAT_ASN1)
if (outformat == FORMAT_ASN1) {
i = i2d_X509_bio(out, x);
else if (outformat == FORMAT_PEM) {
} else if (outformat == FORMAT_PEM) {
if (trustout)
i = PEM_write_bio_X509_AUX(out, x);
else
@@ -874,8 +890,6 @@ int x509_main(int argc, char **argv)
}
ret = 0;
end:
if (need_rand)
app_RAND_write_file(NULL);
NCONF_free(extconf);
BIO_free_all(out);
X509_STORE_free(ctx);
@@ -893,33 +907,27 @@ int x509_main(int argc, char **argv)
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) {
OPENSSL_strlcpy(buf, CAfile, len);
for (p = buf; *p; p++)
if (*p == '.') {
*p = '\0';
break;
}
OPENSSL_strlcat(buf, POSTFIX, len);
} else
OPENSSL_strlcpy(buf, serialfile, len);
const char *p = strchr(CAfile, '.');
size_t len = p != NULL ? (size_t)(p - CAfile) : strlen(CAfile);
serial = load_serial(buf, create, NULL);
buf = app_malloc(len + sizeof(POSTFIX), "serial# buffer");
memcpy(buf, CAfile, len);
memcpy(buf + len, POSTFIX, sizeof(POSTFIX));
serialfile = buf;
}
serial = load_serial(serialfile, create, NULL);
if (serial == NULL)
goto end;
@@ -928,7 +936,7 @@ static ASN1_INTEGER *x509_load_serial(const char *CAfile, const char *serialfile
goto end;
}
if (!save_serial(buf, NULL, serial, &bs))
if (!save_serial(serialfile, NULL, serial, &bs))
goto end;
end:
@@ -942,7 +950,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;
@@ -986,7 +994,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) {
@@ -994,7 +1002,7 @@ static int x509_certify(X509_STORE *ctx, const char *CAfile, const EVP_MD *diges
X509_delete_ext(x, 0);
}
if (conf) {
if (conf != NULL) {
X509V3_CTX ctx2;
X509_set_version(x, 2); /* version 3 certificate */
X509V3_set_ctx(&ctx2, xca, x, NULL, NULL, 0);
@@ -1050,12 +1058,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;
@@ -1063,7 +1072,7 @@ static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext,
while (X509_get_ext_count(x) > 0)
X509_delete_ext(x, 0);
}
if (conf) {
if (conf != NULL) {
X509V3_CTX ctx;
X509_set_version(x, 2); /* version 3 certificate */
X509V3_set_ctx(&ctx, x, x, NULL, NULL, 0);
@@ -1097,3 +1106,93 @@ static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt)
}
return 1;
}
static int parse_ext_names(char *names, const char **result)
{
char *p, *q;
int cnt = 0, len = 0;
p = q = names;
len = strlen(names);
while (q - names <= len) {
if (*q != ',' && *q != '\0') {
q++;
continue;
}
if (p != q) {
/* found */
if (result != NULL) {
result[cnt] = p;
*q = '\0';
}
cnt++;
}
p = ++q;
}
return cnt;
}
static int print_x509v3_exts(BIO *bio, X509 *x, const char *ext_names)
{
const STACK_OF(X509_EXTENSION) *exts = NULL;
STACK_OF(X509_EXTENSION) *exts2 = NULL;
X509_EXTENSION *ext = NULL;
ASN1_OBJECT *obj;
int i, j, ret = 0, num, nn = 0;
const char *sn, **names = NULL;
char *tmp_ext_names = NULL;
exts = X509_get0_extensions(x);
if ((num = sk_X509_EXTENSION_num(exts)) <= 0) {
BIO_printf(bio, "No extensions in certificate\n");
ret = 1;
goto end;
}
/* parse comma separated ext name string */
if ((tmp_ext_names = OPENSSL_strdup(ext_names)) == NULL)
goto end;
if ((nn = parse_ext_names(tmp_ext_names, NULL)) == 0) {
BIO_printf(bio, "Invalid extension names: %s\n", ext_names);
goto end;
}
if ((names = OPENSSL_malloc(sizeof(char *) * nn)) == NULL)
goto end;
parse_ext_names(tmp_ext_names, names);
for (i = 0; i < num; i++) {
ext = sk_X509_EXTENSION_value(exts, i);
/* check if this ext is what we want */
obj = X509_EXTENSION_get_object(ext);
sn = OBJ_nid2sn(OBJ_obj2nid(obj));
if (sn == NULL || strcmp(sn, "UNDEF") == 0)
continue;
for (j = 0; j < nn; j++) {
if (strcmp(sn, names[j]) == 0) {
/* push the extension into a new stack */
if (exts2 == NULL
&& (exts2 = sk_X509_EXTENSION_new_null()) == NULL)
goto end;
if (!sk_X509_EXTENSION_push(exts2, ext))
goto end;
}
}
}
if (!sk_X509_EXTENSION_num(exts2)) {
BIO_printf(bio, "No extensions matched with %s\n", ext_names);
ret = 1;
goto end;
}
ret = X509V3_extensions_print(bio, NULL, exts2, 0, 0);
end:
sk_X509_EXTENSION_free(exts2);
OPENSSL_free(names);
OPENSSL_free(tmp_ext_names);
return ret;
}