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