1#! /usr/bin/env perl 2# Copyright 2020-2023 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 SKIP : { 113 skip "FIPS failure testing", 6 114 if ($nonfips_key eq ''); 115 116 $sigfile = $nonfips_sigfile; 117 $testtext = $prefix.': '. 118 'Sign something with a non-FIPS key'. 119 ' with the default provider'; 120 ok(run(app(['openssl', 'dgst', '-sha256', 121 '-sign', $nonfips_key, 122 '-out', $sigfile, 123 $tbs_data])), 124 $testtext); 125 126 $testtext = $prefix.': '. 127 'Verify something with a non-FIPS key'. 128 ' with the default provider'; 129 ok(run(app(['openssl', 'dgst', '-sha256', 130 '-verify', $nonfips_pub_key, 131 '-signature', $sigfile, 132 $tbs_data])), 133 $testtext); 134 135 $ENV{OPENSSL_CONF} = $fipsconf; 136 137 $testtext = $prefix.': '. 138 'Sign something with a non-FIPS key'. 139 ' (should fail)'; 140 ok(!run(app(['openssl', 'dgst', '-sha256', 141 '-sign', $nonfips_key, 142 '-out', $prefix.'.nonfips.fail.sig', 143 $tbs_data])), 144 $testtext); 145 146 $testtext = $prefix.': '. 147 'Verify something with a non-FIPS key'. 148 ' (should fail)'; 149 ok(!run(app(['openssl', 'dgst', '-sha256', 150 '-verify', $nonfips_pub_key, 151 '-signature', $sigfile, 152 $tbs_data])), 153 $testtext); 154 155 $testtext = $prefix.': '. 156 'Verify something with a non-FIPS key'. 157 ' in FIPS mode but with a non-FIPS property query'; 158 ok(run(app(['openssl', 'dgst', 159 '-provider', 'default', 160 '-propquery', '?fips!=yes', 161 '-sha256', 162 '-verify', $nonfips_pub_key, 163 '-signature', $sigfile, 164 $tbs_data])), 165 $testtext); 166 167 $testtext = $prefix.': '. 168 'Verify a valid signature against the wrong data with a non-FIPS key'. 169 ' (should fail)'; 170 ok(!run(app(['openssl', 'dgst', '-sha256', 171 '-verify', $nonfips_pub_key, 172 '-signature', $sigfile, 173 $bogus_data])), 174 $testtext); 175 } 176} 177 178SKIP : { 179 skip "FIPS EC tests because of no ec in this build", 1 180 if disabled("ec"); 181 182 subtest EC => sub { 183 my $testtext_prefix = 'EC'; 184 my $a_fips_curve = 'prime256v1'; 185 my $fips_key = $testtext_prefix.'.fips.priv.pem'; 186 my $fips_pub_key = $testtext_prefix.'.fips.pub.pem'; 187 my $a_nonfips_curve = 'brainpoolP256r1'; 188 my $nonfips_key = $testtext_prefix.'.nonfips.priv.pem'; 189 my $nonfips_pub_key = $testtext_prefix.'.nonfips.pub.pem'; 190 my $testtext = ''; 191 my $curvename = ''; 192 193 plan tests => 5 + $tsignverify_count; 194 195 $ENV{OPENSSL_CONF} = $defaultconf; 196 $curvename = $a_nonfips_curve; 197 $testtext = $testtext_prefix.': '. 198 'Generate a key with a non-FIPS algorithm with the default provider'; 199 ok(run(app(['openssl', 'genpkey', '-algorithm', 'EC', 200 '-pkeyopt', 'ec_paramgen_curve:'.$curvename, 201 '-out', $nonfips_key])), 202 $testtext); 203 204 pubfrompriv($testtext_prefix, $nonfips_key, $nonfips_pub_key, "non-FIPS"); 205 206 $ENV{OPENSSL_CONF} = $fipsconf; 207 208 $curvename = $a_fips_curve; 209 $testtext = $testtext_prefix.': '. 210 'Generate a key with a FIPS algorithm'; 211 ok(run(app(['openssl', 'genpkey', '-algorithm', 'EC', 212 '-pkeyopt', 'ec_paramgen_curve:'.$curvename, 213 '-out', $fips_key])), 214 $testtext); 215 216 pubfrompriv($testtext_prefix, $fips_key, $fips_pub_key, "FIPS"); 217 218 $curvename = $a_nonfips_curve; 219 $testtext = $testtext_prefix.': '. 220 'Generate a key with a non-FIPS algorithm'. 221 ' (should fail)'; 222 ok(!run(app(['openssl', 'genpkey', '-algorithm', 'EC', 223 '-pkeyopt', 'ec_paramgen_curve:'.$curvename, 224 '-out', $testtext_prefix.'.'.$curvename.'.priv.pem'])), 225 $testtext); 226 227 tsignverify($testtext_prefix, $fips_key, $fips_pub_key, $nonfips_key, 228 $nonfips_pub_key); 229 }; 230} 231 232SKIP: { 233 skip "FIPS RSA tests because of no rsa in this build", 1 234 if disabled("rsa"); 235 236 subtest RSA => sub { 237 my $testtext_prefix = 'RSA'; 238 my $fips_key = $testtext_prefix.'.fips.priv.pem'; 239 my $fips_pub_key = $testtext_prefix.'.fips.pub.pem'; 240 my $nonfips_key = $testtext_prefix.'.nonfips.priv.pem'; 241 my $nonfips_pub_key = $testtext_prefix.'.nonfips.pub.pem'; 242 my $testtext = ''; 243 244 plan tests => 5 + $tsignverify_count; 245 246 $ENV{OPENSSL_CONF} = $defaultconf; 247 $testtext = $testtext_prefix.': '. 248 'Generate a key with a non-FIPS algorithm with the default provider'; 249 ok(run(app(['openssl', 'genpkey', '-algorithm', 'RSA', 250 '-pkeyopt', 'rsa_keygen_bits:512', 251 '-out', $nonfips_key])), 252 $testtext); 253 254 pubfrompriv($testtext_prefix, $nonfips_key, $nonfips_pub_key, "non-FIPS"); 255 256 $ENV{OPENSSL_CONF} = $fipsconf; 257 258 $testtext = $testtext_prefix.': '. 259 'Generate a key with a FIPS algorithm'; 260 ok(run(app(['openssl', 'genpkey', '-algorithm', 'RSA', 261 '-pkeyopt', 'rsa_keygen_bits:2048', 262 '-out', $fips_key])), 263 $testtext); 264 265 pubfrompriv($testtext_prefix, $fips_key, $fips_pub_key, "FIPS"); 266 267 $testtext = $testtext_prefix.': '. 268 'Generate a key with a non-FIPS algorithm'. 269 ' (should fail)'; 270 ok(!run(app(['openssl', 'genpkey', '-algorithm', 'RSA', 271 '-pkeyopt', 'rsa_keygen_bits:512', 272 '-out', $testtext_prefix.'.fail.priv.pem'])), 273 $testtext); 274 275 tsignverify($testtext_prefix, $fips_key, $fips_pub_key, $nonfips_key, 276 $nonfips_pub_key); 277 }; 278} 279 280SKIP : { 281 skip "FIPS DSA tests because of no dsa in this build", 1 282 if disabled("dsa"); 283 284 subtest DSA => sub { 285 my $testtext_prefix = 'DSA'; 286 my $fips_key = $testtext_prefix.'.fips.priv.pem'; 287 my $fips_pub_key = $testtext_prefix.'.fips.pub.pem'; 288 my $nonfips_key = $testtext_prefix.'.nonfips.priv.pem'; 289 my $nonfips_pub_key = $testtext_prefix.'.nonfips.pub.pem'; 290 my $testtext = ''; 291 my $fips_param = $testtext_prefix.'.fips.param.pem'; 292 my $nonfips_param = $testtext_prefix.'.nonfips.param.pem'; 293 my $shortnonfips_param = $testtext_prefix.'.shortnonfips.param.pem'; 294 295 plan tests => 13 + $tsignverify_count; 296 297 $ENV{OPENSSL_CONF} = $defaultconf; 298 299 $testtext = $testtext_prefix.': '. 300 'Generate non-FIPS params with the default provider'; 301 ok(run(app(['openssl', 'genpkey', '-genparam', 302 '-algorithm', 'DSA', 303 '-pkeyopt', 'type:fips186_2', 304 '-pkeyopt', 'dsa_paramgen_bits:512', 305 '-out', $nonfips_param])), 306 $testtext); 307 308 $ENV{OPENSSL_CONF} = $fipsconf; 309 310 $testtext = $testtext_prefix.': '. 311 'Generate FIPS params'; 312 ok(run(app(['openssl', 'genpkey', '-genparam', 313 '-algorithm', 'DSA', 314 '-pkeyopt', 'dsa_paramgen_bits:2048', 315 '-out', $fips_param])), 316 $testtext); 317 318 $testtext = $testtext_prefix.': '. 319 'Generate non-FIPS params'. 320 ' (should fail)'; 321 ok(!run(app(['openssl', 'genpkey', '-genparam', 322 '-algorithm', 'DSA', 323 '-pkeyopt', 'dsa_paramgen_bits:512', 324 '-out', $testtext_prefix.'.fail.param.pem'])), 325 $testtext); 326 327 $testtext = $testtext_prefix.': '. 328 'Generate non-FIPS params using non-FIPS property query'. 329 ' (dsaparam)'; 330 ok(run(app(['openssl', 'dsaparam', '-provider', 'default', 331 '-propquery', '?fips!=yes', 332 '-out', $shortnonfips_param, '1024'])), 333 $testtext); 334 335 $testtext = $testtext_prefix.': '. 336 'Generate non-FIPS params using non-FIPS property query'. 337 ' (genpkey)'; 338 ok(run(app(['openssl', 'genpkey', '-provider', 'default', 339 '-propquery', '?fips!=yes', 340 '-genparam', '-algorithm', 'DSA', 341 '-pkeyopt', 'dsa_paramgen_bits:512'])), 342 $testtext); 343 344 $ENV{OPENSSL_CONF} = $defaultconf; 345 346 $testtext = $testtext_prefix.': '. 347 'Generate a key with non-FIPS params with the default provider'; 348 ok(run(app(['openssl', 'genpkey', 349 '-paramfile', $nonfips_param, 350 '-pkeyopt', 'type:fips186_2', 351 '-out', $nonfips_key])), 352 $testtext); 353 354 pubfrompriv($testtext_prefix, $nonfips_key, $nonfips_pub_key, "non-FIPS"); 355 356 $ENV{OPENSSL_CONF} = $fipsconf; 357 358 $testtext = $testtext_prefix.': '. 359 'Generate a key with FIPS parameters'; 360 ok(run(app(['openssl', 'genpkey', 361 '-paramfile', $fips_param, 362 '-pkeyopt', 'type:fips186_4', 363 '-out', $fips_key])), 364 $testtext); 365 366 pubfrompriv($testtext_prefix, $fips_key, $fips_pub_key, "FIPS"); 367 368 $testtext = $testtext_prefix.': '. 369 'Generate a key with non-FIPS parameters'. 370 ' (should fail)'; 371 ok(!run(app(['openssl', 'genpkey', 372 '-paramfile', $nonfips_param, 373 '-pkeyopt', 'type:fips186_2', 374 '-out', $testtext_prefix.'.fail.priv.pem'])), 375 $testtext); 376 377 $testtext = $testtext_prefix.': '. 378 'Generate a key with non-FIPS parameters using non-FIPS property'. 379 ' query (dsaparam)'; 380 ok(run(app(['openssl', 'dsaparam', '-provider', 'default', 381 '-propquery', '?fips!=yes', 382 '-noout', '-genkey', '1024'])), 383 $testtext); 384 385 $testtext = $testtext_prefix.': '. 386 'Generate a key with non-FIPS parameters using non-FIPS property'. 387 ' query (gendsa)'; 388 ok(run(app(['openssl', 'gendsa', '-provider', 'default', 389 '-propquery', '?fips!=yes', 390 $shortnonfips_param])), 391 $testtext); 392 393 $testtext = $testtext_prefix.': '. 394 'Generate a key with non-FIPS parameters using non-FIPS property'. 395 ' query (genpkey)'; 396 ok(run(app(['openssl', 'genpkey', '-provider', 'default', 397 '-propquery', '?fips!=yes', 398 '-paramfile', $nonfips_param, 399 '-pkeyopt', 'type:fips186_2', 400 '-out', $testtext_prefix.'.fail.priv.pem'])), 401 $testtext); 402 403 tsignverify($testtext_prefix, $fips_key, $fips_pub_key, '', ''); 404 }; 405} 406