home *** CD-ROM | disk | FTP | other *** search
/ PC World 2005 June / PCWorld_2005-06_cd.bin / software / vyzkuste / firewally / firewally.exe / framework-2.3.exe / der_chop < prev    next >
Text File  |  2003-09-30  |  7KB  |  306 lines

  1. #!/usr/bin/perl
  2. #
  3. # der_chop ... this is one total hack that Eric is really not proud of
  4. #              so don't look at it and don't ask for support
  5. #
  6. # The "documentation" for this (i.e. all the comments) are my fault --tjh
  7. #
  8. # This program takes the "raw" output of derparse/asn1parse and 
  9. # converts it into tokens and then runs regular expression matches
  10. # to try to figure out what to grab to get the things that are needed
  11. # and it is possible that this will do the wrong thing as it is a *hack*
  12. #
  13. # SSLeay 0.5.2+ should have direct read support for x509 (via -inform NET)
  14. # [I know ... promises promises :-)]
  15. #
  16. # To convert a Netscape Certificate:
  17. #    der_chop < ServerCert.der > cert.pem
  18. # To convert a Netscape Key (and encrypt it again to protect it)
  19. #    rsa -inform NET -in ServerKey.der -des > key.pem
  20. #
  21. # 23-Apr-96 eay    Added the extra ASN.1 string types, I still think this
  22. #           is an evil hack.  If nothing else the parsing should
  23. #           be relative, not absolute.
  24. # 19-Apr-96 tjh    hacked (with eay) into 0.5.x format
  25. #
  26. # Tim Hudson
  27. # tjh@cryptsoft.com
  28. #
  29.  
  30.  
  31. require 'getopts.pl';
  32.  
  33. $debug=0;
  34.  
  35. # this was the 0.4.x way of doing things ...
  36. $cmd="derparse";
  37. $x509_cmd="x509";
  38. $crl_cmd="crl";
  39. $rc4_cmd="rc4";
  40. $md2_cmd="md2";
  41. $md4_cmd="md4";
  42. $rsa_cmd="rsa -des -inform der ";
  43.  
  44. # this was the 0.5.x way of doing things ...
  45. $cmd="openssl asn1parse";
  46. $x509_cmd="openssl x509";
  47. $crl_cmd="openssl crl";
  48. $rc4_cmd="openssl rc4";
  49. $md2_cmd="openssl md2";
  50. $md4_cmd="openssl md4";
  51. $rsa_cmd="openssl rsa -des -inform der ";
  52.  
  53. &Getopts('vd:') || die "usage:$0 [-v] [-d num] file";
  54. $depth=($opt_d =~ /^\d+$/)?$opt_d:0;
  55.  
  56. &init_der();
  57.  
  58. if ($#ARGV != -1)
  59.     {
  60.     foreach $file (@ARGV)
  61.         {
  62.         print STDERR "doing $file\n";
  63.         &dofile($file);
  64.         }
  65.     }
  66. else
  67.     {
  68.     $file="/tmp/a$$.DER";
  69.     open(OUT,">$file") || die "unable to open $file:$!\n";
  70.     for (;;)
  71.         {
  72.         $i=sysread(STDIN,$b,1024*10);
  73.         last if ($i <= 0);
  74.         $i=syswrite(OUT,$b,$i);
  75.         }
  76.     &dofile($file);
  77.     unlink($file);
  78.     }
  79.     
  80. sub dofile
  81.     {
  82.     local($file)=@_;
  83.     local(@p);
  84.  
  85.     $b=&load_file($file);
  86.     @p=&load_file_parse($file);
  87.  
  88.     foreach $_ (@p)
  89.         {
  90.         ($off,$d,$hl,$len)=&parse_line($_);
  91.         $d-=$depth;
  92.         next if ($d != 0);
  93.         next if ($len == 0);
  94.  
  95.         $o=substr($b,$off,$len+$hl);
  96.         ($str,@data)=&der_str($o);
  97.         print "$str\n" if ($opt_v);
  98.         if ($str =~ /^$crl/)
  99.             {
  100.             open(OUT,"|$crl_cmd -inform d -hash -issuer") ||
  101.                 die "unable to run $crl_cmd:$!\n";
  102.             print OUT $o;
  103.             close(OUT);
  104.             }
  105.         elsif ($str =~ /^$x509/)
  106.             {
  107.             open(OUT,"|$x509_cmd -inform d -hash -subject -issuer")
  108.                 || die "unable to run $x509_cmd:$!\n";
  109.             print OUT $o;
  110.             close(OUT);
  111.             }
  112.         elsif ($str =~ /^$rsa/)
  113.             {
  114.             ($type)=($data[3] =~ /OBJECT_IDENTIFIER :(.*)\s*$/);
  115.             next unless ($type eq "rsaEncryption");
  116.             ($off,$d,$hl,$len)=&parse_line($data[5]);
  117.             $os=substr($o,$off+$hl,$len);
  118.             open(OUT,"|$rsa_cmd")
  119.                 || die "unable to run $rsa_cmd:$!\n";
  120.             print OUT $os;
  121.             close(OUT);
  122.             }
  123.         elsif ($str =~ /^0G-1D-1G/)
  124.             {
  125.             ($off,$d,$hl,$len)=&parse_line($data[1]);
  126.             $os=substr($o,$off+$hl,$len);
  127.             print STDERR "<$os>\n" if $opt_v;
  128.             &do_certificate($o,@data)
  129.                 if (($os eq "certificate") &&
  130.                     ($str =! /^0G-1D-1G-2G-3F-3E-2D/));
  131.             &do_private_key($o,@data)
  132.                 if (($os eq "private-key") &&
  133.                     ($str =! /^0G-1D-1G-2G-3F-3E-2D/));
  134.             }
  135.         }
  136.     }
  137.  
  138. sub der_str
  139.     {
  140.     local($str)=@_;
  141.     local(*OUT,*IN,@a,$t,$d,$ret);
  142.     local($file)="/tmp/b$$.DER";
  143.     local(@ret);
  144.  
  145.     open(OUT,">$file");
  146.     print OUT $str;
  147.     close(OUT);
  148.     open(IN,"$cmd -inform 'd' -in $file |") ||
  149.         die "unable to run $cmd:$!\n";
  150.     $ret="";
  151.     while (<IN>)
  152.         {
  153.         chop;
  154.         push(@ret,$_);
  155.  
  156.         print STDERR "$_\n" if ($debug);
  157.  
  158.         @a=split(/\s*:\s*/);
  159.         ($d)=($a[1] =~ /d=\s*(\d+)/);
  160.         $a[2] =~ s/\s+$//;
  161.         $t=$DER_s2i{$a[2]};
  162.         $ret.="$d$t-";
  163.         }
  164.     close(IN);
  165.     unlink($file);
  166.     chop $ret;
  167.     $ret =~ s/(-3H(-4G-5F-5[IJKMQRS])+)+/-NAME/g;
  168.     $ret =~ s/(-3G-4B-4L)+/-RCERT/g;
  169.     return($ret,@ret);
  170.     }
  171.  
  172. sub init_der
  173.     {
  174.     $crl= "0G-1G-2G-3F-3E-2G-NAME-2L-2L-2G-RCERT-1G-2F-2E-1C";
  175.     $x509="0G-1G-2B-2G-3F-3E-2G-NAME-2G-3L-3L-2G-NAME-2G-3G-4F-4E-3C-1G-2F-2E-1C";
  176.     $rsa= "0G-1B-1G-2F-2E-1D";
  177.  
  178.     %DER_i2s=(
  179.         # SSLeay 0.4.x has this list
  180.         "A","EOC",
  181.         "B","INTEGER",
  182.         "C","BIT STRING",
  183.         "D","OCTET STRING",
  184.         "E","NULL",
  185.         "F","OBJECT",
  186.         "G","SEQUENCE",
  187.         "H","SET",
  188.         "I","PRINTABLESTRING",
  189.         "J","T61STRING",
  190.         "K","IA5STRING",
  191.         "L","UTCTIME",
  192.         "M","NUMERICSTRING",
  193.         "N","VIDEOTEXSTRING",
  194.         "O","GENERALIZEDTIME",
  195.         "P","GRAPHICSTRING",
  196.         "Q","ISO64STRING",
  197.         "R","GENERALSTRING",
  198.         "S","UNIVERSALSTRING",
  199.  
  200.         # SSLeay 0.5.x changed some things ... and I'm
  201.         # leaving in the old stuff but adding in these
  202.         # to handle the new as well --tjh
  203.         # - Well I've just taken them out and added the extra new
  204.         # ones :-) - eay
  205.         );
  206.  
  207.     foreach (keys %DER_i2s)
  208.         { $DER_s2i{$DER_i2s{$_}}=$_; }
  209.     }
  210.  
  211. sub parse_line
  212.     {
  213.     local($_)=@_;
  214.  
  215.     return(/\s*(\d+):d=\s*(\d+)\s+hl=\s*(\d+)\s+l=\s*(\d+|inf)\s/);
  216.     }
  217.  
  218. #  0:d=0 hl=4 l=377 cons: univ: SEQUENCE          
  219. #  4:d=1 hl=2 l= 11 prim: univ: OCTET_STRING      
  220. # 17:d=1 hl=4 l=360 cons: univ: SEQUENCE          
  221. # 21:d=2 hl=2 l= 12 cons: univ: SEQUENCE          
  222. # 23:d=3 hl=2 l=  8 prim: univ: OBJECT_IDENTIFIER :rc4
  223. # 33:d=3 hl=2 l=  0 prim: univ: NULL              
  224. # 35:d=2 hl=4 l=342 prim: univ: OCTET_STRING
  225. sub do_private_key
  226.     {
  227.     local($data,@struct)=@_;
  228.     local($file)="/tmp/b$$.DER";
  229.     local($off,$d,$hl,$len,$_,$b,@p,$s);
  230.  
  231.     ($type)=($struct[4] =~ /OBJECT_IDENTIFIER :(.*)\s*$/);
  232.     if ($type eq "rc4")
  233.         {
  234.         ($off,$d,$hl,$len)=&parse_line($struct[6]);
  235.         open(OUT,"|$rc4_cmd >$file") ||
  236.             die "unable to run $rc4_cmd:$!\n";
  237.         print OUT substr($data,$off+$hl,$len);
  238.         close(OUT);
  239.  
  240.         $b=&load_file($file);
  241.         unlink($file);
  242.  
  243.         ($s,@p)=&der_str($b);
  244.         die "unknown rsa key type\n$s\n"
  245.             if ($s ne '0G-1B-1G-2F-2E-1D');
  246.         local($off,$d,$hl,$len)=&parse_line($p[5]);
  247.         $b=substr($b,$off+$hl,$len);
  248.         ($s,@p)=&der_str($b);
  249.         open(OUT,"|$rsa_cmd") || die "unable to run $rsa_cmd:$!\n";
  250.         print OUT $b;
  251.         close(OUT);
  252.         }
  253.     else
  254.         {
  255.         print "'$type' is unknown\n";
  256.         exit(1);
  257.         }
  258.     }
  259.  
  260. sub do_certificate
  261.     {
  262.     local($data,@struct)=@_;
  263.     local($file)="/tmp/b$$.DER";
  264.     local($off,$d,$hl,$len,$_,$b,@p,$s);
  265.  
  266.     ($off,$d,$hl,$len)=&parse_line($struct[2]);
  267.     $b=substr($data,$off,$len+$hl);
  268.  
  269.     open(OUT,"|$x509_cmd -inform d") || die "unable to run $x509_cmd:$!\n";
  270.     print OUT $b;
  271.     close(OUT);
  272.     }
  273.  
  274. sub load_file
  275.     {
  276.     local($file)=@_;
  277.     local(*IN,$r,$b,$i);
  278.  
  279.     $r="";
  280.     open(IN,"<$file") || die "unable to open $file:$!\n";
  281.     for (;;)
  282.         {
  283.         $i=sysread(IN,$b,10240);
  284.         last if ($i <= 0);
  285.         $r.=$b;
  286.         }
  287.     close(IN);
  288.     return($r);
  289.     }
  290.  
  291. sub load_file_parse
  292.     {
  293.     local($file)=@_;
  294.     local(*IN,$r,@ret,$_,$i,$n,$b);
  295.  
  296.     open(IN,"$cmd -inform d -in $file|")
  297.         || die "unable to run der_parse\n";
  298.     while (<IN>)
  299.         {
  300.         chop;
  301.         push(@ret,$_);
  302.         }
  303.     return($r,@ret);
  304.     }
  305.  
  306.