Change CMS tests to use a library context.
[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.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}", @prov, "-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, 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, KEK, key only",
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       \&final_compare
322     ],
323
324     [ "data content test streaming PEM format",
325       [ "{cmd1}", @prov, "-data_create", "-in", $smcont, "-outform", "PEM",
326         "-nodetach", "-stream", "-out", "{output}.cms" ],
327       [ "{cmd2}", @prov, "-data_out", "-in", "{output}.cms", "-inform", "PEM",
328         "-out", "{output}.txt" ],
329       \&final_compare
330     ],
331
332     [ "encrypted content test streaming PEM format, 128 bit RC2 key",
333       [ "{cmd1}", @legacyprov, "-EncryptedData_encrypt",
334         "-in", $smcont, "-outform", "PEM",
335         "-rc2", "-secretkey", "000102030405060708090A0B0C0D0E0F",
336         "-stream", "-out", "{output}.cms" ],
337       [ "{cmd2}", @legacyprov, "-EncryptedData_decrypt", "-in", "{output}.cms",
338         "-inform", "PEM",
339         "-secretkey", "000102030405060708090A0B0C0D0E0F",
340         "-out", "{output}.txt" ],
341       \&final_compare
342     ],
343
344     [ "encrypted content test streaming PEM format, 40 bit RC2 key",
345       [ "{cmd1}", @legacyprov, "-EncryptedData_encrypt",
346         "-in", $smcont, "-outform", "PEM",
347         "-rc2", "-secretkey", "0001020304",
348         "-stream", "-out", "{output}.cms" ],
349       [ "{cmd2}", @legacyprov, "-EncryptedData_decrypt", "-in", "{output}.cms",
350         "-inform", "PEM",
351         "-secretkey", "0001020304", "-out", "{output}.txt" ],
352       \&final_compare
353     ],
354
355     [ "encrypted content test streaming PEM format, triple DES key",
356       [ "{cmd1}", @prov, "-EncryptedData_encrypt", "-in", $smcont, "-outform", "PEM",
357         "-des3", "-secretkey", "000102030405060708090A0B0C0D0E0F1011121314151617",
358         "-stream", "-out", "{output}.cms" ],
359       [ "{cmd2}", @prov, "-EncryptedData_decrypt", "-in", "{output}.cms",
360         "-inform", "PEM",
361         "-secretkey", "000102030405060708090A0B0C0D0E0F1011121314151617",
362         "-out", "{output}.txt" ],
363       \&final_compare
364     ],
365
366     [ "encrypted content test streaming PEM format, 128 bit AES key",
367       [ "{cmd1}", @prov, "-EncryptedData_encrypt", "-in", $smcont, "-outform", "PEM",
368         "-aes128", "-secretkey", "000102030405060708090A0B0C0D0E0F",
369         "-stream", "-out", "{output}.cms" ],
370       [ "{cmd2}", @prov, "-EncryptedData_decrypt", "-in", "{output}.cms",
371         "-inform", "PEM",
372         "-secretkey", "000102030405060708090A0B0C0D0E0F",
373         "-out", "{output}.txt" ],
374       \&final_compare
375     ],
376
377 );
378
379 my @smime_cms_cades_tests = (
380
381     [ "signed content DER format, RSA key, CAdES-BES compatible",
382       [ "{cmd1}", @prov, "-sign", "-cades", "-in", $smcont, "-outform", "DER",
383          "-nodetach",
384         "-certfile", catfile($smdir, "smroot.pem"),
385         "-signer", catfile($smdir, "smrsa1.pem"), "-out", "{output}.cms" ],
386       [ "{cmd2}", @prov, "-verify", "-cades", "-in", "{output}.cms", "-inform", "DER",
387         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
388       \&final_compare
389     ],
390
391     [ "signed content DER format, RSA key, SHA256 md, CAdES-BES compatible",
392       [ "{cmd1}", @prov, "-sign", "-cades", "-md", "sha256", "-in", $smcont, "-outform",
393         "DER", "-nodetach", "-certfile", catfile($smdir, "smroot.pem"),
394         "-signer", catfile($smdir, "smrsa1.pem"), "-out", "{output}.cms" ],
395       [ "{cmd2}", @prov, "-verify", "-cades", "-in", "{output}.cms", "-inform", "DER",
396         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
397       \&final_compare
398     ],
399
400     [ "signed content DER format, RSA key, SHA512 md, CAdES-BES compatible",
401       [ "{cmd1}", @prov, "-sign", "-cades", "-md", "sha512", "-in", $smcont, "-outform",
402         "DER", "-nodetach", "-certfile", catfile($smdir, "smroot.pem"),
403         "-signer", catfile($smdir, "smrsa1.pem"), "-out", "{output}.cms" ],
404       [ "{cmd2}", @prov, "-verify", "-cades", "-in", "{output}.cms", "-inform", "DER",
405         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
406       \&final_compare
407     ],
408
409     [ "signed content DER format, RSA key, SHA256 md, CAdES-BES compatible",
410       [ "{cmd1}", @prov, "-sign", "-cades", "-binary",  "-nodetach", "-nosmimecap", "-md", "sha256",
411         "-in", $smcont, "-outform", "DER", 
412         "-certfile", catfile($smdir, "smroot.pem"),
413         "-signer", catfile($smdir, "smrsa1.pem"),
414         "-outform", "DER", "-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     [ "resigned 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       [ "{cmd1}", @prov, "-resign", "-cades", "-binary", "-nodetach", "-nosmimecap", "-md", "sha256",
427         "-inform", "DER", "-in", "{output}.cms",
428         "-certfile", catfile($smdir, "smroot.pem"),
429         "-signer", catfile($smdir, "smrsa2.pem"),
430         "-outform", "DER", "-out", "{output}2.cms" ],
431
432       [ "{cmd2}", @prov, "-verify", "-cades", "-in", "{output}2.cms", "-inform", "DER",
433         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
434       \&final_compare
435     ],
436 );
437
438 my @smime_cms_cades_ko_tests = (
439     [ "signed content DER format, RSA key, but verified as CAdES-BES compatible",
440       [ @prov, "-sign", "-in", $smcont, "-outform", "DER", "-nodetach",
441         "-certfile", catfile($smdir, "smroot.pem"),
442         "-signer", catfile($smdir, "smrsa1.pem"), "-out", "{output}.cms" ],
443       [ @prov, "-verify", "-cades", "-in", "{output}.cms", "-inform", "DER",
444         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
445       \&final_compare
446     ]
447 );
448
449 # cades options test - check that some combinations are rejected
450 my @smime_cms_cades_invalid_option_tests = (
451     [
452         [ "-cades", "-noattr" ],
453     ],[
454         [ "-verify", "-cades", "-noattr" ],
455     ],[
456         [ "-verify", "-cades", "-noverify" ],
457     ],
458 );
459
460 my @smime_cms_comp_tests = (
461
462     [ "compressed content test streaming PEM format",
463       [ "{cmd1}", @prov, "-compress", "-in", $smcont, "-outform", "PEM", "-nodetach",
464         "-stream", "-out", "{output}.cms" ],
465       [ "{cmd2}", @prov, "-uncompress", "-in", "{output}.cms", "-inform", "PEM",
466         "-out", "{output}.txt" ],
467       \&final_compare
468     ]
469
470 );
471
472 my @smime_cms_param_tests = (
473     [ "signed content test streaming PEM format, RSA keys, PSS signature",
474       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
475         "-signer", catfile($smdir, "smrsa1.pem"),
476         "-keyopt", "rsa_padding_mode:pss",
477         "-out", "{output}.cms" ],
478       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "PEM",
479         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
480       \&final_compare
481     ],
482
483     [ "signed content test streaming PEM format, RSA keys, PSS signature, saltlen=max",
484       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
485         "-signer", catfile($smdir, "smrsa1.pem"),
486         "-keyopt", "rsa_padding_mode:pss", "-keyopt", "rsa_pss_saltlen:max",
487         "-out", "{output}.cms" ],
488       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "PEM",
489         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
490       \&final_compare
491     ],
492
493     [ "signed content test streaming PEM format, RSA keys, PSS signature, no attributes",
494       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
495         "-noattr",
496         "-signer", catfile($smdir, "smrsa1.pem"),
497         "-keyopt", "rsa_padding_mode:pss",
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, SHA384 MGF1",
505       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
506         "-signer", catfile($smdir, "smrsa1.pem"),
507         "-keyopt", "rsa_padding_mode:pss", "-keyopt", "rsa_mgf1_md:sha384",
508         "-out", "{output}.cms" ],
509       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "PEM",
510         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
511       \&final_compare
512     ],
513
514     [ "enveloped content test streaming S/MIME format, DES, OAEP default parameters",
515       [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
516         "-stream", "-out", "{output}.cms",
517         "-recip", catfile($smdir, "smrsa1.pem"),
518         "-keyopt", "rsa_padding_mode:oaep" ],
519       [ "{cmd2}", @defaultprov, "-decrypt", "-recip", catfile($smdir, "smrsa1.pem"),
520         "-in", "{output}.cms", "-out", "{output}.txt" ],
521       \&final_compare
522     ],
523
524     [ "enveloped content test streaming S/MIME format, DES, OAEP SHA256",
525       [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
526         "-stream", "-out", "{output}.cms",
527         "-recip", catfile($smdir, "smrsa1.pem"),
528         "-keyopt", "rsa_padding_mode:oaep",
529         "-keyopt", "rsa_oaep_md:sha256" ],
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, ECDH",
536       [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
537         "-stream", "-out", "{output}.cms",
538         "-recip", catfile($smdir, "smec1.pem") ],
539       [ "{cmd2}", @defaultprov, "-decrypt", "-recip", catfile($smdir, "smec1.pem"),
540         "-in", "{output}.cms", "-out", "{output}.txt" ],
541       \&final_compare
542     ],
543
544     [ "enveloped content test streaming S/MIME format, DES, ECDH, 2 recipients, key only used",
545       [ "{cmd1}", @defaultprov, "-encrypt", "-in", $smcont,
546         "-stream", "-out", "{output}.cms",
547         catfile($smdir, "smec1.pem"),
548         catfile($smdir, "smec3.pem") ],
549       [ "{cmd2}", @defaultprov, "-decrypt", "-inkey", catfile($smdir, "smec3.pem"),
550         "-in", "{output}.cms", "-out", "{output}.txt" ],
551       \&final_compare
552     ],
553
554     [ "enveloped content test streaming S/MIME format, ECDH, DES, key identifier",
555       [ "{cmd1}", @defaultprov, "-encrypt", "-keyid", "-in", $smcont,
556         "-stream", "-out", "{output}.cms",
557         "-recip", catfile($smdir, "smec1.pem") ],
558       [ "{cmd2}", @defaultprov, "-decrypt", "-recip", catfile($smdir, "smec1.pem"),
559         "-in", "{output}.cms", "-out", "{output}.txt" ],
560       \&final_compare
561     ],
562
563     [ "enveloped content test streaming S/MIME format, ECDH, AES128, SHA256 KDF",
564       [ "{cmd1}", @prov, "-encrypt", "-in", $smcont,
565         "-stream", "-out", "{output}.cms",
566         "-recip", catfile($smdir, "smec1.pem"), "-aes128",
567         "-keyopt", "ecdh_kdf_md:sha256" ],
568       [ "{cmd2}", @prov, "-decrypt", "-recip", catfile($smdir, "smec1.pem"),
569         "-in", "{output}.cms", "-out", "{output}.txt" ],
570       \&final_compare
571     ],
572
573     [ "enveloped content test streaming S/MIME format, ECDH, K-283, cofactor DH",
574       [ "{cmd1}", @prov, "-encrypt", "-in", $smcont,
575         "-stream", "-out", "{output}.cms",
576         "-recip", catfile($smdir, "smec2.pem"), "-aes128",
577         "-keyopt", "ecdh_kdf_md:sha256", "-keyopt", "ecdh_cofactor_mode:1" ],
578       [ "{cmd2}", @prov, "-decrypt", "-recip", catfile($smdir, "smec2.pem"),
579         "-in", "{output}.cms", "-out", "{output}.txt" ],
580       \&final_compare
581     ]
582
583     # TODO(3.0) Add this test back in when "dhpublicnumber" is supported
584     # in the keymanger.
585     #[ "enveloped content test streaming S/MIME format, X9.42 DH",
586     #  [ "{cmd1}", @prov, "-encrypt", "-in", $smcont,
587     #    "-stream", "-out", "{output}.cms",
588     #    "-recip", catfile($smdir, "smdh.pem"), "-aes128" ],
589     #  [ "{cmd2}", "-decrypt", "-recip", catfile($smdir, "smdh.pem"),
590     #    "-in", "{output}.cms", "-out", "{output}.txt" ],
591     #  \&final_compare
592     #]
593 );
594
595 my @contenttype_cms_test = (
596     [ "signed content test - check that content type is added to additional signerinfo, RSA keys",
597       [ "{cmd1}", @prov, "-sign", "-binary", "-nodetach", "-stream", "-in", $smcont,
598         "-outform", "DER",
599         "-signer", catfile($smdir, "smrsa1.pem"), "-md", "SHA256",
600         "-out", "{output}.cms" ],
601       [ "{cmd1}", @prov, "-resign", "-binary", "-nodetach", "-in", "{output}.cms",
602         "-inform", "DER", "-outform", "DER",
603         "-signer", catfile($smdir, "smrsa2.pem"), "-md", "SHA256",
604         "-out", "{output}2.cms" ],
605       sub { my %opts = @_; contentType_matches("$opts{output}2.cms") == 2; },
606       [ "{cmd2}", @prov, "-verify", "-in", "{output}2.cms", "-inform", "DER",
607         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ]
608     ],
609 );
610
611 my @incorrect_attribute_cms_test = (
612     "bad_signtime_attr.cms",
613     "no_ct_attr.cms",
614     "no_md_attr.cms",
615     "ct_multiple_attr.cms"
616 );
617
618 # Runs a standard loop on the input array
619 sub runner_loop {
620     my %opts = ( @_ );
621     my $cnt1 = 0;
622
623     foreach (@{$opts{tests}}) {
624         $cnt1++;
625         $opts{output} = "$opts{prefix}-$cnt1";
626       SKIP: {
627           my $skip_reason = check_availability($$_[0]);
628           skip $skip_reason, 1 if $skip_reason;
629           my $ok = 1;
630           1 while unlink "$opts{output}.txt";
631
632           foreach (@$_[1..$#$_]) {
633               if (ref $_ eq 'CODE') {
634                   $ok &&= $_->(%opts);
635               } else {
636                   my @cmd = map {
637                       my $x = $_;
638                       while ($x =~ /\{([^\}]+)\}/) {
639                           $x = $`.$opts{$1}.$' if exists $opts{$1};
640                       }
641                       $x;
642                   } @$_;
643
644                   diag "CMD: openssl ", join(" ", @cmd);
645                   $ok &&= run(app(["openssl", @cmd]));
646                   $opts{input} = $opts{output};
647               }
648           }
649
650           ok($ok, $$_[0]);
651         }
652     }
653 }
654
655 sub final_compare {
656     my %opts = @_;
657
658     diag "Comparing $smcont with $opts{output}.txt";
659     return compare_text($smcont, "$opts{output}.txt") == 0;
660 }
661
662 subtest "CMS => PKCS#7 compatibility tests\n" => sub {
663     plan tests => scalar @smime_pkcs7_tests;
664
665     runner_loop(prefix => 'cms2pkcs7', cmd1 => 'cms', cmd2 => 'smime',
666                 tests => [ @smime_pkcs7_tests ]);
667 };
668 subtest "CMS <= PKCS#7 compatibility tests\n" => sub {
669     plan tests => scalar @smime_pkcs7_tests;
670
671     runner_loop(prefix => 'pkcs72cms', cmd1 => 'smime', cmd2 => 'cms',
672                 tests => [ @smime_pkcs7_tests ]);
673 };
674
675 subtest "CMS <=> CMS consistency tests\n" => sub {
676     plan tests => (scalar @smime_pkcs7_tests) + (scalar @smime_cms_tests);
677
678     runner_loop(prefix => 'cms2cms-1', cmd1 => 'cms', cmd2 => 'cms',
679                 tests => [ @smime_pkcs7_tests ]);
680     runner_loop(prefix => 'cms2cms-2', cmd1 => 'cms', cmd2 => 'cms',
681                 tests => [ @smime_cms_tests ]);
682 };
683
684 subtest "CMS <=> CMS consistency tests, modified key parameters\n" => sub {
685     plan tests =>
686         (scalar @smime_cms_param_tests) + (scalar @smime_cms_comp_tests);
687
688     runner_loop(prefix => 'cms2cms-mod', cmd1 => 'cms', cmd2 => 'cms',
689                 tests => [ @smime_cms_param_tests ]);
690   SKIP: {
691       skip("Zlib not supported: compression tests skipped",
692            scalar @smime_cms_comp_tests)
693           if $no_zlib;
694
695       runner_loop(prefix => 'cms2cms-comp', cmd1 => 'cms', cmd2 => 'cms',
696                   tests => [ @smime_cms_comp_tests ]);
697     }
698 };
699
700 # Returns the number of matches of a Content Type Attribute in a binary file.
701 sub contentType_matches {
702   # Read in a binary file
703   my ($in) = @_;
704   open (HEX_IN, "$in") or die("open failed for $in : $!");
705   binmode(HEX_IN);
706   local $/;
707   my $str = <HEX_IN>;
708
709   # Find ASN1 data for a Content Type Attribute (with a OID of PKCS7 data)
710   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;
711
712   close(HEX_IN);
713   return scalar(@c);
714 }
715
716 subtest "CMS Check the content type attribute is added for additional signers\n" => sub {
717     plan tests => (scalar @contenttype_cms_test);
718
719     runner_loop(prefix => 'cms2cms-added', cmd1 => 'cms', cmd2 => 'cms',
720                 tests => [ @contenttype_cms_test ]);
721 };
722
723 subtest "CMS Check that bad attributes fail when verifying signers\n" => sub {
724     plan tests =>
725         (scalar @incorrect_attribute_cms_test);
726
727     my $cnt = 0;
728     foreach my $name (@incorrect_attribute_cms_test) {
729         my $out = "incorrect-$cnt.txt";
730
731         ok(!run(app(["openssl", "cms", @prov, "-verify", "-in",
732                      catfile($datadir, $name), "-inform", "DER", "-CAfile",
733                      catfile($smdir, "smroot.pem"), "-out", $out ])),
734             $name);
735     }
736 };
737
738 subtest "CMS Decrypt message encrypted with OpenSSL 1.1.1\n" => sub {
739     plan tests => 1;
740
741     SKIP: {
742         skip "EC or DES isn't supported in this build", 1
743             if disabled("ec") || disabled("des");
744
745         my $out = "smtst.txt";
746
747         ok(run(app(["openssl", "cms", @defaultprov, "-decrypt",
748                     "-inkey", catfile($smdir, "smec3.pem"),
749                     "-in", catfile($datadir, "ciphertext_from_1_1_1.cms"),
750                     "-out", $out ]))
751            && compare_text($smcont, $out) == 0,
752            "Decrypt message from OpenSSL 1.1.1");
753     }
754 };
755
756 subtest "CAdES <=> CAdES consistency tests\n" => sub {
757     plan tests => (scalar @smime_cms_cades_tests);
758
759     runner_loop(prefix => 'cms-cades', cmd1 => 'cms', cmd2 => 'cms',
760                 tests => [ @smime_cms_cades_tests ]);
761 };
762
763 subtest "CAdES; cms incompatible arguments tests\n" => sub {
764     plan tests => (scalar @smime_cms_cades_invalid_option_tests);
765
766     foreach (@smime_cms_cades_invalid_option_tests) {
767         ok(!run(app(["openssl", "cms", @{$$_[0]} ] )));
768     }
769 };
770
771 subtest "CAdES ko tests\n" => sub {
772     plan tests => (scalar @smime_cms_cades_ko_tests);
773
774     foreach (@smime_cms_cades_ko_tests) {
775       SKIP: {
776         my $skip_reason = check_availability($$_[0]);
777         skip $skip_reason, 1 if $skip_reason;
778
779         ok(run(app(["openssl", "cms", @{$$_[1]}]))
780             && !run(app(["openssl", "cms", @{$$_[2]}])),
781             $$_[0]);
782         }
783     }
784 };
785
786 sub check_availability {
787     my $tnam = shift;
788
789     return "$tnam: skipped, EC disabled\n"
790         if ($no_ec && $tnam =~ /ECDH/);
791     return "$tnam: skipped, ECDH disabled\n"
792         if ($no_ec && $tnam =~ /ECDH/);
793     return "$tnam: skipped, EC2M disabled\n"
794         if ($no_ec2m && $tnam =~ /K-283/);
795     return "$tnam: skipped, DH disabled\n"
796         if ($no_dh && $tnam =~ /X9\.42/);
797     return "$tnam: skipped, RC2 disabled\n"
798         if ($no_rc2 && $tnam =~ /RC2/);
799     return "$tnam: skipped, DES disabled\n"
800         if ($no_des && $tnam =~ /DES/);
801     return "$tnam: skipped, DSA disabled\n"
802         if ($no_dsa && $tnam =~ / DSA/);
803
804     return "";
805 }