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 
     45 my $datadir = srctop_dir("test", "recipes", "80-test_cms_data");
     46 my $smdir    = srctop_dir("test", "smime-certs");
     47 my $smcont   = srctop_file("test", "smcont.txt");
     48 my $smcont_zero = srctop_file("test", "smcont_zero.txt");
     49 my ($no_des, $no_dh, $no_dsa, $no_ec, $no_ec2m, $no_rc2, $no_zlib)
     50     = disabled qw/des dh dsa ec ec2m rc2 zlib/;
     51 
     52 $no_rc2 = 1 if disabled("legacy");
     53 
     54 plan tests => 20;
     55 
     56 ok(run(test(["pkcs7_test"])), "test pkcs7");
     57 
     58 unless ($no_fips) {
     59     my $provconf = srctop_file("test", "fips-and-base.cnf");
     60     @config = ( "-config", $provconf );
     61     $provname = 'fips';
     62 
     63     run(test(["fips_version_test", "-config", $provconf, "<3.4.0"]),
     64     capture => 1, statusvar => $old_fips);
     65 }
     66 
     67 $ENV{OPENSSL_TEST_LIBCTX} = "1";
     68 my @prov = ("-provider-path", $provpath,
     69             @config,
     70             "-provider", $provname);
     71 
     72 my $smrsa1024 = catfile($smdir, "smrsa1024.pem");
     73 my $smrsa1 = catfile($smdir, "smrsa1.pem");
     74 my $smroot = catfile($smdir, "smroot.pem");
     75 
     76 my @smime_pkcs7_tests = (
     77 
     78     [ "signed content DER format, RSA key",
     79       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER", "-nodetach",
     80         "-certfile", $smroot, "-signer", $smrsa1, "-out", "{output}.cms" ],
     81       [ "{cmd2}",  @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
     82         "-CAfile", $smroot, "-out", "{output}.txt" ],
     83       \&final_compare
     84     ],
     85 
     86     [ "signed detached content DER format, RSA key",
     87       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER",
     88         "-signer", $smrsa1, "-out", "{output}.cms" ],
     89       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
     90         "-CAfile", $smroot, "-out", "{output}.txt",
     91         "-content", $smcont ],
     92       \&final_compare
     93     ],
     94 
     95     [ "signed content test streaming BER format, RSA",
     96       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER", "-nodetach",
     97         "-stream",
     98         "-signer", $smrsa1, "-out", "{output}.cms" ],
     99       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
    100         "-CAfile", $smroot, "-out", "{output}.txt" ],
    101       \&final_compare
    102     ],
    103 
    104     [ "signed content DER format, DSA key",
    105       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER", "-nodetach",
    106         "-signer", catfile($smdir, "smdsa1.pem"), "-out", "{output}.cms" ],
    107       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
    108         "-CAfile", $smroot, "-out", "{output}.txt" ],
    109       \&final_compare
    110     ],
    111 
    112     [ "signed detached content DER format, DSA key",
    113       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER",
    114         "-signer", catfile($smdir, "smdsa1.pem"), "-out", "{output}.cms" ],
    115       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
    116         "-CAfile", $smroot, "-out", "{output}.txt",
    117         "-content", $smcont ],
    118       \&final_compare
    119     ],
    120 
    121     [ "signed detached content DER format, add RSA signer (with DSA existing)",
    122       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER",
    123         "-signer", catfile($smdir, "smdsa1.pem"), "-out", "{output}.cms" ],
    124       [ "{cmd1}", @prov, "-resign", "-in", "{output}.cms", "-inform", "DER", "-outform", "DER",
    125         "-signer", $smrsa1, "-out", "{output}2.cms" ],
    126       [ "{cmd2}", @prov, "-verify", "-in", "{output}2.cms", "-inform", "DER",
    127         "-CAfile", $smroot, "-out", "{output}.txt",
    128         "-content", $smcont ],
    129       \&final_compare
    130     ],
    131 
    132     [ "signed content test streaming BER format, DSA key",
    133       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER",
    134         "-nodetach", "-stream",
    135         "-signer", catfile($smdir, "smdsa1.pem"), "-out", "{output}.cms" ],
    136       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
    137         "-CAfile", $smroot, "-out", "{output}.txt" ],
    138       \&final_compare
    139     ],
    140 
    141     [ "signed content test streaming BER format, 2 DSA and 2 RSA keys",
    142       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER",
    143         "-nodetach", "-stream",
    144         "-signer", $smrsa1,
    145         "-signer", catfile($smdir, "smrsa2.pem"),
    146         "-signer", catfile($smdir, "smdsa1.pem"),
    147         "-signer", catfile($smdir, "smdsa2.pem"),
    148         "-out", "{output}.cms" ],
    149       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
    150         "-CAfile", $smroot, "-out", "{output}.txt" ],
    151       \&final_compare
    152     ],
    153 
    154     [ "signed content test streaming BER format, 2 DSA and 2 RSA keys, no attributes",
    155       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER",
    156         "-noattr", "-nodetach", "-stream",
    157         "-signer", $smrsa1,
    158         "-signer", catfile($smdir, "smrsa2.pem"),
    159         "-signer", catfile($smdir, "smdsa1.pem"),
    160         "-signer", catfile($smdir, "smdsa2.pem"),
    161         "-out", "{output}.cms" ],
    162       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
    163         "-CAfile", $smroot, "-out", "{output}.txt" ],
    164       \&final_compare
    165     ],
    166 
    167     [ "signed content S/MIME format, RSA key SHA1",
    168       [ "{cmd1}", @defaultprov, "-sign", "-in", $smcont, "-md", "sha1",
    169         "-certfile", $smroot,
    170         "-signer", $smrsa1, "-out", "{output}.cms" ],
    171       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms",
    172         "-CAfile", $smroot, "-out", "{output}.txt" ],
    173       \&final_compare
    174     ],
    175 
    176     [ "signed zero-length content S/MIME format, RSA key SHA1",
    177       [ "{cmd1}", @defaultprov, "-sign", "-in", $smcont_zero, "-md", "sha1",
    178         "-certfile", $smroot, "-signer", $smrsa1, "-out", "{output}.cms" ],
    179       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms",
    180         "-CAfile", $smroot, "-out", "{output}.txt" ],
    181       \&zero_compare
    182     ],
    183 
    184     [ "signed content test streaming S/MIME format, 2 DSA and 2 RSA keys",
    185       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-nodetach",
    186         "-signer", $smrsa1,
    187         "-signer", catfile($smdir, "smrsa2.pem"),
    188         "-signer", catfile($smdir, "smdsa1.pem"),
    189         "-signer", catfile($smdir, "smdsa2.pem"),
    190         "-stream", "-out", "{output}.cms" ],
    191       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms",
    192         "-CAfile", $smroot, "-out", "{output}.txt" ],
    193       \&final_compare
    194     ],
    195 
    196     [ "signed content test streaming multipart S/MIME format, 2 DSA and 2 RSA keys",
    197       [ "{cmd1}", @prov, "-sign", "-in", $smcont,
    198         "-signer", $smrsa1,
    199         "-signer", catfile($smdir, "smrsa2.pem"),
    200         "-signer", catfile($smdir, "smdsa1.pem"),
    201         "-signer", catfile($smdir, "smdsa2.pem"),
    202         "-stream", "-out", "{output}.cms" ],
    203       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms",
    204         "-CAfile", $smroot, "-out", "{output}.txt" ],
    205       \&final_compare
    206     ],
    207 
    208     [ "enveloped content test streaming S/MIME format, DES, 3 recipients",
    209       [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
    210         "-stream", "-out", "{output}.cms",
    211         $smrsa1,
    212         catfile($smdir, "smrsa2.pem"),
    213         catfile($smdir, "smrsa3.pem") ],
    214       [ "{cmd2}", @defaultprov, "-decrypt", "-recip", $smrsa1,
    215         "-in", "{output}.cms", "-out", "{output}.txt" ],
    216       \&final_compare
    217     ],
    218 
    219     [ "enveloped content test streaming S/MIME format, DES, 3 recipients, 3rd used",
    220       [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
    221         "-stream", "-out", "{output}.cms",
    222         $smrsa1,
    223         catfile($smdir, "smrsa2.pem"),
    224         catfile($smdir, "smrsa3.pem") ],
    225       [ "{cmd2}", @defaultprov, "-decrypt", "-recip", catfile($smdir, "smrsa3.pem"),
    226         "-in", "{output}.cms", "-out", "{output}.txt" ],
    227       \&final_compare
    228     ],
    229 
    230     [ "enveloped content test streaming S/MIME format, DES, 3 recipients, cert and key files used",
    231       [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
    232         "-stream", "-out", "{output}.cms",
    233         $smrsa1,
    234         catfile($smdir, "smrsa2.pem"),
    235         catfile($smdir, "smrsa3-cert.pem") ],
    236       [ "{cmd2}", @defaultprov, "-decrypt",
    237 	"-recip", catfile($smdir, "smrsa3-cert.pem"),
    238 	"-inkey", catfile($smdir, "smrsa3-key.pem"),
    239         "-in", "{output}.cms", "-out", "{output}.txt" ],
    240       \&final_compare
    241     ],
    242 
    243     [ "enveloped content test streaming S/MIME format, AES-256 cipher, 3 recipients",
    244       [ "{cmd1}", @prov, "-encrypt", "-in", $smcont,
    245         "-aes256", "-stream", "-out", "{output}.cms",
    246         $smrsa1,
    247         catfile($smdir, "smrsa2.pem"),
    248         catfile($smdir, "smrsa3.pem") ],
    249       [ "{cmd2}", @prov, "-decrypt", "-recip", $smrsa1,
    250         "-in", "{output}.cms", "-out", "{output}.txt" ],
    251       \&final_compare
    252     ],
    253 
    254 );
    255 
    256 my @smime_cms_tests = (
    257 
    258     [ "signed content test streaming BER format, 2 DSA and 2 RSA keys, keyid",
    259       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER",
    260         "-nodetach", "-keyid",
    261         "-signer", $smrsa1,
    262         "-signer", catfile($smdir, "smrsa2.pem"),
    263         "-signer", catfile($smdir, "smdsa1.pem"),
    264         "-signer", catfile($smdir, "smdsa2.pem"),
    265         "-stream", "-out", "{output}.cms" ],
    266       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
    267         "-CAfile", $smroot, "-out", "{output}.txt" ],
    268       \&final_compare
    269     ],
    270 
    271     [ "signed content test streaming PEM format, 2 DSA and 2 RSA keys",
    272       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
    273         "-signer", $smrsa1,
    274         "-signer", catfile($smdir, "smrsa2.pem"),
    275         "-signer", catfile($smdir, "smdsa1.pem"),
    276         "-signer", catfile($smdir, "smdsa2.pem"),
    277         "-stream", "-out", "{output}.cms" ],
    278       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "PEM",
    279         "-CAfile", $smroot, "-out", "{output}.txt" ],
    280       \&final_compare
    281     ],
    282 
    283     [ "signed content MIME format, RSA key, signed receipt request",
    284       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-nodetach",
    285         "-signer", $smrsa1,
    286         "-receipt_request_to", "test\@openssl.org", "-receipt_request_all",
    287         "-out", "{output}.cms" ],
    288       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms",
    289         "-CAfile", $smroot, "-out", "{output}.txt" ],
    290       \&final_compare
    291     ],
    292 
    293     [ "signed receipt MIME format, RSA key",
    294       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-nodetach",
    295         "-signer", $smrsa1,
    296         "-receipt_request_to", "test\@openssl.org", "-receipt_request_all",
    297         "-out", "{output}.cms" ],
    298       [ "{cmd1}", @prov, "-sign_receipt", "-in", "{output}.cms",
    299         "-signer", catfile($smdir, "smrsa2.pem"), "-out", "{output}2.cms" ],
    300       [ "{cmd2}", @prov, "-verify_receipt", "{output}2.cms", "-in", "{output}.cms",
    301         "-CAfile", $smroot ]
    302     ],
    303 
    304     [ "enveloped content test streaming S/MIME format, DES, 3 recipients, keyid",
    305       [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
    306         "-stream", "-out", "{output}.cms", "-keyid",
    307         $smrsa1,
    308         catfile($smdir, "smrsa2.pem"),
    309         catfile($smdir, "smrsa3.pem") ],
    310       [ "{cmd2}", @defaultprov, "-decrypt", "-recip", $smrsa1,
    311         "-in", "{output}.cms", "-out", "{output}.txt" ],
    312       \&final_compare
    313     ],
    314 
    315     [ "enveloped content test streaming PEM format, AES-256-CBC cipher, KEK",
    316       [ "{cmd1}", @prov, "-encrypt", "-in", $smcont, "-outform", "PEM", "-aes128",
    317         "-stream", "-out", "{output}.cms",
    318         "-secretkey", "000102030405060708090A0B0C0D0E0F",
    319         "-secretkeyid", "C0FEE0" ],
    320       [ "{cmd2}", @prov, "-decrypt", "-in", "{output}.cms", "-out", "{output}.txt",
    321         "-inform", "PEM",
    322         "-secretkey", "000102030405060708090A0B0C0D0E0F",
    323         "-secretkeyid", "C0FEE0" ],
    324       \&final_compare
    325     ],
    326 
    327     [ "enveloped content test streaming PEM format, AES-256-GCM cipher, KEK",
    328       [ "{cmd1}", @prov, "-encrypt", "-in", $smcont, "-outform", "PEM", "-aes-128-gcm",
    329         "-stream", "-out", "{output}.cms",
    330         "-secretkey", "000102030405060708090A0B0C0D0E0F",
    331         "-secretkeyid", "C0FEE0" ],
    332       [ "{cmd2}", "-decrypt", "-in", "{output}.cms", "-out", "{output}.txt",
    333         "-inform", "PEM",
    334         "-secretkey", "000102030405060708090A0B0C0D0E0F",
    335         "-secretkeyid", "C0FEE0" ],
    336       \&final_compare
    337     ],
    338 
    339     [ "enveloped content test streaming PEM format, KEK, key only",
    340       [ "{cmd1}", @prov, "-encrypt", "-in", $smcont, "-outform", "PEM", "-aes128",
    341         "-stream", "-out", "{output}.cms",
    342         "-secretkey", "000102030405060708090A0B0C0D0E0F",
    343         "-secretkeyid", "C0FEE0" ],
    344       [ "{cmd2}", @prov, "-decrypt", "-in", "{output}.cms", "-out", "{output}.txt",
    345         "-inform", "PEM",
    346         "-secretkey", "000102030405060708090A0B0C0D0E0F" ],
    347       \&final_compare
    348     ],
    349 
    350     [ "data content test streaming PEM format",
    351       [ "{cmd1}", @prov, "-data_create", "-in", $smcont, "-outform", "PEM",
    352         "-nodetach", "-stream", "-out", "{output}.cms" ],
    353       [ "{cmd2}", @prov, "-data_out", "-in", "{output}.cms", "-inform", "PEM",
    354         "-out", "{output}.txt" ],
    355       \&final_compare
    356     ],
    357 
    358     [ "encrypted content test streaming PEM format, 128 bit RC2 key",
    359       [ "{cmd1}", @legacyprov, "-EncryptedData_encrypt",
    360         "-in", $smcont, "-outform", "PEM",
    361         "-rc2", "-secretkey", "000102030405060708090A0B0C0D0E0F",
    362         "-stream", "-out", "{output}.cms" ],
    363       [ "{cmd2}", @legacyprov, "-EncryptedData_decrypt", "-in", "{output}.cms",
    364         "-inform", "PEM",
    365         "-secretkey", "000102030405060708090A0B0C0D0E0F",
    366         "-out", "{output}.txt" ],
    367       \&final_compare
    368     ],
    369 
    370     [ "encrypted content test streaming PEM format, 40 bit RC2 key",
    371       [ "{cmd1}", @legacyprov, "-EncryptedData_encrypt",
    372         "-in", $smcont, "-outform", "PEM",
    373         "-rc2", "-secretkey", "0001020304",
    374         "-stream", "-out", "{output}.cms" ],
    375       [ "{cmd2}", @legacyprov, "-EncryptedData_decrypt", "-in", "{output}.cms",
    376         "-inform", "PEM",
    377         "-secretkey", "0001020304", "-out", "{output}.txt" ],
    378       \&final_compare
    379     ],
    380 
    381     [ "encrypted content test streaming PEM format, triple DES key",
    382       [ "{cmd1}", @prov, "-EncryptedData_encrypt", "-in", $smcont, "-outform", "PEM",
    383         "-des3", "-secretkey", "000102030405060708090A0B0C0D0E0F1011121314151617",
    384         "-stream", "-out", "{output}.cms" ],
    385       [ "{cmd2}", @prov, "-EncryptedData_decrypt", "-in", "{output}.cms",
    386         "-inform", "PEM",
    387         "-secretkey", "000102030405060708090A0B0C0D0E0F1011121314151617",
    388         "-out", "{output}.txt" ],
    389       \&final_compare
    390     ],
    391 
    392     [ "encrypted content test streaming PEM format, 128 bit AES key",
    393       [ "{cmd1}", @prov, "-EncryptedData_encrypt", "-in", $smcont, "-outform", "PEM",
    394         "-aes128", "-secretkey", "000102030405060708090A0B0C0D0E0F",
    395         "-stream", "-out", "{output}.cms" ],
    396       [ "{cmd2}", @prov, "-EncryptedData_decrypt", "-in", "{output}.cms",
    397         "-inform", "PEM",
    398         "-secretkey", "000102030405060708090A0B0C0D0E0F",
    399         "-out", "{output}.txt" ],
    400       \&final_compare
    401     ],
    402 
    403     [ "encrypted content test streaming PEM format -noout, 128 bit AES key",
    404       [ "{cmd1}", @prov, "-EncryptedData_encrypt", "-in", $smcont, "-outform", "PEM",
    405 	"-aes128", "-secretkey", "000102030405060708090A0B0C0D0E0F",
    406 	"-stream", "-noout" ],
    407       [ "{cmd2}", @prov, "-help" ]
    408     ],
    409 );
    410 
    411 my @smime_cms_cades_tests = (
    412 
    413     [ "signed content DER format, RSA key, CAdES-BES compatible",
    414       [ "{cmd1}", @prov, "-sign", "-cades", "-in", $smcont, "-outform", "DER",
    415          "-nodetach",
    416         "-certfile", $smroot, "-signer", $smrsa1, "-out", "{output}.cms" ],
    417       [ "{cmd2}", @prov, "-verify", "-cades", "-in", "{output}.cms", "-inform", "DER",
    418         "-CAfile", $smroot, "-out", "{output}.txt" ],
    419       \&final_compare
    420     ],
    421 
    422     [ "signed content DER format, RSA key, SHA256 md, CAdES-BES compatible",
    423       [ "{cmd1}", @prov, "-sign", "-cades", "-md", "sha256", "-in", $smcont, "-outform",
    424         "DER", "-nodetach", "-certfile", $smroot,
    425         "-signer", $smrsa1, "-out", "{output}.cms" ],
    426       [ "{cmd2}", @prov, "-verify", "-cades", "-in", "{output}.cms", "-inform", "DER",
    427         "-CAfile", $smroot, "-out", "{output}.txt" ],
    428       \&final_compare
    429     ],
    430 
    431     [ "signed content DER format, RSA key, SHA512 md, CAdES-BES compatible",
    432       [ "{cmd1}", @prov, "-sign", "-cades", "-md", "sha512", "-in", $smcont, "-outform",
    433         "DER", "-nodetach", "-certfile", $smroot,
    434         "-signer", $smrsa1, "-out", "{output}.cms" ],
    435       [ "{cmd2}", @prov, "-verify", "-cades", "-in", "{output}.cms", "-inform", "DER",
    436         "-CAfile", $smroot, "-out", "{output}.txt" ],
    437       \&final_compare
    438     ],
    439 
    440     [ "signed content DER format, RSA key, SHA256 md, CAdES-BES compatible",
    441       [ "{cmd1}", @prov, "-sign", "-cades", "-binary",  "-nodetach", "-nosmimecap", "-md", "sha256",
    442         "-in", $smcont, "-outform", "DER", 
    443         "-certfile", $smroot, "-signer", $smrsa1,
    444         "-outform", "DER", "-out", "{output}.cms"  ],
    445       [ "{cmd2}", @prov, "-verify", "-cades", "-in", "{output}.cms", "-inform", "DER",
    446         "-CAfile", $smroot, "-out", "{output}.txt" ],
    447       \&final_compare
    448     ],
    449 
    450     [ "resigned content DER format, RSA key, SHA256 md, CAdES-BES compatible",
    451       [ "{cmd1}", @prov, "-sign", "-cades", "-binary",  "-nodetach", "-nosmimecap", "-md", "sha256",
    452         "-in", $smcont, "-outform", "DER", 
    453         "-certfile", $smroot, "-signer", $smrsa1,
    454         "-outform", "DER", "-out", "{output}.cms"  ],
    455       [ "{cmd1}", @prov, "-resign", "-cades", "-binary", "-nodetach", "-nosmimecap", "-md", "sha256",
    456         "-inform", "DER", "-in", "{output}.cms",
    457         "-certfile", $smroot, "-signer", catfile($smdir, "smrsa2.pem"),
    458         "-outform", "DER", "-out", "{output}2.cms" ],
    459 
    460       [ "{cmd2}", @prov, "-verify", "-cades", "-in", "{output}2.cms", "-inform", "DER",
    461         "-CAfile", $smroot, "-out", "{output}.txt" ],
    462       \&final_compare
    463     ],
    464 );
    465 
    466 my @smime_cms_cades_ko_tests = (
    467     [ "sign content DER format, RSA key, not CAdES-BES compatible",
    468       [ @prov, "-sign", "-in", $smcont, "-outform", "DER", "-nodetach",
    469         "-certfile", $smroot, "-signer", $smrsa1, "-out", "{output}.cms" ],
    470       "fail to verify token since requiring CAdES-BES compatibility",
    471       [ @prov, "-verify", "-cades", "-in", "{output}.cms", "-inform", "DER",
    472         "-CAfile", $smroot, "-out", "{output}.txt" ],
    473       \&final_compare
    474     ]
    475 );
    476 
    477 # cades options test - check that some combinations are rejected
    478 my @smime_cms_cades_invalid_option_tests = (
    479     [
    480         [ "-cades", "-noattr" ],
    481     ],[
    482         [ "-verify", "-cades", "-noattr" ],
    483     ],[
    484         [ "-verify", "-cades", "-noverify" ],
    485     ],
    486 );
    487 
    488 my @smime_cms_comp_tests = (
    489 
    490     [ "compressed content test streaming PEM format",
    491       [ "{cmd1}", @prov, "-compress", "-in", $smcont, "-outform", "PEM", "-nodetach",
    492         "-stream", "-out", "{output}.cms" ],
    493       [ "{cmd2}", @prov, "-uncompress", "-in", "{output}.cms", "-inform", "PEM",
    494         "-out", "{output}.txt" ],
    495       \&final_compare
    496     ]
    497 
    498 );
    499 
    500 my @smime_cms_param_tests = (
    501     [ "signed content test streaming PEM format, RSA keys, PSS signature",
    502       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
    503         "-signer", $smrsa1,
    504         "-keyopt", "rsa_padding_mode:pss",
    505         "-out", "{output}.cms" ],
    506       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "PEM",
    507         "-CAfile", $smroot, "-out", "{output}.txt" ],
    508       \&final_compare
    509     ],
    510 
    511     [ "signed content test streaming PEM format, RSA keys, PSS signature, saltlen=max",
    512       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
    513         "-signer", $smrsa1,
    514         "-keyopt", "rsa_padding_mode:pss", "-keyopt", "rsa_pss_saltlen:max",
    515         "-out", "{output}.cms" ],
    516       sub { my %opts = @_; rsapssSaltlen("$opts{output}.cms") == 222; },
    517       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "PEM",
    518         "-CAfile", $smroot, "-out", "{output}.txt" ],
    519       \&final_compare
    520     ],
    521 
    522     [ "signed content test streaming PEM format, RSA keys, PSS signature, no attributes",
    523       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
    524         "-noattr", "-signer", $smrsa1,
    525         "-keyopt", "rsa_padding_mode:pss",
    526         "-out", "{output}.cms" ],
    527       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "PEM",
    528         "-CAfile", $smroot, "-out", "{output}.txt" ],
    529       \&final_compare
    530     ],
    531 
    532     [ "signed content test streaming PEM format, RSA keys, PSS signature, SHA384 MGF1",
    533       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
    534         "-signer", $smrsa1,
    535         "-keyopt", "rsa_padding_mode:pss", "-keyopt", "rsa_mgf1_md:sha384",
    536         "-out", "{output}.cms" ],
    537       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "PEM",
    538         "-CAfile", $smroot, "-out", "{output}.txt" ],
    539       \&final_compare
    540     ],
    541 
    542     [ "signed content test streaming PEM format, RSA keys, PSS signature, saltlen=16",
    543       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
    544         "-signer", $smrsa1, "-md", "sha256",
    545         "-keyopt", "rsa_padding_mode:pss", "-keyopt", "rsa_pss_saltlen:16",
    546         "-out", "{output}.cms" ],
    547       sub { my %opts = @_; rsapssSaltlen("$opts{output}.cms") == 16; },
    548       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "PEM",
    549         "-CAfile", $smroot, "-out", "{output}.txt" ],
    550       \&final_compare
    551     ],
    552 
    553     [ "signed content test streaming PEM format, RSA keys, PSS signature, saltlen=digest",
    554       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
    555         "-signer", $smrsa1, "-md", "sha256",
    556         "-keyopt", "rsa_padding_mode:pss", "-keyopt", "rsa_pss_saltlen:digest",
    557         "-out", "{output}.cms" ],
    558       # digest is SHA-256, which produces 32 bytes of output
    559       sub { my %opts = @_; rsapssSaltlen("$opts{output}.cms") == 32; },
    560       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "PEM",
    561         "-CAfile", $smroot, "-out", "{output}.txt" ],
    562       \&final_compare
    563     ],
    564 
    565     [ "enveloped content test streaming S/MIME format, DES, OAEP default parameters",
    566       [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
    567         "-stream", "-out", "{output}.cms",
    568         "-recip", $smrsa1,
    569         "-keyopt", "rsa_padding_mode:oaep" ],
    570       [ "{cmd2}", @defaultprov, "-decrypt", "-recip", $smrsa1,
    571         "-in", "{output}.cms", "-out", "{output}.txt" ],
    572       \&final_compare
    573     ],
    574 
    575     [ "enveloped content test streaming S/MIME format, DES, OAEP SHA256",
    576       [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
    577         "-stream", "-out", "{output}.cms",
    578         "-recip", $smrsa1,
    579         "-keyopt", "rsa_padding_mode:oaep",
    580         "-keyopt", "rsa_oaep_md:sha256" ],
    581       [ "{cmd2}", @defaultprov, "-decrypt", "-recip", $smrsa1,
    582         "-in", "{output}.cms", "-out", "{output}.txt" ],
    583       \&final_compare
    584     ],
    585 
    586     [ "enveloped content test streaming S/MIME format, DES, ECDH",
    587       [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
    588         "-stream", "-out", "{output}.cms",
    589         "-recip", catfile($smdir, "smec1.pem") ],
    590       [ "{cmd2}", @defaultprov, "-decrypt", "-recip", catfile($smdir, "smec1.pem"),
    591         "-in", "{output}.cms", "-out", "{output}.txt" ],
    592       \&final_compare
    593     ],
    594 
    595     [ "enveloped content test streaming S/MIME format, DES, ECDH, 2 recipients, key only used",
    596       [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
    597         "-stream", "-out", "{output}.cms",
    598         catfile($smdir, "smec1.pem"),
    599         catfile($smdir, "smec3.pem") ],
    600       [ "{cmd2}", @defaultprov, "-decrypt", "-inkey", catfile($smdir, "smec3.pem"),
    601         "-in", "{output}.cms", "-out", "{output}.txt" ],
    602       \&final_compare
    603     ],
    604 
    605     [ "enveloped content test streaming S/MIME format, ECDH, DES, key identifier",
    606       [ "{cmd1}", @defaultprov, "-encrypt", "-keyid", "-in", $smcont,
    607         "-stream", "-out", "{output}.cms",
    608         "-recip", catfile($smdir, "smec1.pem") ],
    609       [ "{cmd2}", @defaultprov, "-decrypt", "-recip", catfile($smdir, "smec1.pem"),
    610         "-in", "{output}.cms", "-out", "{output}.txt" ],
    611       \&final_compare
    612     ],
    613 
    614     [ "enveloped content test streaming S/MIME format, ECDH, AES-128-CBC, SHA256 KDF",
    615       [ "{cmd1}", @prov, "-encrypt", "-in", $smcont,
    616         "-stream", "-out", "{output}.cms",
    617         "-recip", catfile($smdir, "smec1.pem"), "-aes128",
    618         "-keyopt", "ecdh_kdf_md:sha256" ],
    619       sub { my %opts = @_; smimeType_matches("$opts{output}.cms", "enveloped-data"); },
    620       [ "{cmd2}", @prov, "-decrypt", "-recip", catfile($smdir, "smec1.pem"),
    621         "-in", "{output}.cms", "-out", "{output}.txt" ],
    622       \&final_compare
    623     ],
    624 
    625     [ "enveloped content test streaming S/MIME format, ECDH, AES-128-GCM cipher, SHA256 KDF",
    626       [ "{cmd1}", @prov, "-encrypt", "-in", $smcont,
    627         "-stream", "-out", "{output}.cms",
    628         "-recip", catfile($smdir, "smec1.pem"), "-aes-128-gcm", "-keyopt", "ecdh_kdf_md:sha256" ],
    629       sub { my %opts = @_; smimeType_matches("$opts{output}.cms", "authEnveloped-data"); },
    630       [ "{cmd2}", "-decrypt", "-recip", catfile($smdir, "smec1.pem"),
    631         "-in", "{output}.cms", "-out", "{output}.txt" ],
    632       \&final_compare
    633     ],
    634 
    635     [ "enveloped content test streaming S/MIME format, ECDH, K-283, cofactor DH",
    636       [ "{cmd1}", @prov, "-encrypt", "-in", $smcont,
    637         "-stream", "-out", "{output}.cms",
    638         "-recip", catfile($smdir, "smec2.pem"), "-aes128",
    639         "-keyopt", "ecdh_kdf_md:sha256", "-keyopt", "ecdh_cofactor_mode:1" ],
    640       [ "{cmd2}", @prov, "-decrypt", "-recip", catfile($smdir, "smec2.pem"),
    641         "-in", "{output}.cms", "-out", "{output}.txt" ],
    642       \&final_compare
    643     ]
    644 );
    645 
    646 if ($no_fips || $old_fips) {
    647     # Only SHA1 supported in dh_cms_encrypt()
    648     push(@smime_cms_param_tests,
    649          [ "enveloped content test streaming S/MIME format, X9.42 DH",
    650            [ "{cmd1}", @prov, "-encrypt", "-in", $smcont,
    651              "-stream", "-out", "{output}.cms",
    652              "-recip", catfile($smdir, "smdh.pem"), "-aes128" ],
    653            [ "{cmd2}", @prov, "-decrypt", "-recip", catfile($smdir, "smdh.pem"),
    654              "-in", "{output}.cms", "-out", "{output}.txt" ],
    655            \&final_compare
    656          ]
    657     );
    658 }
    659 
    660 my @contenttype_cms_test = (
    661     [ "signed content test - check that content type is added to additional signerinfo, RSA keys",
    662       [ "{cmd1}", @prov, "-sign", "-binary", "-nodetach", "-stream", "-in", $smcont,
    663         "-outform", "DER", "-signer", $smrsa1, "-md", "SHA256",
    664         "-out", "{output}.cms" ],
    665       [ "{cmd1}", @prov, "-resign", "-binary", "-nodetach", "-in", "{output}.cms",
    666         "-inform", "DER", "-outform", "DER",
    667         "-signer", catfile($smdir, "smrsa2.pem"), "-md", "SHA256",
    668         "-out", "{output}2.cms" ],
    669       sub { my %opts = @_; contentType_matches("$opts{output}2.cms") == 2; },
    670       [ "{cmd2}", @prov, "-verify", "-in", "{output}2.cms", "-inform", "DER",
    671         "-CAfile", $smroot, "-out", "{output}.txt" ]
    672     ],
    673 );
    674 
    675 my @incorrect_attribute_cms_test = (
    676     "bad_signtime_attr.cms",
    677     "no_ct_attr.cms",
    678     "no_md_attr.cms",
    679     "ct_multiple_attr.cms"
    680 );
    681 
    682 # Runs a standard loop on the input array
    683 sub runner_loop {
    684     my %opts = ( @_ );
    685     my $cnt1 = 0;
    686 
    687     foreach (@{$opts{tests}}) {
    688         $cnt1++;
    689         $opts{output} = "$opts{prefix}-$cnt1";
    690       SKIP: {
    691           my $skip_reason = check_availability($$_[0]);
    692           skip $skip_reason, 1 if $skip_reason;
    693           my $ok = 1;
    694           1 while unlink "$opts{output}.txt";
    695 
    696           foreach (@$_[1..$#$_]) {
    697               if (ref $_ eq 'CODE') {
    698                   $ok &&= $_->(%opts);
    699               } else {
    700                   my @cmd = map {
    701                       my $x = $_;
    702                       while ($x =~ /\{([^\}]+)\}/) {
    703                           $x = $`.$opts{$1}.$' if exists $opts{$1};
    704                       }
    705                       $x;
    706                   } @$_;
    707 
    708                   diag "CMD: openssl ", join(" ", @cmd);
    709                   $ok &&= run(app(["openssl", @cmd]));
    710                   $opts{input} = $opts{output};
    711               }
    712           }
    713 
    714           ok($ok, $$_[0]);
    715         }
    716     }
    717 }
    718 
    719 sub final_compare {
    720     my %opts = @_;
    721 
    722     diag "Comparing $smcont with $opts{output}.txt";
    723     return compare_text($smcont, "$opts{output}.txt") == 0;
    724 }
    725 
    726 sub zero_compare {
    727     my %opts = @_;
    728 
    729     diag "Checking for zero-length file";
    730     return (-e "$opts{output}.txt" && -z "$opts{output}.txt");
    731 }
    732 
    733 subtest "CMS => PKCS#7 compatibility tests\n" => sub {
    734     plan tests => scalar @smime_pkcs7_tests;
    735 
    736     runner_loop(prefix => 'cms2pkcs7', cmd1 => 'cms', cmd2 => 'smime',
    737                 tests => [ @smime_pkcs7_tests ]);
    738 };
    739 subtest "CMS <= PKCS#7 compatibility tests\n" => sub {
    740     plan tests => scalar @smime_pkcs7_tests;
    741 
    742     runner_loop(prefix => 'pkcs72cms', cmd1 => 'smime', cmd2 => 'cms',
    743                 tests => [ @smime_pkcs7_tests ]);
    744 };
    745 
    746 subtest "CMS <=> CMS consistency tests\n" => sub {
    747     plan tests => (scalar @smime_pkcs7_tests) + (scalar @smime_cms_tests);
    748 
    749     runner_loop(prefix => 'cms2cms-1', cmd1 => 'cms', cmd2 => 'cms',
    750                 tests => [ @smime_pkcs7_tests ]);
    751     runner_loop(prefix => 'cms2cms-2', cmd1 => 'cms', cmd2 => 'cms',
    752                 tests => [ @smime_cms_tests ]);
    753 };
    754 
    755 subtest "CMS <=> CMS consistency tests, modified key parameters\n" => sub {
    756     plan tests =>
    757         (scalar @smime_cms_param_tests) + (scalar @smime_cms_comp_tests);
    758 
    759     runner_loop(prefix => 'cms2cms-mod', cmd1 => 'cms', cmd2 => 'cms',
    760                 tests => [ @smime_cms_param_tests ]);
    761   SKIP: {
    762       skip("Zlib not supported: compression tests skipped",
    763            scalar @smime_cms_comp_tests)
    764           if $no_zlib;
    765 
    766       runner_loop(prefix => 'cms2cms-comp', cmd1 => 'cms', cmd2 => 'cms',
    767                   tests => [ @smime_cms_comp_tests ]);
    768     }
    769 };
    770 
    771 # Returns the number of matches of a Content Type Attribute in a binary file.
    772 sub contentType_matches {
    773   # Read in a binary file
    774   my ($in) = @_;
    775   open (HEX_IN, "$in") or die("open failed for $in : $!");
    776   binmode(HEX_IN);
    777   local $/;
    778   my $str = <HEX_IN>;
    779 
    780   # Find ASN1 data for a Content Type Attribute (with a OID of PKCS7 data)
    781   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;
    782 
    783   close(HEX_IN);
    784   return scalar(@c);
    785 }
    786 
    787 # Returns 1 if the smime-type matches the passed parameter, otherwise 0.
    788 sub smimeType_matches {
    789   my ($in, $expected_smime_type) = @_;
    790 
    791   # Read the text file
    792   open(my $fh, '<', $in) or die("open failed for $in : $!");
    793   local $/;
    794   my $content = <$fh>;
    795   close($fh);
    796 
    797   # Extract the Content-Type line with the smime-type attribute
    798   if ($content =~ /Content-Type:\s*application\/pkcs7-mime.*smime-type=([^\s;]+)/) {
    799     my $smime_type = $1;
    800 
    801     # Compare the extracted smime-type with the expected value
    802     return ($smime_type eq $expected_smime_type) ? 1 : 0;
    803   }
    804 
    805   # If no smime-type is found, return 0
    806   return 0;
    807 }
    808 
    809 sub rsapssSaltlen {
    810   my ($in) = @_;
    811   my $exit = 0;
    812 
    813   my @asn1parse = run(app(["openssl", "asn1parse", "-in", $in, "-dump"]),
    814                       capture => 1,
    815                       statusvar => $exit);
    816   return -1 if $exit != 0;
    817 
    818   my $pssparam_offset = -1;
    819   while ($_ = shift @asn1parse) {
    820     chomp;
    821     next unless /:rsassaPss/;
    822     # This line contains :rsassaPss, the next line contains a raw dump of the
    823     # RSA_PSS_PARAMS sequence; obtain its offset
    824     $_ = shift @asn1parse;
    825     if (/^\s*(\d+):/) {
    826       $pssparam_offset = int($1);
    827     }
    828   }
    829 
    830   if ($pssparam_offset == -1) {
    831     note "Failed to determine RSA_PSS_PARAM offset in CMS. " +
    832          "Was the file correctly signed with RSASSA-PSS?";
    833     return -1;
    834   }
    835 
    836   my @pssparam = run(app(["openssl", "asn1parse", "-in", $in,
    837                           "-strparse", $pssparam_offset]),
    838                      capture => 1,
    839                      statusvar => $exit);
    840   return -1 if $exit != 0;
    841 
    842   my $saltlen = -1;
    843   # Can't use asn1parse -item RSA_PSS_PARAMS here, because that's deprecated.
    844   # This assumes the salt length is the last field, which may possibly be
    845   # incorrect if there is a non-standard trailer field, but there almost never
    846   # is in PSS.
    847   if ($pssparam[-1] =~ /prim:\s+INTEGER\s+:([A-Fa-f0-9]+)/) {
    848     $saltlen = hex($1);
    849   }
    850 
    851   if ($saltlen == -1) {
    852     note "Failed to determine salt length from RSA_PSS_PARAM struct. " +
    853          "Was the file correctly signed with RSASSA-PSS?";
    854     return -1;
    855   }
    856 
    857   return $saltlen;
    858 }
    859 
    860 subtest "CMS Check the content type attribute is added for additional signers\n" => sub {
    861     plan tests => (scalar @contenttype_cms_test);
    862 
    863     runner_loop(prefix => 'cms2cms-added', cmd1 => 'cms', cmd2 => 'cms',
    864                 tests => [ @contenttype_cms_test ]);
    865 };
    866 
    867 subtest "CMS Check that bad attributes fail when verifying signers\n" => sub {
    868     plan tests =>
    869         (scalar @incorrect_attribute_cms_test);
    870 
    871     my $cnt = 0;
    872     foreach my $name (@incorrect_attribute_cms_test) {
    873         my $out = "incorrect-$cnt.txt";
    874 
    875         ok(!run(app(["openssl", "cms", @prov, "-verify", "-in",
    876                      catfile($datadir, $name), "-inform", "DER", "-CAfile",
    877                      $smroot, "-out", $out ])),
    878             $name);
    879     }
    880 };
    881 
    882 subtest "CMS Check that bad encryption algorithm fails\n" => sub {
    883     plan tests => 1;
    884 
    885     SKIP: {
    886         skip "DES or Legacy isn't supported in this build", 1
    887             if disabled("des") || disabled("legacy");
    888 
    889         my $out = "smtst.txt";
    890 
    891         ok(!run(app(["openssl", "cms", @legacyprov, "-encrypt",
    892                     "-in", $smcont,
    893                     "-stream", "-recip", $smrsa1,
    894                     "-des-ede3",
    895                     "-out", $out ])),
    896            "Decrypt message from OpenSSL 1.1.1");
    897     }
    898 };
    899 
    900 subtest "CMS Decrypt message encrypted with OpenSSL 1.1.1\n" => sub {
    901     plan tests => 1;
    902 
    903     SKIP: {
    904         skip "EC or DES isn't supported in this build", 1
    905             if disabled("ec") || disabled("des");
    906 
    907         my $out = "smtst.txt";
    908 
    909         ok(run(app(["openssl", "cms", @defaultprov, "-decrypt",
    910                     "-inkey", catfile($smdir, "smec3.pem"),
    911                     "-in", catfile($datadir, "ciphertext_from_1_1_1.cms"),
    912                     "-out", $out ]))
    913            && compare_text($smcont, $out) == 0,
    914            "Decrypt message from OpenSSL 1.1.1");
    915     }
    916 };
    917 
    918 subtest "CAdES <=> CAdES consistency tests\n" => sub {
    919     plan tests => (scalar @smime_cms_cades_tests);
    920 
    921     runner_loop(prefix => 'cms-cades', cmd1 => 'cms', cmd2 => 'cms',
    922                 tests => [ @smime_cms_cades_tests ]);
    923 };
    924 
    925 subtest "CAdES; cms incompatible arguments tests\n" => sub {
    926     plan tests => (scalar @smime_cms_cades_invalid_option_tests);
    927 
    928     foreach (@smime_cms_cades_invalid_option_tests) {
    929         ok(!run(app(["openssl", "cms", @{$$_[0]} ] )));
    930     }
    931 };
    932 
    933 subtest "CAdES ko tests\n" => sub {
    934     plan tests => 2 * scalar @smime_cms_cades_ko_tests;
    935 
    936     foreach (@smime_cms_cades_ko_tests) {
    937       SKIP: {
    938         my $skip_reason = check_availability($$_[0]);
    939         skip $skip_reason, 1 if $skip_reason;
    940 
    941         ok(run(app(["openssl", "cms", @{$$_[1]}])), $$_[0]);
    942         ok(!run(app(["openssl", "cms", @{$$_[3]}])), $$_[2]);
    943         }
    944     }
    945 };
    946 
    947 subtest "CMS binary input tests\n" => sub {
    948     my $input = srctop_file("test", "smcont.bin");
    949     my $signed = "smcont.signed";
    950     my $verified = "smcont.verified";
    951 
    952     plan tests => 11;
    953 
    954     ok(run(app(["openssl", "cms", "-sign", "-md", "sha256", "-signer", $smrsa1,
    955                 "-binary", "-in", $input, "-out", $signed])),
    956        "sign binary input with -binary");
    957     ok(run(app(["openssl", "cms", "-verify", "-CAfile", $smroot,
    958                 "-binary", "-in", $signed, "-out", $verified])),
    959        "verify binary input with -binary");
    960     is(compare($input, $verified), 0, "binary input retained with -binary");
    961 
    962     ok(run(app(["openssl", "cms", "-sign", "-md", "sha256", "-signer", $smrsa1,
    963                 "-in", $input, "-out", $signed.".nobin"])),
    964        "sign binary input without -binary");
    965     ok(run(app(["openssl", "cms", "-verify", "-CAfile", $smroot,
    966                 "-in", $signed.".nobin", "-out", $verified.".nobin"])),
    967        "verify binary input without -binary");
    968     is(compare($input, $verified.".nobin"), 1, "binary input not retained without -binary");
    969     ok(!run(app(["openssl", "cms", "-verify", "-CAfile", $smroot, "-crlfeol",
    970                 "-binary", "-in", $signed, "-out", $verified.".crlfeol"])),
    971        "verify binary input wrong crlfeol");
    972 
    973     ok(run(app(["openssl", "cms", "-sign", "-md", "sha256", "-signer", $smrsa1,
    974                 "-crlfeol",
    975                 "-binary", "-in", $input, "-out", $signed.".crlf"])),
    976        "sign binary input with -binary -crlfeol");
    977     ok(run(app(["openssl", "cms", "-verify", "-CAfile", $smroot, "-crlfeol",
    978                 "-binary", "-in", $signed.".crlf", "-out", $verified.".crlf"])),
    979        "verify binary input with -binary -crlfeol");
    980     is(compare($input, $verified.".crlf"), 0,
    981        "binary input retained with -binary -crlfeol");
    982     ok(!run(app(["openssl", "cms", "-verify", "-CAfile", $smroot,
    983                 "-binary", "-in", $signed.".crlf", "-out", $verified.".crlf2"])),
    984        "verify binary input with -binary missing -crlfeol");
    985 };
    986 
    987 # Test case for missing MD algorithm (must not segfault)
    988 
    989 with({ exit_checker => sub { return shift == 4; } },
    990     sub {
    991         ok(run(app(['openssl', 'smime', '-verify', '-noverify',
    992                     '-inform', 'PEM',
    993                     '-in', data_file("pkcs7-md4.pem"),
    994                    ])),
    995             "Check failure of EVP_DigestInit is handled correctly");
    996     });
    997 
    998 sub check_availability {
    999     my $tnam = shift;
   1000 
   1001     return "$tnam: skipped, EC disabled\n"
   1002         if ($no_ec && $tnam =~ /ECDH/);
   1003     return "$tnam: skipped, ECDH disabled\n"
   1004         if ($no_ec && $tnam =~ /ECDH/);
   1005     return "$tnam: skipped, EC2M disabled\n"
   1006         if ($no_ec2m && $tnam =~ /K-283/);
   1007     return "$tnam: skipped, DH disabled\n"
   1008         if ($no_dh && $tnam =~ /X9\.42/);
   1009     return "$tnam: skipped, RC2 disabled\n"
   1010         if ($no_rc2 && $tnam =~ /RC2/);
   1011     return "$tnam: skipped, DES disabled\n"
   1012         if ($no_des && $tnam =~ /DES/);
   1013     return "$tnam: skipped, DSA disabled\n"
   1014         if ($no_dsa && $tnam =~ / DSA/);
   1015 
   1016     return "";
   1017 }
   1018 
   1019 # Test case for the locking problem reported in #19643.
   1020 # This will fail if the fix is in and deadlock on Windows (and possibly
   1021 # other platforms) if not.
   1022 ok(!run(app(['openssl', 'cms', '-verify',
   1023              '-CAfile', srctop_file("test/certs", "pkitsta.pem"),
   1024              '-policy', 'anyPolicy',
   1025              '-in', srctop_file("test/smime-eml",
   1026                                 "SignedInvalidMappingFromanyPolicyTest7.eml")
   1027             ])),
   1028    "issue#19643");
   1029 
   1030 # Check that kari encryption with originator does not segfault
   1031 with({ exit_checker => sub { return shift == 3; } },
   1032   sub {
   1033     SKIP: {
   1034       skip "EC is not supported in this build", 1 if $no_ec;
   1035 
   1036       ok(run(app(['openssl', 'cms', '-encrypt',
   1037                   '-in', srctop_file("test", "smcont.txt"), '-aes128',
   1038                   '-recip', catfile($smdir, "smec1.pem"),
   1039                   '-originator', catfile($smdir, "smec3.pem"),
   1040                   '-inkey', catfile($smdir, "smec3.pem")
   1041                 ])),
   1042           "Check failure for currently not supported kari encryption with static originator");
   1043     }
   1044   });
   1045 
   1046 # Check that we get the expected failure return code
   1047 with({ exit_checker => sub { return shift == 6; } },
   1048     sub {
   1049         ok(run(app(['openssl', 'cms', '-encrypt',
   1050                     '-in', srctop_file("test", "smcont.txt"),
   1051                     '-aes128', '-stream', '-recip',
   1052                     srctop_file("test/smime-certs", "badrsa.pem"),
   1053                    ])),
   1054             "Check failure during BIO setup with -stream is handled correctly");
   1055     });
   1056 
   1057 # Test case for return value mis-check reported in #21986
   1058 with({ exit_checker => sub { return shift == 3; } },
   1059     sub {
   1060         SKIP: {
   1061           skip "DSA is not supported in this build", 1 if $no_dsa;
   1062 
   1063           ok(run(app(['openssl', 'cms', '-sign',
   1064                       '-in', srctop_file("test", "smcont.txt"),
   1065                       '-signer', srctop_file("test/smime-certs", "smdsa1.pem"),
   1066                       '-md', 'SHAKE256'])),
   1067             "issue#21986");
   1068         }
   1069     });
   1070 
   1071 # Test for problem reported in #22225
   1072 with({ exit_checker => sub { return shift == 3; } },
   1073     sub {
   1074 	ok(run(app(['openssl', 'cms', '-encrypt',
   1075 		    '-in', srctop_file("test", "smcont.txt"),
   1076 		    '-aes-256-ctr', '-recip',
   1077 		    catfile($smdir, "smec1.pem"),
   1078 		   ])),
   1079 	   "Check for failure when cipher does not have an assigned OID (issue#22225)");
   1080      });
   1081 
   1082 # Test encrypt to three recipients, and decrypt using key-only;
   1083 # i.e. do not follow the recommended practice of providing the
   1084 # recipient cert in the decrypt op.
   1085 #
   1086 # Use RSAES-OAEP for key-transport, not RSAES-PKCS-v1_5.
   1087 #
   1088 # Because the cert is not provided during decrypt, all RSA ciphertexts
   1089 # are decrypted in turn, and when/if there is a valid decryption, it
   1090 # is assumed the correct content-key has been recovered.
   1091 #
   1092 # That process may fail with RSAES-PKCS-v1_5 b/c there is a
   1093 # non-negligible chance that decrypting a random input using
   1094 # RSAES-PKCS-v1_5 can result in a valid plaintext (so two content-keys
   1095 # could be recovered and the wrong one might be used).
   1096 #
   1097 # See https://github.com/openssl/project/issues/380
   1098 subtest "encrypt to three recipients with RSA-OAEP, key only decrypt" => sub {
   1099     plan tests => 3;
   1100 
   1101     my $pt = srctop_file("test", "smcont.txt");
   1102     my $ct = "smtst.cms";
   1103     my $ptpt = "smtst.txt";
   1104 
   1105     ok(run(app(['openssl', 'cms',
   1106 		@defaultprov,
   1107 		'-encrypt', '-aes128',
   1108 		'-in', $pt,
   1109 		'-out', $ct,
   1110 		'-stream',
   1111 		'-recip', catfile($smdir, "smrsa1.pem"),
   1112 		'-keyopt', 'rsa_padding_mode:oaep',
   1113 		'-recip', catfile($smdir, "smrsa2.pem"),
   1114 		'-keyopt', 'rsa_padding_mode:oaep',
   1115 		'-recip', catfile($smdir, "smrsa3-cert.pem"),
   1116 		'-keyopt', 'rsa_padding_mode:oaep',
   1117 	       ])),
   1118        "encrypt to three recipients with RSA-OAEP (avoid openssl/project issue#380)");
   1119     ok(run(app(['openssl', 'cms',
   1120 		@defaultprov,
   1121 		'-decrypt', '-aes128',
   1122 		'-in', $ct,
   1123 		'-out', $ptpt,
   1124 		'-inkey', catfile($smdir, "smrsa3-key.pem"),
   1125 	       ])),
   1126        "decrypt with key only");
   1127     is(compare($pt, $ptpt), 0, "compare original message with decrypted ciphertext");
   1128 };
   1129