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