1#! /usr/bin/env perl 2# Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. 3# 4# Licensed under the Apache License 2.0 (the "License"). You may not use 5# this file except in compliance with the License. You can obtain a copy 6# in the file LICENSE in the source distribution or at 7# https://www.openssl.org/source/license.html 8 9 10use strict; 11use warnings; 12 13use OpenSSL::Test qw(:DEFAULT data_file srctop_file); 14use OpenSSL::Test::Utils; 15 16#Tests for the dhparam CLI application 17 18setup("test_dhparam"); 19 20plan skip_all => "DH is not supported in this build" 21 if disabled("dh"); 22plan tests => 21; 23 24my $fipsconf = srctop_file("test", "fips-and-base.cnf"); 25 26sub checkdhparams { 27 my $file = shift; #Filename containing params 28 my $type = shift; #PKCS3 or X9.42? 29 my $gen = shift; #2, 5 or something else (0 is "something else")? 30 my $format = shift; #DER or PEM? 31 my $bits = shift; #Number of bits in p 32 my $pemtype; 33 my $readtype; 34 my $readbits = 0; 35 my $genline; 36 37 if (-T $file) { 38 #Text file. Check it looks like PEM 39 open(PEMFILE, '<', $file) or die $!; 40 if (my $firstline = <PEMFILE>) { 41 $firstline =~ s/\R$//; 42 if ($firstline eq "-----BEGIN DH PARAMETERS-----") { 43 $pemtype = "PKCS3"; 44 } elsif ($firstline eq "-----BEGIN X9.42 DH PARAMETERS-----") { 45 $pemtype = "X9.42"; 46 } else { 47 $pemtype = ""; 48 } 49 } else { 50 $pemtype = ""; 51 } 52 close(PEMFILE); 53 ok(($format eq "PEM") && defined $pemtype, "Checking format is PEM"); 54 } else { 55 ok($format eq "DER", "Checking format is DER"); 56 #No PEM type in this case, so we just set the pemtype to the expected 57 #type so that we never fail that part of the test 58 $pemtype = $type; 59 } 60 my @textdata = run(app(['openssl', 'dhparam', '-in', $file, '-noout', 61 '-text', '-inform', $format]), capture => 1); 62 chomp(@textdata); 63 #Trim trailing whitespace 64 @textdata = grep { s/\s*$//g } @textdata; 65 if (grep { $_ =~ 'Q:' } @textdata) { 66 $readtype = "X9.42"; 67 } else { 68 $readtype = "PKCS3"; 69 } 70 ok(($type eq $pemtype) && ($type eq $readtype), 71 "Checking parameter type is ".$type." ($pemtype, $readtype)"); 72 73 if (defined $textdata[0] && $textdata[0] =~ /DH Parameters: \((\d+) bit\)/) { 74 $readbits = $1; 75 } 76 ok($bits == $readbits, "Checking number of bits is $bits"); 77 if ($gen == 2 || $gen == 5) { 78 #For generators 2 and 5 the value appears on the same line 79 $genline = "G: $gen (0x$gen)"; 80 } else { 81 #For any other generator the value appears on the following line 82 $genline = "G:"; 83 } 84 85 ok((grep { (index($_, $genline) + length ($genline)) == length ($_)} @textdata), 86 "Checking generator is correct"); 87} 88 89#Test some "known good" parameter files to check that we can read them 90subtest "Read: 1024 bit PKCS3 params, generator 2, PEM file" => sub { 91 plan tests => 4; 92 checkdhparams(data_file("pkcs3-2-1024.pem"), "PKCS3", 2, "PEM", 1024); 93}; 94subtest "Read: 1024 bit PKCS3 params, generator 5, PEM file" => sub { 95 plan tests => 4; 96 checkdhparams(data_file("pkcs3-5-1024.pem"), "PKCS3", 5, "PEM", 1024); 97}; 98subtest "Read: 2048 bit PKCS3 params, generator 2, PEM file" => sub { 99 plan tests => 4; 100 checkdhparams(data_file("pkcs3-2-2048.pem"), "PKCS3", 2, "PEM", 2048); 101}; 102subtest "Read: 1024 bit X9.42 params, PEM file" => sub { 103 plan tests => 4; 104 checkdhparams(data_file("x942-0-1024.pem"), "X9.42", 0, "PEM", 1024); 105}; 106subtest "Read: 1024 bit PKCS3 params, generator 2, DER file" => sub { 107 plan tests => 4; 108 checkdhparams(data_file("pkcs3-2-1024.der"), "PKCS3", 2, "DER", 1024); 109}; 110subtest "Read: 1024 bit PKCS3 params, generator 5, DER file" => sub { 111 plan tests => 4; 112 checkdhparams(data_file("pkcs3-5-1024.der"), "PKCS3", 5, "DER", 1024); 113}; 114subtest "Read: 2048 bit PKCS3 params, generator 2, DER file" => sub { 115 plan tests => 4; 116 checkdhparams(data_file("pkcs3-2-2048.der"), "PKCS3", 2, "DER", 2048); 117}; 118subtest "Read: 1024 bit X9.42 params, DER file" => sub { 119 checkdhparams(data_file("x942-0-1024.der"), "X9.42", 0, "DER", 1024); 120}; 121 122#Test that generating parameters of different types creates what we expect. We 123#use 512 for the size for speed reasons. Don't use this in real applications! 124subtest "Generate: 512 bit PKCS3 params, generator 2, PEM file" => sub { 125 plan tests => 5; 126 ok(run(app([ 'openssl', 'dhparam', '-out', 'gen-pkcs3-2-512.pem', 127 '512' ]))); 128 checkdhparams("gen-pkcs3-2-512.pem", "PKCS3", 2, "PEM", 512); 129}; 130subtest "Generate: 512 bit PKCS3 params, explicit generator 2, PEM file" => sub { 131 plan tests => 5; 132 ok(run(app([ 'openssl', 'dhparam', '-out', 'gen-pkcs3-exp2-512.pem', '-2', 133 '512' ]))); 134 checkdhparams("gen-pkcs3-exp2-512.pem", "PKCS3", 2, "PEM", 512); 135}; 136subtest "Generate: 512 bit PKCS3 params, generator 5, PEM file" => sub { 137 plan tests => 5; 138 ok(run(app([ 'openssl', 'dhparam', '-out', 'gen-pkcs3-5-512.pem', '-5', 139 '512' ]))); 140 checkdhparams("gen-pkcs3-5-512.pem", "PKCS3", 5, "PEM", 512); 141}; 142subtest "Generate: 512 bit PKCS3 params, generator 2, explicit PEM file" => sub { 143 plan tests => 5; 144 ok(run(app([ 'openssl', 'dhparam', '-out', 'gen-pkcs3-2-512.exp.pem', 145 '-outform', 'PEM', '512' ]))); 146 checkdhparams("gen-pkcs3-2-512.exp.pem", "PKCS3", 2, "PEM", 512); 147}; 148SKIP: { 149 skip "Skipping tests that require DSA", 4 if disabled("dsa"); 150 151 subtest "Generate: 512 bit X9.42 params, generator 0, PEM file" => sub { 152 plan tests => 5; 153 ok(run(app([ 'openssl', 'dhparam', '-out', 'gen-x942-0-512.pem', 154 '-dsaparam', '512' ]))); 155 checkdhparams("gen-x942-0-512.pem", "X9.42", 0, "PEM", 512); 156 }; 157 subtest "Generate: 512 bit X9.42 params, explicit generator 2, PEM file" => sub { 158 plan tests => 1; 159 #Expected to fail - you cannot select a generator with '-dsaparam' 160 ok(!run(app([ 'openssl', 'dhparam', '-out', 'gen-x942-exp2-512.pem', '-2', 161 '-dsaparam', '512' ]))); 162 }; 163 subtest "Generate: 512 bit X9.42 params, generator 5, PEM file" => sub { 164 plan tests => 1; 165 #Expected to fail - you cannot select a generator with '-dsaparam' 166 ok(!run(app([ 'openssl', 'dhparam', '-out', 'gen-x942-5-512.pem', 167 '-5', '-dsaparam', '512' ]))); 168 }; 169 subtest "Generate: 512 bit X9.42 params, generator 0, DER file" => sub { 170 plan tests => 5; 171 ok(run(app([ 'openssl', 'dhparam', '-out', 'gen-x942-0-512.der', 172 '-dsaparam', '-outform', 'DER', '512' ]))); 173 checkdhparams("gen-x942-0-512.der", "X9.42", 0, "DER", 512); 174 }; 175} 176SKIP: { 177 skip "Skipping tests that are only supported in a fips build with security ". 178 "checks", 4 if (disabled("fips") || disabled("fips-securitychecks")); 179 180 $ENV{OPENSSL_CONF} = $fipsconf; 181 182 ok(!run(app(['openssl', 'dhparam', '-check', '512'])), 183 "Generating 512 bit DH params should fail in FIPS mode"); 184 185 ok(run(app(['openssl', 'dhparam', '-provider', 'default', '-propquery', 186 '?fips!=yes', '-check', '512'])), 187 "Generating 512 bit DH params should succeed in FIPS mode using". 188 " non-FIPS property query"); 189 190 SKIP: { 191 skip "Skipping tests that require DSA", 2 if disabled("dsa"); 192 193 ok(!run(app(['openssl', 'dhparam', '-dsaparam', '-check', '512'])), 194 "Generating 512 bit DSA-style DH params should fail in FIPS mode"); 195 196 ok(run(app(['openssl', 'dhparam', '-provider', 'default', '-propquery', 197 '?fips!=yes', '-dsaparam', '-check', '512'])), 198 "Generating 512 bit DSA-style DH params should succeed in FIPS". 199 " mode using non-FIPS property query"); 200 } 201 202 delete $ENV{OPENSSL_CONF}; 203} 204 205ok(run(app(["openssl", "dhparam", "-noout", "-text"], 206 stdin => data_file("pkcs3-2-1024.pem"))), 207 "stdinbuffer input test that uses BIO_gets"); 208