Commit 3b061a00 authored by Rich Salz's avatar Rich Salz Committed by Rich Salz
Browse files

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: default avatarViktor Dukhovni <viktor@openssl.org>
parent d31fb0b5
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -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]

+0 −1
Original line number Diff line number Diff line
@@ -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>
+2 −0
Original line number Diff line number Diff line
@@ -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);
+20 −6
Original line number Diff line number Diff line
@@ -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 {
+5 −5
Original line number Diff line number Diff line
@@ -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
Loading