Home | History | Annotate | Line # | Download | only in recipes
      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 
     10 use strict;
     11 use warnings;
     12 
     13 use OpenSSL::Test qw(:DEFAULT data_file srctop_file);
     14 use OpenSSL::Test::Utils;
     15 
     16 #Tests for the dhparam CLI application
     17 
     18 setup("test_dhparam");
     19 
     20 plan skip_all => "DH is not supported in this build"
     21     if disabled("dh");
     22 plan tests => 21;
     23 
     24 my $fipsconf = srctop_file("test", "fips-and-base.cnf");
     25 
     26 sub 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
     90 subtest "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 };
     94 subtest "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 };
     98 subtest "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 };
    102 subtest "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 };
    106 subtest "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 };
    110 subtest "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 };
    114 subtest "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 };
    118 subtest "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!
    124 subtest "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 };
    130 subtest "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 };
    136 subtest "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 };
    142 subtest "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 };
    148 SKIP: {
    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 }
    176 SKIP: {
    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 
    205 ok(run(app(["openssl", "dhparam", "-noout", "-text"],
    206            stdin => data_file("pkcs3-2-1024.pem"))),
    207    "stdinbuffer input test that uses BIO_gets");
    208