Add fips checks for rsa signatures.
[openssl.git] / test / recipes / 80-test_cms.t
1 #! /usr/bin/env perl
2 # Copyright 2015-2020 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/;
16 use OpenSSL::Test qw/:DEFAULT srctop_dir srctop_file bldtop_dir bldtop_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 use platform;
27
28 my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0);
29
30 plan skip_all => "CMS is not supported by this OpenSSL build"
31     if disabled("cms");
32
33 my $provpath = bldtop_dir("providers");
34
35 # Some tests require legacy algorithms to be included.
36 my @legacyprov = ("-provider-path", $provpath,
37                   "-provider", "default",
38                   "-provider", "legacy" );
39 my @defaultprov = ("-provider-path", $provpath,
40                    "-provider", "default");
41
42 my @config = ( );
43 my $provname = 'default';
44
45 my $datadir = srctop_dir("test", "recipes", "80-test_cms_data");
46 my $smdir    = srctop_dir("test", "smime-certs");
47 my $smcont   = srctop_file("test", "smcont.txt");
48 my ($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 plan tests =>
52     ($no_fips ? 0 : 1)          # FIPS install test
53     + 10;
54
55 unless ($no_fips) {
56     my $infile = bldtop_file('providers', platform->dso('fips'));
57
58     ok(run(app(['openssl', 'fipsinstall',
59                 '-out', bldtop_file('providers', 'fipsmodule.cnf'),
60                 '-module', $infile])),
61        "fipsinstall");
62     @config = ( "-config", srctop_file("test", "fips-and-base.cnf") );
63     $provname = 'fips';
64 }
65
66 $ENV{OPENSSL_TEST_LIBCTX} = "1";
67 my @prov = ("-provider-path", $provpath,
68             @config,
69             "-provider", $provname);
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", catfile($smdir, "smroot.pem"),
76         "-signer", catfile($smdir, "smrsa1.pem"), "-out", "{output}.cms" ],
77       [ "{cmd2}",  @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
78         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
79       \&final_compare
80     ],
81
82     [ "signed detached content DER format, RSA key",
83       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER",
84         "-signer", catfile($smdir, "smrsa1.pem"), "-out", "{output}.cms" ],
85       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
86         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt",
87         "-content", $smcont ],
88       \&final_compare
89     ],
90
91     [ "signed content test streaming BER format, RSA",
92       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER", "-nodetach",
93         "-stream",
94         "-signer", catfile($smdir, "smrsa1.pem"), "-out", "{output}.cms" ],
95       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
96         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
97       \&final_compare
98     ],
99
100     [ "signed content DER format, DSA key",
101       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER", "-nodetach",
102         "-signer", catfile($smdir, "smdsa1.pem"), "-out", "{output}.cms" ],
103       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
104         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
105       \&final_compare
106     ],
107
108     [ "signed detached content DER format, DSA key",
109       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER",
110         "-signer", catfile($smdir, "smdsa1.pem"), "-out", "{output}.cms" ],
111       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
112         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt",
113         "-content", $smcont ],
114       \&final_compare
115     ],
116
117     [ "signed detached content DER format, add RSA signer (with DSA existing)",
118       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER",
119         "-signer", catfile($smdir, "smdsa1.pem"), "-out", "{output}.cms" ],
120       [ "{cmd1}", @prov, "-resign", "-in", "{output}.cms", "-inform", "DER", "-outform", "DER",
121         "-signer", catfile($smdir, "smrsa1.pem"), "-out", "{output}2.cms" ],
122       [ "{cmd2}", @prov, "-verify", "-in", "{output}2.cms", "-inform", "DER",
123         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt",
124         "-content", $smcont ],
125       \&final_compare
126     ],
127
128     [ "signed content test streaming BER format, DSA key",
129       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER",
130         "-nodetach", "-stream",
131         "-signer", catfile($smdir, "smdsa1.pem"), "-out", "{output}.cms" ],
132       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
133         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
134       \&final_compare
135     ],
136
137     [ "signed content test streaming BER format, 2 DSA and 2 RSA keys",
138       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER",
139         "-nodetach", "-stream",
140         "-signer", catfile($smdir, "smrsa1.pem"),
141         "-signer", catfile($smdir, "smrsa2.pem"),
142         "-signer", catfile($smdir, "smdsa1.pem"),
143         "-signer", catfile($smdir, "smdsa2.pem"),
144         "-out", "{output}.cms" ],
145       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
146         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
147       \&final_compare
148     ],
149
150     [ "signed content test streaming BER format, 2 DSA and 2 RSA keys, no attributes",
151       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER",
152         "-noattr", "-nodetach", "-stream",
153         "-signer", catfile($smdir, "smrsa1.pem"),
154         "-signer", catfile($smdir, "smrsa2.pem"),
155         "-signer", catfile($smdir, "smdsa1.pem"),
156         "-signer", catfile($smdir, "smdsa2.pem"),
157         "-out", "{output}.cms" ],
158       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
159         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
160       \&final_compare
161     ],
162
163     [ "signed content S/MIME format, RSA key SHA1",
164       [ "{cmd1}", @defaultprov, "-sign", "-in", $smcont, "-md", "sha1",
165         "-certfile", catfile($smdir, "smroot.pem"),
166         "-signer", catfile($smdir, "smrsa1.pem"), "-out", "{output}.cms" ],
167       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms",
168         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
169       \&final_compare
170     ],
171
172     [ "signed content test streaming S/MIME format, 2 DSA and 2 RSA keys",
173       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-nodetach",
174         "-signer", catfile($smdir, "smrsa1.pem"),
175         "-signer", catfile($smdir, "smrsa2.pem"),
176         "-signer", catfile($smdir, "smdsa1.pem"),
177         "-signer", catfile($smdir, "smdsa2.pem"),
178         "-stream", "-out", "{output}.cms" ],
179       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms",
180         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
181       \&final_compare
182     ],
183
184     [ "signed content test streaming multipart S/MIME format, 2 DSA and 2 RSA keys",
185       [ "{cmd1}", @prov, "-sign", "-in", $smcont,
186         "-signer", catfile($smdir, "smrsa1.pem"),
187         "-signer", catfile($smdir, "smrsa2.pem"),
188         "-signer", catfile($smdir, "smdsa1.pem"),
189         "-signer", catfile($smdir, "smdsa2.pem"),
190         "-stream", "-out", "{output}.cms" ],
191       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms",
192         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
193       \&final_compare
194     ],
195
196     [ "enveloped content test streaming S/MIME format, DES, 3 recipients",
197       [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
198         "-stream", "-out", "{output}.cms",
199         catfile($smdir, "smrsa1.pem"),
200         catfile($smdir, "smrsa2.pem"),
201         catfile($smdir, "smrsa3.pem") ],
202       [ "{cmd2}", @defaultprov, "-decrypt", "-recip", catfile($smdir, "smrsa1.pem"),
203         "-in", "{output}.cms", "-out", "{output}.txt" ],
204       \&final_compare
205     ],
206
207     [ "enveloped content test streaming S/MIME format, DES, 3 recipients, 3rd used",
208       [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
209         "-stream", "-out", "{output}.cms",
210         catfile($smdir, "smrsa1.pem"),
211         catfile($smdir, "smrsa2.pem"),
212         catfile($smdir, "smrsa3.pem") ],
213       [ "{cmd2}", @defaultprov, "-decrypt", "-recip", catfile($smdir, "smrsa3.pem"),
214         "-in", "{output}.cms", "-out", "{output}.txt" ],
215       \&final_compare
216     ],
217
218     [ "enveloped content test streaming S/MIME format, DES, 3 recipients, key only used",
219       [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
220         "-stream", "-out", "{output}.cms",
221         catfile($smdir, "smrsa1.pem"),
222         catfile($smdir, "smrsa2.pem"),
223         catfile($smdir, "smrsa3.pem") ],
224       [ "{cmd2}", @defaultprov, "-decrypt", "-inkey", catfile($smdir, "smrsa3.pem"),
225         "-in", "{output}.cms", "-out", "{output}.txt" ],
226       \&final_compare
227     ],
228
229     [ "enveloped content test streaming S/MIME format, AES-256 cipher, 3 recipients",
230       [ "{cmd1}", @prov, "-encrypt", "-in", $smcont,
231         "-aes256", "-stream", "-out", "{output}.cms",
232         catfile($smdir, "smrsa1.pem"),
233         catfile($smdir, "smrsa2.pem"),
234         catfile($smdir, "smrsa3.pem") ],
235       [ "{cmd2}", @prov, "-decrypt", "-recip", catfile($smdir, "smrsa1.pem"),
236         "-in", "{output}.cms", "-out", "{output}.txt" ],
237       \&final_compare
238     ],
239
240 );
241
242 my @smime_cms_tests = (
243
244     [ "signed content test streaming BER format, 2 DSA and 2 RSA keys, keyid",
245       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER",
246         "-nodetach", "-keyid",
247         "-signer", catfile($smdir, "smrsa1.pem"),
248         "-signer", catfile($smdir, "smrsa2.pem"),
249         "-signer", catfile($smdir, "smdsa1.pem"),
250         "-signer", catfile($smdir, "smdsa2.pem"),
251         "-stream", "-out", "{output}.cms" ],
252       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
253         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
254       \&final_compare
255     ],
256
257     [ "signed content test streaming PEM format, 2 DSA and 2 RSA keys",
258       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
259         "-signer", catfile($smdir, "smrsa1.pem"),
260         "-signer", catfile($smdir, "smrsa2.pem"),
261         "-signer", catfile($smdir, "smdsa1.pem"),
262         "-signer", catfile($smdir, "smdsa2.pem"),
263         "-stream", "-out", "{output}.cms" ],
264       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "PEM",
265         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
266       \&final_compare
267     ],
268
269     [ "signed content MIME format, RSA key, signed receipt request",
270       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-nodetach",
271         "-signer", catfile($smdir, "smrsa1.pem"),
272         "-receipt_request_to", "test\@openssl.org", "-receipt_request_all",
273         "-out", "{output}.cms" ],
274       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms",
275         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
276       \&final_compare
277     ],
278
279     [ "signed receipt MIME format, RSA key",
280       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-nodetach",
281         "-signer", catfile($smdir, "smrsa1.pem"),
282         "-receipt_request_to", "test\@openssl.org", "-receipt_request_all",
283         "-out", "{output}.cms" ],
284       [ "{cmd1}", @prov, "-sign_receipt", "-in", "{output}.cms",
285         "-signer", catfile($smdir, "smrsa2.pem"), "-out", "{output}2.cms" ],
286       [ "{cmd2}", @prov, "-verify_receipt", "{output}2.cms", "-in", "{output}.cms",
287         "-CAfile", catfile($smdir, "smroot.pem") ]
288     ],
289
290     [ "enveloped content test streaming S/MIME format, DES, 3 recipients, keyid",
291       [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
292         "-stream", "-out", "{output}.cms", "-keyid",
293         catfile($smdir, "smrsa1.pem"),
294         catfile($smdir, "smrsa2.pem"),
295         catfile($smdir, "smrsa3.pem") ],
296       [ "{cmd2}", @defaultprov, "-decrypt", "-recip", catfile($smdir, "smrsa1.pem"),
297         "-in", "{output}.cms", "-out", "{output}.txt" ],
298       \&final_compare
299     ],
300
301     [ "enveloped content test streaming PEM format, AES-256-CBC cipher, KEK",
302       [ "{cmd1}", @prov, "-encrypt", "-in", $smcont, "-outform", "PEM", "-aes128",
303         "-stream", "-out", "{output}.cms",
304         "-secretkey", "000102030405060708090A0B0C0D0E0F",
305         "-secretkeyid", "C0FEE0" ],
306       [ "{cmd2}", @prov, "-decrypt", "-in", "{output}.cms", "-out", "{output}.txt",
307         "-inform", "PEM",
308         "-secretkey", "000102030405060708090A0B0C0D0E0F",
309         "-secretkeyid", "C0FEE0" ],
310       \&final_compare
311     ],
312
313     [ "enveloped content test streaming PEM format, AES-256-GCM cipher, KEK",
314       [ "{cmd1}", @prov, "-encrypt", "-in", $smcont, "-outform", "PEM", "-aes-128-gcm",
315         "-stream", "-out", "{output}.cms",
316         "-secretkey", "000102030405060708090A0B0C0D0E0F",
317         "-secretkeyid", "C0FEE0" ],
318       [ "{cmd2}", "-decrypt", "-in", "{output}.cms", "-out", "{output}.txt",
319         "-inform", "PEM",
320         "-secretkey", "000102030405060708090A0B0C0D0E0F",
321         "-secretkeyid", "C0FEE0" ],
322       \&final_compare
323     ],
324
325     [ "enveloped content test streaming PEM format, KEK, key only",
326       [ "{cmd1}", @prov, "-encrypt", "-in", $smcont, "-outform", "PEM", "-aes128",
327         "-stream", "-out", "{output}.cms",
328         "-secretkey", "000102030405060708090A0B0C0D0E0F",
329         "-secretkeyid", "C0FEE0" ],
330       [ "{cmd2}", @prov, "-decrypt", "-in", "{output}.cms", "-out", "{output}.txt",
331         "-inform", "PEM",
332         "-secretkey", "000102030405060708090A0B0C0D0E0F" ],
333       \&final_compare
334     ],
335
336     [ "data content test streaming PEM format",
337       [ "{cmd1}", @prov, "-data_create", "-in", $smcont, "-outform", "PEM",
338         "-nodetach", "-stream", "-out", "{output}.cms" ],
339       [ "{cmd2}", @prov, "-data_out", "-in", "{output}.cms", "-inform", "PEM",
340         "-out", "{output}.txt" ],
341       \&final_compare
342     ],
343
344     [ "encrypted content test streaming PEM format, 128 bit RC2 key",
345       [ "{cmd1}", @legacyprov, "-EncryptedData_encrypt",
346         "-in", $smcont, "-outform", "PEM",
347         "-rc2", "-secretkey", "000102030405060708090A0B0C0D0E0F",
348         "-stream", "-out", "{output}.cms" ],
349       [ "{cmd2}", @legacyprov, "-EncryptedData_decrypt", "-in", "{output}.cms",
350         "-inform", "PEM",
351         "-secretkey", "000102030405060708090A0B0C0D0E0F",
352         "-out", "{output}.txt" ],
353       \&final_compare
354     ],
355
356     [ "encrypted content test streaming PEM format, 40 bit RC2 key",
357       [ "{cmd1}", @legacyprov, "-EncryptedData_encrypt",
358         "-in", $smcont, "-outform", "PEM",
359         "-rc2", "-secretkey", "0001020304",
360         "-stream", "-out", "{output}.cms" ],
361       [ "{cmd2}", @legacyprov, "-EncryptedData_decrypt", "-in", "{output}.cms",
362         "-inform", "PEM",
363         "-secretkey", "0001020304", "-out", "{output}.txt" ],
364       \&final_compare
365     ],
366
367     [ "encrypted content test streaming PEM format, triple DES key",
368       [ "{cmd1}", @prov, "-EncryptedData_encrypt", "-in", $smcont, "-outform", "PEM",
369         "-des3", "-secretkey", "000102030405060708090A0B0C0D0E0F1011121314151617",
370         "-stream", "-out", "{output}.cms" ],
371       [ "{cmd2}", @prov, "-EncryptedData_decrypt", "-in", "{output}.cms",
372         "-inform", "PEM",
373         "-secretkey", "000102030405060708090A0B0C0D0E0F1011121314151617",
374         "-out", "{output}.txt" ],
375       \&final_compare
376     ],
377
378     [ "encrypted content test streaming PEM format, 128 bit AES key",
379       [ "{cmd1}", @prov, "-EncryptedData_encrypt", "-in", $smcont, "-outform", "PEM",
380         "-aes128", "-secretkey", "000102030405060708090A0B0C0D0E0F",
381         "-stream", "-out", "{output}.cms" ],
382       [ "{cmd2}", @prov, "-EncryptedData_decrypt", "-in", "{output}.cms",
383         "-inform", "PEM",
384         "-secretkey", "000102030405060708090A0B0C0D0E0F",
385         "-out", "{output}.txt" ],
386       \&final_compare
387     ],
388 );
389
390 my @smime_cms_cades_tests = (
391
392     [ "signed content DER format, RSA key, CAdES-BES compatible",
393       [ "{cmd1}", @prov, "-sign", "-cades", "-in", $smcont, "-outform", "DER",
394          "-nodetach",
395         "-certfile", catfile($smdir, "smroot.pem"),
396         "-signer", catfile($smdir, "smrsa1.pem"), "-out", "{output}.cms" ],
397       [ "{cmd2}", @prov, "-verify", "-cades", "-in", "{output}.cms", "-inform", "DER",
398         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
399       \&final_compare
400     ],
401
402     [ "signed content DER format, RSA key, SHA256 md, CAdES-BES compatible",
403       [ "{cmd1}", @prov, "-sign", "-cades", "-md", "sha256", "-in", $smcont, "-outform",
404         "DER", "-nodetach", "-certfile", catfile($smdir, "smroot.pem"),
405         "-signer", catfile($smdir, "smrsa1.pem"), "-out", "{output}.cms" ],
406       [ "{cmd2}", @prov, "-verify", "-cades", "-in", "{output}.cms", "-inform", "DER",
407         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
408       \&final_compare
409     ],
410
411     [ "signed content DER format, RSA key, SHA512 md, CAdES-BES compatible",
412       [ "{cmd1}", @prov, "-sign", "-cades", "-md", "sha512", "-in", $smcont, "-outform",
413         "DER", "-nodetach", "-certfile", catfile($smdir, "smroot.pem"),
414         "-signer", catfile($smdir, "smrsa1.pem"), "-out", "{output}.cms" ],
415       [ "{cmd2}", @prov, "-verify", "-cades", "-in", "{output}.cms", "-inform", "DER",
416         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
417       \&final_compare
418     ],
419
420     [ "signed content DER format, RSA key, SHA256 md, CAdES-BES compatible",
421       [ "{cmd1}", @prov, "-sign", "-cades", "-binary",  "-nodetach", "-nosmimecap", "-md", "sha256",
422         "-in", $smcont, "-outform", "DER", 
423         "-certfile", catfile($smdir, "smroot.pem"),
424         "-signer", catfile($smdir, "smrsa1.pem"),
425         "-outform", "DER", "-out", "{output}.cms"  ],
426       [ "{cmd2}", @prov, "-verify", "-cades", "-in", "{output}.cms", "-inform", "DER",
427         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
428       \&final_compare
429     ],
430
431     [ "resigned content DER format, RSA key, SHA256 md, CAdES-BES compatible",
432       [ "{cmd1}", @prov, "-sign", "-cades", "-binary",  "-nodetach", "-nosmimecap", "-md", "sha256",
433         "-in", $smcont, "-outform", "DER", 
434         "-certfile", catfile($smdir, "smroot.pem"),
435         "-signer", catfile($smdir, "smrsa1.pem"),
436         "-outform", "DER", "-out", "{output}.cms"  ],
437       [ "{cmd1}", @prov, "-resign", "-cades", "-binary", "-nodetach", "-nosmimecap", "-md", "sha256",
438         "-inform", "DER", "-in", "{output}.cms",
439         "-certfile", catfile($smdir, "smroot.pem"),
440         "-signer", catfile($smdir, "smrsa2.pem"),
441         "-outform", "DER", "-out", "{output}2.cms" ],
442
443       [ "{cmd2}", @prov, "-verify", "-cades", "-in", "{output}2.cms", "-inform", "DER",
444         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
445       \&final_compare
446     ],
447 );
448
449 my @smime_cms_cades_ko_tests = (
450     [ "signed content DER format, RSA key, but verified as CAdES-BES compatible",
451       [ @prov, "-sign", "-in", $smcont, "-outform", "DER", "-nodetach",
452         "-certfile", catfile($smdir, "smroot.pem"),
453         "-signer", catfile($smdir, "smrsa1.pem"), "-out", "{output}.cms" ],
454       [ @prov, "-verify", "-cades", "-in", "{output}.cms", "-inform", "DER",
455         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
456       \&final_compare
457     ]
458 );
459
460 # cades options test - check that some combinations are rejected
461 my @smime_cms_cades_invalid_option_tests = (
462     [
463         [ "-cades", "-noattr" ],
464     ],[
465         [ "-verify", "-cades", "-noattr" ],
466     ],[
467         [ "-verify", "-cades", "-noverify" ],
468     ],
469 );
470
471 my @smime_cms_comp_tests = (
472
473     [ "compressed content test streaming PEM format",
474       [ "{cmd1}", @prov, "-compress", "-in", $smcont, "-outform", "PEM", "-nodetach",
475         "-stream", "-out", "{output}.cms" ],
476       [ "{cmd2}", @prov, "-uncompress", "-in", "{output}.cms", "-inform", "PEM",
477         "-out", "{output}.txt" ],
478       \&final_compare
479     ]
480
481 );
482
483 my @smime_cms_param_tests = (
484     [ "signed content test streaming PEM format, RSA keys, PSS signature",
485       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
486         "-signer", catfile($smdir, "smrsa1.pem"),
487         "-keyopt", "rsa_padding_mode:pss",
488         "-out", "{output}.cms" ],
489       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "PEM",
490         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
491       \&final_compare
492     ],
493
494     [ "signed content test streaming PEM format, RSA keys, PSS signature, saltlen=max",
495       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
496         "-signer", catfile($smdir, "smrsa1.pem"),
497         "-keyopt", "rsa_padding_mode:pss", "-keyopt", "rsa_pss_saltlen:max",
498         "-out", "{output}.cms" ],
499       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "PEM",
500         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
501       \&final_compare
502     ],
503
504     [ "signed content test streaming PEM format, RSA keys, PSS signature, no attributes",
505       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
506         "-noattr",
507         "-signer", catfile($smdir, "smrsa1.pem"),
508         "-keyopt", "rsa_padding_mode:pss",
509         "-out", "{output}.cms" ],
510       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "PEM",
511         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
512       \&final_compare
513     ],
514
515     [ "signed content test streaming PEM format, RSA keys, PSS signature, SHA384 MGF1",
516       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
517         "-signer", catfile($smdir, "smrsa1.pem"),
518         "-keyopt", "rsa_padding_mode:pss", "-keyopt", "rsa_mgf1_md:sha384",
519         "-out", "{output}.cms" ],
520       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "PEM",
521         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
522       \&final_compare
523     ],
524
525     [ "enveloped content test streaming S/MIME format, DES, OAEP default parameters",
526       [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
527         "-stream", "-out", "{output}.cms",
528         "-recip", catfile($smdir, "smrsa1.pem"),
529         "-keyopt", "rsa_padding_mode:oaep" ],
530       [ "{cmd2}", @defaultprov, "-decrypt", "-recip", catfile($smdir, "smrsa1.pem"),
531         "-in", "{output}.cms", "-out", "{output}.txt" ],
532       \&final_compare
533     ],
534
535     [ "enveloped content test streaming S/MIME format, DES, OAEP SHA256",
536       [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
537         "-stream", "-out", "{output}.cms",
538         "-recip", catfile($smdir, "smrsa1.pem"),
539         "-keyopt", "rsa_padding_mode:oaep",
540         "-keyopt", "rsa_oaep_md:sha256" ],
541       [ "{cmd2}", @defaultprov, "-decrypt", "-recip", catfile($smdir, "smrsa1.pem"),
542         "-in", "{output}.cms", "-out", "{output}.txt" ],
543       \&final_compare
544     ],
545
546     [ "enveloped content test streaming S/MIME format, DES, ECDH",
547       [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
548         "-stream", "-out", "{output}.cms",
549         "-recip", catfile($smdir, "smec1.pem") ],
550       [ "{cmd2}", @defaultprov, "-decrypt", "-recip", catfile($smdir, "smec1.pem"),
551         "-in", "{output}.cms", "-out", "{output}.txt" ],
552       \&final_compare
553     ],
554
555     [ "enveloped content test streaming S/MIME format, DES, ECDH, 2 recipients, key only used",
556       [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
557         "-stream", "-out", "{output}.cms",
558         catfile($smdir, "smec1.pem"),
559         catfile($smdir, "smec3.pem") ],
560       [ "{cmd2}", @defaultprov, "-decrypt", "-inkey", catfile($smdir, "smec3.pem"),
561         "-in", "{output}.cms", "-out", "{output}.txt" ],
562       \&final_compare
563     ],
564
565     [ "enveloped content test streaming S/MIME format, ECDH, DES, key identifier",
566       [ "{cmd1}", @defaultprov, "-encrypt", "-keyid", "-in", $smcont,
567         "-stream", "-out", "{output}.cms",
568         "-recip", catfile($smdir, "smec1.pem") ],
569       [ "{cmd2}", @defaultprov, "-decrypt", "-recip", catfile($smdir, "smec1.pem"),
570         "-in", "{output}.cms", "-out", "{output}.txt" ],
571       \&final_compare
572     ],
573
574     [ "enveloped content test streaming S/MIME format, ECDH, AES-128-CBC, SHA256 KDF",
575       [ "{cmd1}", @prov, "-encrypt", "-in", $smcont,
576         "-stream", "-out", "{output}.cms",
577         "-recip", catfile($smdir, "smec1.pem"), "-aes128",
578         "-keyopt", "ecdh_kdf_md:sha256" ],
579       [ "{cmd2}", @prov, "-decrypt", "-recip", catfile($smdir, "smec1.pem"),
580         "-in", "{output}.cms", "-out", "{output}.txt" ],
581       \&final_compare
582     ],
583
584     [ "enveloped content test streaming S/MIME format, ECDH, AES-128-GCM cipher, SHA256 KDF",
585       [ "{cmd1}", @prov, "-encrypt", "-in", $smcont,
586         "-stream", "-out", "{output}.cms",
587         "-recip", catfile($smdir, "smec1.pem"), "-aes-128-gcm", "-keyopt", "ecdh_kdf_md:sha256" ],
588       [ "{cmd2}", "-decrypt", "-recip", catfile($smdir, "smec1.pem"),
589               "-in", "{output}.cms", "-out", "{output}.txt" ],
590       \&final_compare
591     ],
592
593     [ "enveloped content test streaming S/MIME format, ECDH, K-283, cofactor DH",
594       [ "{cmd1}", @prov, "-encrypt", "-in", $smcont,
595         "-stream", "-out", "{output}.cms",
596         "-recip", catfile($smdir, "smec2.pem"), "-aes128",
597         "-keyopt", "ecdh_kdf_md:sha256", "-keyopt", "ecdh_cofactor_mode:1" ],
598       [ "{cmd2}", @prov, "-decrypt", "-recip", catfile($smdir, "smec2.pem"),
599         "-in", "{output}.cms", "-out", "{output}.txt" ],
600       \&final_compare
601     ]
602
603     # TODO(3.0) Add this test back in when "dhpublicnumber" is supported
604     # in the keymanger.
605     #[ "enveloped content test streaming S/MIME format, X9.42 DH",
606     #  [ "{cmd1}", @prov, "-encrypt", "-in", $smcont,
607     #    "-stream", "-out", "{output}.cms",
608     #    "-recip", catfile($smdir, "smdh.pem"), "-aes128" ],
609     #  [ "{cmd2}", "-decrypt", "-recip", catfile($smdir, "smdh.pem"),
610     #    "-in", "{output}.cms", "-out", "{output}.txt" ],
611     #  \&final_compare
612     #]
613 );
614
615 my @contenttype_cms_test = (
616     [ "signed content test - check that content type is added to additional signerinfo, RSA keys",
617       [ "{cmd1}", @prov, "-sign", "-binary", "-nodetach", "-stream", "-in", $smcont,
618         "-outform", "DER",
619         "-signer", catfile($smdir, "smrsa1.pem"), "-md", "SHA256",
620         "-out", "{output}.cms" ],
621       [ "{cmd1}", @prov, "-resign", "-binary", "-nodetach", "-in", "{output}.cms",
622         "-inform", "DER", "-outform", "DER",
623         "-signer", catfile($smdir, "smrsa2.pem"), "-md", "SHA256",
624         "-out", "{output}2.cms" ],
625       sub { my %opts = @_; contentType_matches("$opts{output}2.cms") == 2; },
626       [ "{cmd2}", @prov, "-verify", "-in", "{output}2.cms", "-inform", "DER",
627         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ]
628     ],
629 );
630
631 my @incorrect_attribute_cms_test = (
632     "bad_signtime_attr.cms",
633     "no_ct_attr.cms",
634     "no_md_attr.cms",
635     "ct_multiple_attr.cms"
636 );
637
638 # Runs a standard loop on the input array
639 sub runner_loop {
640     my %opts = ( @_ );
641     my $cnt1 = 0;
642
643     foreach (@{$opts{tests}}) {
644         $cnt1++;
645         $opts{output} = "$opts{prefix}-$cnt1";
646       SKIP: {
647           my $skip_reason = check_availability($$_[0]);
648           skip $skip_reason, 1 if $skip_reason;
649           my $ok = 1;
650           1 while unlink "$opts{output}.txt";
651
652           foreach (@$_[1..$#$_]) {
653               if (ref $_ eq 'CODE') {
654                   $ok &&= $_->(%opts);
655               } else {
656                   my @cmd = map {
657                       my $x = $_;
658                       while ($x =~ /\{([^\}]+)\}/) {
659                           $x = $`.$opts{$1}.$' if exists $opts{$1};
660                       }
661                       $x;
662                   } @$_;
663
664                   diag "CMD: openssl ", join(" ", @cmd);
665                   $ok &&= run(app(["openssl", @cmd]));
666                   $opts{input} = $opts{output};
667               }
668           }
669
670           ok($ok, $$_[0]);
671         }
672     }
673 }
674
675 sub final_compare {
676     my %opts = @_;
677
678     diag "Comparing $smcont with $opts{output}.txt";
679     return compare_text($smcont, "$opts{output}.txt") == 0;
680 }
681
682 subtest "CMS => PKCS#7 compatibility tests\n" => sub {
683     plan tests => scalar @smime_pkcs7_tests;
684
685     runner_loop(prefix => 'cms2pkcs7', cmd1 => 'cms', cmd2 => 'smime',
686                 tests => [ @smime_pkcs7_tests ]);
687 };
688 subtest "CMS <= PKCS#7 compatibility tests\n" => sub {
689     plan tests => scalar @smime_pkcs7_tests;
690
691     runner_loop(prefix => 'pkcs72cms', cmd1 => 'smime', cmd2 => 'cms',
692                 tests => [ @smime_pkcs7_tests ]);
693 };
694
695 subtest "CMS <=> CMS consistency tests\n" => sub {
696     plan tests => (scalar @smime_pkcs7_tests) + (scalar @smime_cms_tests);
697
698     runner_loop(prefix => 'cms2cms-1', cmd1 => 'cms', cmd2 => 'cms',
699                 tests => [ @smime_pkcs7_tests ]);
700     runner_loop(prefix => 'cms2cms-2', cmd1 => 'cms', cmd2 => 'cms',
701                 tests => [ @smime_cms_tests ]);
702 };
703
704 subtest "CMS <=> CMS consistency tests, modified key parameters\n" => sub {
705     plan tests =>
706         (scalar @smime_cms_param_tests) + (scalar @smime_cms_comp_tests);
707
708     runner_loop(prefix => 'cms2cms-mod', cmd1 => 'cms', cmd2 => 'cms',
709                 tests => [ @smime_cms_param_tests ]);
710   SKIP: {
711       skip("Zlib not supported: compression tests skipped",
712            scalar @smime_cms_comp_tests)
713           if $no_zlib;
714
715       runner_loop(prefix => 'cms2cms-comp', cmd1 => 'cms', cmd2 => 'cms',
716                   tests => [ @smime_cms_comp_tests ]);
717     }
718 };
719
720 # Returns the number of matches of a Content Type Attribute in a binary file.
721 sub contentType_matches {
722   # Read in a binary file
723   my ($in) = @_;
724   open (HEX_IN, "$in") or die("open failed for $in : $!");
725   binmode(HEX_IN);
726   local $/;
727   my $str = <HEX_IN>;
728
729   # Find ASN1 data for a Content Type Attribute (with a OID of PKCS7 data)
730   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;
731
732   close(HEX_IN);
733   return scalar(@c);
734 }
735
736 subtest "CMS Check the content type attribute is added for additional signers\n" => sub {
737     plan tests => (scalar @contenttype_cms_test);
738
739     runner_loop(prefix => 'cms2cms-added', cmd1 => 'cms', cmd2 => 'cms',
740                 tests => [ @contenttype_cms_test ]);
741 };
742
743 subtest "CMS Check that bad attributes fail when verifying signers\n" => sub {
744     plan tests =>
745         (scalar @incorrect_attribute_cms_test);
746
747     my $cnt = 0;
748     foreach my $name (@incorrect_attribute_cms_test) {
749         my $out = "incorrect-$cnt.txt";
750
751         ok(!run(app(["openssl", "cms", @prov, "-verify", "-in",
752                      catfile($datadir, $name), "-inform", "DER", "-CAfile",
753                      catfile($smdir, "smroot.pem"), "-out", $out ])),
754             $name);
755     }
756 };
757
758 subtest "CMS Decrypt message encrypted with OpenSSL 1.1.1\n" => sub {
759     plan tests => 1;
760
761     SKIP: {
762         skip "EC or DES isn't supported in this build", 1
763             if disabled("ec") || disabled("des");
764
765         my $out = "smtst.txt";
766
767         ok(run(app(["openssl", "cms", @defaultprov, "-decrypt",
768                     "-inkey", catfile($smdir, "smec3.pem"),
769                     "-in", catfile($datadir, "ciphertext_from_1_1_1.cms"),
770                     "-out", $out ]))
771            && compare_text($smcont, $out) == 0,
772            "Decrypt message from OpenSSL 1.1.1");
773     }
774 };
775
776 subtest "CAdES <=> CAdES consistency tests\n" => sub {
777     plan tests => (scalar @smime_cms_cades_tests);
778
779     runner_loop(prefix => 'cms-cades', cmd1 => 'cms', cmd2 => 'cms',
780                 tests => [ @smime_cms_cades_tests ]);
781 };
782
783 subtest "CAdES; cms incompatible arguments tests\n" => sub {
784     plan tests => (scalar @smime_cms_cades_invalid_option_tests);
785
786     foreach (@smime_cms_cades_invalid_option_tests) {
787         ok(!run(app(["openssl", "cms", @{$$_[0]} ] )));
788     }
789 };
790
791 subtest "CAdES ko tests\n" => sub {
792     plan tests => (scalar @smime_cms_cades_ko_tests);
793
794     foreach (@smime_cms_cades_ko_tests) {
795       SKIP: {
796         my $skip_reason = check_availability($$_[0]);
797         skip $skip_reason, 1 if $skip_reason;
798
799         ok(run(app(["openssl", "cms", @{$$_[1]}]))
800             && !run(app(["openssl", "cms", @{$$_[2]}])),
801             $$_[0]);
802         }
803     }
804 };
805
806 sub check_availability {
807     my $tnam = shift;
808
809     return "$tnam: skipped, EC disabled\n"
810         if ($no_ec && $tnam =~ /ECDH/);
811     return "$tnam: skipped, ECDH disabled\n"
812         if ($no_ec && $tnam =~ /ECDH/);
813     return "$tnam: skipped, EC2M disabled\n"
814         if ($no_ec2m && $tnam =~ /K-283/);
815     return "$tnam: skipped, DH disabled\n"
816         if ($no_dh && $tnam =~ /X9\.42/);
817     return "$tnam: skipped, RC2 disabled\n"
818         if ($no_rc2 && $tnam =~ /RC2/);
819     return "$tnam: skipped, DES disabled\n"
820         if ($no_des && $tnam =~ /DES/);
821     return "$tnam: skipped, DSA disabled\n"
822         if ($no_dsa && $tnam =~ / DSA/);
823
824     return "";
825 }