• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
9use strict;
10use warnings;
11
12use File::Spec;
13use File::Spec::Functions qw/curdir abs2rel/;
14use File::Copy;
15use OpenSSL::Glob;
16use OpenSSL::Test qw/:DEFAULT srctop_dir bldtop_dir bldtop_file srctop_file data_file/;
17use OpenSSL::Test::Utils;
18
19BEGIN {
20    setup("test_cli_fips");
21}
22use lib srctop_dir('Configurations');
23use lib bldtop_dir('.');
24use platform;
25
26my $no_check = disabled("fips") || disabled('fips-securitychecks');
27plan skip_all => "Test only supported in a fips build with security checks"
28    if $no_check;
29plan tests => 11;
30
31my $fipsmodule = bldtop_file('providers', platform->dso('fips'));
32my $fipsconf = srctop_file("test", "fips-and-base.cnf");
33my $defaultconf = srctop_file("test", "default.cnf");
34my $tbs_data = $fipsmodule;
35my $bogus_data = $fipsconf;
36
37$ENV{OPENSSL_CONF} = $fipsconf;
38
39ok(run(app(['openssl', 'list', '-public-key-methods', '-verbose'])),
40   "provider listing of public key methods");
41ok(run(app(['openssl', 'list', '-public-key-algorithms', '-verbose'])),
42   "provider listing of public key algorithms");
43ok(run(app(['openssl', 'list', '-key-managers', '-verbose'])),
44   "provider listing of keymanagers");
45ok(run(app(['openssl', 'list', '-key-exchange-algorithms', '-verbose'])),
46   "provider listing of key exchange algorithms");
47ok(run(app(['openssl', 'list', '-kem-algorithms', '-verbose'])),
48   "provider listing of key encapsulation algorithms");
49ok(run(app(['openssl', 'list', '-signature-algorithms', '-verbose'])),
50   "provider listing of signature algorithms");
51ok(run(app(['openssl', 'list', '-asymcipher-algorithms', '-verbose'])),
52   "provider listing of encryption algorithms");
53ok(run(app(['openssl', 'list', '-key-managers', '-verbose', '-select', 'DSA' ])),
54   "provider listing of one item in the keymanager");
55
56sub pubfrompriv {
57    my $prefix = shift;
58    my $key = shift;
59    my $pub_key = shift;
60    my $type = shift;
61
62    ok(run(app(['openssl', 'pkey',
63                '-in', $key,
64                '-pubout',
65                '-out', $pub_key])),
66        $prefix.': '."Create the public key with $type parameters");
67
68}
69
70my $tsignverify_count = 9;
71sub tsignverify {
72    my $prefix = shift;
73    my $fips_key = shift;
74    my $fips_pub_key = shift;
75    my $nonfips_key = shift;
76    my $nonfips_pub_key = shift;
77    my $fips_sigfile = $prefix.'.fips.sig';
78    my $nonfips_sigfile = $prefix.'.nonfips.sig';
79    my $sigfile = '';
80    my $testtext = '';
81
82    $ENV{OPENSSL_CONF} = $fipsconf;
83
84    $sigfile = $fips_sigfile;
85    $testtext = $prefix.': '.
86        'Sign something with a FIPS key';
87    ok(run(app(['openssl', 'dgst', '-sha256',
88                '-sign', $fips_key,
89                '-out', $sigfile,
90                $tbs_data])),
91       $testtext);
92
93    $testtext = $prefix.': '.
94        'Verify something with a FIPS key';
95    ok(run(app(['openssl', 'dgst', '-sha256',
96                '-verify', $fips_pub_key,
97                '-signature', $sigfile,
98                $tbs_data])),
99       $testtext);
100
101    $testtext = $prefix.': '.
102        'Verify a valid signature against the wrong data with a FIPS key'.
103        ' (should fail)';
104    ok(!run(app(['openssl', 'dgst', '-sha256',
105                 '-verify', $fips_pub_key,
106                 '-signature', $sigfile,
107                 $bogus_data])),
108       $testtext);
109
110    $ENV{OPENSSL_CONF} = $defaultconf;
111
112    $sigfile = $nonfips_sigfile;
113    $testtext = $prefix.': '.
114        'Sign something with a non-FIPS key'.
115        ' with the default provider';
116    ok(run(app(['openssl', 'dgst', '-sha256',
117                '-sign', $nonfips_key,
118                '-out', $sigfile,
119                $tbs_data])),
120       $testtext);
121
122    $testtext = $prefix.': '.
123        'Verify something with a non-FIPS key'.
124        ' with the default provider';
125    ok(run(app(['openssl', 'dgst', '-sha256',
126                '-verify', $nonfips_pub_key,
127                '-signature', $sigfile,
128                $tbs_data])),
129       $testtext);
130
131    $ENV{OPENSSL_CONF} = $fipsconf;
132
133    $testtext = $prefix.': '.
134        'Sign something with a non-FIPS key'.
135        ' (should fail)';
136    ok(!run(app(['openssl', 'dgst', '-sha256',
137                 '-sign', $nonfips_key,
138                 '-out', $prefix.'.nonfips.fail.sig',
139                 $tbs_data])),
140       $testtext);
141
142    $testtext = $prefix.': '.
143        'Verify something with a non-FIPS key'.
144        ' (should fail)';
145    ok(!run(app(['openssl', 'dgst', '-sha256',
146                 '-verify', $nonfips_pub_key,
147                 '-signature', $sigfile,
148                 $tbs_data])),
149       $testtext);
150
151    $testtext = $prefix.': '.
152        'Verify something with a non-FIPS key'.
153		' in FIPS mode but with a non-FIPS property query';
154    ok(run(app(['openssl', 'dgst',
155				'-provider', 'default',
156				'-propquery', '?fips!=yes',
157				'-sha256',
158                '-verify', $nonfips_pub_key,
159                '-signature', $sigfile,
160                $tbs_data])),
161       $testtext);
162
163    $testtext = $prefix.': '.
164        'Verify a valid signature against the wrong data with a non-FIPS key'.
165        ' (should fail)';
166    ok(!run(app(['openssl', 'dgst', '-sha256',
167                 '-verify', $nonfips_pub_key,
168                 '-signature', $sigfile,
169                 $bogus_data])),
170       $testtext);
171}
172
173SKIP : {
174    skip "FIPS EC tests because of no ec in this build", 1
175        if disabled("ec");
176
177    subtest EC => sub {
178        my $testtext_prefix = 'EC';
179        my $a_fips_curve = 'prime256v1';
180        my $fips_key = $testtext_prefix.'.fips.priv.pem';
181        my $fips_pub_key = $testtext_prefix.'.fips.pub.pem';
182        my $a_nonfips_curve = 'brainpoolP256r1';
183        my $nonfips_key = $testtext_prefix.'.nonfips.priv.pem';
184        my $nonfips_pub_key = $testtext_prefix.'.nonfips.pub.pem';
185        my $testtext = '';
186        my $curvename = '';
187
188        plan tests => 5 + $tsignverify_count;
189
190        $ENV{OPENSSL_CONF} = $defaultconf;
191        $curvename = $a_nonfips_curve;
192        $testtext = $testtext_prefix.': '.
193            'Generate a key with a non-FIPS algorithm with the default provider';
194        ok(run(app(['openssl', 'genpkey', '-algorithm', 'EC',
195                    '-pkeyopt', 'ec_paramgen_curve:'.$curvename,
196                    '-out', $nonfips_key])),
197           $testtext);
198
199        pubfrompriv($testtext_prefix, $nonfips_key, $nonfips_pub_key, "non-FIPS");
200
201        $ENV{OPENSSL_CONF} = $fipsconf;
202
203        $curvename = $a_fips_curve;
204        $testtext = $testtext_prefix.': '.
205            'Generate a key with a FIPS algorithm';
206        ok(run(app(['openssl', 'genpkey', '-algorithm', 'EC',
207                    '-pkeyopt', 'ec_paramgen_curve:'.$curvename,
208                    '-out', $fips_key])),
209           $testtext);
210
211        pubfrompriv($testtext_prefix, $fips_key, $fips_pub_key, "FIPS");
212
213        $curvename = $a_nonfips_curve;
214        $testtext = $testtext_prefix.': '.
215            'Generate a key with a non-FIPS algorithm'.
216            ' (should fail)';
217        ok(!run(app(['openssl', 'genpkey', '-algorithm', 'EC',
218                     '-pkeyopt', 'ec_paramgen_curve:'.$curvename,
219                     '-out', $testtext_prefix.'.'.$curvename.'.priv.pem'])),
220           $testtext);
221
222        tsignverify($testtext_prefix, $fips_key, $fips_pub_key, $nonfips_key,
223                    $nonfips_pub_key);
224    };
225}
226
227SKIP: {
228    skip "FIPS RSA tests because of no rsa in this build", 1
229        if disabled("rsa");
230
231    subtest RSA => sub {
232        my $testtext_prefix = 'RSA';
233        my $fips_key = $testtext_prefix.'.fips.priv.pem';
234        my $fips_pub_key = $testtext_prefix.'.fips.pub.pem';
235        my $nonfips_key = $testtext_prefix.'.nonfips.priv.pem';
236        my $nonfips_pub_key = $testtext_prefix.'.nonfips.pub.pem';
237        my $testtext = '';
238
239        plan tests => 5 + $tsignverify_count;
240
241        $ENV{OPENSSL_CONF} = $defaultconf;
242        $testtext = $testtext_prefix.': '.
243            'Generate a key with a non-FIPS algorithm with the default provider';
244        ok(run(app(['openssl', 'genpkey', '-algorithm', 'RSA',
245                    '-pkeyopt', 'rsa_keygen_bits:512',
246                    '-out', $nonfips_key])),
247           $testtext);
248
249        pubfrompriv($testtext_prefix, $nonfips_key, $nonfips_pub_key, "non-FIPS");
250
251        $ENV{OPENSSL_CONF} = $fipsconf;
252
253        $testtext = $testtext_prefix.': '.
254            'Generate a key with a FIPS algorithm';
255        ok(run(app(['openssl', 'genpkey', '-algorithm', 'RSA',
256                    '-pkeyopt', 'rsa_keygen_bits:2048',
257                    '-out', $fips_key])),
258           $testtext);
259
260        pubfrompriv($testtext_prefix, $fips_key, $fips_pub_key, "FIPS");
261
262        $testtext = $testtext_prefix.': '.
263            'Generate a key with a non-FIPS algorithm'.
264            ' (should fail)';
265        ok(!run(app(['openssl', 'genpkey', '-algorithm', 'RSA',
266                    '-pkeyopt', 'rsa_keygen_bits:512',
267                     '-out', $testtext_prefix.'.fail.priv.pem'])),
268           $testtext);
269
270        tsignverify($testtext_prefix, $fips_key, $fips_pub_key, $nonfips_key,
271                    $nonfips_pub_key);
272    };
273}
274
275SKIP : {
276    skip "FIPS DSA tests because of no dsa in this build", 1
277        if disabled("dsa");
278
279    subtest DSA => sub {
280        my $testtext_prefix = 'DSA';
281        my $fips_key = $testtext_prefix.'.fips.priv.pem';
282        my $fips_pub_key = $testtext_prefix.'.fips.pub.pem';
283        my $nonfips_key = $testtext_prefix.'.nonfips.priv.pem';
284        my $nonfips_pub_key = $testtext_prefix.'.nonfips.pub.pem';
285        my $testtext = '';
286        my $fips_param = $testtext_prefix.'.fips.param.pem';
287        my $nonfips_param = $testtext_prefix.'.nonfips.param.pem';
288        my $shortnonfips_param = $testtext_prefix.'.shortnonfips.param.pem';
289
290        plan tests => 13 + $tsignverify_count;
291
292        $ENV{OPENSSL_CONF} = $defaultconf;
293
294        $testtext = $testtext_prefix.': '.
295            'Generate non-FIPS params with the default provider';
296        ok(run(app(['openssl', 'genpkey', '-genparam',
297                    '-algorithm', 'DSA',
298                    '-pkeyopt', 'type:fips186_2',
299                    '-pkeyopt', 'dsa_paramgen_bits:512',
300                    '-out', $nonfips_param])),
301           $testtext);
302
303        $ENV{OPENSSL_CONF} = $fipsconf;
304
305        $testtext = $testtext_prefix.': '.
306            'Generate FIPS params';
307        ok(run(app(['openssl', 'genpkey', '-genparam',
308                    '-algorithm', 'DSA',
309                    '-pkeyopt', 'dsa_paramgen_bits:2048',
310                    '-out', $fips_param])),
311           $testtext);
312
313        $testtext = $testtext_prefix.': '.
314            'Generate non-FIPS params'.
315            ' (should fail)';
316        ok(!run(app(['openssl', 'genpkey', '-genparam',
317                     '-algorithm', 'DSA',
318                    '-pkeyopt', 'dsa_paramgen_bits:512',
319                     '-out', $testtext_prefix.'.fail.param.pem'])),
320           $testtext);
321
322        $testtext = $testtext_prefix.': '.
323            'Generate non-FIPS params using non-FIPS property query'.
324            ' (dsaparam)';
325        ok(run(app(['openssl', 'dsaparam', '-provider', 'default',
326                    '-propquery', '?fips!=yes',
327                    '-out', $shortnonfips_param, '1024'])),
328            $testtext);
329
330        $testtext = $testtext_prefix.': '.
331            'Generate non-FIPS params using non-FIPS property query'.
332            ' (genpkey)';
333        ok(run(app(['openssl', 'genpkey', '-provider', 'default',
334                    '-propquery', '?fips!=yes',
335                    '-genparam', '-algorithm', 'DSA',
336                    '-pkeyopt', 'dsa_paramgen_bits:512'])),
337            $testtext);
338
339        $ENV{OPENSSL_CONF} = $defaultconf;
340
341        $testtext = $testtext_prefix.': '.
342            'Generate a key with non-FIPS params with the default provider';
343        ok(run(app(['openssl', 'genpkey',
344                    '-paramfile', $nonfips_param,
345                    '-pkeyopt', 'type:fips186_2',
346                    '-out', $nonfips_key])),
347           $testtext);
348
349        pubfrompriv($testtext_prefix, $nonfips_key, $nonfips_pub_key, "non-FIPS");
350
351        $ENV{OPENSSL_CONF} = $fipsconf;
352
353        $testtext = $testtext_prefix.': '.
354            'Generate a key with FIPS parameters';
355        ok(run(app(['openssl', 'genpkey',
356                    '-paramfile', $fips_param,
357                    '-pkeyopt', 'type:fips186_4',
358                    '-out', $fips_key])),
359           $testtext);
360
361        pubfrompriv($testtext_prefix, $fips_key, $fips_pub_key, "FIPS");
362
363        $testtext = $testtext_prefix.': '.
364            'Generate a key with non-FIPS parameters'.
365            ' (should fail)';
366        ok(!run(app(['openssl', 'genpkey',
367                     '-paramfile', $nonfips_param,
368                     '-pkeyopt', 'type:fips186_2',
369                     '-out', $testtext_prefix.'.fail.priv.pem'])),
370           $testtext);
371
372        $testtext = $testtext_prefix.': '.
373            'Generate a key with non-FIPS parameters using non-FIPS property'.
374            ' query (dsaparam)';
375        ok(run(app(['openssl', 'dsaparam', '-provider', 'default',
376                    '-propquery', '?fips!=yes',
377                    '-noout', '-genkey', '1024'])),
378            $testtext);
379
380        $testtext = $testtext_prefix.': '.
381            'Generate a key with non-FIPS parameters using non-FIPS property'.
382            ' query (gendsa)';
383        ok(run(app(['openssl', 'gendsa', '-provider', 'default',
384                    '-propquery', '?fips!=yes',
385                    $shortnonfips_param])),
386            $testtext);
387
388        $testtext = $testtext_prefix.': '.
389            'Generate a key with non-FIPS parameters using non-FIPS property'.
390            ' query (genpkey)';
391        ok(run(app(['openssl', 'genpkey', '-provider', 'default',
392                    '-propquery', '?fips!=yes',
393                    '-paramfile', $nonfips_param,
394                    '-pkeyopt', 'type:fips186_2',
395                    '-out', $testtext_prefix.'.fail.priv.pem'])),
396            $testtext);
397
398        tsignverify($testtext_prefix, $fips_key, $fips_pub_key, $nonfips_key,
399                    $nonfips_pub_key);
400    };
401}
402