1# test/cms-examples.pl 2# Written by Dr Stephen N Henson (steve@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@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 56use MIME::Base64; 57 58my $badttest = 0; 59my $verbose = 1; 60 61my $cmscmd; 62my $exdir = "./"; 63my $exfile = "./rfc4134.txt"; 64 65if (-f "../apps/openssl") 66 { 67 $cmscmd = "../util/shlib_wrap.sh ../apps/openssl cms"; 68 } 69elsif (-f "..\\out32dll\\openssl.exe") 70 { 71 $cmscmd = "..\\out32dll\\openssl.exe cms"; 72 } 73elsif (-f "..\\out32\\openssl.exe") 74 { 75 $cmscmd = "..\\out32\\openssl.exe cms"; 76 } 77 78my @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 104my ( $filename, $data ); 105 106my @cleanup = ( "cms.out", "cms.err", "tmp.der", "tmp.txt" ); 107 108$data = ""; 109 110open( IN, $exfile ) || die "Can't Open RFC examples file $exfile"; 111 112while (<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 145my $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 148foreach (@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 175foreach (@cleanup) { 176 unlink $_; 177} 178 179if ($badtest) { 180 print "\n$badtest TESTS FAILED!!\n"; 181} 182else { 183 print "\n***All tests successful***\n"; 184} 185 186sub 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 202sub 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 222sub 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 239sub 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 259sub 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 292sub 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 322sub 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 346sub 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 369sub 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