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