Tomato 1.28
[tomato.git] / release / src / router / openssl / apps / der_chop.in
blob9070b032fc38b79a86bdda406ee0f3a9b079fba2
1 #!/usr/local/bin/perl
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
6 # The "documentation" for this (i.e. all the comments) are my fault --tjh
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*
13 # SSLeay 0.5.2+ should have direct read support for x509 (via -inform NET)
14 # [I know ... promises promises :-)]
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
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
26 # Tim Hudson
27 # tjh@cryptsoft.com
31 require 'getopts.pl';
33 $debug=0;
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 ";
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 ";
53 &Getopts('vd:') || die "usage:$0 [-v] [-d num] file";
54 $depth=($opt_d =~ /^\d+$/)?$opt_d:0;
56 &init_der();
58 if ($#ARGV != -1)
60 foreach $file (@ARGV)
62 print STDERR "doing $file\n";
63 &dofile($file);
66 else
68 $file="/tmp/a$$.DER";
69 open(OUT,">$file") || die "unable to open $file:$!\n";
70 for (;;)
72 $i=sysread(STDIN,$b,1024*10);
73 last if ($i <= 0);
74 $i=syswrite(OUT,$b,$i);
76 &dofile($file);
77 unlink($file);
80 sub dofile
82 local($file)=@_;
83 local(@p);
85 $b=&load_file($file);
86 @p=&load_file_parse($file);
88 foreach $_ (@p)
90 ($off,$d,$hl,$len)=&parse_line($_);
91 $d-=$depth;
92 next if ($d != 0);
93 next if ($len == 0);
95 $o=substr($b,$off,$len+$hl);
96 ($str,@data)=&der_str($o);
97 print "$str\n" if ($opt_v);
98 if ($str =~ /^$crl/)
100 open(OUT,"|$crl_cmd -inform d -hash -issuer") ||
101 die "unable to run $crl_cmd:$!\n";
102 print OUT $o;
103 close(OUT);
105 elsif ($str =~ /^$x509/)
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);
112 elsif ($str =~ /^$rsa/)
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);
123 elsif ($str =~ /^0G-1D-1G/)
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/));
138 sub der_str
140 local($str)=@_;
141 local(*OUT,*IN,@a,$t,$d,$ret);
142 local($file)="/tmp/b$$.DER";
143 local(@ret);
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>)
153 chop;
154 push(@ret,$_);
156 print STDERR "$_\n" if ($debug);
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-";
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);
172 sub init_der
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";
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",
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
207 foreach (keys %DER_i2s)
208 { $DER_s2i{$DER_i2s{$_}}=$_; }
211 sub parse_line
213 local($_)=@_;
215 return(/\s*(\d+):d=\s*(\d+)\s+hl=\s*(\d+)\s+l=\s*(\d+|inf)\s/);
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
227 local($data,@struct)=@_;
228 local($file)="/tmp/b$$.DER";
229 local($off,$d,$hl,$len,$_,$b,@p,$s);
231 ($type)=($struct[4] =~ /OBJECT_IDENTIFIER :(.*)\s*$/);
232 if ($type eq "rc4")
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);
240 $b=&load_file($file);
241 unlink($file);
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);
253 else
255 print "'$type' is unknown\n";
256 exit(1);
260 sub do_certificate
262 local($data,@struct)=@_;
263 local($file)="/tmp/b$$.DER";
264 local($off,$d,$hl,$len,$_,$b,@p,$s);
266 ($off,$d,$hl,$len)=&parse_line($struct[2]);
267 $b=substr($data,$off,$len+$hl);
269 open(OUT,"|$x509_cmd -inform d") || die "unable to run $x509_cmd:$!\n";
270 print OUT $b;
271 close(OUT);
274 sub load_file
276 local($file)=@_;
277 local(*IN,$r,$b,$i);
279 $r="";
280 open(IN,"<$file") || die "unable to open $file:$!\n";
281 for (;;)
283 $i=sysread(IN,$b,10240);
284 last if ($i <= 0);
285 $r.=$b;
287 close(IN);
288 return($r);
291 sub load_file_parse
293 local($file)=@_;
294 local(*IN,$r,@ret,$_,$i,$n,$b);
296 open(IN,"$cmd -inform d -in $file|")
297 || die "unable to run der_parse\n";
298 while (<IN>)
300 chop;
301 push(@ret,$_);
303 return($r,@ret);