Home | History | Annotate | Line # | Download | only in test
cms-examples.pl revision 1.1.1.1
      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 
    366