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