Skip to content

Commit

Permalink
Use OSSL_STORE for load_{,pub}key() and load_cert() in apps/lib/apps.c
Browse files Browse the repository at this point in the history
This also adds the more flexible and general load_key_cert_crl()
as well as helper functions get_passwd(), cleanse(), and clear_free()
to be used also in apps/cmp.c etc.

Reviewed-by: Richard Levitte <[email protected]>
Reviewed-by: David von Oheimb <[email protected]>
(Merged from openssl#11755)
  • Loading branch information
DDvO committed May 15, 2020
1 parent 60d5331 commit 6d382c7
Show file tree
Hide file tree
Showing 43 changed files with 455 additions and 547 deletions.
9 changes: 4 additions & 5 deletions apps/ca.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,12 +215,12 @@ const OPTIONS ca_options[] = {
OPT_SECTION("Signing"),
{"md", OPT_MD, 's', "md to use; one of md2, md5, sha or sha1"},
{"keyfile", OPT_KEYFILE, 's', "Private key"},
{"keyform", OPT_KEYFORM, 'f', "Private key file format (PEM or ENGINE)"},
{"keyform", OPT_KEYFORM, 'f', "Private key file format (ENGINE, other values ignored)"},
{"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
{"key", OPT_KEY, 's', "Key to decode the private key if it is encrypted"},
{"cert", OPT_CERT, '<', "The CA cert"},
{"certform", OPT_CERTFORM, 'F',
"certificate input format (DER or PEM); default PEM"},
"certificate input format (DER/PEM/P12); has no effect"},
{"selfsign", OPT_SELFSIGN, '-',
"Sign a cert with the key associated with it"},
{"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"},
Expand Down Expand Up @@ -385,7 +385,7 @@ int ca_main(int argc, char **argv)
certfile = opt_arg();
break;
case OPT_CERTFORM:
if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &certformat))
if (!opt_format(opt_arg(), OPT_FMT_ANY, &certformat))
goto opthelp;
break;
case OPT_SELFSIGN:
Expand Down Expand Up @@ -573,8 +573,7 @@ int ca_main(int argc, char **argv)
}
}
pkey = load_key(keyfile, keyformat, 0, key, e, "CA private key");
if (key != NULL)
OPENSSL_cleanse(key, strlen(key));
cleanse(key);
if (pkey == NULL)
/* load_key() has already printed an appropriate message */
goto end;
Expand Down
153 changes: 1 addition & 152 deletions apps/cmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,157 +46,6 @@ DEFINE_STACK_OF(X509)
DEFINE_STACK_OF(X509_EXTENSION)
DEFINE_STACK_OF(OSSL_CMP_ITAV)

/* start TODO remove when PR #11755 is merged */
static char *get_passwd(const char *pass, const char *desc)
{
char *result = NULL;

app_passwd(pass, NULL, &result, NULL);
return result;
}

static void cleanse(char *str)
{
if (str != NULL)
OPENSSL_cleanse(str, strlen(str));
}

static void clear_free(char *str)
{
if (str != NULL)
OPENSSL_clear_free(str, strlen(str));
}

static int load_key_cert_crl(const char *uri, int maybe_stdin,
const char *pass, const char *desc,
EVP_PKEY **ppkey, X509 **pcert, X509_CRL **pcrl)
{
PW_CB_DATA uidata;
OSSL_STORE_CTX *ctx = NULL;
int ret = 0;

if (ppkey != NULL)
*ppkey = NULL;
if (pcert != NULL)
*pcert = NULL;
if (pcrl != NULL)
*pcrl = NULL;

uidata.password = pass;
uidata.prompt_info = uri;

ctx = OSSL_STORE_open(uri, get_ui_method(), &uidata, NULL, NULL);
if (ctx == NULL) {
BIO_printf(bio_err, "Could not open file or uri %s for loading %s\n",
uri, desc);
goto end;
}

for (;;) {
OSSL_STORE_INFO *info = OSSL_STORE_load(ctx);
int type = info == NULL ? 0 : OSSL_STORE_INFO_get_type(info);
const char *infostr =
info == NULL ? NULL : OSSL_STORE_INFO_type_string(type);
int err = 0;

if (info == NULL) {
if (OSSL_STORE_eof(ctx))
ret = 1;
break;
}

switch (type) {
case OSSL_STORE_INFO_PKEY:
if (ppkey != NULL && *ppkey == NULL)
err = ((*ppkey = OSSL_STORE_INFO_get1_PKEY(info)) == NULL);
break;
case OSSL_STORE_INFO_CERT:
if (pcert != NULL && *pcert == NULL)
err = ((*pcert = OSSL_STORE_INFO_get1_CERT(info)) == NULL);
break;
case OSSL_STORE_INFO_CRL:
if (pcrl != NULL && *pcrl == NULL)
err = ((*pcrl = OSSL_STORE_INFO_get1_CRL(info)) == NULL);
break;
default:
/* skip any other type */
break;
}
OSSL_STORE_INFO_free(info);
if (err) {
BIO_printf(bio_err, "Could not read %s of %s from %s\n",
infostr, desc, uri);
break;
}
}

end:
if (ctx != NULL)
OSSL_STORE_close(ctx);
if (!ret)
ERR_print_errors(bio_err);
return ret;
}

static
EVP_PKEY *load_key_preliminary(const char *uri, int format, int may_stdin,
const char *pass, ENGINE *e, const char *desc)
{
EVP_PKEY *pkey = NULL;

if (desc == NULL)
desc = "private key";

if (format == FORMAT_ENGINE) {
if (e == NULL) {
BIO_printf(bio_err, "No engine specified for loading %s\n", desc);
} else {
#ifndef OPENSSL_NO_ENGINE
PW_CB_DATA cb_data;

cb_data.password = pass;
cb_data.prompt_info = uri;
if (ENGINE_init(e)) {
pkey = ENGINE_load_private_key(e, uri,
(UI_METHOD *)get_ui_method(),
&cb_data);
ENGINE_finish(e);
}
if (pkey == NULL) {
BIO_printf(bio_err, "Cannot load %s from engine\n", desc);
ERR_print_errors(bio_err);
}
#else
BIO_printf(bio_err, "Engines not supported for loading %s\n", desc);
#endif
}
} else {
(void)load_key_cert_crl(uri, may_stdin, pass, desc, &pkey, NULL, NULL);
}

if (pkey == NULL) {
BIO_printf(bio_err, "Unable to load %s\n", desc);
ERR_print_errors(bio_err);
}
return pkey;
}

static X509 *load_cert_pass(const char *uri, int maybe_stdin,
const char *pass, const char *desc)
{
X509 *cert = NULL;

if (desc == NULL)
desc = "certificate";
(void)load_key_cert_crl(uri, maybe_stdin, pass, desc, NULL, &cert, NULL);
if (cert == NULL) {
BIO_printf(bio_err, "Unable to load %s\n", desc);
ERR_print_errors(bio_err);
}
return cert;
}
/* end TODO remove when PR #11755 is merged */

static char *opt_config = NULL;
#define CMP_SECTION "cmp"
#define SECTION_NAME_MAX 40 /* max length of section name */
Expand Down Expand Up @@ -832,7 +681,7 @@ static EVP_PKEY *load_key_pwd(const char *uri, int format,
const char *pass, ENGINE *e, const char *desc)
{
char *pass_string = get_passwd(pass, desc);
EVP_PKEY *pkey = load_key_preliminary(uri, format, 0, pass_string, e, desc);
EVP_PKEY *pkey = load_key(uri, format, 0, pass_string, e, desc);

clear_free(pass_string);
return pkey;
Expand Down
15 changes: 8 additions & 7 deletions apps/cms.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ const OPTIONS cms_options[] = {
{"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
{"inkey", OPT_INKEY, 's',
"Input private key (if not signer or recipient)"},
{"keyform", OPT_KEYFORM, 'f', "Input private key format (PEM or ENGINE)"},
{"keyform", OPT_KEYFORM, 'f', "Input private key format (ENGINE, other values ignored)"},
{"keyopt", OPT_KEYOPT, 's', "Set public key parameters as n:v pairs"},

OPT_SECTION("Mail header"),
Expand Down Expand Up @@ -576,7 +576,7 @@ int cms_main(int argc, char **argv)
if (operation == SMIME_ENCRYPT) {
if (encerts == NULL && (encerts = sk_X509_new_null()) == NULL)
goto end;
cert = load_cert(opt_arg(), FORMAT_PEM,
cert = load_cert(opt_arg(), FORMAT_UNDEF,
"recipient certificate file");
if (cert == NULL)
goto end;
Expand Down Expand Up @@ -756,7 +756,7 @@ int cms_main(int argc, char **argv)
if ((encerts = sk_X509_new_null()) == NULL)
goto end;
while (*argv) {
if ((cert = load_cert(*argv, FORMAT_PEM,
if ((cert = load_cert(*argv, FORMAT_UNDEF,
"recipient certificate file")) == NULL)
goto end;
sk_X509_push(encerts, cert);
Expand All @@ -774,23 +774,23 @@ int cms_main(int argc, char **argv)
}

if (recipfile != NULL && (operation == SMIME_DECRYPT)) {
if ((recip = load_cert(recipfile, FORMAT_PEM,
if ((recip = load_cert(recipfile, FORMAT_UNDEF,
"recipient certificate file")) == NULL) {
ERR_print_errors(bio_err);
goto end;
}
}

if (originatorfile != NULL) {
if ((originator = load_cert(originatorfile, FORMAT_PEM,
if ((originator = load_cert(originatorfile, FORMAT_UNDEF,
"originator certificate file")) == NULL) {
ERR_print_errors(bio_err);
goto end;
}
}

if (operation == SMIME_SIGN_RECEIPT) {
if ((signer = load_cert(signerfile, FORMAT_PEM,
if ((signer = load_cert(signerfile, FORMAT_UNDEF,
"receipt signer certificate file")) == NULL) {
ERR_print_errors(bio_err);
goto end;
Expand Down Expand Up @@ -1019,7 +1019,8 @@ int cms_main(int argc, char **argv)
signerfile = sk_OPENSSL_STRING_value(sksigners, i);
keyfile = sk_OPENSSL_STRING_value(skkeys, i);

signer = load_cert(signerfile, FORMAT_PEM, "signer certificate");
signer = load_cert(signerfile, FORMAT_UNDEF,
"signer certificate");
if (signer == NULL) {
ret = 2;
goto end;
Expand Down
6 changes: 3 additions & 3 deletions apps/crl.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ const OPTIONS crl_options[] = {

OPT_SECTION("Input"),
{"in", OPT_IN, '<', "Input file - default stdin"},
{"inform", OPT_INFORM, 'F', "Input format; default PEM"},
{"inform", OPT_INFORM, 'F', "CRL input format (DER or PEM); has no effect"},
{"key", OPT_KEY, '<', "CRL signing Private key to use"},
{"keyform", OPT_KEYFORM, 'F', "Private key file format (PEM or ENGINE)"},
{"keyform", OPT_KEYFORM, 'F', "Private key file format (DER/PEM/P12); has no effect"},

OPT_SECTION("Output"),
{"out", OPT_OUT, '>', "output file - default stdout"},
Expand Down Expand Up @@ -122,7 +122,7 @@ int crl_main(int argc, char **argv)
outfile = opt_arg();
break;
case OPT_KEYFORM:
if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &keyformat))
if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyformat))
goto opthelp;
break;
case OPT_KEY:
Expand Down
2 changes: 1 addition & 1 deletion apps/dgst.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ const OPTIONS dgst_options[] = {
{"c", OPT_C, '-', "Print the digest with separating colons"},
{"r", OPT_R, '-', "Print the digest in coreutils format"},
{"out", OPT_OUT, '>', "Output to filename rather than stdout"},
{"keyform", OPT_KEYFORM, 'f', "Key file format (PEM or ENGINE)"},
{"keyform", OPT_KEYFORM, 'f', "Key file format (ENGINE, other values ignored)"},
{"hex", OPT_HEX, '-', "Print as hex dump"},
{"binary", OPT_BINARY, '-', "Print in binary form"},
{"d", OPT_DEBUG, '-', "Print debug info"},
Expand Down
2 changes: 1 addition & 1 deletion apps/dsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ const OPTIONS dsa_options[] = {

OPT_SECTION("Input"),
{"in", OPT_IN, 's', "Input key"},
{"inform", OPT_INFORM, 'f', "Input format, DER PEM PVK"},
{"inform", OPT_INFORM, 'f', "Input format (DER/PEM/PVK); has no effect"},
{"pubin", OPT_PUBIN, '-', "Expect a public key in input file"},
{"passin", OPT_PASSIN, 's', "Input file pass phrase source"},

Expand Down
2 changes: 1 addition & 1 deletion apps/ec.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const OPTIONS ec_options[] = {

OPT_SECTION("Input"),
{"in", OPT_IN, 's', "Input file"},
{"inform", OPT_INFORM, 'f', "Input format - DER or PEM"},
{"inform", OPT_INFORM, 'f', "Input format (DER/PEM/P12/ENGINE)"},
{"pubin", OPT_PUBIN, '-', "Expect a public key in input file"},
{"passin", OPT_PASSIN, 's', "Input file pass phrase source"},
{"check", OPT_CHECK, '-', "check key consistency"},
Expand Down
2 changes: 1 addition & 1 deletion apps/enc.c
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,7 @@ int enc_main(int argc, char **argv)
goto end;
}
/* wiping secret data as we no longer need it */
OPENSSL_cleanse(hkey, strlen(hkey));
cleanse(hkey);
}

if ((benc = BIO_new(BIO_f_cipher())) == NULL)
Expand Down
17 changes: 13 additions & 4 deletions apps/include/apps.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,19 +102,28 @@ 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);
int copy_extensions(X509 *x, X509_REQ *req, int copy_type);
char *get_passwd(const char *pass, const char *desc);
int app_passwd(const char *arg1, const char *arg2, char **pass1, char **pass2);
int add_oid_section(CONF *conf);
X509_REQ *load_csr(const char *file, int format, const char *desc);
X509 *load_cert(const char *file, int format, const char *desc);
X509_CRL *load_crl(const char *infile, int format, const char *desc);
EVP_PKEY *load_key(const char *file, int format, int maybe_stdin,
X509 *load_cert_pass(const char *uri, int maybe_stdin,
const char *pass, const char *desc);
/* the format parameter is meanwhile not needed anymore and thus ignored */
X509 *load_cert(const char *uri, int format, const char *desc);
X509_CRL *load_crl(const char *uri, int format, const char *desc);
void cleanse(char *str);
void clear_free(char *str);
EVP_PKEY *load_key(const char *uri, int format, int maybe_stdin,
const char *pass, ENGINE *e, const char *desc);
EVP_PKEY *load_pubkey(const char *file, int format, int maybe_stdin,
EVP_PKEY *load_pubkey(const char *uri, int format, int maybe_stdin,
const char *pass, ENGINE *e, const char *desc);
int load_certs(const char *file, STACK_OF(X509) **certs, int format,
const char *pass, const char *desc);
int load_crls(const char *file, STACK_OF(X509_CRL) **crls, int format,
const char *pass, const char *desc);
int load_key_cert_crl(const char *uri, int maybe_stdin,
const char *pass, const char *desc,
EVP_PKEY **ppkey, X509 **pcert, X509_CRL **pcrl);
X509_STORE *setup_verify(const char *CAfile, int noCAfile,
const char *CApath, int noCApath,
const char *CAstore, int noCAstore);
Expand Down
4 changes: 2 additions & 2 deletions apps/include/opt.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,9 @@
{ "xchain_build", OPT_X_CHAIN_BUILD, '-', \
"build certificate chain for the extended certificates"}, \
{ "xcertform", OPT_X_CERTFORM, 'F', \
"format of Extended certificate (PEM or DER) PEM default " }, \
"format of Extended certificate (PEM/DER/P12); has no effect" }, \
{ "xkeyform", OPT_X_KEYFORM, 'F', \
"format of Extended certificate's key (PEM or DER) PEM default"}
"format of Extended certificate's key (DER/PEM/P12); has no effect"}

# define OPT_X_CASES \
OPT_X__FIRST: case OPT_X__LAST: break; \
Expand Down
Loading

0 comments on commit 6d382c7

Please sign in to comment.