apps/pkcs12: print multiple PKCS#12 safeBag attribute values if present
[openssl.git] / test / cms-examples.pl
1 #! /usr/bin/env perl
2 # Copyright 2008-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 # Perl script to run tests against S/MIME examples in RFC4134
10 # Assumes RFC is in current directory and called "rfc4134.txt"
11
12 use MIME::Base64;
13
14 my $badttest = 0;
15 my $verbose  = 1;
16
17 my $cmscmd;
18 my $exdir  = "./";
19 my $exfile = "./rfc4134.txt";
20
21 if (-f "../apps/openssl")
22         {
23         $cmscmd = "../util/shlib_wrap.sh ../apps/openssl cms";
24         }
25 elsif (-f "..\\out32dll\\openssl.exe")
26         {
27         $cmscmd = "..\\out32dll\\openssl.exe cms";
28         }
29 elsif (-f "..\\out32\\openssl.exe")
30         {
31         $cmscmd = "..\\out32\\openssl.exe cms";
32         }
33
34 my @test_list = (
35     [ "3.1.bin"  => "dataout" ],
36     [ "3.2.bin"  => "encode, dataout" ],
37     [ "4.1.bin"  => "encode, verifyder, cont, dss" ],
38     [ "4.2.bin"  => "encode, verifyder, cont, rsa" ],
39     [ "4.3.bin"  => "encode, verifyder, cont_extern, dss" ],
40     [ "4.4.bin"  => "encode, verifyder, cont, dss" ],
41     [ "4.5.bin"  => "verifyder, cont, rsa" ],
42     [ "4.6.bin"  => "encode, verifyder, cont, dss" ],
43     [ "4.7.bin"  => "encode, verifyder, cont, dss" ],
44     [ "4.8.eml"  => "verifymime, dss" ],
45     [ "4.9.eml"  => "verifymime, dss" ],
46     [ "4.10.bin" => "encode, verifyder, cont, dss" ],
47     [ "4.11.bin" => "encode, certsout" ],
48     [ "5.1.bin"  => "encode, envelopeder, cont" ],
49     [ "5.2.bin"  => "encode, envelopeder, cont" ],
50     [ "5.3.eml"  => "envelopemime, cont" ],
51     [ "6.0.bin"  => "encode, digest, cont" ],
52     [ "7.1.bin"  => "encode, encrypted, cont" ],
53     [ "7.2.bin"  => "encode, encrypted, cont" ]
54 );
55
56 # Extract examples from RFC4134 text.
57 # Base64 decode all examples, certificates and
58 # private keys are converted to PEM format.
59
60 my ( $filename, $data );
61
62 my @cleanup = ( "cms.out", "cms.err", "tmp.der", "tmp.txt" );
63
64 $data = "";
65
66 open( IN, $exfile ) || die "Can't Open RFC examples file $exfile";
67
68 while (<IN>) {
69     next unless (/^\|/);
70     s/^\|//;
71     next if (/^\*/);
72     if (/^>(.*)$/) {
73         $filename = $1;
74         next;
75     }
76     if (/^</) {
77         $filename = "$exdir/$filename";
78         if ( $filename =~ /\.bin$/ || $filename =~ /\.eml$/ ) {
79             $data = decode_base64($data);
80             open OUT, ">$filename";
81             binmode OUT;
82             print OUT $data;
83             close OUT;
84             push @cleanup, $filename;
85         }
86         elsif ( $filename =~ /\.cer$/ ) {
87             write_pem( $filename, "CERTIFICATE", $data );
88         }
89         elsif ( $filename =~ /\.pri$/ ) {
90             write_pem( $filename, "PRIVATE KEY", $data );
91         }
92         $data     = "";
93         $filename = "";
94     }
95     else {
96         $data .= $_;
97     }
98
99 }
100
101 my $secretkey =
102   "73:7c:79:1f:25:ea:d0:e0:46:29:25:43:52:f7:dc:62:91:e5:cb:26:91:7a:da:32";
103
104 foreach (@test_list) {
105     my ( $file, $tlist ) = @$_;
106     print "Example file $file:\n";
107     if ( $tlist =~ /encode/ ) {
108         run_reencode_test( $exdir, $file );
109     }
110     if ( $tlist =~ /certsout/ ) {
111         run_certsout_test( $exdir, $file );
112     }
113     if ( $tlist =~ /dataout/ ) {
114         run_dataout_test( $exdir, $file );
115     }
116     if ( $tlist =~ /verify/ ) {
117         run_verify_test( $exdir, $tlist, $file );
118     }
119     if ( $tlist =~ /digest/ ) {
120         run_digest_test( $exdir, $tlist, $file );
121     }
122     if ( $tlist =~ /encrypted/ ) {
123         run_encrypted_test( $exdir, $tlist, $file, $secretkey );
124     }
125     if ( $tlist =~ /envelope/ ) {
126         run_envelope_test( $exdir, $tlist, $file );
127     }
128
129 }
130
131 foreach (@cleanup) {
132     unlink $_;
133 }
134
135 if ($badtest) {
136     print "\n$badtest TESTS FAILED!!\n";
137 }
138 else {
139     print "\n***All tests successful***\n";
140 }
141
142 sub write_pem {
143     my ( $filename, $str, $data ) = @_;
144
145     $filename =~ s/\.[^.]*$/.pem/;
146
147     push @cleanup, $filename;
148
149     open OUT, ">$filename";
150
151     print OUT "-----BEGIN $str-----\n";
152     print OUT $data;
153     print OUT "-----END $str-----\n";
154
155     close OUT;
156 }
157
158 sub run_reencode_test {
159     my ( $cmsdir, $tfile ) = @_;
160     unlink "tmp.der";
161
162     system( "$cmscmd -cmsout -inform DER -outform DER"
163           . " -in $cmsdir/$tfile -out tmp.der" );
164
165     if ($?) {
166         print "\tReencode command FAILED!!\n";
167         $badtest++;
168     }
169     elsif ( !cmp_files( "$cmsdir/$tfile", "tmp.der" ) ) {
170         print "\tReencode FAILED!!\n";
171         $badtest++;
172     }
173     else {
174         print "\tReencode passed\n" if $verbose;
175     }
176 }
177
178 sub run_certsout_test {
179     my ( $cmsdir, $tfile ) = @_;
180     unlink "tmp.der";
181     unlink "tmp.pem";
182
183     system( "$cmscmd -cmsout -inform DER -certsout tmp.pem"
184           . " -in $cmsdir/$tfile -out tmp.der" );
185
186     if ($?) {
187         print "\tCertificate output command FAILED!!\n";
188         $badtest++;
189     }
190     else {
191         print "\tCertificate output passed\n" if $verbose;
192     }
193 }
194
195 sub run_dataout_test {
196     my ( $cmsdir, $tfile ) = @_;
197     unlink "tmp.txt";
198
199     system(
200         "$cmscmd -data_out -inform DER" . " -in $cmsdir/$tfile -out tmp.txt" );
201
202     if ($?) {
203         print "\tDataout command FAILED!!\n";
204         $badtest++;
205     }
206     elsif ( !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) ) {
207         print "\tDataout compare FAILED!!\n";
208         $badtest++;
209     }
210     else {
211         print "\tDataout passed\n" if $verbose;
212     }
213 }
214
215 sub run_verify_test {
216     my ( $cmsdir, $tlist, $tfile ) = @_;
217     unlink "tmp.txt";
218
219     $form   = "DER"                     if $tlist =~ /verifyder/;
220     $form   = "SMIME"                   if $tlist =~ /verifymime/;
221     $cafile = "$cmsdir/CarlDSSSelf.pem" if $tlist =~ /dss/;
222     $cafile = "$cmsdir/CarlRSASelf.pem" if $tlist =~ /rsa/;
223
224     $cmd =
225         "$cmscmd -verify -inform $form"
226       . " -CAfile $cafile"
227       . " -in $cmsdir/$tfile -out tmp.txt";
228
229     $cmd .= " -content $cmsdir/ExContent.bin" if $tlist =~ /cont_extern/;
230
231     system("$cmd 2>cms.err 1>cms.out");
232
233     if ($?) {
234         print "\tVerify command FAILED!!\n";
235         $badtest++;
236     }
237     elsif ( $tlist =~ /cont/
238         && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) )
239     {
240         print "\tVerify content compare FAILED!!\n";
241         $badtest++;
242     }
243     else {
244         print "\tVerify passed\n" if $verbose;
245     }
246 }
247
248 sub run_envelope_test {
249     my ( $cmsdir, $tlist, $tfile ) = @_;
250     unlink "tmp.txt";
251
252     $form = "DER"   if $tlist =~ /envelopeder/;
253     $form = "SMIME" if $tlist =~ /envelopemime/;
254
255     $cmd =
256         "$cmscmd -decrypt -inform $form"
257       . " -recip $cmsdir/BobRSASignByCarl.pem"
258       . " -inkey $cmsdir/BobPrivRSAEncrypt.pem"
259       . " -in $cmsdir/$tfile -out tmp.txt";
260
261     system("$cmd 2>cms.err 1>cms.out");
262
263     if ($?) {
264         print "\tDecrypt command FAILED!!\n";
265         $badtest++;
266     }
267     elsif ( $tlist =~ /cont/
268         && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) )
269     {
270         print "\tDecrypt content compare FAILED!!\n";
271         $badtest++;
272     }
273     else {
274         print "\tDecrypt passed\n" if $verbose;
275     }
276 }
277
278 sub run_digest_test {
279     my ( $cmsdir, $tlist, $tfile ) = @_;
280     unlink "tmp.txt";
281
282     my $cmd =
283       "$cmscmd -digest_verify -inform DER" . " -in $cmsdir/$tfile -out tmp.txt";
284
285     system("$cmd 2>cms.err 1>cms.out");
286
287     if ($?) {
288         print "\tDigest verify command FAILED!!\n";
289         $badtest++;
290     }
291     elsif ( $tlist =~ /cont/
292         && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) )
293     {
294         print "\tDigest verify content compare FAILED!!\n";
295         $badtest++;
296     }
297     else {
298         print "\tDigest verify passed\n" if $verbose;
299     }
300 }
301
302 sub run_encrypted_test {
303     my ( $cmsdir, $tlist, $tfile, $key ) = @_;
304     unlink "tmp.txt";
305
306     system( "$cmscmd -EncryptedData_decrypt -inform DER"
307           . " -secretkey $key"
308           . " -in $cmsdir/$tfile -out tmp.txt" );
309
310     if ($?) {
311         print "\tEncrypted Data command FAILED!!\n";
312         $badtest++;
313     }
314     elsif ( $tlist =~ /cont/
315         && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) )
316     {
317         print "\tEncrypted Data content compare FAILED!!\n";
318         $badtest++;
319     }
320     else {
321         print "\tEncryptedData verify passed\n" if $verbose;
322     }
323 }
324
325 sub cmp_files {
326     my ( $f1, $f2 ) = @_;
327     my ( $fp1, $fp2 );
328
329     my ( $rd1, $rd2 );
330
331     if ( !open( $fp1, "<$f1" ) ) {
332         print STDERR "Can't Open file $f1\n";
333         return 0;
334     }
335
336     if ( !open( $fp2, "<$f2" ) ) {
337         print STDERR "Can't Open file $f2\n";
338         return 0;
339     }
340
341     binmode $fp1;
342     binmode $fp2;
343
344     my $ret = 0;
345
346     for ( ; ; ) {
347         $n1 = sysread $fp1, $rd1, 4096;
348         $n2 = sysread $fp2, $rd2, 4096;
349         last if ( $n1 != $n2 );
350         last if ( $rd1 ne $rd2 );
351
352         if ( $n1 == 0 ) {
353             $ret = 1;
354             last;
355         }
356
357     }
358
359     close $fp1;
360     close $fp2;
361
362     return $ret;
363
364 }
365