Home | History | Annotate | Line # | Download | only in recipes
      1 #! /usr/bin/env perl
      2 # Copyright 2015-2025 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 
      9 
     10 use strict;
     11 use warnings;
     12 
     13 use POSIX;
     14 use File::Spec::Functions qw/catfile/;
     15 use File::Compare qw/compare_text compare/;
     16 use OpenSSL::Test qw/:DEFAULT srctop_dir srctop_file bldtop_dir bldtop_file with data_file/;
     17 
     18 use OpenSSL::Test::Utils;
     19 
     20 BEGIN {
     21     setup("test_cms");
     22 }
     23 
     24 use lib srctop_dir('Configurations');
     25 use lib bldtop_dir('.');
     26 
     27 my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0);
     28 my $old_fips = 0;
     29 
     30 plan skip_all => "CMS is not supported by this OpenSSL build"
     31     if disabled("cms");
     32 
     33 my $provpath = bldtop_dir("providers");
     34 
     35 # Some tests require legacy algorithms to be included.
     36 my @legacyprov = ("-provider-path", $provpath,
     37                   "-provider", "default",
     38                   "-provider", "legacy" );
     39 my @defaultprov = ("-provider-path", $provpath,
     40                    "-provider", "default");
     41 
     42 my @config = ( );
     43 my $provname = 'default';
     44 my $dsaallow = '1';
     45 my $no_pqc = 0;
     46 
     47 my $datadir = srctop_dir("test", "recipes", "80-test_cms_data");
     48 my $smdir    = srctop_dir("test", "smime-certs");
     49 my $smcont   = srctop_file("test", "smcont.txt");
     50 my $smcont_zero = srctop_file("test", "smcont_zero.txt");
     51 my ($no_des, $no_dh, $no_dsa, $no_ec, $no_ec2m, $no_rc2, $no_zlib)
     52     = disabled qw/des dh dsa ec ec2m rc2 zlib/;
     53 
     54 $no_rc2 = 1 if disabled("legacy");
     55 
     56 plan tests => 31;
     57 
     58 ok(run(test(["pkcs7_test"])), "test pkcs7");
     59 
     60 unless ($no_fips) {
     61     my $provconf = srctop_file("test", "fips-and-base.cnf");
     62     @config = ( "-config", $provconf );
     63     $provname = 'fips';
     64 
     65     run(test(["fips_version_test", "-config", $provconf, "<3.4.0"]),
     66         capture => 1, statusvar => \$dsaallow);
     67     $no_dsa = 1 if $dsaallow == '0';
     68     $old_fips = 1 if $dsaallow != '0';
     69     run(test(["fips_version_test", "-config", $provconf, "<3.5.0"]),
     70         capture => 1, statusvar => \$no_pqc);
     71 }
     72 
     73 $ENV{OPENSSL_TEST_LIBCTX} = "1";
     74 my @prov = ("-provider-path", $provpath,
     75             @config,
     76             "-provider", $provname);
     77 
     78 my $smrsa1024 = catfile($smdir, "smrsa1024.pem");
     79 my $smrsa1 = catfile($smdir, "smrsa1.pem");
     80 my $smroot = catfile($smdir, "smroot.pem");
     81 
     82 my @smime_pkcs7_tests = (
     83 
     84     [ "signed content DER format, RSA key",
     85       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER", "-nodetach",
     86         "-certfile", $smroot, "-signer", $smrsa1, "-out", "{output}.cms" ],
     87       [ "{cmd2}",  @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
     88         "-CAfile", $smroot, "-out", "{output}.txt" ],
     89       \&final_compare
     90     ],
     91 
     92     [ "signed text content DER format, RSA key",
     93       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER", "-nodetach",
     94         "-certfile", $smroot, "-signer", $smrsa1, "-text",
     95         "-out", "{output}.cms" ],
     96       [ "{cmd2}",  @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
     97         "-text", "-CAfile", $smroot, "-out", "{output}.txt" ],
     98       \&final_compare
     99     ],
    100 
    101     [ "signed detached content DER format, RSA key",
    102       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER",
    103         "-signer", $smrsa1, "-out", "{output}.cms" ],
    104       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
    105         "-CAfile", $smroot, "-out", "{output}.txt",
    106         "-content", $smcont ],
    107       \&final_compare
    108     ],
    109 
    110     [ "signed content test streaming BER format, RSA",
    111       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER", "-nodetach",
    112         "-stream",
    113         "-signer", $smrsa1, "-out", "{output}.cms" ],
    114       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
    115         "-CAfile", $smroot, "-out", "{output}.txt" ],
    116       \&final_compare
    117     ],
    118 
    119     [ "signed content DER format, DSA key",
    120       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER", "-nodetach",
    121         "-signer", catfile($smdir, "smdsa1.pem"), "-out", "{output}.cms" ],
    122       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
    123         "-CAfile", $smroot, "-out", "{output}.txt" ],
    124       \&final_compare
    125     ],
    126 
    127     [ "signed detached content DER format, DSA key",
    128       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER",
    129         "-signer", catfile($smdir, "smdsa1.pem"), "-out", "{output}.cms" ],
    130       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
    131         "-CAfile", $smroot, "-out", "{output}.txt",
    132         "-content", $smcont ],
    133       \&final_compare
    134     ],
    135 
    136     [ "signed detached content DER format, add RSA signer (with DSA existing)",
    137       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER",
    138         "-signer", catfile($smdir, "smdsa1.pem"), "-out", "{output}.cms" ],
    139       [ "{cmd1}", @prov, "-resign", "-in", "{output}.cms", "-inform", "DER", "-outform", "DER",
    140         "-signer", $smrsa1, "-out", "{output}2.cms" ],
    141       [ "{cmd2}", @prov, "-verify", "-in", "{output}2.cms", "-inform", "DER",
    142         "-CAfile", $smroot, "-out", "{output}.txt",
    143         "-content", $smcont ],
    144       \&final_compare
    145     ],
    146 
    147     [ "signed content test streaming BER format, DSA key",
    148       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER",
    149         "-nodetach", "-stream",
    150         "-signer", catfile($smdir, "smdsa1.pem"), "-out", "{output}.cms" ],
    151       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
    152         "-CAfile", $smroot, "-out", "{output}.txt" ],
    153       \&final_compare
    154     ],
    155 
    156     [ "signed content test streaming BER format, 2 DSA and 2 RSA keys",
    157       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER",
    158         "-nodetach", "-stream",
    159         "-signer", $smrsa1,
    160         "-signer", catfile($smdir, "smrsa2.pem"),
    161         "-signer", catfile($smdir, "smdsa1.pem"),
    162         "-signer", catfile($smdir, "smdsa2.pem"),
    163         "-out", "{output}.cms" ],
    164       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
    165         "-CAfile", $smroot, "-out", "{output}.txt" ],
    166       \&final_compare
    167     ],
    168 
    169     [ "signed content test streaming BER format, 2 DSA and 2 RSA keys, no attributes",
    170       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER",
    171         "-noattr", "-nodetach", "-stream",
    172         "-signer", $smrsa1,
    173         "-signer", catfile($smdir, "smrsa2.pem"),
    174         "-signer", catfile($smdir, "smdsa1.pem"),
    175         "-signer", catfile($smdir, "smdsa2.pem"),
    176         "-out", "{output}.cms" ],
    177       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
    178         "-CAfile", $smroot, "-out", "{output}.txt" ],
    179       \&final_compare
    180     ],
    181 
    182     [ "signed content S/MIME format, RSA key SHA1",
    183       [ "{cmd1}", @defaultprov, "-sign", "-in", $smcont, "-md", "sha1",
    184         "-certfile", $smroot,
    185         "-signer", $smrsa1, "-out", "{output}.cms" ],
    186       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms",
    187         "-CAfile", $smroot, "-out", "{output}.txt" ],
    188       \&final_compare
    189     ],
    190 
    191     [ "signed zero-length content S/MIME format, RSA key SHA1",
    192       [ "{cmd1}", @defaultprov, "-sign", "-in", $smcont_zero, "-md", "sha1",
    193         "-certfile", $smroot, "-signer", $smrsa1, "-out", "{output}.cms" ],
    194       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms",
    195         "-CAfile", $smroot, "-out", "{output}.txt" ],
    196       \&zero_compare
    197     ],
    198 
    199     [ "signed content test streaming S/MIME format, 2 DSA and 2 RSA keys",
    200       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-nodetach",
    201         "-signer", $smrsa1,
    202         "-signer", catfile($smdir, "smrsa2.pem"),
    203         "-signer", catfile($smdir, "smdsa1.pem"),
    204         "-signer", catfile($smdir, "smdsa2.pem"),
    205         "-stream", "-out", "{output}.cms" ],
    206       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms",
    207         "-CAfile", $smroot, "-out", "{output}.txt" ],
    208       \&final_compare
    209     ],
    210 
    211     [ "signed content test streaming multipart S/MIME format, 2 DSA and 2 RSA keys",
    212       [ "{cmd1}", @prov, "-sign", "-in", $smcont,
    213         "-signer", $smrsa1,
    214         "-signer", catfile($smdir, "smrsa2.pem"),
    215         "-signer", catfile($smdir, "smdsa1.pem"),
    216         "-signer", catfile($smdir, "smdsa2.pem"),
    217         "-stream", "-out", "{output}.cms" ],
    218       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms",
    219         "-CAfile", $smroot, "-out", "{output}.txt" ],
    220       \&final_compare
    221     ],
    222 
    223     [ "enveloped content test streaming S/MIME format, DES, 3 recipients",
    224       [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
    225         "-stream", "-out", "{output}.cms",
    226         $smrsa1,
    227         catfile($smdir, "smrsa2.pem"),
    228         catfile($smdir, "smrsa3.pem") ],
    229       [ "{cmd2}", @defaultprov, "-decrypt", "-recip", $smrsa1,
    230         "-in", "{output}.cms", "-out", "{output}.txt" ],
    231       \&final_compare
    232     ],
    233 
    234     [ "enveloped text content streaming S/MIME format, DES, 1 recipient",
    235       [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
    236         "-stream", "-text", "-out", "{output}.cms", $smrsa1 ],
    237       [ "{cmd2}", @defaultprov, "-decrypt", "-recip", $smrsa1,
    238         "-in", "{output}.cms", "-text", "-out", "{output}.txt" ],
    239       \&final_compare
    240     ],
    241 
    242     [ "enveloped content test streaming S/MIME format, DES, 3 recipients, 3rd used",
    243       [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
    244         "-stream", "-out", "{output}.cms",
    245         $smrsa1,
    246         catfile($smdir, "smrsa2.pem"),
    247         catfile($smdir, "smrsa3.pem") ],
    248       [ "{cmd2}", @defaultprov, "-decrypt", "-recip", catfile($smdir, "smrsa3.pem"),
    249         "-in", "{output}.cms", "-out", "{output}.txt" ],
    250       \&final_compare
    251     ],
    252 
    253     [ "enveloped content test streaming S/MIME format, DES, 3 recipients, cert and key files used",
    254       [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
    255         "-stream", "-out", "{output}.cms",
    256         $smrsa1,
    257         catfile($smdir, "smrsa2.pem"),
    258         catfile($smdir, "smrsa3-cert.pem") ],
    259       [ "{cmd2}", @defaultprov, "-decrypt",
    260 	"-recip", catfile($smdir, "smrsa3-cert.pem"),
    261 	"-inkey", catfile($smdir, "smrsa3-key.pem"),
    262         "-in", "{output}.cms", "-out", "{output}.txt" ],
    263       \&final_compare
    264     ],
    265 
    266 );
    267 
    268 if ($no_fips || $old_fips) {
    269     push(@smime_pkcs7_tests,
    270          [ "enveloped content test streaming S/MIME format, AES-256 cipher, 3 recipients",
    271            [ "{cmd1}", @prov, "-encrypt", "-in", $smcont,
    272              "-aes256", "-stream", "-out", "{output}.cms",
    273              $smrsa1,
    274              catfile($smdir, "smrsa2.pem"),
    275              catfile($smdir, "smrsa3.pem") ],
    276            [ "{cmd2}", @prov, "-decrypt", "-recip", $smrsa1,
    277              "-in", "{output}.cms", "-out", "{output}.txt" ],
    278            \&final_compare
    279          ]
    280     );
    281 }
    282 
    283 my @smime_cms_tests = (
    284 
    285     [ "signed content test streaming BER format, 2 DSA and 2 RSA keys, keyid",
    286       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER",
    287         "-nodetach", "-keyid",
    288         "-signer", $smrsa1,
    289         "-signer", catfile($smdir, "smrsa2.pem"),
    290         "-signer", catfile($smdir, "smdsa1.pem"),
    291         "-signer", catfile($smdir, "smdsa2.pem"),
    292         "-stream", "-out", "{output}.cms" ],
    293       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
    294         "-CAfile", $smroot, "-out", "{output}.txt" ],
    295       \&final_compare
    296     ],
    297 
    298     [ "signed content test streaming PEM format, 2 DSA and 2 RSA keys",
    299       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
    300         "-signer", $smrsa1,
    301         "-signer", catfile($smdir, "smrsa2.pem"),
    302         "-signer", catfile($smdir, "smdsa1.pem"),
    303         "-signer", catfile($smdir, "smdsa2.pem"),
    304         "-stream", "-out", "{output}.cms" ],
    305       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "PEM",
    306         "-CAfile", $smroot, "-out", "{output}.txt" ],
    307       \&final_compare
    308     ],
    309 
    310     [ "signed content MIME format, RSA key, signed receipt request",
    311       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-nodetach",
    312         "-signer", $smrsa1,
    313         "-receipt_request_to", "test\@openssl.org", "-receipt_request_all",
    314         "-out", "{output}.cms" ],
    315       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms",
    316         "-CAfile", $smroot, "-out", "{output}.txt" ],
    317       \&final_compare
    318     ],
    319 
    320     [ "signed receipt MIME format, RSA key",
    321       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-nodetach",
    322         "-signer", $smrsa1,
    323         "-receipt_request_to", "test\@openssl.org", "-receipt_request_all",
    324         "-out", "{output}.cms" ],
    325       [ "{cmd1}", @prov, "-sign_receipt", "-in", "{output}.cms",
    326         "-signer", catfile($smdir, "smrsa2.pem"), "-out", "{output}2.cms" ],
    327       [ "{cmd2}", @prov, "-verify_receipt", "{output}2.cms", "-in", "{output}.cms",
    328         "-CAfile", $smroot ]
    329     ],
    330 
    331     [ "enveloped content test streaming S/MIME format, DES, 3 recipients, keyid",
    332       [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
    333         "-stream", "-out", "{output}.cms", "-keyid",
    334         $smrsa1,
    335         catfile($smdir, "smrsa2.pem"),
    336         catfile($smdir, "smrsa3.pem") ],
    337       [ "{cmd2}", @defaultprov, "-decrypt", "-recip", $smrsa1,
    338         "-in", "{output}.cms", "-out", "{output}.txt" ],
    339       \&final_compare
    340     ],
    341 
    342     [ "enveloped content test streaming PEM format, AES-256-CBC cipher, KEK",
    343       [ "{cmd1}", @prov, "-encrypt", "-in", $smcont, "-outform", "PEM", "-aes128",
    344         "-stream", "-out", "{output}.cms",
    345         "-secretkey", "000102030405060708090A0B0C0D0E0F",
    346         "-secretkeyid", "C0FEE0" ],
    347       [ "{cmd2}", @prov, "-decrypt", "-in", "{output}.cms", "-out", "{output}.txt",
    348         "-inform", "PEM",
    349         "-secretkey", "000102030405060708090A0B0C0D0E0F",
    350         "-secretkeyid", "C0FEE0" ],
    351       \&final_compare
    352     ],
    353 
    354     [ "enveloped content test streaming PEM format, AES-256-GCM cipher, KEK",
    355       [ "{cmd1}", @prov, "-encrypt", "-in", $smcont, "-outform", "PEM", "-aes-128-gcm",
    356         "-stream", "-out", "{output}.cms",
    357         "-secretkey", "000102030405060708090A0B0C0D0E0F",
    358         "-secretkeyid", "C0FEE0" ],
    359       [ "{cmd2}", "-decrypt", "-in", "{output}.cms", "-out", "{output}.txt",
    360         "-inform", "PEM",
    361         "-secretkey", "000102030405060708090A0B0C0D0E0F",
    362         "-secretkeyid", "C0FEE0" ],
    363       \&final_compare
    364     ],
    365 
    366     [ "enveloped content test streaming PEM format, KEK, key only",
    367       [ "{cmd1}", @prov, "-encrypt", "-in", $smcont, "-outform", "PEM", "-aes128",
    368         "-stream", "-out", "{output}.cms",
    369         "-secretkey", "000102030405060708090A0B0C0D0E0F",
    370         "-secretkeyid", "C0FEE0" ],
    371       [ "{cmd2}", @prov, "-decrypt", "-in", "{output}.cms", "-out", "{output}.txt",
    372         "-inform", "PEM",
    373         "-secretkey", "000102030405060708090A0B0C0D0E0F" ],
    374       \&final_compare
    375     ],
    376 
    377     [ "enveloped content test streaming PEM format, AES-128-CBC cipher, password",
    378       [ "{cmd1}", @prov, "-encrypt", "-in", $smcont, "-outform", "PEM", "-aes128",
    379         "-stream", "-out", "{output}.cms",
    380         "-pwri_password", "test" ],
    381       [ "{cmd2}", @prov, "-decrypt", "-in", "{output}.cms", "-out", "{output}.txt",
    382         "-inform", "PEM",
    383         "-pwri_password", "test" ],
    384       \&final_compare
    385     ],
    386 
    387     [ "data content test streaming PEM format",
    388       [ "{cmd1}", @prov, "-data_create", "-in", $smcont, "-outform", "PEM",
    389         "-nodetach", "-stream", "-out", "{output}.cms" ],
    390       [ "{cmd2}", @prov, "-data_out", "-in", "{output}.cms", "-inform", "PEM",
    391         "-out", "{output}.txt" ],
    392       \&final_compare
    393     ],
    394 
    395     [ "encrypted content test streaming PEM format, 128 bit RC2 key",
    396       [ "{cmd1}", @legacyprov, "-EncryptedData_encrypt",
    397         "-in", $smcont, "-outform", "PEM",
    398         "-rc2", "-secretkey", "000102030405060708090A0B0C0D0E0F",
    399         "-stream", "-out", "{output}.cms" ],
    400       [ "{cmd2}", @legacyprov, "-EncryptedData_decrypt", "-in", "{output}.cms",
    401         "-inform", "PEM",
    402         "-secretkey", "000102030405060708090A0B0C0D0E0F",
    403         "-out", "{output}.txt" ],
    404       \&final_compare
    405     ],
    406 
    407     [ "encrypted content test streaming PEM format, 40 bit RC2 key",
    408       [ "{cmd1}", @legacyprov, "-EncryptedData_encrypt",
    409         "-in", $smcont, "-outform", "PEM",
    410         "-rc2", "-secretkey", "0001020304",
    411         "-stream", "-out", "{output}.cms" ],
    412       [ "{cmd2}", @legacyprov, "-EncryptedData_decrypt", "-in", "{output}.cms",
    413         "-inform", "PEM",
    414         "-secretkey", "0001020304", "-out", "{output}.txt" ],
    415       \&final_compare
    416     ],
    417 
    418     [ "encrypted content test streaming PEM format, triple DES key",
    419       [ "{cmd1}", @defaultprov, "-EncryptedData_encrypt", "-in", $smcont, "-outform", "PEM",
    420         "-des3", "-secretkey", "000102030405060708090A0B0C0D0E0F1011121314151617",
    421         "-stream", "-out", "{output}.cms" ],
    422       [ "{cmd2}", @prov, "-EncryptedData_decrypt", "-in", "{output}.cms",
    423         "-inform", "PEM",
    424         "-secretkey", "000102030405060708090A0B0C0D0E0F1011121314151617",
    425         "-out", "{output}.txt" ],
    426       \&final_compare
    427     ],
    428 
    429     [ "encrypted content test streaming PEM format, 128 bit AES key",
    430       [ "{cmd1}", @prov, "-EncryptedData_encrypt", "-in", $smcont, "-outform", "PEM",
    431         "-aes128", "-secretkey", "000102030405060708090A0B0C0D0E0F",
    432         "-stream", "-out", "{output}.cms" ],
    433       [ "{cmd2}", @prov, "-EncryptedData_decrypt", "-in", "{output}.cms",
    434         "-inform", "PEM",
    435         "-secretkey", "000102030405060708090A0B0C0D0E0F",
    436         "-out", "{output}.txt" ],
    437       \&final_compare
    438     ],
    439 
    440     [ "encrypted content test streaming PEM format -noout, 128 bit AES key",
    441       [ "{cmd1}", @prov, "-EncryptedData_encrypt", "-in", $smcont, "-outform", "PEM",
    442 	"-aes128", "-secretkey", "000102030405060708090A0B0C0D0E0F",
    443 	"-stream", "-noout" ],
    444       [ "{cmd2}", @prov, "-help" ]
    445     ],
    446 );
    447 
    448 my @smime_cms_cades_tests = (
    449 
    450     [ "signed content DER format, RSA key, CAdES-BES compatible",
    451       [ "{cmd1}", @prov, "-sign", "-cades", "-in", $smcont, "-outform", "DER",
    452          "-nodetach",
    453         "-certfile", $smroot, "-signer", $smrsa1, "-out", "{output}.cms" ],
    454       [ "{cmd2}", @prov, "-verify", "-cades", "-in", "{output}.cms", "-inform", "DER",
    455         "-CAfile", $smroot, "-out", "{output}.txt" ],
    456       \&final_compare
    457     ],
    458 
    459     [ "signed content DER format, RSA key, SHA256 md, CAdES-BES compatible",
    460       [ "{cmd1}", @prov, "-sign", "-cades", "-md", "sha256", "-in", $smcont, "-outform",
    461         "DER", "-nodetach", "-certfile", $smroot,
    462         "-signer", $smrsa1, "-out", "{output}.cms" ],
    463       [ "{cmd2}", @prov, "-verify", "-cades", "-in", "{output}.cms", "-inform", "DER",
    464         "-CAfile", $smroot, "-out", "{output}.txt" ],
    465       \&final_compare
    466     ],
    467 
    468     [ "signed content DER format, RSA key, SHA512 md, CAdES-BES compatible",
    469       [ "{cmd1}", @prov, "-sign", "-cades", "-md", "sha512", "-in", $smcont, "-outform",
    470         "DER", "-nodetach", "-certfile", $smroot,
    471         "-signer", $smrsa1, "-out", "{output}.cms" ],
    472       [ "{cmd2}", @prov, "-verify", "-cades", "-in", "{output}.cms", "-inform", "DER",
    473         "-CAfile", $smroot, "-out", "{output}.txt" ],
    474       \&final_compare
    475     ],
    476 
    477     [ "signed content DER format, RSA key, SHA256 md, CAdES-BES compatible",
    478       [ "{cmd1}", @prov, "-sign", "-cades", "-binary",  "-nodetach", "-nosmimecap", "-md", "sha256",
    479         "-in", $smcont, "-outform", "DER", 
    480         "-certfile", $smroot, "-signer", $smrsa1,
    481         "-outform", "DER", "-out", "{output}.cms"  ],
    482       [ "{cmd2}", @prov, "-verify", "-cades", "-in", "{output}.cms", "-inform", "DER",
    483         "-CAfile", $smroot, "-out", "{output}.txt" ],
    484       \&final_compare
    485     ],
    486 
    487     [ "resigned content DER format, RSA key, SHA256 md, CAdES-BES compatible",
    488       [ "{cmd1}", @prov, "-sign", "-cades", "-binary",  "-nodetach", "-nosmimecap", "-md", "sha256",
    489         "-in", $smcont, "-outform", "DER", 
    490         "-certfile", $smroot, "-signer", $smrsa1,
    491         "-outform", "DER", "-out", "{output}.cms"  ],
    492       [ "{cmd1}", @prov, "-resign", "-cades", "-binary", "-nodetach", "-nosmimecap", "-md", "sha256",
    493         "-inform", "DER", "-in", "{output}.cms",
    494         "-certfile", $smroot, "-signer", catfile($smdir, "smrsa2.pem"),
    495         "-outform", "DER", "-out", "{output}2.cms" ],
    496 
    497       [ "{cmd2}", @prov, "-verify", "-cades", "-in", "{output}2.cms", "-inform", "DER",
    498         "-CAfile", $smroot, "-out", "{output}.txt" ],
    499       \&final_compare
    500     ],
    501 );
    502 
    503 my @smime_cms_cades_ko_tests = (
    504     [ "sign content DER format, RSA key, not CAdES-BES compatible",
    505       [ @prov, "-sign", "-in", $smcont, "-outform", "DER", "-nodetach",
    506         "-certfile", $smroot, "-signer", $smrsa1, "-out", "cades-ko.cms" ],
    507       "fail to verify token since requiring CAdES-BES compatibility",
    508       [ @prov, "-verify", "-cades", "-in", "cades-ko.cms", "-inform", "DER",
    509         "-CAfile", $smroot, "-out", "cades-ko.txt" ],
    510       \&final_compare
    511     ]
    512 );
    513 
    514 # cades options test - check that some combinations are rejected
    515 my @smime_cms_cades_invalid_option_tests = (
    516     [
    517         [ "-cades", "-noattr" ],
    518     ],[
    519         [ "-verify", "-cades", "-noattr" ],
    520     ],[
    521         [ "-verify", "-cades", "-noverify" ],
    522     ],
    523 );
    524 
    525 my @smime_cms_comp_tests = (
    526 
    527     [ "compressed content test streaming PEM format",
    528       [ "{cmd1}", @prov, "-compress", "-in", $smcont, "-outform", "PEM", "-nodetach",
    529         "-stream", "-out", "{output}.cms" ],
    530       [ "{cmd2}", @prov, "-uncompress", "-in", "{output}.cms", "-inform", "PEM",
    531         "-out", "{output}.txt" ],
    532       \&final_compare
    533     ]
    534 
    535 );
    536 
    537 my @smime_cms_param_tests = (
    538     [ "signed content test streaming PEM format, RSA keys, PSS signature",
    539       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
    540         "-signer", $smrsa1,
    541         "-keyopt", "rsa_padding_mode:pss",
    542         "-out", "{output}.cms" ],
    543       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "PEM",
    544         "-CAfile", $smroot, "-out", "{output}.txt" ],
    545       \&final_compare
    546     ],
    547 
    548     [ "signed content test streaming PEM format, RSA keys, PSS signature, saltlen=max",
    549       [ "{cmd1}", @defaultprov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
    550         "-signer", $smrsa1,
    551         "-keyopt", "rsa_padding_mode:pss", "-keyopt", "rsa_pss_saltlen:max",
    552         "-out", "{output}.cms" ],
    553       sub { my %opts = @_; rsapssSaltlen("$opts{output}.cms") == 222; },
    554       [ "{cmd2}", @defaultprov, "-verify", "-in", "{output}.cms", "-inform", "PEM",
    555         "-CAfile", $smroot, "-out", "{output}.txt" ],
    556       \&final_compare
    557     ],
    558 
    559     [ "signed content test streaming PEM format, RSA keys, PSS signature, no attributes",
    560       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
    561         "-noattr", "-signer", $smrsa1,
    562         "-keyopt", "rsa_padding_mode:pss",
    563         "-out", "{output}.cms" ],
    564       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "PEM",
    565         "-CAfile", $smroot, "-out", "{output}.txt" ],
    566       \&final_compare
    567     ],
    568 
    569     [ "signed content test streaming PEM format, RSA keys, PSS signature, SHA384 MGF1",
    570       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
    571         "-signer", $smrsa1,
    572         "-keyopt", "rsa_padding_mode:pss", "-keyopt", "rsa_mgf1_md:sha384",
    573         "-out", "{output}.cms" ],
    574       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "PEM",
    575         "-CAfile", $smroot, "-out", "{output}.txt" ],
    576       \&final_compare
    577     ],
    578 
    579     [ "signed content test streaming PEM format, RSA keys, PSS signature, saltlen=16",
    580       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
    581         "-signer", $smrsa1, "-md", "sha256",
    582         "-keyopt", "rsa_padding_mode:pss", "-keyopt", "rsa_pss_saltlen:16",
    583         "-out", "{output}.cms" ],
    584       sub { my %opts = @_; rsapssSaltlen("$opts{output}.cms") == 16; },
    585       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "PEM",
    586         "-CAfile", $smroot, "-out", "{output}.txt" ],
    587       \&final_compare
    588     ],
    589 
    590     [ "signed content test streaming PEM format, RSA keys, PSS signature, saltlen=digest",
    591       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
    592         "-signer", $smrsa1, "-md", "sha256",
    593         "-keyopt", "rsa_padding_mode:pss", "-keyopt", "rsa_pss_saltlen:digest",
    594         "-out", "{output}.cms" ],
    595       # digest is SHA-256, which produces 32 bytes of output
    596       sub { my %opts = @_; rsapssSaltlen("$opts{output}.cms") == 32; },
    597       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "PEM",
    598         "-CAfile", $smroot, "-out", "{output}.txt" ],
    599       \&final_compare
    600     ],
    601 
    602     [ "enveloped content test streaming S/MIME format, DES, OAEP default parameters",
    603       [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
    604         "-stream", "-out", "{output}.cms",
    605         "-recip", $smrsa1,
    606         "-keyopt", "rsa_padding_mode:oaep" ],
    607       [ "{cmd2}", @defaultprov, "-decrypt", "-recip", $smrsa1,
    608         "-in", "{output}.cms", "-out", "{output}.txt" ],
    609       \&final_compare
    610     ],
    611 
    612     [ "enveloped content test streaming S/MIME format, DES, OAEP SHA256",
    613       [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
    614         "-stream", "-out", "{output}.cms",
    615         "-recip", $smrsa1,
    616         "-keyopt", "rsa_padding_mode:oaep",
    617         "-keyopt", "rsa_oaep_md:sha256" ],
    618       [ "{cmd2}", @defaultprov, "-decrypt", "-recip", $smrsa1,
    619         "-in", "{output}.cms", "-out", "{output}.txt" ],
    620       \&final_compare
    621     ],
    622 
    623     [ "enveloped content test streaming S/MIME format, DES, ECDH",
    624       [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
    625         "-stream", "-out", "{output}.cms",
    626         "-recip", catfile($smdir, "smec1.pem") ],
    627       [ "{cmd2}", @defaultprov, "-decrypt", "-recip", catfile($smdir, "smec1.pem"),
    628         "-in", "{output}.cms", "-out", "{output}.txt" ],
    629       \&final_compare
    630     ],
    631 
    632     [ "enveloped content test streaming S/MIME format, DES, ECDH, 2 recipients, key only used",
    633       [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
    634         "-stream", "-out", "{output}.cms",
    635         catfile($smdir, "smec1.pem"),
    636         catfile($smdir, "smec3.pem") ],
    637       [ "{cmd2}", @defaultprov, "-decrypt", "-inkey", catfile($smdir, "smec3.pem"),
    638         "-in", "{output}.cms", "-out", "{output}.txt" ],
    639       \&final_compare
    640     ],
    641 
    642     [ "enveloped content test streaming S/MIME format, ECDH, DES, key identifier",
    643       [ "{cmd1}", @defaultprov, "-encrypt", "-keyid", "-in", $smcont,
    644         "-stream", "-out", "{output}.cms",
    645         "-recip", catfile($smdir, "smec1.pem") ],
    646       [ "{cmd2}", @defaultprov, "-decrypt", "-recip", catfile($smdir, "smec1.pem"),
    647         "-in", "{output}.cms", "-out", "{output}.txt" ],
    648       \&final_compare
    649     ],
    650 
    651     [ "enveloped content test streaming S/MIME format, ECDH, AES-128-CBC, SHA256 KDF",
    652       [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
    653         "-stream", "-out", "{output}.cms",
    654         "-recip", catfile($smdir, "smec1.pem"), "-aes128",
    655         "-keyopt", "ecdh_kdf_md:sha256" ],
    656       sub { my %opts = @_; smimeType_matches("$opts{output}.cms", "enveloped-data"); },
    657       [ "{cmd2}", @defaultprov, "-decrypt", "-recip", catfile($smdir, "smec1.pem"),
    658         "-in", "{output}.cms", "-out", "{output}.txt" ],
    659       \&final_compare
    660     ],
    661 
    662     [ "enveloped content test streaming S/MIME format, ECDH, AES-128-GCM cipher, SHA256 KDF",
    663       [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
    664         "-stream", "-out", "{output}.cms",
    665         "-recip", catfile($smdir, "smec1.pem"), "-aes-128-gcm", "-keyopt", "ecdh_kdf_md:sha256" ],
    666       sub { my %opts = @_; smimeType_matches("$opts{output}.cms", "authEnveloped-data"); },
    667       [ "{cmd2}", "-decrypt", "-recip", catfile($smdir, "smec1.pem"),
    668         "-in", "{output}.cms", "-out", "{output}.txt" ],
    669       \&final_compare
    670     ],
    671 
    672     [ "enveloped content test streaming S/MIME format, ECDH, K-283, cofactor DH",
    673       [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
    674         "-stream", "-out", "{output}.cms",
    675         "-recip", catfile($smdir, "smec2.pem"), "-aes128",
    676         "-keyopt", "ecdh_kdf_md:sha256", "-keyopt", "ecdh_cofactor_mode:1" ],
    677       [ "{cmd2}", @defaultprov, "-decrypt", "-recip", catfile($smdir, "smec2.pem"),
    678         "-in", "{output}.cms", "-out", "{output}.txt" ],
    679       \&final_compare
    680     ]
    681 );
    682 
    683 if ($no_fips || $old_fips) {
    684     # Only SHA1 supported in dh_cms_encrypt()
    685     push(@smime_cms_param_tests,
    686 
    687 	 [ "enveloped content test streaming S/MIME format, X9.42 DH",
    688 	   [ "{cmd1}", @prov, "-encrypt", "-in", $smcont,
    689 	     "-stream", "-out", "{output}.cms",
    690 	     "-recip", catfile($smdir, "smdh.pem"), "-aes128" ],
    691 	   [ "{cmd2}", @prov, "-decrypt", "-recip", catfile($smdir, "smdh.pem"),
    692 	     "-in", "{output}.cms", "-out", "{output}.txt" ],
    693 	   \&final_compare
    694 	 ]
    695     );
    696 }
    697 
    698 my @smime_cms_param_tests_autodigestmax = (
    699     [ "signed content test streaming PEM format, RSA keys, PSS signature, saltlen=auto-digestmax, digestsize < maximum salt length",
    700       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
    701         "-signer", $smrsa1, "-md", "sha256",
    702         "-keyopt", "rsa_padding_mode:pss", "-keyopt", "rsa_pss_saltlen:auto-digestmax",
    703         "-out", "{output}.cms" ],
    704       # digest is SHA-256, which produces 32, bytes of output
    705       sub { my %opts = @_; rsapssSaltlen("$opts{output}.cms") == 32; },
    706       [ "{cmd2}", @defaultprov, "-verify", "-in", "{output}.cms", "-inform", "PEM",
    707         "-CAfile", $smroot, "-out", "{output}.txt" ],
    708       \&final_compare
    709     ],
    710 
    711     [ "signed content test streaming PEM format, RSA keys, PSS signature, saltlen=auto-digestmax, digestsize > maximum salt length",
    712       [ "{cmd1}", @defaultprov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
    713         "-signer", $smrsa1024, "-md", "sha512",
    714         "-keyopt", "rsa_padding_mode:pss", "-keyopt", "rsa_pss_saltlen:auto-digestmax",
    715         "-out", "{output}.cms" ],
    716       # digest is SHA-512, which produces 64, bytes of output, but an RSA-PSS
    717       # signature with a 1024 bit RSA key can only accommodate 62
    718       sub { my %opts = @_; rsapssSaltlen("$opts{output}.cms") == 62; },
    719       [ "{cmd2}", @defaultprov, "-verify", "-in", "{output}.cms", "-inform", "PEM",
    720         "-CAfile", $smroot, "-out", "{output}.txt" ],
    721       \&final_compare
    722     ]
    723 );
    724 
    725 
    726 my @contenttype_cms_test = (
    727     [ "signed content test - check that content type is added to additional signerinfo, RSA keys",
    728       [ "{cmd1}", @prov, "-sign", "-binary", "-nodetach", "-stream", "-in", $smcont,
    729         "-outform", "DER", "-signer", $smrsa1, "-md", "SHA256",
    730         "-out", "{output}.cms" ],
    731       [ "{cmd1}", @prov, "-resign", "-binary", "-nodetach", "-in", "{output}.cms",
    732         "-inform", "DER", "-outform", "DER",
    733         "-signer", catfile($smdir, "smrsa2.pem"), "-md", "SHA256",
    734         "-out", "{output}2.cms" ],
    735       sub { my %opts = @_; contentType_matches("$opts{output}2.cms") == 2; },
    736       [ "{cmd2}", @prov, "-verify", "-in", "{output}2.cms", "-inform", "DER",
    737         "-CAfile", $smroot, "-out", "{output}.txt" ]
    738     ],
    739 );
    740 
    741 my @incorrect_attribute_cms_test = (
    742     "bad_signtime_attr.cms",
    743     "no_ct_attr.cms",
    744     "no_md_attr.cms",
    745     "ct_multiple_attr.cms"
    746 );
    747 
    748 # Runs a standard loop on the input array
    749 sub runner_loop {
    750     my %opts = ( @_ );
    751     my $cnt1 = 0;
    752 
    753     foreach (@{$opts{tests}}) {
    754         $cnt1++;
    755         $opts{output} = "$opts{prefix}-$cnt1";
    756       SKIP: {
    757           my $skip_reason = check_availability($$_[0]);
    758           skip $skip_reason, 1 if $skip_reason;
    759           my $ok = 1;
    760           1 while unlink "$opts{output}.txt";
    761 
    762           foreach (@$_[1..$#$_]) {
    763               if (ref $_ eq 'CODE') {
    764                   $ok &&= $_->(%opts);
    765               } else {
    766                   my @cmd = map {
    767                       my $x = $_;
    768                       while ($x =~ /\{([^\}]+)\}/) {
    769                           $x = $`.$opts{$1}.$' if exists $opts{$1};
    770                       }
    771                       $x;
    772                   } @$_;
    773 
    774                   diag "CMD: openssl ", join(" ", @cmd);
    775                   $ok &&= run(app(["openssl", @cmd]));
    776                   $opts{input} = $opts{output};
    777               }
    778           }
    779 
    780           ok($ok, $$_[0]);
    781         }
    782     }
    783 }
    784 
    785 sub final_compare {
    786     my %opts = @_;
    787 
    788     diag "Comparing $smcont with $opts{output}.txt";
    789     return compare_text($smcont, "$opts{output}.txt") == 0;
    790 }
    791 
    792 sub zero_compare {
    793     my %opts = @_;
    794 
    795     diag "Checking for zero-length file";
    796     return (-e "$opts{output}.txt" && -z "$opts{output}.txt");
    797 }
    798 
    799 subtest "CMS => PKCS#7 compatibility tests\n" => sub {
    800     plan tests => scalar @smime_pkcs7_tests;
    801 
    802     runner_loop(prefix => 'cms2pkcs7', cmd1 => 'cms', cmd2 => 'smime',
    803                 tests => [ @smime_pkcs7_tests ]);
    804 };
    805 subtest "CMS <= PKCS#7 compatibility tests\n" => sub {
    806     plan tests => scalar @smime_pkcs7_tests;
    807 
    808     runner_loop(prefix => 'pkcs72cms', cmd1 => 'smime', cmd2 => 'cms',
    809                 tests => [ @smime_pkcs7_tests ]);
    810 };
    811 
    812 subtest "CMS <=> CMS consistency tests\n" => sub {
    813     plan tests => (scalar @smime_pkcs7_tests) + (scalar @smime_cms_tests);
    814 
    815     runner_loop(prefix => 'cms2cms-1', cmd1 => 'cms', cmd2 => 'cms',
    816                 tests => [ @smime_pkcs7_tests ]);
    817     runner_loop(prefix => 'cms2cms-2', cmd1 => 'cms', cmd2 => 'cms',
    818                 tests => [ @smime_cms_tests ]);
    819 };
    820 
    821 subtest "CMS <=> CMS consistency tests, modified key parameters\n" => sub {
    822     plan tests =>
    823         (scalar @smime_cms_param_tests) + (scalar @smime_cms_comp_tests) +
    824         (scalar @smime_cms_param_tests_autodigestmax) + 1;
    825 
    826     ok(run(app(["openssl", "cms", @prov,
    827                 "-sign", "-in", $smcont,
    828                 "-outform", "PEM",
    829                 "-nodetach",
    830                 "-signer", $smrsa1,
    831                 "-keyopt", "rsa_padding_mode:pss",
    832                 "-keyopt", "rsa_pss_saltlen:auto-digestmax",
    833                 "-out", "digestmaxtest.cms"])));
    834     # Providers that do not support rsa_pss_saltlen:auto-digestmax will parse
    835     # it as 0
    836     my $no_autodigestmax = rsapssSaltlen("digestmaxtest.cms") == 0;
    837     1 while unlink "digestmaxtest.cms";
    838 
    839     runner_loop(prefix => 'cms2cms-mod', cmd1 => 'cms', cmd2 => 'cms',
    840                 tests => [ @smime_cms_param_tests ]);
    841   SKIP: {
    842       skip("Zlib not supported: compression tests skipped",
    843            scalar @smime_cms_comp_tests)
    844           if $no_zlib;
    845 
    846       runner_loop(prefix => 'cms2cms-comp', cmd1 => 'cms', cmd2 => 'cms',
    847                   tests => [ @smime_cms_comp_tests ]);
    848     }
    849 
    850   SKIP: {
    851     skip("rsa_pss_saltlen:auto-digestmax not supported",
    852          scalar @smime_cms_param_tests_autodigestmax)
    853        if $no_autodigestmax;
    854 
    855        runner_loop(prefix => 'cms2cms-comp', 'cmd1' => 'cms', cmd2 => 'cms',
    856                    tests => [ @smime_cms_param_tests_autodigestmax ]);
    857   }
    858 };
    859 
    860 # Returns the number of matches of a Content Type Attribute in a binary file.
    861 sub contentType_matches {
    862   # Read in a binary file
    863   my ($in) = @_;
    864   open (HEX_IN, "$in") or die("open failed for $in : $!");
    865   binmode(HEX_IN);
    866   local $/;
    867   my $str = <HEX_IN>;
    868 
    869   # Find ASN1 data for a Content Type Attribute (with a OID of PKCS7 data)
    870   my @c = $str =~ /\x30\x18\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x09\x03\x31\x0B\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x07\x01/gs;
    871 
    872   close(HEX_IN);
    873   return scalar(@c);
    874 }
    875 
    876 # Returns 1 if the smime-type matches the passed parameter, otherwise 0.
    877 sub smimeType_matches {
    878   my ($in, $expected_smime_type) = @_;
    879 
    880   # Read the text file
    881   open(my $fh, '<', $in) or die("open failed for $in : $!");
    882   local $/;
    883   my $content = <$fh>;
    884   close($fh);
    885 
    886   # Extract the Content-Type line with the smime-type attribute
    887   if ($content =~ /Content-Type:\s*application\/pkcs7-mime.*smime-type=([^\s;]+)/) {
    888     my $smime_type = $1;
    889 
    890     # Compare the extracted smime-type with the expected value
    891     return ($smime_type eq $expected_smime_type) ? 1 : 0;
    892   }
    893 
    894   # If no smime-type is found, return 0
    895   return 0;
    896 }
    897 
    898 sub rsapssSaltlen {
    899   my ($in) = @_;
    900   my $exit = 0;
    901 
    902   my @asn1parse = run(app(["openssl", "asn1parse", "-in", $in, "-dump"]),
    903                       capture => 1,
    904                       statusvar => $exit);
    905   return -1 if $exit != 0;
    906 
    907   my $pssparam_offset = -1;
    908   while ($_ = shift @asn1parse) {
    909     chomp;
    910     next unless /:rsassaPss/;
    911     # This line contains :rsassaPss, the next line contains a raw dump of the
    912     # RSA_PSS_PARAMS sequence; obtain its offset
    913     $_ = shift @asn1parse;
    914     if (/^\s*(\d+):/) {
    915       $pssparam_offset = int($1);
    916     }
    917   }
    918 
    919   if ($pssparam_offset == -1) {
    920     note "Failed to determine RSA_PSS_PARAM offset in CMS. " +
    921          "Was the file correctly signed with RSASSA-PSS?";
    922     return -1;
    923   }
    924 
    925   my @pssparam = run(app(["openssl", "asn1parse", "-in", $in,
    926                           "-strparse", $pssparam_offset]),
    927                      capture => 1,
    928                      statusvar => $exit);
    929   return -1 if $exit != 0;
    930 
    931   my $saltlen = -1;
    932   # Can't use asn1parse -item RSA_PSS_PARAMS here, because that's deprecated.
    933   # This assumes the salt length is the last field, which may possibly be
    934   # incorrect if there is a non-standard trailer field, but there almost never
    935   # is in PSS.
    936   if ($pssparam[-1] =~ /prim:\s+INTEGER\s+:([A-Fa-f0-9]+)/) {
    937     $saltlen = hex($1);
    938   }
    939 
    940   if ($saltlen == -1) {
    941     note "Failed to determine salt length from RSA_PSS_PARAM struct. " +
    942          "Was the file correctly signed with RSASSA-PSS?";
    943     return -1;
    944   }
    945 
    946   return $saltlen;
    947 }
    948 
    949 subtest "CMS Check the content type attribute is added for additional signers\n" => sub {
    950     plan tests => (scalar @contenttype_cms_test);
    951 
    952     runner_loop(prefix => 'cms2cms-added', cmd1 => 'cms', cmd2 => 'cms',
    953                 tests => [ @contenttype_cms_test ]);
    954 };
    955 
    956 subtest "CMS Check that bad attributes fail when verifying signers\n" => sub {
    957     plan tests =>
    958         (scalar @incorrect_attribute_cms_test);
    959 
    960     my $cnt = 0;
    961     foreach my $name (@incorrect_attribute_cms_test) {
    962         my $out = "incorrect-$cnt.txt";
    963 
    964         ok(!run(app(["openssl", "cms", @prov, "-verify", "-in",
    965                      catfile($datadir, $name), "-inform", "DER", "-CAfile",
    966                      $smroot, "-out", $out ])),
    967             $name);
    968     }
    969 };
    970 
    971 subtest "CMS Check that bad encryption algorithm fails\n" => sub {
    972     plan tests => 1;
    973 
    974     SKIP: {
    975         skip "DES or Legacy isn't supported in this build", 1
    976             if disabled("des") || disabled("legacy");
    977 
    978         my $out = "smtst.txt";
    979 
    980         ok(!run(app(["openssl", "cms", @legacyprov, "-encrypt",
    981                     "-in", $smcont,
    982                     "-stream", "-recip", $smrsa1,
    983                     "-des-ede3",
    984                     "-out", $out ])),
    985            "Decrypt message from OpenSSL 1.1.1");
    986     }
    987 };
    988 
    989 subtest "CMS Decrypt message encrypted with OpenSSL 1.1.1\n" => sub {
    990     plan tests => 1;
    991 
    992     SKIP: {
    993         skip "EC or DES isn't supported in this build", 1
    994             if disabled("ec") || disabled("des");
    995 
    996         my $out = "smtst.txt";
    997 
    998         ok(run(app(["openssl", "cms", @defaultprov, "-decrypt",
    999                     "-inkey", catfile($smdir, "smec3.pem"),
   1000                     "-in", catfile($datadir, "ciphertext_from_1_1_1.cms"),
   1001                     "-out", $out ]))
   1002            && compare_text($smcont, $out) == 0,
   1003            "Decrypt message from OpenSSL 1.1.1");
   1004     }
   1005 };
   1006 
   1007 subtest "CAdES <=> CAdES consistency tests\n" => sub {
   1008     plan tests => (scalar @smime_cms_cades_tests);
   1009 
   1010     runner_loop(prefix => 'cms-cades', cmd1 => 'cms', cmd2 => 'cms',
   1011                 tests => [ @smime_cms_cades_tests ]);
   1012 };
   1013 
   1014 subtest "CAdES; cms incompatible arguments tests\n" => sub {
   1015     plan tests => (scalar @smime_cms_cades_invalid_option_tests);
   1016 
   1017     foreach (@smime_cms_cades_invalid_option_tests) {
   1018         ok(!run(app(["openssl", "cms", @{$$_[0]} ] )));
   1019     }
   1020 };
   1021 
   1022 subtest "CAdES ko tests\n" => sub {
   1023     plan tests => 2 * scalar @smime_cms_cades_ko_tests;
   1024 
   1025     foreach (@smime_cms_cades_ko_tests) {
   1026       SKIP: {
   1027         my $skip_reason = check_availability($$_[0]);
   1028         skip $skip_reason, 1 if $skip_reason;
   1029         1 while unlink "cades-ko.txt";
   1030 
   1031         ok(run(app(["openssl", "cms", @{$$_[1]}])), $$_[0]);
   1032         ok(!run(app(["openssl", "cms", @{$$_[3]}])), $$_[2]);
   1033         }
   1034     }
   1035 };
   1036 
   1037 subtest "CMS binary input tests\n" => sub {
   1038     my $input = srctop_file("test", "smcont.bin");
   1039     my $signed = "smcont.signed";
   1040     my $verified = "smcont.verified";
   1041 
   1042     plan tests => 11;
   1043 
   1044     ok(run(app(["openssl", "cms", "-sign", "-md", "sha256", "-signer", $smrsa1,
   1045                 "-binary", "-in", $input, "-out", $signed])),
   1046        "sign binary input with -binary");
   1047     ok(run(app(["openssl", "cms", "-verify", "-CAfile", $smroot,
   1048                 "-binary", "-in", $signed, "-out", $verified])),
   1049        "verify binary input with -binary");
   1050     is(compare($input, $verified), 0, "binary input retained with -binary");
   1051 
   1052     ok(run(app(["openssl", "cms", "-sign", "-md", "sha256", "-signer", $smrsa1,
   1053                 "-in", $input, "-out", $signed.".nobin"])),
   1054        "sign binary input without -binary");
   1055     ok(run(app(["openssl", "cms", "-verify", "-CAfile", $smroot,
   1056                 "-in", $signed.".nobin", "-out", $verified.".nobin"])),
   1057        "verify binary input without -binary");
   1058     is(compare($input, $verified.".nobin"), 1, "binary input not retained without -binary");
   1059     ok(!run(app(["openssl", "cms", "-verify", "-CAfile", $smroot, "-crlfeol",
   1060                 "-binary", "-in", $signed, "-out", $verified.".crlfeol"])),
   1061        "verify binary input wrong crlfeol");
   1062 
   1063     ok(run(app(["openssl", "cms", "-sign", "-md", "sha256", "-signer", $smrsa1,
   1064                 "-crlfeol",
   1065                 "-binary", "-in", $input, "-out", $signed.".crlf"])),
   1066        "sign binary input with -binary -crlfeol");
   1067     ok(run(app(["openssl", "cms", "-verify", "-CAfile", $smroot, "-crlfeol",
   1068                 "-binary", "-in", $signed.".crlf", "-out", $verified.".crlf"])),
   1069        "verify binary input with -binary -crlfeol");
   1070     is(compare($input, $verified.".crlf"), 0,
   1071        "binary input retained with -binary -crlfeol");
   1072     ok(!run(app(["openssl", "cms", "-verify", "-CAfile", $smroot,
   1073                 "-binary", "-in", $signed.".crlf", "-out", $verified.".crlf2"])),
   1074        "verify binary input with -binary missing -crlfeol");
   1075 };
   1076 
   1077 subtest "CMS signed digest, DER format" => sub {
   1078     plan tests => 2;
   1079 
   1080     # Pre-computed SHA256 digest of $smcont in hexadecimal form
   1081     my $digest = "ff236ef61b396355f75a4cc6e1c306d4c309084ae271a9e2ad6888f10a101b32";
   1082 
   1083     my $sig_file = "signature.der";
   1084     ok(run(app(["openssl", "cms", @prov, "-sign", "-digest", $digest,
   1085                     "-outform", "DER",
   1086                     "-certfile", catfile($smdir, "smroot.pem"),
   1087                     "-signer", catfile($smdir, "smrsa1.pem"),
   1088                     "-out", $sig_file])),
   1089         "CMS sign pre-computed digest, DER format");
   1090 
   1091     ok(run(app(["openssl", "cms", @prov, "-verify", "-in", $sig_file,
   1092                     "-inform", "DER",
   1093                     "-CAfile", catfile($smdir, "smroot.pem"),
   1094                     "-content", $smcont])),
   1095        "Verify CMS signed digest, DER format");
   1096 };
   1097 
   1098 subtest "CMS signed digest, DER format, no signing time" => sub {
   1099     # This test also enables CAdES mode and disables S/MIME capabilities
   1100     # to approximate the kind of signature required for a PAdES-compliant
   1101     # PDF signature.
   1102     plan tests => 4;
   1103 
   1104     # Pre-computed SHA256 digest of $smcont in hexadecimal form
   1105     my $digest = "ff236ef61b396355f75a4cc6e1c306d4c309084ae271a9e2ad6888f10a101b32";
   1106 
   1107     my $sig_file = "signature.der";
   1108     ok(run(app(["openssl", "cms", @prov, "-sign", "-digest", $digest,
   1109                     "-outform", "DER",
   1110                     "-no_signing_time",
   1111                     "-nosmimecap",
   1112                     "-cades",
   1113                     "-certfile", catfile($smdir, "smroot.pem"),
   1114                     "-signer", catfile($smdir, "smrsa1.pem"),
   1115                     "-out", $sig_file])),
   1116         "CMS sign pre-computed digest, DER format, no signing time");
   1117 
   1118     my $exit = 0;
   1119     my $dump = join "\n",
   1120                run(app(["openssl", "cms", @prov, "-cmsout", "-noout", "-print",
   1121                             "-in", $sig_file,
   1122                             "-inform", "DER"]),
   1123                    capture => 1,
   1124                    statusvar => $exit);
   1125 
   1126     is($exit, 0, "Parse CMS signed digest, DER format, no signing time");
   1127     is(index($dump, 'signingTime'), -1,
   1128         "Check that CMS signed digest does not contain signing time");
   1129 
   1130     ok(run(app(["openssl", "cms", @prov, "-verify", "-in", $sig_file,
   1131                     "-inform", "DER",
   1132                     "-CAfile", catfile($smdir, "smroot.pem"),
   1133                     "-content", $smcont])),
   1134        "Verify CMS signed digest, DER format, no signing time");
   1135 };
   1136 
   1137 
   1138 subtest "CMS signed digest, S/MIME format" => sub {
   1139     plan tests => 2;
   1140 
   1141     # Pre-computed SHA256 digest of $smcont in hexadecimal form
   1142     my $digest = "ff236ef61b396355f75a4cc6e1c306d4c309084ae271a9e2ad6888f10a101b32";
   1143 
   1144     my $sig_file = "signature.smime";
   1145     ok(run(app(["openssl", "cms", @prov, "-sign", "-digest", $digest,
   1146                     "-outform", "SMIME",
   1147                     "-certfile", catfile($smdir, "smroot.pem"),
   1148                     "-signer", catfile($smdir, "smrsa1.pem"),
   1149                     "-out", $sig_file])),
   1150         "CMS sign pre-computed digest, S/MIME format");
   1151 
   1152     ok(run(app(["openssl", "cms", @prov, "-verify", "-in", $sig_file,
   1153                     "-inform", "SMIME",
   1154                     "-CAfile", catfile($smdir, "smroot.pem"),
   1155                     "-content", $smcont])),
   1156        "Verify CMS signed digest, S/MIME format");
   1157 };
   1158 
   1159 sub path_tests {
   1160     our $app = shift;
   1161     our @path = qw(test certs);
   1162     our $key = srctop_file(@path, "ee-key.pem");
   1163     our $ee = srctop_file(@path, "ee-cert.pem");
   1164     our $ca = srctop_file(@path, "ca-cert.pem");
   1165     our $root = srctop_file(@path, "root-cert.pem");
   1166     our $sig_file = "signature.p7s";
   1167 
   1168     sub sign {
   1169         my $inter = shift;
   1170         my @inter = $inter ? ("-certfile", $inter) : ();
   1171         my $msg = shift;
   1172         ok(run(app(["openssl", $app, @prov, "-sign", "-in", $smcont,
   1173                     "-inkey", $key, "-signer", $ee, @inter,
   1174                     "-out", $sig_file],
   1175                    "accept $app sign with EE $msg".
   1176                    " intermediate CA certificates")));
   1177     }
   1178     sub verify {
   1179         my $inter = shift;
   1180         my @inter = $inter ? ("-certfile", $inter) : ();
   1181         my $msg = shift;
   1182         my $res = shift;
   1183         ok($res == run(app(["openssl", $app, @prov, "-verify", "-in", $sig_file,
   1184                             "-purpose", "sslserver", "-CAfile", $root, @inter,
   1185                             "-content", $smcont],
   1186                            "accept $app verify with EE ".
   1187                            "$msg intermediate CA certificates")));
   1188     }
   1189     sign($ca, "and");
   1190     verify(0, "with included", 1);
   1191     sign(0, "without");
   1192     verify(0, "without", 0);
   1193     verify($ca, "with added", 1);
   1194 };
   1195 subtest "CMS sign+verify cert path tests" => sub {
   1196     plan tests => 5;
   1197 
   1198     path_tests("cms");
   1199 };
   1200 subtest "PKCS7 sign+verify cert path tests" => sub {
   1201     plan tests => 5;
   1202 
   1203     path_tests("smime");
   1204 };
   1205 
   1206 subtest "CMS code signing test" => sub {
   1207     plan tests => 7;
   1208     my $sig_file = "signature.p7s";
   1209     ok(run(app(["openssl", "cms", @prov, "-sign", "-in", $smcont,
   1210                    "-certfile", catfile($smdir, "smroot.pem"),
   1211                    "-signer", catfile($smdir, "smrsa1.pem"),
   1212                    "-out", $sig_file])),
   1213        "accept perform CMS signature with smime certificate");
   1214 
   1215     ok(run(app(["openssl", "cms", @prov, "-verify", "-in", $sig_file,
   1216                     "-CAfile", catfile($smdir, "smroot.pem"),
   1217                     "-content", $smcont])),
   1218        "accept verify CMS signature with smime certificate");
   1219 
   1220     ok(!run(app(["openssl", "cms", @prov, "-verify", "-in", $sig_file,
   1221                     "-CAfile", catfile($smdir, "smroot.pem"),
   1222                     "-purpose", "codesign",
   1223                     "-content", $smcont])),
   1224        "fail verify CMS signature with smime certificate for purpose code signing");
   1225 
   1226     ok(!run(app(["openssl", "cms", @prov, "-verify", "-in", $sig_file,
   1227                     "-CAfile", catfile($smdir, "smroot.pem"),
   1228                     "-purpose", "football",
   1229                     "-content", $smcont])),
   1230        "fail verify CMS signature with invalid purpose argument");
   1231 
   1232     ok(run(app(["openssl", "cms", @prov, "-sign", "-in", $smcont,
   1233                    "-certfile", catfile($smdir, "smroot.pem"),
   1234                    "-signer", catfile($smdir, "csrsa1.pem"),
   1235                    "-out", $sig_file])),
   1236         "accept perform CMS signature with code signing certificate");
   1237 
   1238     ok(run(app(["openssl", "cms", @prov, "-verify", "-in", $sig_file,
   1239                     "-CAfile", catfile($smdir, "smroot.pem"),
   1240                     "-purpose", "codesign",
   1241                     "-content", $smcont])),
   1242        "accept verify CMS signature with code signing certificate for purpose code signing");
   1243 
   1244     ok(!run(app(["openssl", "cms", @prov, "-verify", "-in", $sig_file,
   1245                     "-CAfile", catfile($smdir, "smroot.pem"),
   1246                     "-content", $smcont])),
   1247        "fail verify CMS signature with code signing certificate for purpose smime_sign");
   1248 };
   1249 
   1250 # Test case for missing MD algorithm (must not segfault)
   1251 
   1252 with({ exit_checker => sub { return shift == 4; } },
   1253     sub {
   1254         ok(run(app(['openssl', 'smime', '-verify', '-noverify',
   1255                     '-inform', 'PEM',
   1256                     '-in', data_file("pkcs7-md4.pem"),
   1257                    ])),
   1258             "Check failure of EVP_DigestInit in PKCS7 signed is handled");
   1259 
   1260         ok(run(app(['openssl', 'smime', '-decrypt',
   1261                     '-inform', 'PEM',
   1262                     '-in', data_file("pkcs7-md4-encrypted.pem"),
   1263                     '-recip', srctop_file("test", "certs", "ee-cert.pem"),
   1264                     '-inkey', srctop_file("test", "certs", "ee-key.pem")
   1265                    ])),
   1266             "Check failure of EVP_DigestInit in PKCS7 signedAndEnveloped is handled");
   1267     });
   1268 
   1269 sub check_availability {
   1270     my $tnam = shift;
   1271 
   1272     return "$tnam: skipped, EC disabled\n"
   1273         if ($no_ec && $tnam =~ /ECDH/);
   1274     return "$tnam: skipped, ECDH disabled\n"
   1275         if ($no_ec && $tnam =~ /ECDH/);
   1276     return "$tnam: skipped, EC2M disabled\n"
   1277         if ($no_ec2m && $tnam =~ /K-283/);
   1278     return "$tnam: skipped, DH disabled\n"
   1279         if ($no_dh && $tnam =~ /X9\.42/);
   1280     return "$tnam: skipped, RC2 disabled\n"
   1281         if ($no_rc2 && $tnam =~ /RC2/);
   1282     return "$tnam: skipped, DES disabled\n"
   1283         if ($no_des && $tnam =~ /DES/);
   1284     return "$tnam: skipped, DSA disabled\n"
   1285         if ($no_dsa && $tnam =~ / DSA/);
   1286 
   1287     return "";
   1288 }
   1289 
   1290 # Test case for the locking problem reported in #19643.
   1291 # This will fail if the fix is in and deadlock on Windows (and possibly
   1292 # other platforms) if not.
   1293 ok(!run(app(['openssl', 'cms', '-verify',
   1294              '-CAfile', srctop_file("test/certs", "pkitsta.pem"),
   1295              '-policy', 'anyPolicy',
   1296              '-in', srctop_file("test/smime-eml",
   1297                                 "SignedInvalidMappingFromanyPolicyTest7.eml")
   1298             ])),
   1299    "issue#19643");
   1300 
   1301 # Check that users get error when using incorrect envelope type for AEAD algorithms
   1302 ok(!run(app(['openssl', 'cms', '-decrypt',
   1303              '-inform', 'PEM', '-stream',
   1304              '-secretkey', '000102030405060708090A0B0C0D0E0F',
   1305              '-secretkeyid', 'C0FEE0',
   1306              '-in', srctop_file("test/cms-msg",
   1307                                 "enveloped-content-type-for-aes-gcm.pem")
   1308             ])),
   1309    "Error AES-GCM in enveloped content type");
   1310 
   1311 # Check that kari encryption with originator does not segfault
   1312 with({ exit_checker => sub { return shift == 3; } },
   1313   sub {
   1314     SKIP: {
   1315       skip "EC is not supported in this build", 1 if $no_ec;
   1316 
   1317       ok(run(app(['openssl', 'cms', '-encrypt',
   1318                   '-in', srctop_file("test", "smcont.txt"), '-aes128',
   1319                   '-recip', catfile($smdir, "smec1.pem"),
   1320                   '-originator', catfile($smdir, "smec3.pem"),
   1321                   '-inkey', catfile($smdir, "smec3.pem")
   1322                 ])),
   1323           "Check failure for currently not supported kari encryption with static originator");
   1324     }
   1325   });
   1326 
   1327 # Check that we get the expected failure return code
   1328 with({ exit_checker => sub { return shift == 6; } },
   1329     sub {
   1330         ok(run(app(['openssl', 'cms', '-encrypt',
   1331                     '-in', srctop_file("test", "smcont.txt"),
   1332                     '-aes128', '-stream', '-recip',
   1333                     srctop_file("test/smime-certs", "badrsa.pem"),
   1334                    ])),
   1335             "Check failure during BIO setup with -stream is handled correctly");
   1336     });
   1337 
   1338 # Test case for return value mis-check reported in #21986
   1339 with({ exit_checker => sub { return shift == 3; } },
   1340     sub {
   1341         SKIP: {
   1342           skip "DSA is not supported in this build", 1 if $no_dsa;
   1343 
   1344           ok(run(app(['openssl', 'cms', '-sign',
   1345                       '-in', srctop_file("test", "smcont.txt"),
   1346                       '-signer', srctop_file("test/smime-certs", "smdsa1.pem"),
   1347                       '-md', 'SHAKE256'])),
   1348             "issue#21986");
   1349         }
   1350     });
   1351 
   1352 # Test for problem reported in #22225
   1353 with({ exit_checker => sub { return shift == 3; } },
   1354     sub {
   1355 	ok(run(app(['openssl', 'cms', '-encrypt',
   1356 		    '-in', srctop_file("test", "smcont.txt"),
   1357 		    '-aes-256-ctr', '-recip',
   1358 		    catfile($smdir, "smec1.pem"),
   1359 		   ])),
   1360 	   "Check for failure when cipher does not have an assigned OID (issue#22225)");
   1361      });
   1362 
   1363 # Test encrypt to three recipients, and decrypt using key-only;
   1364 # i.e. do not follow the recommended practice of providing the
   1365 # recipient cert in the decrypt op.
   1366 #
   1367 # Use RSAES-OAEP for key-transport, not RSAES-PKCS-v1_5.
   1368 #
   1369 # Because the cert is not provided during decrypt, all RSA ciphertexts
   1370 # are decrypted in turn, and when/if there is a valid decryption, it
   1371 # is assumed the correct content-key has been recovered.
   1372 #
   1373 # That process may fail with RSAES-PKCS-v1_5 b/c there is a
   1374 # non-negligible chance that decrypting a random input using
   1375 # RSAES-PKCS-v1_5 can result in a valid plaintext (so two content-keys
   1376 # could be recovered and the wrong one might be used).
   1377 #
   1378 # See https://github.com/openssl/project/issues/380
   1379 subtest "encrypt to three recipients with RSA-OAEP, key only decrypt" => sub {
   1380     plan tests => 3;
   1381 
   1382     my $pt = srctop_file("test", "smcont.txt");
   1383     my $ct = "smtst.cms";
   1384     my $ptpt = "smtst.txt";
   1385 
   1386     ok(run(app(['openssl', 'cms',
   1387 		@defaultprov,
   1388 		'-encrypt', '-aes128',
   1389 		'-in', $pt,
   1390 		'-out', $ct,
   1391 		'-stream',
   1392 		'-recip', catfile($smdir, "smrsa1.pem"),
   1393 		'-keyopt', 'rsa_padding_mode:oaep',
   1394 		'-recip', catfile($smdir, "smrsa2.pem"),
   1395 		'-keyopt', 'rsa_padding_mode:oaep',
   1396 		'-recip', catfile($smdir, "smrsa3-cert.pem"),
   1397 		'-keyopt', 'rsa_padding_mode:oaep',
   1398 	       ])),
   1399        "encrypt to three recipients with RSA-OAEP (avoid openssl/project issue#380)");
   1400     ok(run(app(['openssl', 'cms',
   1401 		@defaultprov,
   1402 		'-decrypt', '-aes128',
   1403 		'-in', $ct,
   1404 		'-out', $ptpt,
   1405 		'-inkey', catfile($smdir, "smrsa3-key.pem"),
   1406 	       ])),
   1407        "decrypt with key only");
   1408     is(compare($pt, $ptpt), 0, "compare original message with decrypted ciphertext");
   1409 };
   1410 
   1411 subtest "EdDSA tests for CMS" => sub {
   1412     plan tests => 2;
   1413 
   1414     SKIP: {
   1415         skip "ECX (EdDSA) is not supported in this build", 2
   1416             if disabled("ecx");
   1417 
   1418         my $crt1 = srctop_file("test", "certs", "root-ed25519.pem");
   1419         my $key1 = srctop_file("test", "certs", "root-ed25519.privkey.pem");
   1420         my $sig1 = "sig1.cms";
   1421 
   1422         ok(run(app(["openssl", "cms", @prov, "-sign", "-md", "sha512", "-in", $smcont,
   1423                     "-signer", $crt1, "-inkey", $key1, "-out", $sig1])),
   1424            "accept CMS signature with Ed25519");
   1425 
   1426         ok(run(app(["openssl", "cms", @prov, "-verify", "-in", $sig1,
   1427                     "-CAfile", $crt1, "-content", $smcont])),
   1428            "accept CMS verify with Ed25519");
   1429     }
   1430 };
   1431 
   1432 subtest "ML-DSA tests for CMS" => sub {
   1433     plan tests => 2;
   1434 
   1435     SKIP: {
   1436         skip "ML-DSA is not supported in this build", 2
   1437             if disabled("ml-dsa") || $no_pqc;
   1438 
   1439         my $sig1 = "sig1.cms";
   1440 
   1441         # draft-ietf-lamps-cms-ml-dsa: use SHA512 with ML-DSA
   1442         ok(run(app(["openssl", "cms", @prov, "-sign", "-md", "sha512", "-in", $smcont,
   1443                     "-certfile", $smroot, "-signer", catfile($smdir, "sm_mldsa44.pem"),
   1444                     "-out", $sig1])),
   1445            "accept CMS signature with ML-DSA-44");
   1446 
   1447         ok(run(app(["openssl", "cms", @prov, "-verify", "-in", $sig1,
   1448                     "-CAfile", $smroot, "-content", $smcont])),
   1449            "accept CMS verify with ML-DSA-44");
   1450     }
   1451 };
   1452 
   1453 subtest "SLH-DSA tests for CMS" => sub {
   1454     plan tests => 6;
   1455 
   1456     SKIP: {
   1457         skip "SLH-DSA is not supported in this build", 6
   1458             if disabled("slh-dsa") || $no_pqc;
   1459 
   1460         my $sig1 = "sig1.cms";
   1461 
   1462         # draft-ietf-lamps-cms-sphincs-plus: use SHA512 with SLH-DSA-SHA2
   1463         ok(run(app(["openssl", "cms", @prov, "-sign", "-md", "sha512", "-in", $smcont,
   1464                     "-certfile", $smroot, "-signer", catfile($smdir, "sm_slhdsa_sha2_128s.pem"),
   1465                     "-out", $sig1])),
   1466            "accept CMS signature with SLH-DSA-SHA2-128s");
   1467 
   1468         ok(run(app(["openssl", "cms", @prov, "-verify", "-in", $sig1,
   1469                     "-CAfile", $smroot, "-content", $smcont])),
   1470            "accept CMS verify with SLH-DSA-SHA2-128s");
   1471 
   1472         # draft-ietf-lamps-cms-sphincs-plus: use SHAKE128 with SLH-DSA-SHAKE-128*
   1473         ok(run(app(["openssl", "cms", @prov, "-sign", "-md", "shake128", "-in", $smcont,
   1474                     "-certfile", $smroot, "-signer", catfile($smdir, "sm_slhdsa_shake_128s.pem"),
   1475                     "-out", $sig1])),
   1476            "accept CMS signature with SLH-DSA-SHAKE-128s");
   1477 
   1478         ok(run(app(["openssl", "cms", @prov, "-verify", "-in", $sig1,
   1479                     "-CAfile", $smroot, "-content", $smcont])),
   1480            "accept CMS verify with SLH-DSA-SHAKE-128s");
   1481 
   1482         # draft-ietf-lamps-cms-sphincs-plus: use SHAKE256 with SLH-DSA-SHAKE-256*
   1483         ok(run(app(["openssl", "cms", @prov, "-sign", "-md", "shake256", "-in", $smcont,
   1484                     "-certfile", $smroot, "-signer", catfile($smdir, "sm_slhdsa_shake_256s.pem"),
   1485                     "-out", $sig1])),
   1486            "accept CMS signature with SLH-DSA-SHAKE-256s");
   1487 
   1488         ok(run(app(["openssl", "cms", @prov, "-verify", "-in", $sig1,
   1489                     "-CAfile", $smroot, "-content", $smcont])),
   1490            "accept CMS verify with SLH-DSA-SHAKE-256s");
   1491     }
   1492 };
   1493