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