1183234Ssimon# test/cms-examples.pl 2183234Ssimon# Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 3183234Ssimon# project. 4183234Ssimon# 5183234Ssimon# ==================================================================== 6183234Ssimon# Copyright (c) 2008 The OpenSSL Project. All rights reserved. 7183234Ssimon# 8183234Ssimon# Redistribution and use in source and binary forms, with or without 9183234Ssimon# modification, are permitted provided that the following conditions 10183234Ssimon# are met: 11183234Ssimon# 12183234Ssimon# 1. Redistributions of source code must retain the above copyright 13183234Ssimon# notice, this list of conditions and the following disclaimer. 14183234Ssimon# 15183234Ssimon# 2. Redistributions in binary form must reproduce the above copyright 16183234Ssimon# notice, this list of conditions and the following disclaimer in 17183234Ssimon# the documentation and/or other materials provided with the 18183234Ssimon# distribution. 19183234Ssimon# 20183234Ssimon# 3. All advertising materials mentioning features or use of this 21183234Ssimon# software must display the following acknowledgment: 22183234Ssimon# "This product includes software developed by the OpenSSL Project 23183234Ssimon# for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24183234Ssimon# 25183234Ssimon# 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26183234Ssimon# endorse or promote products derived from this software without 27183234Ssimon# prior written permission. For written permission, please contact 28183234Ssimon# licensing@OpenSSL.org. 29183234Ssimon# 30183234Ssimon# 5. Products derived from this software may not be called "OpenSSL" 31183234Ssimon# nor may "OpenSSL" appear in their names without prior written 32183234Ssimon# permission of the OpenSSL Project. 33183234Ssimon# 34183234Ssimon# 6. Redistributions of any form whatsoever must retain the following 35183234Ssimon# acknowledgment: 36183234Ssimon# "This product includes software developed by the OpenSSL Project 37183234Ssimon# for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38183234Ssimon# 39183234Ssimon# THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40183234Ssimon# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41183234Ssimon# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42183234Ssimon# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43183234Ssimon# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44183234Ssimon# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45183234Ssimon# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46183234Ssimon# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47183234Ssimon# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48183234Ssimon# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49183234Ssimon# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50183234Ssimon# OF THE POSSIBILITY OF SUCH DAMAGE. 51183234Ssimon# ==================================================================== 52183234Ssimon 53183234Ssimon# Perl script to run tests against S/MIME examples in RFC4134 54183234Ssimon# Assumes RFC is in current directory and called "rfc4134.txt" 55183234Ssimon 56183234Ssimonuse MIME::Base64; 57183234Ssimon 58183234Ssimonmy $badttest = 0; 59183234Ssimonmy $verbose = 1; 60183234Ssimon 61183234Ssimonmy $cmscmd; 62183234Ssimonmy $exdir = "./"; 63183234Ssimonmy $exfile = "./rfc4134.txt"; 64183234Ssimon 65183234Ssimonif (-f "../apps/openssl") 66183234Ssimon { 67183234Ssimon $cmscmd = "../util/shlib_wrap.sh ../apps/openssl cms"; 68183234Ssimon } 69183234Ssimonelsif (-f "..\\out32dll\\openssl.exe") 70183234Ssimon { 71183234Ssimon $cmscmd = "..\\out32dll\\openssl.exe cms"; 72183234Ssimon } 73183234Ssimonelsif (-f "..\\out32\\openssl.exe") 74183234Ssimon { 75183234Ssimon $cmscmd = "..\\out32\\openssl.exe cms"; 76183234Ssimon } 77183234Ssimon 78183234Ssimonmy @test_list = ( 79183234Ssimon [ "3.1.bin" => "dataout" ], 80183234Ssimon [ "3.2.bin" => "encode, dataout" ], 81183234Ssimon [ "4.1.bin" => "encode, verifyder, cont, dss" ], 82183234Ssimon [ "4.2.bin" => "encode, verifyder, cont, rsa" ], 83183234Ssimon [ "4.3.bin" => "encode, verifyder, cont_extern, dss" ], 84183234Ssimon [ "4.4.bin" => "encode, verifyder, cont, dss" ], 85183234Ssimon [ "4.5.bin" => "verifyder, cont, rsa" ], 86183234Ssimon [ "4.6.bin" => "encode, verifyder, cont, dss" ], 87183234Ssimon [ "4.7.bin" => "encode, verifyder, cont, dss" ], 88183234Ssimon [ "4.8.eml" => "verifymime, dss" ], 89183234Ssimon [ "4.9.eml" => "verifymime, dss" ], 90183234Ssimon [ "4.10.bin" => "encode, verifyder, cont, dss" ], 91183234Ssimon [ "4.11.bin" => "encode, certsout" ], 92183234Ssimon [ "5.1.bin" => "encode, envelopeder, cont" ], 93183234Ssimon [ "5.2.bin" => "encode, envelopeder, cont" ], 94183234Ssimon [ "5.3.eml" => "envelopemime, cont" ], 95183234Ssimon [ "6.0.bin" => "encode, digest, cont" ], 96183234Ssimon [ "7.1.bin" => "encode, encrypted, cont" ], 97183234Ssimon [ "7.2.bin" => "encode, encrypted, cont" ] 98183234Ssimon); 99183234Ssimon 100183234Ssimon# Extract examples from RFC4134 text. 101183234Ssimon# Base64 decode all examples, certificates and 102183234Ssimon# private keys are converted to PEM format. 103183234Ssimon 104183234Ssimonmy ( $filename, $data ); 105183234Ssimon 106183234Ssimonmy @cleanup = ( "cms.out", "cms.err", "tmp.der", "tmp.txt" ); 107183234Ssimon 108183234Ssimon$data = ""; 109183234Ssimon 110183234Ssimonopen( IN, $exfile ) || die "Can't Open RFC examples file $exfile"; 111183234Ssimon 112183234Ssimonwhile (<IN>) { 113183234Ssimon next unless (/^\|/); 114183234Ssimon s/^\|//; 115183234Ssimon next if (/^\*/); 116183234Ssimon if (/^>(.*)$/) { 117183234Ssimon $filename = $1; 118183234Ssimon next; 119183234Ssimon } 120183234Ssimon if (/^</) { 121183234Ssimon $filename = "$exdir/$filename"; 122183234Ssimon if ( $filename =~ /\.bin$/ || $filename =~ /\.eml$/ ) { 123183234Ssimon $data = decode_base64($data); 124183234Ssimon open OUT, ">$filename"; 125183234Ssimon binmode OUT; 126183234Ssimon print OUT $data; 127183234Ssimon close OUT; 128183234Ssimon push @cleanup, $filename; 129183234Ssimon } 130183234Ssimon elsif ( $filename =~ /\.cer$/ ) { 131183234Ssimon write_pem( $filename, "CERTIFICATE", $data ); 132183234Ssimon } 133183234Ssimon elsif ( $filename =~ /\.pri$/ ) { 134183234Ssimon write_pem( $filename, "PRIVATE KEY", $data ); 135183234Ssimon } 136183234Ssimon $data = ""; 137183234Ssimon $filename = ""; 138183234Ssimon } 139183234Ssimon else { 140183234Ssimon $data .= $_; 141183234Ssimon } 142183234Ssimon 143183234Ssimon} 144183234Ssimon 145183234Ssimonmy $secretkey = 146183234Ssimon "73:7c:79:1f:25:ea:d0:e0:46:29:25:43:52:f7:dc:62:91:e5:cb:26:91:7a:da:32"; 147183234Ssimon 148183234Ssimonforeach (@test_list) { 149183234Ssimon my ( $file, $tlist ) = @$_; 150183234Ssimon print "Example file $file:\n"; 151183234Ssimon if ( $tlist =~ /encode/ ) { 152183234Ssimon run_reencode_test( $exdir, $file ); 153183234Ssimon } 154183234Ssimon if ( $tlist =~ /certsout/ ) { 155183234Ssimon run_certsout_test( $exdir, $file ); 156183234Ssimon } 157183234Ssimon if ( $tlist =~ /dataout/ ) { 158183234Ssimon run_dataout_test( $exdir, $file ); 159183234Ssimon } 160183234Ssimon if ( $tlist =~ /verify/ ) { 161183234Ssimon run_verify_test( $exdir, $tlist, $file ); 162183234Ssimon } 163183234Ssimon if ( $tlist =~ /digest/ ) { 164183234Ssimon run_digest_test( $exdir, $tlist, $file ); 165183234Ssimon } 166183234Ssimon if ( $tlist =~ /encrypted/ ) { 167183234Ssimon run_encrypted_test( $exdir, $tlist, $file, $secretkey ); 168183234Ssimon } 169183234Ssimon if ( $tlist =~ /envelope/ ) { 170183234Ssimon run_envelope_test( $exdir, $tlist, $file ); 171183234Ssimon } 172183234Ssimon 173183234Ssimon} 174183234Ssimon 175183234Ssimonforeach (@cleanup) { 176183234Ssimon unlink $_; 177183234Ssimon} 178183234Ssimon 179183234Ssimonif ($badtest) { 180183234Ssimon print "\n$badtest TESTS FAILED!!\n"; 181183234Ssimon} 182183234Ssimonelse { 183183234Ssimon print "\n***All tests successful***\n"; 184183234Ssimon} 185183234Ssimon 186183234Ssimonsub write_pem { 187183234Ssimon my ( $filename, $str, $data ) = @_; 188183234Ssimon 189183234Ssimon $filename =~ s/\.[^.]*$/.pem/; 190183234Ssimon 191183234Ssimon push @cleanup, $filename; 192183234Ssimon 193183234Ssimon open OUT, ">$filename"; 194183234Ssimon 195183234Ssimon print OUT "-----BEGIN $str-----\n"; 196183234Ssimon print OUT $data; 197183234Ssimon print OUT "-----END $str-----\n"; 198183234Ssimon 199183234Ssimon close OUT; 200183234Ssimon} 201183234Ssimon 202183234Ssimonsub run_reencode_test { 203183234Ssimon my ( $cmsdir, $tfile ) = @_; 204183234Ssimon unlink "tmp.der"; 205183234Ssimon 206183234Ssimon system( "$cmscmd -cmsout -inform DER -outform DER" 207183234Ssimon . " -in $cmsdir/$tfile -out tmp.der" ); 208183234Ssimon 209183234Ssimon if ($?) { 210183234Ssimon print "\tReencode command FAILED!!\n"; 211183234Ssimon $badtest++; 212183234Ssimon } 213183234Ssimon elsif ( !cmp_files( "$cmsdir/$tfile", "tmp.der" ) ) { 214183234Ssimon print "\tReencode FAILED!!\n"; 215183234Ssimon $badtest++; 216183234Ssimon } 217183234Ssimon else { 218183234Ssimon print "\tReencode passed\n" if $verbose; 219183234Ssimon } 220183234Ssimon} 221183234Ssimon 222183234Ssimonsub run_certsout_test { 223183234Ssimon my ( $cmsdir, $tfile ) = @_; 224183234Ssimon unlink "tmp.der"; 225183234Ssimon unlink "tmp.pem"; 226183234Ssimon 227183234Ssimon system( "$cmscmd -cmsout -inform DER -certsout tmp.pem" 228183234Ssimon . " -in $cmsdir/$tfile -out tmp.der" ); 229183234Ssimon 230183234Ssimon if ($?) { 231183234Ssimon print "\tCertificate output command FAILED!!\n"; 232183234Ssimon $badtest++; 233183234Ssimon } 234183234Ssimon else { 235183234Ssimon print "\tCertificate output passed\n" if $verbose; 236183234Ssimon } 237183234Ssimon} 238183234Ssimon 239183234Ssimonsub run_dataout_test { 240183234Ssimon my ( $cmsdir, $tfile ) = @_; 241183234Ssimon unlink "tmp.txt"; 242183234Ssimon 243183234Ssimon system( 244183234Ssimon "$cmscmd -data_out -inform DER" . " -in $cmsdir/$tfile -out tmp.txt" ); 245183234Ssimon 246183234Ssimon if ($?) { 247183234Ssimon print "\tDataout command FAILED!!\n"; 248183234Ssimon $badtest++; 249183234Ssimon } 250183234Ssimon elsif ( !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) ) { 251183234Ssimon print "\tDataout compare FAILED!!\n"; 252183234Ssimon $badtest++; 253183234Ssimon } 254183234Ssimon else { 255183234Ssimon print "\tDataout passed\n" if $verbose; 256183234Ssimon } 257183234Ssimon} 258183234Ssimon 259183234Ssimonsub run_verify_test { 260183234Ssimon my ( $cmsdir, $tlist, $tfile ) = @_; 261183234Ssimon unlink "tmp.txt"; 262183234Ssimon 263183234Ssimon $form = "DER" if $tlist =~ /verifyder/; 264183234Ssimon $form = "SMIME" if $tlist =~ /verifymime/; 265183234Ssimon $cafile = "$cmsdir/CarlDSSSelf.pem" if $tlist =~ /dss/; 266183234Ssimon $cafile = "$cmsdir/CarlRSASelf.pem" if $tlist =~ /rsa/; 267183234Ssimon 268183234Ssimon $cmd = 269183234Ssimon "$cmscmd -verify -inform $form" 270183234Ssimon . " -CAfile $cafile" 271183234Ssimon . " -in $cmsdir/$tfile -out tmp.txt"; 272183234Ssimon 273183234Ssimon $cmd .= " -content $cmsdir/ExContent.bin" if $tlist =~ /cont_extern/; 274183234Ssimon 275183234Ssimon system("$cmd 2>cms.err 1>cms.out"); 276183234Ssimon 277183234Ssimon if ($?) { 278183234Ssimon print "\tVerify command FAILED!!\n"; 279183234Ssimon $badtest++; 280183234Ssimon } 281183234Ssimon elsif ( $tlist =~ /cont/ 282183234Ssimon && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) ) 283183234Ssimon { 284183234Ssimon print "\tVerify content compare FAILED!!\n"; 285183234Ssimon $badtest++; 286183234Ssimon } 287183234Ssimon else { 288183234Ssimon print "\tVerify passed\n" if $verbose; 289183234Ssimon } 290183234Ssimon} 291183234Ssimon 292183234Ssimonsub run_envelope_test { 293183234Ssimon my ( $cmsdir, $tlist, $tfile ) = @_; 294183234Ssimon unlink "tmp.txt"; 295183234Ssimon 296183234Ssimon $form = "DER" if $tlist =~ /envelopeder/; 297183234Ssimon $form = "SMIME" if $tlist =~ /envelopemime/; 298183234Ssimon 299183234Ssimon $cmd = 300183234Ssimon "$cmscmd -decrypt -inform $form" 301183234Ssimon . " -recip $cmsdir/BobRSASignByCarl.pem" 302183234Ssimon . " -inkey $cmsdir/BobPrivRSAEncrypt.pem" 303183234Ssimon . " -in $cmsdir/$tfile -out tmp.txt"; 304183234Ssimon 305183234Ssimon system("$cmd 2>cms.err 1>cms.out"); 306183234Ssimon 307183234Ssimon if ($?) { 308183234Ssimon print "\tDecrypt command FAILED!!\n"; 309183234Ssimon $badtest++; 310183234Ssimon } 311183234Ssimon elsif ( $tlist =~ /cont/ 312183234Ssimon && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) ) 313183234Ssimon { 314183234Ssimon print "\tDecrypt content compare FAILED!!\n"; 315183234Ssimon $badtest++; 316183234Ssimon } 317183234Ssimon else { 318183234Ssimon print "\tDecrypt passed\n" if $verbose; 319183234Ssimon } 320183234Ssimon} 321183234Ssimon 322183234Ssimonsub run_digest_test { 323183234Ssimon my ( $cmsdir, $tlist, $tfile ) = @_; 324183234Ssimon unlink "tmp.txt"; 325183234Ssimon 326183234Ssimon my $cmd = 327183234Ssimon "$cmscmd -digest_verify -inform DER" . " -in $cmsdir/$tfile -out tmp.txt"; 328183234Ssimon 329183234Ssimon system("$cmd 2>cms.err 1>cms.out"); 330183234Ssimon 331183234Ssimon if ($?) { 332183234Ssimon print "\tDigest verify command FAILED!!\n"; 333183234Ssimon $badtest++; 334183234Ssimon } 335183234Ssimon elsif ( $tlist =~ /cont/ 336183234Ssimon && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) ) 337183234Ssimon { 338183234Ssimon print "\tDigest verify content compare FAILED!!\n"; 339183234Ssimon $badtest++; 340183234Ssimon } 341183234Ssimon else { 342183234Ssimon print "\tDigest verify passed\n" if $verbose; 343183234Ssimon } 344183234Ssimon} 345183234Ssimon 346183234Ssimonsub run_encrypted_test { 347183234Ssimon my ( $cmsdir, $tlist, $tfile, $key ) = @_; 348183234Ssimon unlink "tmp.txt"; 349183234Ssimon 350183234Ssimon system( "$cmscmd -EncryptedData_decrypt -inform DER" 351183234Ssimon . " -secretkey $key" 352183234Ssimon . " -in $cmsdir/$tfile -out tmp.txt" ); 353183234Ssimon 354183234Ssimon if ($?) { 355183234Ssimon print "\tEncrypted Data command FAILED!!\n"; 356183234Ssimon $badtest++; 357183234Ssimon } 358183234Ssimon elsif ( $tlist =~ /cont/ 359183234Ssimon && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) ) 360183234Ssimon { 361183234Ssimon print "\tEncrypted Data content compare FAILED!!\n"; 362183234Ssimon $badtest++; 363183234Ssimon } 364183234Ssimon else { 365183234Ssimon print "\tEncryptedData verify passed\n" if $verbose; 366183234Ssimon } 367183234Ssimon} 368183234Ssimon 369183234Ssimonsub cmp_files { 370183234Ssimon my ( $f1, $f2 ) = @_; 371183234Ssimon my ( $fp1, $fp2 ); 372183234Ssimon 373183234Ssimon my ( $rd1, $rd2 ); 374183234Ssimon 375183234Ssimon if ( !open( $fp1, "<$f1" ) ) { 376183234Ssimon print STDERR "Can't Open file $f1\n"; 377183234Ssimon return 0; 378183234Ssimon } 379183234Ssimon 380183234Ssimon if ( !open( $fp2, "<$f2" ) ) { 381183234Ssimon print STDERR "Can't Open file $f2\n"; 382183234Ssimon return 0; 383183234Ssimon } 384183234Ssimon 385183234Ssimon binmode $fp1; 386183234Ssimon binmode $fp2; 387183234Ssimon 388183234Ssimon my $ret = 0; 389183234Ssimon 390183234Ssimon for ( ; ; ) { 391183234Ssimon $n1 = sysread $fp1, $rd1, 4096; 392183234Ssimon $n2 = sysread $fp2, $rd2, 4096; 393183234Ssimon last if ( $n1 != $n2 ); 394183234Ssimon last if ( $rd1 ne $rd2 ); 395183234Ssimon 396183234Ssimon if ( $n1 == 0 ) { 397183234Ssimon $ret = 1; 398183234Ssimon last; 399183234Ssimon } 400183234Ssimon 401183234Ssimon } 402183234Ssimon 403183234Ssimon close $fp1; 404183234Ssimon close $fp2; 405183234Ssimon 406183234Ssimon return $ret; 407183234Ssimon 408183234Ssimon} 409183234Ssimon 410