Home | History | Annotate | Line # | Download | only in test
cms-examples.pl revision 1.1.1.1
      1 # test/cms-examples.pl
      2 # Written by Dr Stephen N Henson (steve (at] openssl.org) for the OpenSSL
      3 # project.
      4 #
      5 # ====================================================================
      6 # Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
      7 #
      8 # Redistribution and use in source and binary forms, with or without
      9 # modification, are permitted provided that the following conditions
     10 # are met:
     11 #
     12 # 1. Redistributions of source code must retain the above copyright
     13 #    notice, this list of conditions and the following disclaimer.
     14 #
     15 # 2. Redistributions in binary form must reproduce the above copyright
     16 #    notice, this list of conditions and the following disclaimer in
     17 #    the documentation and/or other materials provided with the
     18 #    distribution.
     19 #
     20 # 3. All advertising materials mentioning features or use of this
     21 #    software must display the following acknowledgment:
     22 #    "This product includes software developed by the OpenSSL Project
     23 #    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
     24 #
     25 # 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
     26 #    endorse or promote products derived from this software without
     27 #    prior written permission. For written permission, please contact
     28 #    licensing (at] OpenSSL.org.
     29 #
     30 # 5. Products derived from this software may not be called "OpenSSL"
     31 #    nor may "OpenSSL" appear in their names without prior written
     32 #    permission of the OpenSSL Project.
     33 #
     34 # 6. Redistributions of any form whatsoever must retain the following
     35 #    acknowledgment:
     36 #    "This product includes software developed by the OpenSSL Project
     37 #    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
     38 #
     39 # THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
     40 # EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     41 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     42 # PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
     43 # ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     44 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     45 # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     46 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     47 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     48 # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     49 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     50 # OF THE POSSIBILITY OF SUCH DAMAGE.
     51 # ====================================================================
     52 
     53 # Perl script to run tests against S/MIME examples in RFC4134
     54 # Assumes RFC is in current directory and called "rfc4134.txt"
     55 
     56 use MIME::Base64;
     57 
     58 my $badttest = 0;
     59 my $verbose  = 1;
     60 
     61 my $cmscmd;
     62 my $exdir  = "./";
     63 my $exfile = "./rfc4134.txt";
     64 
     65 if (-f "../apps/openssl")
     66 	{
     67 	$cmscmd = "../util/shlib_wrap.sh ../apps/openssl cms";
     68 	}
     69 elsif (-f "..\\out32dll\\openssl.exe")
     70 	{
     71 	$cmscmd = "..\\out32dll\\openssl.exe cms";
     72 	}
     73 elsif (-f "..\\out32\\openssl.exe")
     74 	{
     75 	$cmscmd = "..\\out32\\openssl.exe cms";
     76 	}
     77 
     78 my @test_list = (
     79     [ "3.1.bin"  => "dataout" ],
     80     [ "3.2.bin"  => "encode, dataout" ],
     81     [ "4.1.bin"  => "encode, verifyder, cont, dss" ],
     82     [ "4.2.bin"  => "encode, verifyder, cont, rsa" ],
     83     [ "4.3.bin"  => "encode, verifyder, cont_extern, dss" ],
     84     [ "4.4.bin"  => "encode, verifyder, cont, dss" ],
     85     [ "4.5.bin"  => "verifyder, cont, rsa" ],
     86     [ "4.6.bin"  => "encode, verifyder, cont, dss" ],
     87     [ "4.7.bin"  => "encode, verifyder, cont, dss" ],
     88     [ "4.8.eml"  => "verifymime, dss" ],
     89     [ "4.9.eml"  => "verifymime, dss" ],
     90     [ "4.10.bin" => "encode, verifyder, cont, dss" ],
     91     [ "4.11.bin" => "encode, certsout" ],
     92     [ "5.1.bin"  => "encode, envelopeder, cont" ],
     93     [ "5.2.bin"  => "encode, envelopeder, cont" ],
     94     [ "5.3.eml"  => "envelopemime, cont" ],
     95     [ "6.0.bin"  => "encode, digest, cont" ],
     96     [ "7.1.bin"  => "encode, encrypted, cont" ],
     97     [ "7.2.bin"  => "encode, encrypted, cont" ]
     98 );
     99 
    100 # Extract examples from RFC4134 text.
    101 # Base64 decode all examples, certificates and
    102 # private keys are converted to PEM format.
    103 
    104 my ( $filename, $data );
    105 
    106 my @cleanup = ( "cms.out", "cms.err", "tmp.der", "tmp.txt" );
    107 
    108 $data = "";
    109 
    110 open( IN, $exfile ) || die "Can't Open RFC examples file $exfile";
    111 
    112 while (<IN>) {
    113     next unless (/^\|/);
    114     s/^\|//;
    115     next if (/^\*/);
    116     if (/^>(.*)$/) {
    117         $filename = $1;
    118         next;
    119     }
    120     if (/^</) {
    121         $filename = "$exdir/$filename";
    122         if ( $filename =~ /\.bin$/ || $filename =~ /\.eml$/ ) {
    123             $data = decode_base64($data);
    124             open OUT, ">$filename";
    125             binmode OUT;
    126             print OUT $data;
    127             close OUT;
    128             push @cleanup, $filename;
    129         }
    130         elsif ( $filename =~ /\.cer$/ ) {
    131             write_pem( $filename, "CERTIFICATE", $data );
    132         }
    133         elsif ( $filename =~ /\.pri$/ ) {
    134             write_pem( $filename, "PRIVATE KEY", $data );
    135         }
    136         $data     = "";
    137         $filename = "";
    138     }
    139     else {
    140         $data .= $_;
    141     }
    142 
    143 }
    144 
    145 my $secretkey =
    146   "73:7c:79:1f:25:ea:d0:e0:46:29:25:43:52:f7:dc:62:91:e5:cb:26:91:7a:da:32";
    147 
    148 foreach (@test_list) {
    149     my ( $file, $tlist ) = @$_;
    150     print "Example file $file:\n";
    151     if ( $tlist =~ /encode/ ) {
    152         run_reencode_test( $exdir, $file );
    153     }
    154     if ( $tlist =~ /certsout/ ) {
    155         run_certsout_test( $exdir, $file );
    156     }
    157     if ( $tlist =~ /dataout/ ) {
    158         run_dataout_test( $exdir, $file );
    159     }
    160     if ( $tlist =~ /verify/ ) {
    161         run_verify_test( $exdir, $tlist, $file );
    162     }
    163     if ( $tlist =~ /digest/ ) {
    164         run_digest_test( $exdir, $tlist, $file );
    165     }
    166     if ( $tlist =~ /encrypted/ ) {
    167         run_encrypted_test( $exdir, $tlist, $file, $secretkey );
    168     }
    169     if ( $tlist =~ /envelope/ ) {
    170         run_envelope_test( $exdir, $tlist, $file );
    171     }
    172 
    173 }
    174 
    175 foreach (@cleanup) {
    176     unlink $_;
    177 }
    178 
    179 if ($badtest) {
    180     print "\n$badtest TESTS FAILED!!\n";
    181 }
    182 else {
    183     print "\n***All tests successful***\n";
    184 }
    185 
    186 sub write_pem {
    187     my ( $filename, $str, $data ) = @_;
    188 
    189     $filename =~ s/\.[^.]*$/.pem/;
    190 
    191     push @cleanup, $filename;
    192 
    193     open OUT, ">$filename";
    194 
    195     print OUT "-----BEGIN $str-----\n";
    196     print OUT $data;
    197     print OUT "-----END $str-----\n";
    198 
    199     close OUT;
    200 }
    201 
    202 sub run_reencode_test {
    203     my ( $cmsdir, $tfile ) = @_;
    204     unlink "tmp.der";
    205 
    206     system( "$cmscmd -cmsout -inform DER -outform DER"
    207           . " -in $cmsdir/$tfile -out tmp.der" );
    208 
    209     if ($?) {
    210         print "\tReencode command FAILED!!\n";
    211         $badtest++;
    212     }
    213     elsif ( !cmp_files( "$cmsdir/$tfile", "tmp.der" ) ) {
    214         print "\tReencode FAILED!!\n";
    215         $badtest++;
    216     }
    217     else {
    218         print "\tReencode passed\n" if $verbose;
    219     }
    220 }
    221 
    222 sub run_certsout_test {
    223     my ( $cmsdir, $tfile ) = @_;
    224     unlink "tmp.der";
    225     unlink "tmp.pem";
    226 
    227     system( "$cmscmd -cmsout -inform DER -certsout tmp.pem"
    228           . " -in $cmsdir/$tfile -out tmp.der" );
    229 
    230     if ($?) {
    231         print "\tCertificate output command FAILED!!\n";
    232         $badtest++;
    233     }
    234     else {
    235         print "\tCertificate output passed\n" if $verbose;
    236     }
    237 }
    238 
    239 sub run_dataout_test {
    240     my ( $cmsdir, $tfile ) = @_;
    241     unlink "tmp.txt";
    242 
    243     system(
    244         "$cmscmd -data_out -inform DER" . " -in $cmsdir/$tfile -out tmp.txt" );
    245 
    246     if ($?) {
    247         print "\tDataout command FAILED!!\n";
    248         $badtest++;
    249     }
    250     elsif ( !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) ) {
    251         print "\tDataout compare FAILED!!\n";
    252         $badtest++;
    253     }
    254     else {
    255         print "\tDataout passed\n" if $verbose;
    256     }
    257 }
    258 
    259 sub run_verify_test {
    260     my ( $cmsdir, $tlist, $tfile ) = @_;
    261     unlink "tmp.txt";
    262 
    263     $form   = "DER"                     if $tlist =~ /verifyder/;
    264     $form   = "SMIME"                   if $tlist =~ /verifymime/;
    265     $cafile = "$cmsdir/CarlDSSSelf.pem" if $tlist =~ /dss/;
    266     $cafile = "$cmsdir/CarlRSASelf.pem" if $tlist =~ /rsa/;
    267 
    268     $cmd =
    269         "$cmscmd -verify -inform $form"
    270       . " -CAfile $cafile"
    271       . " -in $cmsdir/$tfile -out tmp.txt";
    272 
    273     $cmd .= " -content $cmsdir/ExContent.bin" if $tlist =~ /cont_extern/;
    274 
    275     system("$cmd 2>cms.err 1>cms.out");
    276 
    277     if ($?) {
    278         print "\tVerify command FAILED!!\n";
    279         $badtest++;
    280     }
    281     elsif ( $tlist =~ /cont/
    282         && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) )
    283     {
    284         print "\tVerify content compare FAILED!!\n";
    285         $badtest++;
    286     }
    287     else {
    288         print "\tVerify passed\n" if $verbose;
    289     }
    290 }
    291 
    292 sub run_envelope_test {
    293     my ( $cmsdir, $tlist, $tfile ) = @_;
    294     unlink "tmp.txt";
    295 
    296     $form = "DER"   if $tlist =~ /envelopeder/;
    297     $form = "SMIME" if $tlist =~ /envelopemime/;
    298 
    299     $cmd =
    300         "$cmscmd -decrypt -inform $form"
    301       . " -recip $cmsdir/BobRSASignByCarl.pem"
    302       . " -inkey $cmsdir/BobPrivRSAEncrypt.pem"
    303       . " -in $cmsdir/$tfile -out tmp.txt";
    304 
    305     system("$cmd 2>cms.err 1>cms.out");
    306 
    307     if ($?) {
    308         print "\tDecrypt command FAILED!!\n";
    309         $badtest++;
    310     }
    311     elsif ( $tlist =~ /cont/
    312         && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) )
    313     {
    314         print "\tDecrypt content compare FAILED!!\n";
    315         $badtest++;
    316     }
    317     else {
    318         print "\tDecrypt passed\n" if $verbose;
    319     }
    320 }
    321 
    322 sub run_digest_test {
    323     my ( $cmsdir, $tlist, $tfile ) = @_;
    324     unlink "tmp.txt";
    325 
    326     my $cmd =
    327       "$cmscmd -digest_verify -inform DER" . " -in $cmsdir/$tfile -out tmp.txt";
    328 
    329     system("$cmd 2>cms.err 1>cms.out");
    330 
    331     if ($?) {
    332         print "\tDigest verify command FAILED!!\n";
    333         $badtest++;
    334     }
    335     elsif ( $tlist =~ /cont/
    336         && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) )
    337     {
    338         print "\tDigest verify content compare FAILED!!\n";
    339         $badtest++;
    340     }
    341     else {
    342         print "\tDigest verify passed\n" if $verbose;
    343     }
    344 }
    345 
    346 sub run_encrypted_test {
    347     my ( $cmsdir, $tlist, $tfile, $key ) = @_;
    348     unlink "tmp.txt";
    349 
    350     system( "$cmscmd -EncryptedData_decrypt -inform DER"
    351           . " -secretkey $key"
    352           . " -in $cmsdir/$tfile -out tmp.txt" );
    353 
    354     if ($?) {
    355         print "\tEncrypted Data command FAILED!!\n";
    356         $badtest++;
    357     }
    358     elsif ( $tlist =~ /cont/
    359         && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) )
    360     {
    361         print "\tEncrypted Data content compare FAILED!!\n";
    362         $badtest++;
    363     }
    364     else {
    365         print "\tEncryptedData verify passed\n" if $verbose;
    366     }
    367 }
    368 
    369 sub cmp_files {
    370     my ( $f1, $f2 ) = @_;
    371     my ( $fp1, $fp2 );
    372 
    373     my ( $rd1, $rd2 );
    374 
    375     if ( !open( $fp1, "<$f1" ) ) {
    376         print STDERR "Can't Open file $f1\n";
    377         return 0;
    378     }
    379 
    380     if ( !open( $fp2, "<$f2" ) ) {
    381         print STDERR "Can't Open file $f2\n";
    382         return 0;
    383     }
    384 
    385     binmode $fp1;
    386     binmode $fp2;
    387 
    388     my $ret = 0;
    389 
    390     for ( ; ; ) {
    391         $n1 = sysread $fp1, $rd1, 4096;
    392         $n2 = sysread $fp2, $rd2, 4096;
    393         last if ( $n1 != $n2 );
    394         last if ( $rd1 ne $rd2 );
    395 
    396         if ( $n1 == 0 ) {
    397             $ret = 1;
    398             last;
    399         }
    400 
    401     }
    402 
    403     close $fp1;
    404     close $fp2;
    405 
    406     return $ret;
    407 
    408 }
    409 
    410