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