From: Dr. David von Oheimb Date: Fri, 27 Sep 2024 05:39:17 +0000 (+0200) Subject: APPS/dsaparam: fix case where infile and outfile are the same X-Git-Tag: openssl-3.5.0-alpha1~1059 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=32189981a3eb26b7172b4b917f37d301b8d5e65e;p=thirdparty%2Fopenssl.git APPS/dsaparam: fix case where infile and outfile are the same Reviewed-by: Viktor Dukhovni Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/25552) --- diff --git a/apps/dsaparam.c b/apps/dsaparam.c index 8bd2e1361bf..99fc3ee7b80 100644 --- a/apps/dsaparam.c +++ b/apps/dsaparam.c @@ -150,10 +150,6 @@ int dsaparam_main(int argc, char **argv) numbits = num; private = genkey ? 1 : 0; - out = bio_open_owner(outfile, outformat, private); - if (out == NULL) - goto end; - ctx = EVP_PKEY_CTX_new_from_name(app_get0_libctx(), "DSA", app_get0_propq()); if (ctx == NULL) { BIO_printf(bio_err, @@ -200,6 +196,10 @@ int dsaparam_main(int argc, char **argv) goto end; } + out = bio_open_owner(outfile, outformat, private); + if (out == NULL) + goto end; + if (text) { EVP_PKEY_print_params(out, params, 0, NULL); } diff --git a/doc/man1/openssl-dsaparam.pod.in b/doc/man1/openssl-dsaparam.pod.in index 62d44314575..d2e8973ee0e 100644 --- a/doc/man1/openssl-dsaparam.pod.in +++ b/doc/man1/openssl-dsaparam.pod.in @@ -53,15 +53,17 @@ This is compatible with RFC 2459 B structure. =item B<-in> I -This specifies the input filename to read parameters from or standard input if +This specifies the input file to read parameters from or standard input if this option is not specified. If the I parameter is included then this option will be ignored. =item B<-out> I -This specifies the output filename parameters to. Standard output is used -if this option is not present. The output filename should B be the same -as the input filename. +This specifies the output file to write parameters to. Standard output is used +if this option is not present. +The output filename can be the same as the input filename, +which leads to replacing the file contents. +Note that file I/O is not atomic. The output file is truncated and then written. =item B<-noout> diff --git a/test/recipes/15-test_dsaparam.t b/test/recipes/15-test_dsaparam.t index 2f06c1f4e05..5fd854c474d 100644 --- a/test/recipes/15-test_dsaparam.t +++ b/test/recipes/15-test_dsaparam.t @@ -10,6 +10,8 @@ use strict; use warnings; use File::Spec; +use File::Copy; +use File::Compare qw/compare/; use OpenSSL::Glob; use OpenSSL::Test qw/:DEFAULT data_file/; use OpenSSL::Test::Utils; @@ -66,7 +68,7 @@ plan skip_all => "DSA isn't supported in this build" my @valid = glob(data_file("valid", "*.pem")); my @invalid = glob(data_file("invalid", "*.pem")); -my $num_tests = scalar @valid + scalar @invalid; +my $num_tests = scalar @valid + scalar @invalid + 2; plan tests => $num_tests; foreach (@valid) { @@ -76,3 +78,10 @@ foreach (@valid) { foreach (@invalid) { ok(!run(app([qw{openssl pkeyparam -noout -check -in}, $_]))); } + +my $input = data_file("valid", "p3072_q256_t1864.pem"); +my $inout = "inout.pem"; +copy($input, $inout); +ok(run(app(['openssl', 'dsaparam', '-in', $inout, '-out', $inout])), + "identical infile and outfile"); +ok(!compare($input, $inout), "converted file $inout did not change");