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