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