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