| #! /usr/bin/env perl |
| # Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. |
| # |
| # Licensed under the Apache License 2.0 (the "License"). You may not use |
| # this file except in compliance with the License. You can obtain a copy |
| # in the file LICENSE in the source distribution or at |
| # https://www.openssl.org/source/license.html |
| |
| use strict; |
| use warnings; |
| |
| use File::Spec; |
| use File::Spec::Functions qw/curdir abs2rel/; |
| use File::Copy; |
| use OpenSSL::Glob; |
| use OpenSSL::Test qw/:DEFAULT srctop_dir bldtop_dir bldtop_file srctop_file data_file/; |
| use OpenSSL::Test::Utils; |
| |
| BEGIN { |
| setup("test_cli_fips"); |
| } |
| use lib srctop_dir('Configurations'); |
| use lib bldtop_dir('.'); |
| use platform; |
| |
| my $no_check = disabled("fips") || disabled('fips-securitychecks'); |
| plan skip_all => "Test only supported in a fips build with security checks" |
| if $no_check; |
| plan tests => 11; |
| |
| my $fipsmodule = bldtop_file('providers', platform->dso('fips')); |
| my $fipsconf = srctop_file("test", "fips-and-base.cnf"); |
| my $defaultconf = srctop_file("test", "default.cnf"); |
| my $tbs_data = $fipsmodule; |
| my $bogus_data = $fipsconf; |
| |
| $ENV{OPENSSL_CONF} = $fipsconf; |
| |
| ok(run(app(['openssl', 'list', '-public-key-methods', '-verbose'])), |
| "provider listing of public key methods"); |
| ok(run(app(['openssl', 'list', '-public-key-algorithms', '-verbose'])), |
| "provider listing of public key algorithms"); |
| ok(run(app(['openssl', 'list', '-key-managers', '-verbose'])), |
| "provider listing of keymanagers"); |
| ok(run(app(['openssl', 'list', '-key-exchange-algorithms', '-verbose'])), |
| "provider listing of key exchange algorithms"); |
| ok(run(app(['openssl', 'list', '-kem-algorithms', '-verbose'])), |
| "provider listing of key encapsulation algorithms"); |
| ok(run(app(['openssl', 'list', '-signature-algorithms', '-verbose'])), |
| "provider listing of signature algorithms"); |
| ok(run(app(['openssl', 'list', '-asymcipher-algorithms', '-verbose'])), |
| "provider listing of encryption algorithms"); |
| ok(run(app(['openssl', 'list', '-key-managers', '-verbose', '-select', 'DSA' ])), |
| "provider listing of one item in the keymanager"); |
| |
| sub pubfrompriv { |
| my $prefix = shift; |
| my $key = shift; |
| my $pub_key = shift; |
| my $type = shift; |
| |
| ok(run(app(['openssl', 'pkey', |
| '-in', $key, |
| '-pubout', |
| '-out', $pub_key])), |
| $prefix.': '."Create the public key with $type parameters"); |
| |
| } |
| |
| my $tsignverify_count = 8; |
| sub tsignverify { |
| my $prefix = shift; |
| my $fips_key = shift; |
| my $fips_pub_key = shift; |
| my $nonfips_key = shift; |
| my $nonfips_pub_key = shift; |
| my $fips_sigfile = $prefix.'.fips.sig'; |
| my $nonfips_sigfile = $prefix.'.nonfips.sig'; |
| my $sigfile = ''; |
| my $testtext = ''; |
| |
| $ENV{OPENSSL_CONF} = $fipsconf; |
| |
| $sigfile = $fips_sigfile; |
| $testtext = $prefix.': '. |
| 'Sign something with a FIPS key'; |
| ok(run(app(['openssl', 'dgst', '-sha256', |
| '-sign', $fips_key, |
| '-out', $sigfile, |
| $tbs_data])), |
| $testtext); |
| |
| $testtext = $prefix.': '. |
| 'Verify something with a FIPS key'; |
| ok(run(app(['openssl', 'dgst', '-sha256', |
| '-verify', $fips_pub_key, |
| '-signature', $sigfile, |
| $tbs_data])), |
| $testtext); |
| |
| $testtext = $prefix.': '. |
| 'Verify a valid signature against the wrong data with a FIPS key'. |
| ' (should fail)'; |
| ok(!run(app(['openssl', 'dgst', '-sha256', |
| '-verify', $fips_pub_key, |
| '-signature', $sigfile, |
| $bogus_data])), |
| $testtext); |
| |
| $ENV{OPENSSL_CONF} = $defaultconf; |
| |
| $sigfile = $nonfips_sigfile; |
| $testtext = $prefix.': '. |
| 'Sign something with a non-FIPS key'. |
| ' with the default provider'; |
| ok(run(app(['openssl', 'dgst', '-sha256', |
| '-sign', $nonfips_key, |
| '-out', $sigfile, |
| $tbs_data])), |
| $testtext); |
| |
| $testtext = $prefix.': '. |
| 'Verify something with a non-FIPS key'. |
| ' with the default provider'; |
| ok(run(app(['openssl', 'dgst', '-sha256', |
| '-verify', $nonfips_pub_key, |
| '-signature', $sigfile, |
| $tbs_data])), |
| $testtext); |
| |
| $ENV{OPENSSL_CONF} = $fipsconf; |
| |
| $testtext = $prefix.': '. |
| 'Sign something with a non-FIPS key'. |
| ' (should fail)'; |
| ok(!run(app(['openssl', 'dgst', '-sha256', |
| '-sign', $nonfips_key, |
| '-out', $prefix.'.nonfips.fail.sig', |
| $tbs_data])), |
| $testtext); |
| |
| $testtext = $prefix.': '. |
| 'Verify something with a non-FIPS key'. |
| ' (should fail)'; |
| ok(!run(app(['openssl', 'dgst', '-sha256', |
| '-verify', $nonfips_pub_key, |
| '-signature', $sigfile, |
| $tbs_data])), |
| $testtext); |
| |
| $testtext = $prefix.': '. |
| 'Verify a valid signature against the wrong data with a non-FIPS key'. |
| ' (should fail)'; |
| ok(!run(app(['openssl', 'dgst', '-sha256', |
| '-verify', $nonfips_pub_key, |
| '-signature', $sigfile, |
| $bogus_data])), |
| $testtext); |
| } |
| |
| SKIP : { |
| skip "FIPS EC tests because of no ec in this build", 1 |
| if disabled("ec"); |
| |
| subtest EC => sub { |
| my $testtext_prefix = 'EC'; |
| my $a_fips_curve = 'prime256v1'; |
| my $fips_key = $testtext_prefix.'.fips.priv.pem'; |
| my $fips_pub_key = $testtext_prefix.'.fips.pub.pem'; |
| my $a_nonfips_curve = 'brainpoolP256r1'; |
| my $nonfips_key = $testtext_prefix.'.nonfips.priv.pem'; |
| my $nonfips_pub_key = $testtext_prefix.'.nonfips.pub.pem'; |
| my $testtext = ''; |
| my $curvename = ''; |
| |
| plan tests => 5 + $tsignverify_count; |
| |
| $ENV{OPENSSL_CONF} = $defaultconf; |
| $curvename = $a_nonfips_curve; |
| $testtext = $testtext_prefix.': '. |
| 'Generate a key with a non-FIPS algorithm with the default provider'; |
| ok(run(app(['openssl', 'genpkey', '-algorithm', 'EC', |
| '-pkeyopt', 'ec_paramgen_curve:'.$curvename, |
| '-out', $nonfips_key])), |
| $testtext); |
| |
| pubfrompriv($testtext_prefix, $nonfips_key, $nonfips_pub_key, "non-FIPS"); |
| |
| $ENV{OPENSSL_CONF} = $fipsconf; |
| |
| $curvename = $a_fips_curve; |
| $testtext = $testtext_prefix.': '. |
| 'Generate a key with a FIPS algorithm'; |
| ok(run(app(['openssl', 'genpkey', '-algorithm', 'EC', |
| '-pkeyopt', 'ec_paramgen_curve:'.$curvename, |
| '-out', $fips_key])), |
| $testtext); |
| |
| pubfrompriv($testtext_prefix, $fips_key, $fips_pub_key, "FIPS"); |
| |
| $curvename = $a_nonfips_curve; |
| $testtext = $testtext_prefix.': '. |
| 'Generate a key with a non-FIPS algorithm'. |
| ' (should fail)'; |
| ok(!run(app(['openssl', 'genpkey', '-algorithm', 'EC', |
| '-pkeyopt', 'ec_paramgen_curve:'.$curvename, |
| '-out', $testtext_prefix.'.'.$curvename.'.priv.pem'])), |
| $testtext); |
| |
| tsignverify($testtext_prefix, $fips_key, $fips_pub_key, $nonfips_key, |
| $nonfips_pub_key); |
| }; |
| } |
| |
| SKIP: { |
| skip "FIPS RSA tests because of no rsa in this build", 1 |
| if disabled("rsa"); |
| |
| subtest RSA => sub { |
| my $testtext_prefix = 'RSA'; |
| my $fips_key = $testtext_prefix.'.fips.priv.pem'; |
| my $fips_pub_key = $testtext_prefix.'.fips.pub.pem'; |
| my $nonfips_key = $testtext_prefix.'.nonfips.priv.pem'; |
| my $nonfips_pub_key = $testtext_prefix.'.nonfips.pub.pem'; |
| my $testtext = ''; |
| |
| plan tests => 5 + $tsignverify_count; |
| |
| $ENV{OPENSSL_CONF} = $defaultconf; |
| $testtext = $testtext_prefix.': '. |
| 'Generate a key with a non-FIPS algorithm with the default provider'; |
| ok(run(app(['openssl', 'genpkey', '-algorithm', 'RSA', |
| '-pkeyopt', 'rsa_keygen_bits:512', |
| '-out', $nonfips_key])), |
| $testtext); |
| |
| pubfrompriv($testtext_prefix, $nonfips_key, $nonfips_pub_key, "non-FIPS"); |
| |
| $ENV{OPENSSL_CONF} = $fipsconf; |
| |
| $testtext = $testtext_prefix.': '. |
| 'Generate a key with a FIPS algorithm'; |
| ok(run(app(['openssl', 'genpkey', '-algorithm', 'RSA', |
| '-pkeyopt', 'rsa_keygen_bits:2048', |
| '-out', $fips_key])), |
| $testtext); |
| |
| pubfrompriv($testtext_prefix, $fips_key, $fips_pub_key, "FIPS"); |
| |
| $testtext = $testtext_prefix.': '. |
| 'Generate a key with a non-FIPS algorithm'. |
| ' (should fail)'; |
| ok(!run(app(['openssl', 'genpkey', '-algorithm', 'RSA', |
| '-pkeyopt', 'rsa_keygen_bits:512', |
| '-out', $testtext_prefix.'.fail.priv.pem'])), |
| $testtext); |
| |
| tsignverify($testtext_prefix, $fips_key, $fips_pub_key, $nonfips_key, |
| $nonfips_pub_key); |
| }; |
| } |
| |
| SKIP : { |
| skip "FIPS DSA tests because of no dsa in this build", 1 |
| if disabled("dsa"); |
| |
| subtest DSA => sub { |
| my $testtext_prefix = 'DSA'; |
| my $fips_key = $testtext_prefix.'.fips.priv.pem'; |
| my $fips_pub_key = $testtext_prefix.'.fips.pub.pem'; |
| my $nonfips_key = $testtext_prefix.'.nonfips.priv.pem'; |
| my $nonfips_pub_key = $testtext_prefix.'.nonfips.pub.pem'; |
| my $testtext = ''; |
| my $fips_param = $testtext_prefix.'.fips.param.pem'; |
| my $nonfips_param = $testtext_prefix.'.nonfips.param.pem'; |
| |
| plan tests => 8 + $tsignverify_count; |
| |
| $ENV{OPENSSL_CONF} = $defaultconf; |
| |
| $testtext = $testtext_prefix.': '. |
| 'Generate non-FIPS params with the default provider'; |
| ok(run(app(['openssl', 'genpkey', '-genparam', |
| '-algorithm', 'DSA', |
| '-pkeyopt', 'type:fips186_2', |
| '-pkeyopt', 'dsa_paramgen_bits:512', |
| '-out', $nonfips_param])), |
| $testtext); |
| |
| $ENV{OPENSSL_CONF} = $fipsconf; |
| |
| $testtext = $testtext_prefix.': '. |
| 'Generate FIPS params'; |
| ok(run(app(['openssl', 'genpkey', '-genparam', |
| '-algorithm', 'DSA', |
| '-pkeyopt', 'dsa_paramgen_bits:2048', |
| '-out', $fips_param])), |
| $testtext); |
| |
| $testtext = $testtext_prefix.': '. |
| 'Generate non-FIPS params'. |
| ' (should fail)'; |
| ok(!run(app(['openssl', 'genpkey', '-genparam', |
| '-algorithm', 'DSA', |
| '-pkeyopt', 'dsa_paramgen_bits:512', |
| '-out', $testtext_prefix.'.fail.param.pem'])), |
| $testtext); |
| |
| $ENV{OPENSSL_CONF} = $defaultconf; |
| |
| $testtext = $testtext_prefix.': '. |
| 'Generate a key with non-FIPS params with the default provider'; |
| ok(run(app(['openssl', 'genpkey', |
| '-paramfile', $nonfips_param, |
| '-pkeyopt', 'type:fips186_2', |
| '-out', $nonfips_key])), |
| $testtext); |
| |
| pubfrompriv($testtext_prefix, $nonfips_key, $nonfips_pub_key, "non-FIPS"); |
| |
| $ENV{OPENSSL_CONF} = $fipsconf; |
| |
| $testtext = $testtext_prefix.': '. |
| 'Generate a key with FIPS parameters'; |
| ok(run(app(['openssl', 'genpkey', |
| '-paramfile', $fips_param, |
| '-pkeyopt', 'type:fips186_4', |
| '-out', $fips_key])), |
| $testtext); |
| |
| pubfrompriv($testtext_prefix, $fips_key, $fips_pub_key, "FIPS"); |
| |
| $testtext = $testtext_prefix.': '. |
| 'Generate a key with non-FIPS parameters'. |
| ' (should fail)'; |
| ok(!run(app(['openssl', 'genpkey', |
| '-paramfile', $nonfips_param, |
| '-pkeyopt', 'type:fips186_2', |
| '-out', $testtext_prefix.'.fail.priv.pem'])), |
| $testtext); |
| |
| tsignverify($testtext_prefix, $fips_key, $fips_pub_key, $nonfips_key, |
| $nonfips_pub_key); |
| }; |
| } |