20-test_dhparam.t 8.3 KB

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