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