diff options
author | Rich Salz <rsalz@akamai.com> | 2015-05-02 10:01:33 -0400 |
---|---|---|
committer | Rich Salz <rsalz@openssl.org> | 2015-06-15 18:26:56 -0400 |
commit | 3b061a00e39d2e4ad524ff01cbdc0c53fe8171ee (patch) | |
tree | 0389af5c46f6c56ab6f88c737f55aa07493dfd39 | |
parent | d31fb0b5b341aa7883b487d07e6a56d216224e25 (diff) |
RT2547: Tighten perms on generated privkey files
When generating a private key, try to make the output file be readable
only by the owner. Put it in CHANGES file since it might be noticeable.
Add "int private" flag to apps that write private keys, and check that it's
set whenever we do write a private key. Checked via assert so that this
bug (security-related) gets fixed. Thanks to Viktor for help in tracing
the code-paths where private keys are written.
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
-rw-r--r-- | CHANGES | 4 | ||||
-rw-r--r-- | apps/apps.c | 1 | ||||
-rw-r--r-- | apps/apps.h | 2 | ||||
-rw-r--r-- | apps/dsa.c | 26 | ||||
-rw-r--r-- | apps/dsaparam.c | 10 | ||||
-rw-r--r-- | apps/ec.c | 19 | ||||
-rw-r--r-- | apps/ecparam.c | 9 | ||||
-rw-r--r-- | apps/gendsa.c | 6 | ||||
-rw-r--r-- | apps/genpkey.c | 13 | ||||
-rw-r--r-- | apps/genrsa.c | 22 | ||||
-rw-r--r-- | apps/openssl.c | 71 | ||||
-rw-r--r-- | apps/opt.c | 1 | ||||
-rw-r--r-- | apps/passwd.c | 1 | ||||
-rw-r--r-- | apps/pkcs12.c | 8 | ||||
-rw-r--r-- | apps/pkcs8.c | 8 | ||||
-rw-r--r-- | apps/pkey.c | 12 | ||||
-rw-r--r-- | apps/req.c | 8 | ||||
-rw-r--r-- | apps/rsa.c | 22 | ||||
-rw-r--r-- | apps/s_cb.c | 1 | ||||
-rw-r--r-- | apps/s_client.c | 1 | ||||
-rw-r--r-- | apps/s_server.c | 1 | ||||
-rw-r--r-- | apps/x509.c | 1 |
22 files changed, 184 insertions, 63 deletions
@@ -41,6 +41,10 @@ code and the associated standard is no longer considered fit-for-purpose. [Matt Caswell] + *) RT2547 was closed. When generating a private key, try to make the + output file readable only by the owner. This behavior change might + be noticeable when interacting with other software. + *) Added HTTP GET support to the ocsp command. [Rich Salz] diff --git a/apps/apps.c b/apps/apps.c index 60f71c3b8b..3f2c049404 100644 --- a/apps/apps.c +++ b/apps/apps.c @@ -124,7 +124,6 @@ #include <sys/types.h> #include <ctype.h> #include <errno.h> -#include <assert.h> #include <openssl/err.h> #include <openssl/x509.h> #include <openssl/x509v3.h> diff --git a/apps/apps.h b/apps/apps.h index a8652a1bb7..b83d4b2aee 100644 --- a/apps/apps.h +++ b/apps/apps.h @@ -113,6 +113,7 @@ # define HEADER_APPS_H # include "e_os.h" +# include <assert.h> # include <openssl/bio.h> # include <openssl/x509.h> @@ -153,6 +154,7 @@ extern BIO *bio_out; extern BIO *bio_err; BIO *dup_bio_in(void); BIO *dup_bio_out(void); +BIO *bio_open_owner(const char *filename, const char *mode, int private); BIO *bio_open_default(const char *filename, const char *mode); BIO *bio_open_default_quiet(const char *filename, const char *mode); CONF *app_load_config(const char *filename); diff --git a/apps/dsa.c b/apps/dsa.c index f61e151f88..9998bfe30a 100644 --- a/apps/dsa.c +++ b/apps/dsa.c @@ -114,6 +114,7 @@ int dsa_main(int argc, char **argv) OPTION_CHOICE o; int informat = FORMAT_PEM, outformat = FORMAT_PEM, text = 0, noout = 0; int i, modulus = 0, pubin = 0, pubout = 0, pvk_encr = 2, ret = 1; + int private = 0; prog = opt_init(argc, argv, dsa_options); while ((o = opt_next()) != OPT_EOF) { @@ -192,6 +193,9 @@ int dsa_main(int argc, char **argv) } argc = opt_num_rest(); argv = opt_rest(); + private = pubin || pubout ? 0 : 1; + if (text) + private = 1; if (!app_passwd(passinarg, passoutarg, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); @@ -221,16 +225,18 @@ int dsa_main(int argc, char **argv) goto end; } - out = bio_open_default(outfile, "w"); + out = bio_open_owner(outfile, "w", private); if (out == NULL) goto end; - if (text) + if (text) { + assert(private); if (!DSA_print(out, dsa, 0)) { perror(outfile); ERR_print_errors(bio_err); goto end; } + } if (modulus) { BIO_printf(out, "Public Key="); @@ -246,25 +252,33 @@ int dsa_main(int argc, char **argv) if (outformat == FORMAT_ASN1) { 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) i = PEM_write_bio_DSA_PUBKEY(out, dsa); - else + else { + assert(private); i = PEM_write_bio_DSAPrivateKey(out, dsa, enc, NULL, 0, NULL, passout); + } # if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_RC4) } else if (outformat == FORMAT_MSBLOB || outformat == FORMAT_PVK) { EVP_PKEY *pk; pk = EVP_PKEY_new(); EVP_PKEY_set1_DSA(pk, dsa); - if (outformat == FORMAT_PVK) + if (outformat == FORMAT_PVK) { + assert(private); i = i2b_PVK_bio(out, pk, pvk_encr, 0, passout); + } else if (pubin || pubout) i = i2b_PublicKey_bio(out, pk); - else + else { + assert(private); i = i2b_PrivateKey_bio(out, pk); + } EVP_PKEY_free(pk); # endif } else { diff --git a/apps/dsaparam.c b/apps/dsaparam.c index 27170a22a2..8d48313d2b 100644 --- a/apps/dsaparam.c +++ b/apps/dsaparam.c @@ -58,7 +58,6 @@ #include <openssl/opensslconf.h> /* for OPENSSL_NO_DSA */ #ifndef OPENSSL_NO_DSA -# include <assert.h> # include <stdio.h> # include <stdlib.h> # include <time.h> @@ -118,9 +117,8 @@ int dsaparam_main(int argc, char **argv) BIO *in = NULL, *out = NULL; BN_GENCB *cb = NULL; int numbits = -1, num = 0, genkey = 0, need_rand = 0, non_fips_allow = 0; - int informat = FORMAT_PEM, outformat = FORMAT_PEM, noout = 0, C = 0, ret = - 1; - int i, text = 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 @@ -195,11 +193,12 @@ int dsaparam_main(int argc, char **argv) numbits = num; need_rand = 1; } + private = genkey ? 1 : 0; in = bio_open_default(infile, "r"); if (in == NULL) goto end; - out = bio_open_default(outfile, "w"); + out = bio_open_owner(outfile, "w", private); if (out == NULL) goto end; @@ -320,6 +319,7 @@ int dsaparam_main(int argc, char **argv) DSA_free(dsakey); goto end; } + assert(private); if (outformat == FORMAT_ASN1) i = i2d_DSAPrivateKey_bio(out, dsakey); else @@ -121,7 +121,7 @@ int ec_main(int argc, char **argv) OPTION_CHOICE o; int asn1_flag = OPENSSL_EC_NAMED_CURVE, new_form = 0, new_asn1_flag = 0; int informat = FORMAT_PEM, outformat = FORMAT_PEM, text = 0, noout = 0; - int pubin = 0, pubout = 0, param_out = 0, i, ret = 1; + int pubin = 0, pubout = 0, param_out = 0, i, ret = 1, private = 0; prog = opt_init(argc, argv, ec_options); while ((o = opt_next()) != OPT_EOF) { @@ -193,6 +193,9 @@ int ec_main(int argc, char **argv) } argc = opt_num_rest(); argv = opt_rest(); + private = param_out || pubin || pubout ? 0 : 1; + if (text) + private = 1; if (!app_passwd(passinarg, passoutarg, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); @@ -224,7 +227,7 @@ int ec_main(int argc, char **argv) goto end; } - out = bio_open_default(outfile, WB(outformat)); + out = bio_open_owner(outfile, WB(outformat), private); if (out == NULL) goto end; @@ -236,12 +239,14 @@ int ec_main(int argc, char **argv) if (new_asn1_flag) EC_KEY_set_asn1_flag(eckey, asn1_flag); - if (text) + if (text) { + assert(private); if (!EC_KEY_print(out, eckey, 0)) { perror(outfile); ERR_print_errors(bio_err); goto end; } + } if (noout) { ret = 0; @@ -254,16 +259,20 @@ int ec_main(int argc, char **argv) i = i2d_ECPKParameters_bio(out, group); 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) i = PEM_write_bio_ECPKParameters(out, group); 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); + } } if (!i) { diff --git a/apps/ecparam.c b/apps/ecparam.c index ae755735b7..a0781c525b 100644 --- a/apps/ecparam.c +++ b/apps/ecparam.c @@ -70,7 +70,6 @@ #include <openssl/opensslconf.h> #ifndef OPENSSL_NO_EC -# include <assert.h> # include <stdio.h> # include <stdlib.h> # include <time.h> @@ -142,8 +141,8 @@ int ecparam_main(int argc, char **argv) unsigned char *buffer = NULL; OPTION_CHOICE o; int asn1_flag = OPENSSL_EC_NAMED_CURVE, new_asn1_flag = 0; - int informat = FORMAT_PEM, outformat = FORMAT_PEM, noout = 0, C = 0, ret = - 1; + 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; @@ -219,6 +218,7 @@ int ecparam_main(int argc, char **argv) } argc = opt_num_rest(); argv = opt_rest(); + private = genkey ? 1 : 0; if (!app_load_modules(NULL)) goto end; @@ -226,7 +226,7 @@ int ecparam_main(int argc, char **argv) in = bio_open_default(infile, RB(informat)); if (in == NULL) goto end; - out = bio_open_default(outfile, WB(outformat)); + out = bio_open_owner(outfile, WB(outformat), private); if (out == NULL) goto end; @@ -473,6 +473,7 @@ int ecparam_main(int argc, char **argv) EC_KEY_free(eckey); goto end; } + assert(private); if (outformat == FORMAT_ASN1) i = i2d_ECPrivateKey_bio(out, eckey); else diff --git a/apps/gendsa.c b/apps/gendsa.c index 01bbcebf0e..087a44a1e8 100644 --- a/apps/gendsa.c +++ b/apps/gendsa.c @@ -99,7 +99,7 @@ int gendsa_main(int argc, char **argv) char *inrand = NULL, *dsaparams = NULL; char *outfile = NULL, *passoutarg = NULL, *passout = NULL, *prog; OPTION_CHOICE o; - int ret = 1; + int ret = 1, private = 0; prog = opt_init(argc, argv, gendsa_options); while ((o = opt_next()) != OPT_EOF) { @@ -133,6 +133,7 @@ int gendsa_main(int argc, char **argv) } argc = opt_num_rest(); argv = opt_rest(); + private = 1; if (argc != 1) goto opthelp; @@ -157,7 +158,7 @@ int gendsa_main(int argc, char **argv) BIO_free(in); in = NULL; - out = bio_open_default(outfile, "w"); + out = bio_open_owner(outfile, "w", private); if (out == NULL) goto end2; @@ -175,6 +176,7 @@ int gendsa_main(int argc, char **argv) app_RAND_write_file(NULL); + assert(private); if (!PEM_write_bio_DSAPrivateKey(out, dsa, enc, NULL, 0, NULL, passout)) goto end; ret = 0; diff --git a/apps/genpkey.c b/apps/genpkey.c index 7c8d551827..dbbedaa35e 100644 --- a/apps/genpkey.c +++ b/apps/genpkey.c @@ -105,6 +105,7 @@ int genpkey_main(int argc, char **argv) const EVP_CIPHER *cipher = NULL; OPTION_CHOICE o; int outformat = FORMAT_PEM, text = 0, ret = 1, rv, do_param = 0; + int private = 0; prog = opt_init(argc, argv, genpkey_options); while ((o = opt_next()) != OPT_EOF) { @@ -125,7 +126,6 @@ int genpkey_main(int argc, char **argv) case OPT_OUT: outfile = opt_arg(); break; - case OPT_PASS: passarg = opt_arg(); break; @@ -171,6 +171,7 @@ int genpkey_main(int argc, char **argv) } argc = opt_num_rest(); argv = opt_rest(); + private = do_param ? 0 : 1; if (ctx == NULL) goto opthelp; @@ -183,7 +184,7 @@ int genpkey_main(int argc, char **argv) if (!app_load_modules(NULL)) goto end; - out = bio_open_default(outfile, "wb"); + out = bio_open_owner(outfile, "wb", private); if (out == NULL) goto end; @@ -206,11 +207,13 @@ int genpkey_main(int argc, char **argv) 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) + } else if (outformat == FORMAT_ASN1) { + assert(private); rv = i2d_PrivateKey_bio(out, pkey); - else { + } else { BIO_printf(bio_err, "Bad format specified for key\n"); goto end; } diff --git a/apps/genrsa.c b/apps/genrsa.c index 80d9ea6f01..bb8437fa48 100644 --- a/apps/genrsa.c +++ b/apps/genrsa.c @@ -102,12 +102,13 @@ OPTIONS genrsa_options[] = { int genrsa_main(int argc, char **argv) { BN_GENCB *cb = BN_GENCB_new(); + PW_CB_DATA cb_data; ENGINE *e = NULL; BIGNUM *bn = BN_new(); BIO *out = NULL; RSA *rsa = NULL; const EVP_CIPHER *enc = NULL; - int ret = 1, non_fips_allow = 0, num = DEFBITS; + int ret = 1, non_fips_allow = 0, num = DEFBITS, private = 0; unsigned long f4 = RSA_F4; char *outfile = NULL, *passoutarg = NULL, *passout = NULL; char *inrand = NULL, *prog, *hexe, *dece; @@ -157,6 +158,7 @@ int genrsa_main(int argc, char **argv) } argc = opt_num_rest(); argv = opt_rest(); + private = 1; if (argv[0] && (!opt_int(argv[0], &num) || num <= 0)) goto end; @@ -169,7 +171,7 @@ int genrsa_main(int argc, char **argv) if (!app_load_modules(NULL)) goto end; - out = bio_open_default(outfile, "w"); + out = bio_open_owner(outfile, "w", private); if (out == NULL) goto end; @@ -203,15 +205,13 @@ int genrsa_main(int argc, char **argv) } OPENSSL_free(hexe); OPENSSL_free(dece); - { - PW_CB_DATA cb_data; - cb_data.password = passout; - cb_data.prompt_info = outfile; - if (!PEM_write_bio_RSAPrivateKey(out, rsa, enc, NULL, 0, - (pem_password_cb *)password_callback, - &cb_data)) - goto end; - } + cb_data.password = passout; + cb_data.prompt_info = outfile; + assert(private); + if (!PEM_write_bio_RSAPrivateKey(out, rsa, enc, NULL, 0, + (pem_password_cb *)password_callback, + &cb_data)) + goto end; ret = 0; end: diff --git a/apps/openssl.c b/apps/openssl.c index 911772649a..7c202cf8d1 100644 --- a/apps/openssl.c +++ b/apps/openssl.c @@ -122,13 +122,23 @@ #ifndef OPENSSL_NO_ENGINE # include <openssl/engine.h> #endif -/* needed for the _O_BINARY defs in the MS world */ -#define USE_SOCKETS -#include "s_apps.h" #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 +#ifndef NO_SYS_TYPES_H +# include <sys/types.h> +#endif +#ifndef OPENSSL_NO_POSIX_IO +# include <sys/stat.h> +# include <fcntl.h> +#endif #define INCLUDE_FUNCTION_TABLE #include "apps.h" @@ -289,6 +299,59 @@ void unbuffer(FILE *fp) setbuf(fp, NULL); } +/* + * Open a file for writing, owner-read-only. + */ +BIO *bio_open_owner(const char *filename, const char *modestr, int private) +{ + FILE *fp = NULL; + BIO *b = NULL; + int fd = -1, bflags, mode, binmode; + + if (!private || filename == NULL || strcmp(filename, "-") == 0) + return bio_open_default(filename, modestr); + + mode = O_WRONLY; +#ifdef O_CREAT + mode |= O_CREAT; +#endif +#ifdef O_TRUNC + mode |= O_TRUNC; +#endif + binmode = strchr(modestr, 'b') != NULL; + if (binmode) { +#ifdef O_BINARY + mode |= O_BINARY; +#elif defined(_O_BINARY) + mode |= _O_BINARY; +#endif + } + + fd = open(filename, mode, 0600); + if (fd < 0) + goto err; + fp = fdopen(fd, modestr); + if (fp == NULL) + goto err; + bflags = BIO_CLOSE; + if (!binmode) + bflags |= BIO_FP_TEXT; + b = BIO_new_fp(fp, bflags); + if (b) + return b; + + err: + BIO_printf(bio_err, "%s: Can't open \"%s\" for writing, %s\n", + opt_getprog(), filename, strerror(errno)); + ERR_print_errors(bio_err); + /* If we have fp, then fdopen took over fd, so don't close both. */ + if (fp) + fclose(fp); + else if (fd >= 0) + close(fd); + return NULL; +} + static BIO *bio_open_default_(const char *filename, const char *mode, int quiet) { BIO *ret; @@ -320,10 +383,12 @@ static BIO *bio_open_default_(const char *filename, const char *mode, int quiet) ERR_print_errors(bio_err); return NULL; } + BIO *bio_open_default(const char *filename, const char *mode) { return bio_open_default_(filename, mode, 0); } + BIO *bio_open_default_quiet(const char *filename, const char *mode) { return bio_open_default_(filename, mode, 1); diff --git a/apps/opt.c b/apps/opt.c index 3e2831cc1f..b81cec4fa7 100644 --- a/apps/opt.c +++ b/apps/opt.c @@ -49,7 +49,6 @@ /* #define COMPILE_STANDALONE_TEST_DRIVER */ #include "apps.h" -#include <assert.h> #include <string.h> #if !defined(OPENSSL_SYS_MSDOS) # include OPENSSL_UNISTD diff --git a/apps/passwd.c b/apps/passwd.c index 0e168c4a86..dbae620645 100644 --- a/apps/passwd.c +++ b/apps/passwd.c @@ -53,7 +53,6 @@ #if !defined(OPENSSL_NO_DES) || !defined(NO_MD5CRYPT_1) -# include <assert.h> # include <string.h> # include "apps.h" diff --git a/apps/pkcs12.c b/apps/pkcs12.c index 05bb1ad98d..5b14dd5320 100644 --- a/apps/pkcs12.c +++ b/apps/pkcs12.c @@ -169,7 +169,7 @@ int pkcs12_main(int argc, char **argv) int cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; # endif int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; - int ret = 1, macver = 1, noprompt = 0, add_lmk = 0; + int ret = 1, macver = 1, noprompt = 0, add_lmk = 0, private = 0; char *passinarg = NULL, *passoutarg = NULL, *passarg = NULL; char *passin = NULL, *passout = NULL, *inrand = NULL, *macalg = NULL; char *cpass = NULL, *mpass = NULL, *CApath = NULL, *CAfile = NULL; @@ -314,6 +314,7 @@ int pkcs12_main(int argc, char **argv) } argc = opt_num_rest(); argv = opt_rest(); + private = 1; if (passarg) { if (export_cert) @@ -355,8 +356,7 @@ int pkcs12_main(int argc, char **argv) in = bio_open_default(infile, "rb"); if (in == NULL) goto end; - - out = bio_open_default(outfile, "wb"); + out = bio_open_owner(outfile, "wb", private); if (out == NULL) goto end; @@ -500,6 +500,7 @@ int pkcs12_main(int argc, char **argv) if (maciter != -1) PKCS12_set_mac(p12, mpass, -1, NULL, 0, maciter, macmd); + assert(private); i2d_PKCS12_bio(out, p12); ret = 0; @@ -545,6 +546,7 @@ int pkcs12_main(int argc, char **argv) } } + assert(private); if (!dump_certs_keys_p12(out, p12, cpass, -1, options, passout, enc)) { BIO_printf(bio_err, "Error outputting keys and certificates\n"); ERR_print_errors(bio_err); diff --git a/apps/pkcs8.c b/apps/pkcs8.c index e94a232f22..919b8f1370 100644 --- a/apps/pkcs8.c +++ b/apps/pkcs8.c @@ -115,6 +115,7 @@ int pkcs8_main(int argc, char **argv) OPTION_CHOICE o; int nocrypt = 0, ret = 1, iter = PKCS12_DEFAULT_ITER, p8_broken = PKCS8_OK; int informat = FORMAT_PEM, outformat = FORMAT_PEM, topk8 = 0, pbe_nid = -1; + int private = 0; unsigned long scrypt_N = 0, scrypt_r = 0, scrypt_p = 0; prog = opt_init(argc, argv, pkcs8_options); @@ -217,6 +218,7 @@ int pkcs8_main(int argc, char **argv) } argc = opt_num_rest(); argv = opt_rest(); + private = 1; if (!app_passwd(passinarg, passoutarg, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); @@ -232,9 +234,10 @@ int pkcs8_main(int argc, char **argv) in = bio_open_default(infile, "rb"); if (in == NULL) goto end; - out = bio_open_default(outfile, "wb"); + out = bio_open_owner(outfile, "wb", private); if (out == NULL) goto end; + if (topk8) { pkey = load_key(infile, informat, 1, passin, e, "key"); if (!pkey) @@ -245,6 +248,7 @@ int pkcs8_main(int argc, char **argv) goto end; } if (nocrypt) { + assert(private); if (outformat == FORMAT_PEM) PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8inf); else if (outformat == FORMAT_ASN1) @@ -289,6 +293,7 @@ int pkcs8_main(int argc, char **argv) goto end; } app_RAND_write_file(NULL); + assert(private); if (outformat == FORMAT_PEM) PEM_write_bio_PKCS8(out, p8); else if (outformat == FORMAT_ASN1) @@ -373,6 +378,7 @@ int pkcs8_main(int argc, char **argv) } } + assert(private); if (outformat == FORMAT_PEM) PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL, passout); else if (outformat == FORMAT_ASN1) diff --git a/apps/pkey.c b/apps/pkey.c index 875087fd18..80c2e154dd 100644 --- a/apps/pkey.c +++ b/apps/pkey.c @@ -101,6 +101,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; prog = opt_init(argc, argv, pkey_options); while ((o = opt_next()) != OPT_EOF) { @@ -159,6 +160,9 @@ int pkey_main(int argc, char **argv) } argc = opt_num_rest(); argv = opt_rest(); + private = !noout && !pubout ? 1 : 0; + if (text && !pubtext) + private = 1; if (!app_passwd(passinarg, passoutarg, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); @@ -168,7 +172,7 @@ int pkey_main(int argc, char **argv) if (!app_load_modules(NULL)) goto end; - out = bio_open_default(outfile, "wb"); + out = bio_open_owner(outfile, "wb", private); if (out == NULL) goto end; @@ -181,12 +185,14 @@ int pkey_main(int argc, char **argv) if (!noout) { if (outformat == FORMAT_PEM) { + assert(private); if (pubout) PEM_write_bio_PUBKEY(out, pkey); else PEM_write_bio_PrivateKey(out, pkey, cipher, NULL, 0, NULL, passout); } else if (outformat == FORMAT_ASN1) { + assert(private); if (pubout) i2d_PUBKEY_bio(out, pkey); else @@ -201,8 +207,10 @@ int pkey_main(int argc, char **argv) if (text) { if (pubtext) EVP_PKEY_print_public(out, pkey, 0, NULL); - else + else { + assert(private); EVP_PKEY_print_private(out, pkey, 0, NULL); + } } ret = 0; diff --git a/apps/req.c b/apps/req.c index 712037dc17..03736cc34b 100644 --- a/apps/req.c +++ b/apps/req.c @@ -204,8 +204,8 @@ 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, pkey_type = -1; + int ret = 1, x509 = 0, days = 30, 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, kludge = 0, newhdr = 0, subject = 0, pubkey = 0; @@ -375,6 +375,7 @@ int req_main(int argc, char **argv) } argc = opt_num_rest(); argv = opt_rest(); + private = newreq && (pkey == NULL) ? 1 : 0; if (!app_passwd(passargin, passargout, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); @@ -569,7 +570,7 @@ int req_main(int argc, char **argv) BIO_printf(bio_err, "writing new private key to stdout\n"); else BIO_printf(bio_err, "writing new private key to '%s'\n", keyout); - out = bio_open_default(keyout, "w"); + out = bio_open_owner(keyout, "w", private); if (out == NULL) goto end; @@ -587,6 +588,7 @@ int req_main(int argc, char **argv) i = 0; loop: + assert(private); if (!PEM_write_bio_PrivateKey(out, pkey, cipher, NULL, 0, NULL, passout)) { if ((ERR_GET_REASON(ERR_peek_error()) == diff --git a/apps/rsa.c b/apps/rsa.c index 51581aed28..f6961d9baf 100644 --- a/apps/rsa.c +++ b/apps/rsa.c @@ -162,7 +162,7 @@ int rsa_main(int argc, char **argv) const EVP_CIPHER *enc = NULL; char *infile = NULL, *outfile = NULL, *prog; char *passin = NULL, *passout = NULL, *passinarg = NULL, *passoutarg = NULL; - int i; + int i, private = 0; int informat = FORMAT_PEM, outformat = FORMAT_PEM, text = 0, check = 0; int noout = 0, modulus = 0, pubin = 0, pubout = 0, pvk_encr = 2, ret = 1; OPTION_CHOICE o; @@ -250,6 +250,7 @@ int rsa_main(int argc, char **argv) } argc = opt_num_rest(); argv = opt_rest(); + private = text || (!pubout && !noout) ? 1 : 0; if (!app_passwd(passinarg, passoutarg, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); @@ -291,16 +292,18 @@ int rsa_main(int argc, char **argv) goto end; } - out = bio_open_default(outfile, "w"); + out = bio_open_owner(outfile, "w", private); if (out == NULL) goto end; - if (text) + if (text) { + assert(private); if (!RSA_print(out, rsa, 0)) { perror(outfile); ERR_print_errors(bio_err); goto end; } + } if (modulus) { BIO_printf(out, "Modulus="); @@ -344,8 +347,10 @@ int rsa_main(int argc, char **argv) i = i2d_RSAPublicKey_bio(out, rsa); else i = i2d_RSA_PUBKEY_bio(out, rsa); - } else + } else { + assert(private); i = i2d_RSAPrivateKey_bio(out, rsa); + } } # ifndef OPENSSL_NO_RC4 else if (outformat == FORMAT_NETSCAPE) { @@ -353,6 +358,7 @@ int rsa_main(int argc, char **argv) int size = i2d_RSA_NET(rsa, NULL, NULL, 0); save = p = app_malloc(size, "RSA i2d buffer"); + assert(private); i2d_RSA_NET(rsa, &p, NULL, 0); BIO_write(out, (char *)save, size); OPENSSL_free(save); @@ -365,9 +371,11 @@ int rsa_main(int argc, char **argv) i = PEM_write_bio_RSAPublicKey(out, rsa); else i = PEM_write_bio_RSA_PUBKEY(out, rsa); - } else + } else { + assert(private); i = PEM_write_bio_RSAPrivateKey(out, rsa, enc, NULL, 0, NULL, passout); + } # if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4) |