cms-examples.pl 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  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. # Perl script to run tests against S/MIME examples in RFC4134
  9. # Assumes RFC is in current directory and called "rfc4134.txt"
  10. use MIME::Base64;
  11. my $badttest = 0;
  12. my $verbose = 1;
  13. my $cmscmd;
  14. my $exdir = "./";
  15. my $exfile = "./rfc4134.txt";
  16. if (-f "../apps/openssl")
  17. {
  18. $cmscmd = "../util/shlib_wrap.sh ../apps/openssl cms";
  19. }
  20. elsif (-f "..\\out32dll\\openssl.exe")
  21. {
  22. $cmscmd = "..\\out32dll\\openssl.exe cms";
  23. }
  24. elsif (-f "..\\out32\\openssl.exe")
  25. {
  26. $cmscmd = "..\\out32\\openssl.exe cms";
  27. }
  28. my @test_list = (
  29. [ "3.1.bin" => "dataout" ],
  30. [ "3.2.bin" => "encode, dataout" ],
  31. [ "4.1.bin" => "encode, verifyder, cont, dss" ],
  32. [ "4.2.bin" => "encode, verifyder, cont, rsa" ],
  33. [ "4.3.bin" => "encode, verifyder, cont_extern, dss" ],
  34. [ "4.4.bin" => "encode, verifyder, cont, dss" ],
  35. [ "4.5.bin" => "verifyder, cont, rsa" ],
  36. [ "4.6.bin" => "encode, verifyder, cont, dss" ],
  37. [ "4.7.bin" => "encode, verifyder, cont, dss" ],
  38. [ "4.8.eml" => "verifymime, dss" ],
  39. [ "4.9.eml" => "verifymime, dss" ],
  40. [ "4.10.bin" => "encode, verifyder, cont, dss" ],
  41. [ "4.11.bin" => "encode, certsout" ],
  42. [ "5.1.bin" => "encode, envelopeder, cont" ],
  43. [ "5.2.bin" => "encode, envelopeder, cont" ],
  44. [ "5.3.eml" => "envelopemime, cont" ],
  45. [ "6.0.bin" => "encode, digest, cont" ],
  46. [ "7.1.bin" => "encode, encrypted, cont" ],
  47. [ "7.2.bin" => "encode, encrypted, cont" ]
  48. );
  49. # Extract examples from RFC4134 text.
  50. # Base64 decode all examples, certificates and
  51. # private keys are converted to PEM format.
  52. my ( $filename, $data );
  53. my @cleanup = ( "cms.out", "cms.err", "tmp.der", "tmp.txt" );
  54. $data = "";
  55. open( IN, $exfile ) || die "Can't Open RFC examples file $exfile";
  56. while (<IN>) {
  57. next unless (/^\|/);
  58. s/^\|//;
  59. next if (/^\*/);
  60. if (/^>(.*)$/) {
  61. $filename = $1;
  62. next;
  63. }
  64. if (/^</) {
  65. $filename = "$exdir/$filename";
  66. if ( $filename =~ /\.bin$/ || $filename =~ /\.eml$/ ) {
  67. $data = decode_base64($data);
  68. open OUT, ">$filename";
  69. binmode OUT;
  70. print OUT $data;
  71. close OUT;
  72. push @cleanup, $filename;
  73. }
  74. elsif ( $filename =~ /\.cer$/ ) {
  75. write_pem( $filename, "CERTIFICATE", $data );
  76. }
  77. elsif ( $filename =~ /\.pri$/ ) {
  78. write_pem( $filename, "PRIVATE KEY", $data );
  79. }
  80. $data = "";
  81. $filename = "";
  82. }
  83. else {
  84. $data .= $_;
  85. }
  86. }
  87. my $secretkey =
  88. "73:7c:79:1f:25:ea:d0:e0:46:29:25:43:52:f7:dc:62:91:e5:cb:26:91:7a:da:32";
  89. foreach (@test_list) {
  90. my ( $file, $tlist ) = @$_;
  91. print "Example file $file:\n";
  92. if ( $tlist =~ /encode/ ) {
  93. run_reencode_test( $exdir, $file );
  94. }
  95. if ( $tlist =~ /certsout/ ) {
  96. run_certsout_test( $exdir, $file );
  97. }
  98. if ( $tlist =~ /dataout/ ) {
  99. run_dataout_test( $exdir, $file );
  100. }
  101. if ( $tlist =~ /verify/ ) {
  102. run_verify_test( $exdir, $tlist, $file );
  103. }
  104. if ( $tlist =~ /digest/ ) {
  105. run_digest_test( $exdir, $tlist, $file );
  106. }
  107. if ( $tlist =~ /encrypted/ ) {
  108. run_encrypted_test( $exdir, $tlist, $file, $secretkey );
  109. }
  110. if ( $tlist =~ /envelope/ ) {
  111. run_envelope_test( $exdir, $tlist, $file );
  112. }
  113. }
  114. foreach (@cleanup) {
  115. unlink $_;
  116. }
  117. if ($badtest) {
  118. print "\n$badtest TESTS FAILED!!\n";
  119. }
  120. else {
  121. print "\n***All tests successful***\n";
  122. }
  123. sub write_pem {
  124. my ( $filename, $str, $data ) = @_;
  125. $filename =~ s/\.[^.]*$/.pem/;
  126. push @cleanup, $filename;
  127. open OUT, ">$filename";
  128. print OUT "-----BEGIN $str-----\n";
  129. print OUT $data;
  130. print OUT "-----END $str-----\n";
  131. close OUT;
  132. }
  133. sub run_reencode_test {
  134. my ( $cmsdir, $tfile ) = @_;
  135. unlink "tmp.der";
  136. system( "$cmscmd -cmsout -inform DER -outform DER"
  137. . " -in $cmsdir/$tfile -out tmp.der" );
  138. if ($?) {
  139. print "\tReencode command FAILED!!\n";
  140. $badtest++;
  141. }
  142. elsif ( !cmp_files( "$cmsdir/$tfile", "tmp.der" ) ) {
  143. print "\tReencode FAILED!!\n";
  144. $badtest++;
  145. }
  146. else {
  147. print "\tReencode passed\n" if $verbose;
  148. }
  149. }
  150. sub run_certsout_test {
  151. my ( $cmsdir, $tfile ) = @_;
  152. unlink "tmp.der";
  153. unlink "tmp.pem";
  154. system( "$cmscmd -cmsout -inform DER -certsout tmp.pem"
  155. . " -in $cmsdir/$tfile -out tmp.der" );
  156. if ($?) {
  157. print "\tCertificate output command FAILED!!\n";
  158. $badtest++;
  159. }
  160. else {
  161. print "\tCertificate output passed\n" if $verbose;
  162. }
  163. }
  164. sub run_dataout_test {
  165. my ( $cmsdir, $tfile ) = @_;
  166. unlink "tmp.txt";
  167. system(
  168. "$cmscmd -data_out -inform DER" . " -in $cmsdir/$tfile -out tmp.txt" );
  169. if ($?) {
  170. print "\tDataout command FAILED!!\n";
  171. $badtest++;
  172. }
  173. elsif ( !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) ) {
  174. print "\tDataout compare FAILED!!\n";
  175. $badtest++;
  176. }
  177. else {
  178. print "\tDataout passed\n" if $verbose;
  179. }
  180. }
  181. sub run_verify_test {
  182. my ( $cmsdir, $tlist, $tfile ) = @_;
  183. unlink "tmp.txt";
  184. $form = "DER" if $tlist =~ /verifyder/;
  185. $form = "SMIME" if $tlist =~ /verifymime/;
  186. $cafile = "$cmsdir/CarlDSSSelf.pem" if $tlist =~ /dss/;
  187. $cafile = "$cmsdir/CarlRSASelf.pem" if $tlist =~ /rsa/;
  188. $cmd =
  189. "$cmscmd -verify -inform $form"
  190. . " -CAfile $cafile"
  191. . " -in $cmsdir/$tfile -out tmp.txt";
  192. $cmd .= " -content $cmsdir/ExContent.bin" if $tlist =~ /cont_extern/;
  193. system("$cmd 2>cms.err 1>cms.out");
  194. if ($?) {
  195. print "\tVerify command FAILED!!\n";
  196. $badtest++;
  197. }
  198. elsif ( $tlist =~ /cont/
  199. && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) )
  200. {
  201. print "\tVerify content compare FAILED!!\n";
  202. $badtest++;
  203. }
  204. else {
  205. print "\tVerify passed\n" if $verbose;
  206. }
  207. }
  208. sub run_envelope_test {
  209. my ( $cmsdir, $tlist, $tfile ) = @_;
  210. unlink "tmp.txt";
  211. $form = "DER" if $tlist =~ /envelopeder/;
  212. $form = "SMIME" if $tlist =~ /envelopemime/;
  213. $cmd =
  214. "$cmscmd -decrypt -inform $form"
  215. . " -recip $cmsdir/BobRSASignByCarl.pem"
  216. . " -inkey $cmsdir/BobPrivRSAEncrypt.pem"
  217. . " -in $cmsdir/$tfile -out tmp.txt";
  218. system("$cmd 2>cms.err 1>cms.out");
  219. if ($?) {
  220. print "\tDecrypt command FAILED!!\n";
  221. $badtest++;
  222. }
  223. elsif ( $tlist =~ /cont/
  224. && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) )
  225. {
  226. print "\tDecrypt content compare FAILED!!\n";
  227. $badtest++;
  228. }
  229. else {
  230. print "\tDecrypt passed\n" if $verbose;
  231. }
  232. }
  233. sub run_digest_test {
  234. my ( $cmsdir, $tlist, $tfile ) = @_;
  235. unlink "tmp.txt";
  236. my $cmd =
  237. "$cmscmd -digest_verify -inform DER" . " -in $cmsdir/$tfile -out tmp.txt";
  238. system("$cmd 2>cms.err 1>cms.out");
  239. if ($?) {
  240. print "\tDigest verify command FAILED!!\n";
  241. $badtest++;
  242. }
  243. elsif ( $tlist =~ /cont/
  244. && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) )
  245. {
  246. print "\tDigest verify content compare FAILED!!\n";
  247. $badtest++;
  248. }
  249. else {
  250. print "\tDigest verify passed\n" if $verbose;
  251. }
  252. }
  253. sub run_encrypted_test {
  254. my ( $cmsdir, $tlist, $tfile, $key ) = @_;
  255. unlink "tmp.txt";
  256. system( "$cmscmd -EncryptedData_decrypt -inform DER"
  257. . " -secretkey $key"
  258. . " -in $cmsdir/$tfile -out tmp.txt" );
  259. if ($?) {
  260. print "\tEncrypted Data command FAILED!!\n";
  261. $badtest++;
  262. }
  263. elsif ( $tlist =~ /cont/
  264. && !cmp_files( "$cmsdir/ExContent.bin", "tmp.txt" ) )
  265. {
  266. print "\tEncrypted Data content compare FAILED!!\n";
  267. $badtest++;
  268. }
  269. else {
  270. print "\tEncryptedData verify passed\n" if $verbose;
  271. }
  272. }
  273. sub cmp_files {
  274. my ( $f1, $f2 ) = @_;
  275. my ( $fp1, $fp2 );
  276. my ( $rd1, $rd2 );
  277. if ( !open( $fp1, "<$f1" ) ) {
  278. print STDERR "Can't Open file $f1\n";
  279. return 0;
  280. }
  281. if ( !open( $fp2, "<$f2" ) ) {
  282. print STDERR "Can't Open file $f2\n";
  283. return 0;
  284. }
  285. binmode $fp1;
  286. binmode $fp2;
  287. my $ret = 0;
  288. for ( ; ; ) {
  289. $n1 = sysread $fp1, $rd1, 4096;
  290. $n2 = sysread $fp2, $rd2, 4096;
  291. last if ( $n1 != $n2 );
  292. last if ( $rd1 ne $rd2 );
  293. if ( $n1 == 0 ) {
  294. $ret = 1;
  295. last;
  296. }
  297. }
  298. close $fp1;
  299. close $fp2;
  300. return $ret;
  301. }