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