Update copyright year
[openssl.git] / test / recipes / 80-test_cms.t
1 #! /usr/bin/env perl
2 # Copyright 2015-2021 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     [ "enveloped content test streaming S/MIME format, X9.42 DH",
616       [ "{cmd1}", @prov, "-encrypt", "-in", $smcont,
617         "-stream", "-out", "{output}.cms",
618         "-recip", catfile($smdir, "smdh.pem"), "-aes128" ],
619       [ "{cmd2}", @prov, "-decrypt", "-recip", catfile($smdir, "smdh.pem"),
620         "-in", "{output}.cms", "-out", "{output}.txt" ],
621       \&final_compare
622     ]
623 );
624
625 my @contenttype_cms_test = (
626     [ "signed content test - check that content type is added to additional signerinfo, RSA keys",
627       [ "{cmd1}", @prov, "-sign", "-binary", "-nodetach", "-stream", "-in", $smcont,
628         "-outform", "DER",
629         "-signer", catfile($smdir, "smrsa1.pem"), "-md", "SHA256",
630         "-out", "{output}.cms" ],
631       [ "{cmd1}", @prov, "-resign", "-binary", "-nodetach", "-in", "{output}.cms",
632         "-inform", "DER", "-outform", "DER",
633         "-signer", catfile($smdir, "smrsa2.pem"), "-md", "SHA256",
634         "-out", "{output}2.cms" ],
635       sub { my %opts = @_; contentType_matches("$opts{output}2.cms") == 2; },
636       [ "{cmd2}", @prov, "-verify", "-in", "{output}2.cms", "-inform", "DER",
637         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ]
638     ],
639 );
640
641 my @incorrect_attribute_cms_test = (
642     "bad_signtime_attr.cms",
643     "no_ct_attr.cms",
644     "no_md_attr.cms",
645     "ct_multiple_attr.cms"
646 );
647
648 # Runs a standard loop on the input array
649 sub runner_loop {
650     my %opts = ( @_ );
651     my $cnt1 = 0;
652
653     foreach (@{$opts{tests}}) {
654         $cnt1++;
655         $opts{output} = "$opts{prefix}-$cnt1";
656       SKIP: {
657           my $skip_reason = check_availability($$_[0]);
658           skip $skip_reason, 1 if $skip_reason;
659           my $ok = 1;
660           1 while unlink "$opts{output}.txt";
661
662           foreach (@$_[1..$#$_]) {
663               if (ref $_ eq 'CODE') {
664                   $ok &&= $_->(%opts);
665               } else {
666                   my @cmd = map {
667                       my $x = $_;
668                       while ($x =~ /\{([^\}]+)\}/) {
669                           $x = $`.$opts{$1}.$' if exists $opts{$1};
670                       }
671                       $x;
672                   } @$_;
673
674                   diag "CMD: openssl ", join(" ", @cmd);
675                   $ok &&= run(app(["openssl", @cmd]));
676                   $opts{input} = $opts{output};
677               }
678           }
679
680           ok($ok, $$_[0]);
681         }
682     }
683 }
684
685 sub final_compare {
686     my %opts = @_;
687
688     diag "Comparing $smcont with $opts{output}.txt";
689     return compare_text($smcont, "$opts{output}.txt") == 0;
690 }
691
692 sub zero_compare {
693     my %opts = @_;
694
695     diag "Checking for zero-length file";
696     return (-e "$opts{output}.txt" && -z "$opts{output}.txt");
697 }
698
699 subtest "CMS => PKCS#7 compatibility tests\n" => sub {
700     plan tests => scalar @smime_pkcs7_tests;
701
702     runner_loop(prefix => 'cms2pkcs7', cmd1 => 'cms', cmd2 => 'smime',
703                 tests => [ @smime_pkcs7_tests ]);
704 };
705 subtest "CMS <= PKCS#7 compatibility tests\n" => sub {
706     plan tests => scalar @smime_pkcs7_tests;
707
708     runner_loop(prefix => 'pkcs72cms', cmd1 => 'smime', cmd2 => 'cms',
709                 tests => [ @smime_pkcs7_tests ]);
710 };
711
712 subtest "CMS <=> CMS consistency tests\n" => sub {
713     plan tests => (scalar @smime_pkcs7_tests) + (scalar @smime_cms_tests);
714
715     runner_loop(prefix => 'cms2cms-1', cmd1 => 'cms', cmd2 => 'cms',
716                 tests => [ @smime_pkcs7_tests ]);
717     runner_loop(prefix => 'cms2cms-2', cmd1 => 'cms', cmd2 => 'cms',
718                 tests => [ @smime_cms_tests ]);
719 };
720
721 subtest "CMS <=> CMS consistency tests, modified key parameters\n" => sub {
722     plan tests =>
723         (scalar @smime_cms_param_tests) + (scalar @smime_cms_comp_tests);
724
725     runner_loop(prefix => 'cms2cms-mod', cmd1 => 'cms', cmd2 => 'cms',
726                 tests => [ @smime_cms_param_tests ]);
727   SKIP: {
728       skip("Zlib not supported: compression tests skipped",
729            scalar @smime_cms_comp_tests)
730           if $no_zlib;
731
732       runner_loop(prefix => 'cms2cms-comp', cmd1 => 'cms', cmd2 => 'cms',
733                   tests => [ @smime_cms_comp_tests ]);
734     }
735 };
736
737 # Returns the number of matches of a Content Type Attribute in a binary file.
738 sub contentType_matches {
739   # Read in a binary file
740   my ($in) = @_;
741   open (HEX_IN, "$in") or die("open failed for $in : $!");
742   binmode(HEX_IN);
743   local $/;
744   my $str = <HEX_IN>;
745
746   # Find ASN1 data for a Content Type Attribute (with a OID of PKCS7 data)
747   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;
748
749   close(HEX_IN);
750   return scalar(@c);
751 }
752
753 subtest "CMS Check the content type attribute is added for additional signers\n" => sub {
754     plan tests => (scalar @contenttype_cms_test);
755
756     runner_loop(prefix => 'cms2cms-added', cmd1 => 'cms', cmd2 => 'cms',
757                 tests => [ @contenttype_cms_test ]);
758 };
759
760 subtest "CMS Check that bad attributes fail when verifying signers\n" => sub {
761     plan tests =>
762         (scalar @incorrect_attribute_cms_test);
763
764     my $cnt = 0;
765     foreach my $name (@incorrect_attribute_cms_test) {
766         my $out = "incorrect-$cnt.txt";
767
768         ok(!run(app(["openssl", "cms", @prov, "-verify", "-in",
769                      catfile($datadir, $name), "-inform", "DER", "-CAfile",
770                      catfile($smdir, "smroot.pem"), "-out", $out ])),
771             $name);
772     }
773 };
774
775 subtest "CMS Decrypt message encrypted with OpenSSL 1.1.1\n" => sub {
776     plan tests => 1;
777
778     SKIP: {
779         skip "EC or DES isn't supported in this build", 1
780             if disabled("ec") || disabled("des");
781
782         my $out = "smtst.txt";
783
784         ok(run(app(["openssl", "cms", @defaultprov, "-decrypt",
785                     "-inkey", catfile($smdir, "smec3.pem"),
786                     "-in", catfile($datadir, "ciphertext_from_1_1_1.cms"),
787                     "-out", $out ]))
788            && compare_text($smcont, $out) == 0,
789            "Decrypt message from OpenSSL 1.1.1");
790     }
791 };
792
793 subtest "CAdES <=> CAdES consistency tests\n" => sub {
794     plan tests => (scalar @smime_cms_cades_tests);
795
796     runner_loop(prefix => 'cms-cades', cmd1 => 'cms', cmd2 => 'cms',
797                 tests => [ @smime_cms_cades_tests ]);
798 };
799
800 subtest "CAdES; cms incompatible arguments tests\n" => sub {
801     plan tests => (scalar @smime_cms_cades_invalid_option_tests);
802
803     foreach (@smime_cms_cades_invalid_option_tests) {
804         ok(!run(app(["openssl", "cms", @{$$_[0]} ] )));
805     }
806 };
807
808 subtest "CAdES ko tests\n" => sub {
809     plan tests => (scalar @smime_cms_cades_ko_tests);
810
811     foreach (@smime_cms_cades_ko_tests) {
812       SKIP: {
813         my $skip_reason = check_availability($$_[0]);
814         skip $skip_reason, 1 if $skip_reason;
815
816         ok(run(app(["openssl", "cms", @{$$_[1]}]))
817             && !run(app(["openssl", "cms", @{$$_[2]}])),
818             $$_[0]);
819         }
820     }
821 };
822
823 sub check_availability {
824     my $tnam = shift;
825
826     return "$tnam: skipped, EC disabled\n"
827         if ($no_ec && $tnam =~ /ECDH/);
828     return "$tnam: skipped, ECDH disabled\n"
829         if ($no_ec && $tnam =~ /ECDH/);
830     return "$tnam: skipped, EC2M disabled\n"
831         if ($no_ec2m && $tnam =~ /K-283/);
832     return "$tnam: skipped, DH disabled\n"
833         if ($no_dh && $tnam =~ /X9\.42/);
834     return "$tnam: skipped, RC2 disabled\n"
835         if ($no_rc2 && $tnam =~ /RC2/);
836     return "$tnam: skipped, DES disabled\n"
837         if ($no_des && $tnam =~ /DES/);
838     return "$tnam: skipped, DSA disabled\n"
839         if ($no_dsa && $tnam =~ / DSA/);
840
841     return "";
842 }