db2fce650d519e13f212a35099d9401b2c260190
[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 => 7;
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     [ "signed content DER format, RSA key, CAdES-BES compatible",
255       [ "{cmd1}", "-sign", "-cades", "-in", $smcont, "-outform", "DER",
256         "-nodetach",
257         "-certfile", catfile($smdir, "smroot.pem"),
258         "-signer", catfile($smdir, "smrsa1.pem"), "-out", "{output}.cms" ],
259       [ "{cmd2}", "-verify", "-in", "{output}.cms", "-inform", "DER",
260         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
261       \&final_compare
262     ],
263
264     [ "signed content DER format, RSA key, SHA256 md, CAdES-BES compatible",
265       [ "{cmd1}", "-sign", "-cades", "-md", "sha256", "-in", $smcont,
266         "-outform", "DER", "-nodetach",
267         "-certfile", catfile($smdir, "smroot.pem"),
268         "-signer", catfile($smdir, "smrsa1.pem"), "-out", "{output}.cms" ],
269       [ "{cmd2}", "-verify", "-in", "{output}.cms", "-inform", "DER",
270         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
271       \&final_compare
272     ],
273
274     [ "enveloped content test streaming S/MIME format, DES, 3 recipients, keyid",
275       [ "{cmd1}", "-encrypt", "-in", $smcont,
276         "-stream", "-out", "{output}.cms", "-keyid",
277         catfile($smdir, "smrsa1.pem"),
278         catfile($smdir, "smrsa2.pem"),
279         catfile($smdir, "smrsa3.pem") ],
280       [ "{cmd2}", "-decrypt", "-recip", catfile($smdir, "smrsa1.pem"),
281         "-in", "{output}.cms", "-out", "{output}.txt" ],
282       \&final_compare
283     ],
284
285     [ "enveloped content test streaming PEM format, KEK",
286       [ "{cmd1}", "-encrypt", "-in", $smcont, "-outform", "PEM", "-aes128",
287         "-stream", "-out", "{output}.cms",
288         "-secretkey", "000102030405060708090A0B0C0D0E0F",
289         "-secretkeyid", "C0FEE0" ],
290       [ "{cmd2}", "-decrypt", "-in", "{output}.cms", "-out", "{output}.txt",
291         "-inform", "PEM",
292         "-secretkey", "000102030405060708090A0B0C0D0E0F",
293         "-secretkeyid", "C0FEE0" ],
294       \&final_compare
295     ],
296
297     [ "enveloped content test streaming PEM format, KEK, key only",
298       [ "{cmd1}", "-encrypt", "-in", $smcont, "-outform", "PEM", "-aes128",
299         "-stream", "-out", "{output}.cms",
300         "-secretkey", "000102030405060708090A0B0C0D0E0F",
301         "-secretkeyid", "C0FEE0" ],
302       [ "{cmd2}", "-decrypt", "-in", "{output}.cms", "-out", "{output}.txt",
303         "-inform", "PEM",
304         "-secretkey", "000102030405060708090A0B0C0D0E0F" ],
305       \&final_compare
306     ],
307
308     [ "data content test streaming PEM format",
309       [ "{cmd1}", "-data_create", "-in", $smcont, "-outform", "PEM",
310         "-nodetach", "-stream", "-out", "{output}.cms" ],
311       [ "{cmd2}", "-data_out", "-in", "{output}.cms", "-inform", "PEM",
312         "-out", "{output}.txt" ],
313       \&final_compare
314     ],
315
316     [ "encrypted content test streaming PEM format, 128 bit RC2 key",
317       [ "{cmd1}", @prov, "-EncryptedData_encrypt",
318         "-in", $smcont, "-outform", "PEM",
319         "-rc2", "-secretkey", "000102030405060708090A0B0C0D0E0F",
320         "-stream", "-out", "{output}.cms" ],
321       [ "{cmd2}", @prov, "-EncryptedData_decrypt", "-in", "{output}.cms",
322         "-inform", "PEM",
323         "-secretkey", "000102030405060708090A0B0C0D0E0F",
324         "-out", "{output}.txt" ],
325       \&final_compare
326     ],
327
328     [ "encrypted content test streaming PEM format, 40 bit RC2 key",
329       [ "{cmd1}", @prov, "-EncryptedData_encrypt",
330         "-in", $smcont, "-outform", "PEM",
331         "-rc2", "-secretkey", "0001020304",
332         "-stream", "-out", "{output}.cms" ],
333       [ "{cmd2}", @prov, "-EncryptedData_decrypt", "-in", "{output}.cms",
334         "-inform", "PEM",
335         "-secretkey", "0001020304", "-out", "{output}.txt" ],
336       \&final_compare
337     ],
338
339     [ "encrypted content test streaming PEM format, triple DES key",
340       [ "{cmd1}", "-EncryptedData_encrypt", "-in", $smcont, "-outform", "PEM",
341         "-des3", "-secretkey", "000102030405060708090A0B0C0D0E0F1011121314151617",
342         "-stream", "-out", "{output}.cms" ],
343       [ "{cmd2}", "-EncryptedData_decrypt", "-in", "{output}.cms",
344         "-inform", "PEM",
345         "-secretkey", "000102030405060708090A0B0C0D0E0F1011121314151617",
346         "-out", "{output}.txt" ],
347       \&final_compare
348     ],
349
350     [ "encrypted content test streaming PEM format, 128 bit AES key",
351       [ "{cmd1}", "-EncryptedData_encrypt", "-in", $smcont, "-outform", "PEM",
352         "-aes128", "-secretkey", "000102030405060708090A0B0C0D0E0F",
353         "-stream", "-out", "{output}.cms" ],
354       [ "{cmd2}", "-EncryptedData_decrypt", "-in", "{output}.cms",
355         "-inform", "PEM",
356         "-secretkey", "000102030405060708090A0B0C0D0E0F",
357         "-out", "{output}.txt" ],
358       \&final_compare
359     ],
360
361 );
362
363 my @smime_cms_comp_tests = (
364
365     [ "compressed content test streaming PEM format",
366       [ "{cmd1}", "-compress", "-in", $smcont, "-outform", "PEM", "-nodetach",
367         "-stream", "-out", "{output}.cms" ],
368       [ "{cmd2}", "-uncompress", "-in", "{output}.cms", "-inform", "PEM",
369         "-out", "{output}.txt" ],
370       \&final_compare
371     ]
372
373 );
374
375 my @smime_cms_param_tests = (
376     [ "signed content test streaming PEM format, RSA keys, PSS signature",
377       [ "{cmd1}", "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
378         "-signer", catfile($smdir, "smrsa1.pem"),
379         "-keyopt", "rsa_padding_mode:pss",
380         "-out", "{output}.cms" ],
381       [ "{cmd2}", "-verify", "-in", "{output}.cms", "-inform", "PEM",
382         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
383       \&final_compare
384     ],
385
386     [ "signed content test streaming PEM format, RSA keys, PSS signature, saltlen=max",
387       [ "{cmd1}", "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
388         "-signer", catfile($smdir, "smrsa1.pem"),
389         "-keyopt", "rsa_padding_mode:pss", "-keyopt", "rsa_pss_saltlen:max",
390         "-out", "{output}.cms" ],
391       [ "{cmd2}", "-verify", "-in", "{output}.cms", "-inform", "PEM",
392         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
393       \&final_compare
394     ],
395
396     [ "signed content test streaming PEM format, RSA keys, PSS signature, no attributes",
397       [ "{cmd1}", "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
398         "-noattr",
399         "-signer", catfile($smdir, "smrsa1.pem"),
400         "-keyopt", "rsa_padding_mode:pss",
401         "-out", "{output}.cms" ],
402       [ "{cmd2}", "-verify", "-in", "{output}.cms", "-inform", "PEM",
403         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
404       \&final_compare
405     ],
406
407     [ "signed content test streaming PEM format, RSA keys, PSS signature, SHA384 MGF1",
408       [ "{cmd1}", "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
409         "-signer", catfile($smdir, "smrsa1.pem"),
410         "-keyopt", "rsa_padding_mode:pss", "-keyopt", "rsa_mgf1_md:sha384",
411         "-out", "{output}.cms" ],
412       [ "{cmd2}", "-verify", "-in", "{output}.cms", "-inform", "PEM",
413         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ],
414       \&final_compare
415     ],
416
417     [ "enveloped content test streaming S/MIME format, DES, OAEP default parameters",
418       [ "{cmd1}", "-encrypt", "-in", $smcont,
419         "-stream", "-out", "{output}.cms",
420         "-recip", catfile($smdir, "smrsa1.pem"),
421         "-keyopt", "rsa_padding_mode:oaep" ],
422       [ "{cmd2}", "-decrypt", "-recip", catfile($smdir, "smrsa1.pem"),
423         "-in", "{output}.cms", "-out", "{output}.txt" ],
424       \&final_compare
425     ],
426
427     [ "enveloped content test streaming S/MIME format, DES, OAEP SHA256",
428       [ "{cmd1}", "-encrypt", "-in", $smcont,
429         "-stream", "-out", "{output}.cms",
430         "-recip", catfile($smdir, "smrsa1.pem"),
431         "-keyopt", "rsa_padding_mode:oaep",
432         "-keyopt", "rsa_oaep_md:sha256" ],
433       [ "{cmd2}", "-decrypt", "-recip", catfile($smdir, "smrsa1.pem"),
434         "-in", "{output}.cms", "-out", "{output}.txt" ],
435       \&final_compare
436     ],
437
438     [ "enveloped content test streaming S/MIME format, DES, ECDH",
439       [ "{cmd1}", "-encrypt", "-in", $smcont,
440         "-stream", "-out", "{output}.cms",
441         "-recip", catfile($smdir, "smec1.pem") ],
442       [ "{cmd2}", "-decrypt", "-recip", catfile($smdir, "smec1.pem"),
443         "-in", "{output}.cms", "-out", "{output}.txt" ],
444       \&final_compare
445     ],
446
447     [ "enveloped content test streaming S/MIME format, DES, ECDH, 2 recipients, key only used",
448       [ "{cmd1}", "-encrypt", "-in", $smcont,
449         "-stream", "-out", "{output}.cms",
450         catfile($smdir, "smec1.pem"),
451         catfile($smdir, "smec3.pem") ],
452       [ "{cmd2}", "-decrypt", "-inkey", catfile($smdir, "smec3.pem"),
453         "-in", "{output}.cms", "-out", "{output}.txt" ],
454       \&final_compare
455     ],
456
457     [ "enveloped content test streaming S/MIME format, ECDH, DES, key identifier",
458       [ "{cmd1}", "-encrypt", "-keyid", "-in", $smcont,
459         "-stream", "-out", "{output}.cms",
460         "-recip", catfile($smdir, "smec1.pem") ],
461       [ "{cmd2}", "-decrypt", "-recip", catfile($smdir, "smec1.pem"),
462         "-in", "{output}.cms", "-out", "{output}.txt" ],
463       \&final_compare
464     ],
465
466     [ "enveloped content test streaming S/MIME format, ECDH, AES128, SHA256 KDF",
467       [ "{cmd1}", "-encrypt", "-in", $smcont,
468         "-stream", "-out", "{output}.cms",
469         "-recip", catfile($smdir, "smec1.pem"), "-aes128",
470         "-keyopt", "ecdh_kdf_md:sha256" ],
471       [ "{cmd2}", "-decrypt", "-recip", catfile($smdir, "smec1.pem"),
472         "-in", "{output}.cms", "-out", "{output}.txt" ],
473       \&final_compare
474     ],
475
476     [ "enveloped content test streaming S/MIME format, ECDH, K-283, cofactor DH",
477       [ "{cmd1}", "-encrypt", "-in", $smcont,
478         "-stream", "-out", "{output}.cms",
479         "-recip", catfile($smdir, "smec2.pem"), "-aes128",
480         "-keyopt", "ecdh_kdf_md:sha256", "-keyopt", "ecdh_cofactor_mode:1" ],
481       [ "{cmd2}", "-decrypt", "-recip", catfile($smdir, "smec2.pem"),
482         "-in", "{output}.cms", "-out", "{output}.txt" ],
483       \&final_compare
484     ],
485
486     [ "enveloped content test streaming S/MIME format, X9.42 DH",
487       [ "{cmd1}", "-encrypt", "-in", $smcont,
488         "-stream", "-out", "{output}.cms",
489         "-recip", catfile($smdir, "smdh.pem"), "-aes128" ],
490       [ "{cmd2}", "-decrypt", "-recip", catfile($smdir, "smdh.pem"),
491         "-in", "{output}.cms", "-out", "{output}.txt" ],
492       \&final_compare
493     ]
494     );
495
496 my @contenttype_cms_test = (
497     [ "signed content test - check that content type is added to additional signerinfo, RSA keys",
498       [ "{cmd1}", "-sign", "-binary", "-nodetach", "-stream", "-in", $smcont,
499         "-outform", "DER",
500         "-signer", catfile($smdir, "smrsa1.pem"), "-md", "SHA256",
501         "-out", "{output}.cms" ],
502       [ "{cmd1}", "-resign", "-binary", "-nodetach", "-in", "{output}.cms",
503         "-inform", "DER", "-outform", "DER",
504         "-signer", catfile($smdir, "smrsa2.pem"), "-md", "SHA256",
505         "-out", "{output}2.cms" ],
506       sub { my %opts = @_; contentType_matches("$opts{output}2.cms") == 2; },
507       [ "{cmd2}", "-verify", "-in", "{output}2.cms", "-inform", "DER",
508         "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ]
509     ],
510 );
511
512 my @incorrect_attribute_cms_test = (
513     "bad_signtime_attr.cms",
514     "no_ct_attr.cms",
515     "no_md_attr.cms",
516     "ct_multiple_attr.cms"
517 );
518
519 # Runs a standard loop on the input array
520 sub runner_loop {
521     my %opts = ( @_ );
522     my $cnt1 = 0;
523
524     foreach (@{$opts{tests}}) {
525         $cnt1++;
526         $opts{output} = "$opts{prefix}-$cnt1";
527       SKIP: {
528           my $skip_reason = check_availability($$_[0]);
529           skip $skip_reason, 1 if $skip_reason;
530           my $ok = 1;
531           1 while unlink "$opts{output}.txt";
532
533           foreach (@$_[1..$#$_]) {
534               if (ref $_ eq 'CODE') {
535                   $ok &&= $_->(%opts);
536               } else {
537                   my @cmd = map {
538                       my $x = $_;
539                       while ($x =~ /\{([^\}]+)\}/) {
540                           $x = $`.$opts{$1}.$' if exists $opts{$1};
541                       }
542                       $x;
543                   } @$_;
544
545                   diag "CMD: openssl", join(" ", @cmd);
546                   $ok &&= run(app(["openssl", @cmd]));
547                   $opts{input} = $opts{output};
548               }
549           }
550
551           ok($ok, $$_[0]);
552         }
553     }
554 }
555
556 sub final_compare {
557     my %opts = @_;
558
559     diag "Comparing $smcont with $opts{output}.txt";
560     return compare_text($smcont, "$opts{output}.txt") == 0;
561 }
562
563 subtest "CMS => PKCS#7 compatibility tests\n" => sub {
564     plan tests => scalar @smime_pkcs7_tests;
565
566     runner_loop(prefix => 'cms2pkcs7', cmd1 => 'cms', cmd2 => 'smime',
567                 tests => [ @smime_pkcs7_tests ]);
568 };
569 subtest "CMS <= PKCS#7 compatibility tests\n" => sub {
570     plan tests => scalar @smime_pkcs7_tests;
571
572     runner_loop(prefix => 'pkcs72cms', cmd1 => 'smime', cmd2 => 'cms',
573                 tests => [ @smime_pkcs7_tests ]);
574 };
575
576 subtest "CMS <=> CMS consistency tests\n" => sub {
577     plan tests => (scalar @smime_pkcs7_tests) + (scalar @smime_cms_tests);
578
579     runner_loop(prefix => 'cms2cms-1', cmd1 => 'cms', cmd2 => 'cms',
580                 tests => [ @smime_pkcs7_tests ]);
581     runner_loop(prefix => 'cms2cms-2', cmd1 => 'cms', cmd2 => 'cms',
582                 tests => [ @smime_cms_tests ]);
583 };
584
585 subtest "CMS <=> CMS consistency tests, modified key parameters\n" => sub {
586     plan tests =>
587         (scalar @smime_cms_param_tests) + (scalar @smime_cms_comp_tests);
588
589     runner_loop(prefix => 'cms2cms-mod', cmd1 => 'cms', cmd2 => 'cms',
590                 tests => [ @smime_cms_param_tests ]);
591   SKIP: {
592       skip("Zlib not supported: compression tests skipped",
593            scalar @smime_cms_comp_tests)
594           if $no_zlib;
595
596       runner_loop(prefix => 'cms2cms-comp', cmd1 => 'cms', cmd2 => 'cms',
597                   tests => [ @smime_cms_comp_tests ]);
598     }
599 };
600
601 # Returns the number of matches of a Content Type Attribute in a binary file.
602 sub contentType_matches {
603   # Read in a binary file
604   my ($in) = @_;
605   open (HEX_IN, "$in") or die("open failed for $in : $!");
606   binmode(HEX_IN);
607   local $/;
608   my $str = <HEX_IN>;
609
610   # Find ASN1 data for a Content Type Attribute (with a OID of PKCS7 data)
611   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;
612
613   close(HEX_IN);
614   return scalar(@c);
615 }
616
617 subtest "CMS Check the content type attribute is added for additional signers\n" => sub {
618     plan tests => (scalar @contenttype_cms_test);
619
620     runner_loop(prefix => 'cms2cms-added', cmd1 => 'cms', cmd2 => 'cms',
621                 tests => [ @contenttype_cms_test ]);
622 };
623
624 subtest "CMS Check that bad attributes fail when verifying signers\n" => sub {
625     plan tests =>
626         (scalar @incorrect_attribute_cms_test);
627
628     my $cnt = 0;
629     foreach my $name (@incorrect_attribute_cms_test) {
630         my $out = "incorrect-$cnt.txt";
631
632         ok(!run(app(["openssl", "cms", "-verify", "-in",
633                      catfile($datadir, $name), "-inform", "DER", "-CAfile",
634                      catfile($smdir, "smroot.pem"), "-out", $out ])),
635             $name);
636     }
637 };
638
639 subtest "CMS Decrypt message encrypted with OpenSSL 1.1.1\n" => sub {
640     plan tests => 1;
641
642     SKIP: {
643         skip "EC or DES isn't supported in this build", 1
644             if disabled("ec") || disabled("des");
645
646         my $out = "smtst.txt";
647
648         ok(run(app(["openssl", "cms", "-decrypt",
649                     "-inkey", catfile($smdir, "smec3.pem"),
650                     "-in", catfile($datadir, "ciphertext_from_1_1_1.cms"),
651                     "-out", $out ]))
652            && compare_text($smcont, $out) == 0,
653            "Decrypt message from OpenSSL 1.1.1");
654     }
655 };
656
657 sub check_availability {
658     my $tnam = shift;
659
660     return "$tnam: skipped, EC disabled\n"
661         if ($no_ec && $tnam =~ /ECDH/);
662     return "$tnam: skipped, ECDH disabled\n"
663         if ($no_ec && $tnam =~ /ECDH/);
664     return "$tnam: skipped, EC2M disabled\n"
665         if ($no_ec2m && $tnam =~ /K-283/);
666     return "$tnam: skipped, DH disabled\n"
667         if ($no_dh && $tnam =~ /X9\.42/);
668     return "$tnam: skipped, RC2 disabled\n"
669         if ($no_rc2 && $tnam =~ /RC2/);
670     return "$tnam: skipped, DES disabled\n"
671         if ($no_des && $tnam =~ /DES/);
672     return "$tnam: skipped, DSA disabled\n"
673         if ($no_dsa && $tnam =~ / DSA/);
674
675     return "";
676 }