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