1# Copyright (c) Stephan Martin <sm@sm-zone.net>
2#
3# $Id: REQ.pm,v 1.8 2006/10/21 21:12:09 sm Exp $
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; either version 2 of the License, or
8# (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
18
19use strict;
20
21package REQ;
22
23use POSIX;
24
25sub new {
26   my $that = shift;
27   my $class = ref($that) || $that;
28
29   my $self = {};
30
31   $self->{'OpenSSL'} = shift;
32
33   bless($self, $class);
34}
35
36#
37# check if all data for creating a new request is available
38#
39sub get_req_create {
40   my ($self, $main, $opts, $box) = @_;
41
42   $box->destroy() if(defined($box));
43
44   my ($name, $action, $parsed, $reqfile, $keyfile, $ca, $t);
45
46   $ca   = $main->{'CA'}->{'actca'};
47
48   if(!(defined($opts)) || !(ref($opts))) {
49      if(defined($opts) && $opts eq "signserver") {
50         $opts = {};
51         $opts->{'sign'} = 1;
52         $opts->{'type'} = "server";
53      } elsif(defined($opts) && $opts eq "signclient") {
54         $opts = {};
55         $opts->{'sign'} = 1;
56         $opts->{'type'} = "client";
57      } elsif (defined($opts)) {
58         $t = sprintf(_("Strange value for 'opts': %s"), $opts);
59         GUI::HELPERS::print_error($t);
60      }
61      $opts->{'bits'}   = 4096;
62      $opts->{'digest'} = 'sha1';
63      $opts->{'algo'}   = 'rsa';
64      if(defined($opts) && $opts eq "sign") {
65         $opts->{'sign'} = 1;
66      }
67
68      $parsed = $main->{'CERT'}->parse_cert($main, 'CA');
69
70      defined($parsed) ||
71         GUI::HELPERS::print_error(_("Can't read CA certificate"));
72
73      # set defaults
74      if(defined $parsed->{'C'}) {
75         $opts->{'C'} = $parsed->{'C'};
76      }
77      if(defined $parsed->{'ST'}) {
78         $opts->{'ST'} = $parsed->{'ST'};
79      }
80      if(defined $parsed->{'L'}) {
81         $opts->{'L'} = $parsed->{'L'};
82      }
83      if(defined $parsed->{'O'}) {
84         $opts->{'O'} = $parsed->{'O'};
85      }
86      my $cc = 0;
87      foreach my $ou (@{$parsed->{'OU'}}) {
88         $opts->{'OU'}->[$cc++] = $ou;
89      }
90
91      $main->show_req_dialog($opts);
92      return;
93   }
94
95   if((not defined($opts->{'CN'})) ||
96      ($opts->{'CN'} eq "") ||
97      (not defined($opts->{'passwd'})) ||
98      ($opts->{'passwd'} eq "")) {
99      $main->show_req_dialog($opts);
100      GUI::HELPERS::print_warning(
101            _("Please specify at least Common Name ")
102            ._("and Password"));
103      return;
104   }
105
106   if((not defined($opts->{'passwd2'})) ||
107       $opts->{'passwd'} ne $opts->{'passwd2'}) {
108      $main->show_req_dialog($opts);
109      GUI::HELPERS::print_warning(_("Passwords don't match"));
110      return;
111   }
112
113   $opts->{'C'} = uc($opts->{'C'});
114
115   if((defined $opts->{'C'}) &&
116      ($opts->{'C'} ne "") &&
117      (length($opts->{'C'}) != 2)) {
118      $main->show_req_dialog($opts);
119      GUI::HELPERS::print_warning(
120            _("Country must be exact 2 letter code"));
121      return;
122   }
123
124   if(($opts->{'digest'} =~ /^sha512/ || $opts->{'digest'} =~ /^sha256/) &&
125         $main->{'OpenSSL'}->{'version'} =~ "0.9.7") {
126         $t = sprintf(
127               _("Hash %s is not supported with OpenSSL older than 0.9.8"),
128               $opts->{'digest'}
129               );
130         $main->show_req_dialog($opts);
131         GUI::HELPERS::print_warning($t);
132         return;
133   }
134
135   $name = HELPERS::gen_name($opts);
136
137   $opts->{'reqname'} = HELPERS::enc_base64($name);
138
139   $reqfile = $main->{'CA'}->{$ca}->{'dir'}."/req/".$opts->{'reqname'}.".pem";
140   $keyfile = $main->{'CA'}->{$ca}->{'dir'}."/keys/".$opts->{'reqname'}.".pem";
141
142   if(-s $reqfile || -s $keyfile) {
143      $main->show_req_overwrite_warning($opts);
144      return;
145   }
146
147   $self->create_req($main, $opts);
148
149   return;
150}
151
152#
153# create new request and key
154#
155sub create_req {
156   my ($self, $main, $opts) = @_;
157
158   my($reqfile, $keyfile, $ca, $ret, $ext, $cadir);
159
160   GUI::HELPERS::set_cursor($main, 1);
161
162   $ca    = $main->{'CA'}->{'actca'};
163   $cadir = $main->{'CA'}->{$ca}->{'dir'};
164
165   $reqfile = $cadir."/req/".$opts->{'reqname'}.".pem";
166   $keyfile = $cadir."/keys/".$opts->{'reqname'}.".pem";
167
168   ($ret, $ext) = $self->{'OpenSSL'}->newkey(
169         'algo'    => $opts->{'algo'},
170         'bits'    => $opts->{'bits'},
171         'outfile' => $keyfile,
172         'pass'    => $opts->{'passwd'}
173         );
174
175   if (not -s $keyfile || $ret) {
176      unlink($keyfile);
177      GUI::HELPERS::set_cursor($main, 0);
178      GUI::HELPERS::print_warning(_("Generating key failed"), $ext);
179      return;
180   }
181
182   my @dn = ( $opts->{'C'}, $opts->{'ST'}, $opts->{'L'}, $opts->{'O'} );
183   if(ref($opts->{'OU'})) {
184      foreach my $ou (@{$opts->{'OU'}}) {
185      	push(@dn,$ou);
186      }
187   } else {
188      push(@dn, $opts->{'OU'});
189   }
190   @dn = (@dn, $opts->{'CN'}, $opts->{'EMAIL'}, '', '');
191   ($ret, $ext) = $self->{'OpenSSL'}->newreq(
192         'config'   => $main->{'CA'}->{$ca}->{'cnf'},
193         'outfile'  => $reqfile,
194         'keyfile'  => $keyfile,
195         'digest'   => $opts->{'digest'},
196         'pass'     => $opts->{'passwd'},
197         'dn'       => \@dn,
198         );
199
200   if (not -s $reqfile || $ret) {
201      unlink($keyfile);
202      unlink($reqfile);
203      GUI::HELPERS::set_cursor($main, 0);
204      GUI::HELPERS::print_warning(_("Generating Request failed"), $ext);
205      return;
206   }
207
208   my $parsed = $self->parse_req($main, $opts->{'reqname'}, 1);
209
210   $main->{'reqbrowser'}->update($cadir."/req",
211                                 $cadir."/crl/crl.pem",
212                                 $cadir."/index.txt",
213                                 0);
214
215   $main->{'keybrowser'}->update($cadir."/keys",
216                                 $cadir."/crl/crl.pem",
217                                 $cadir."/index.txt",
218                                 0);
219
220   GUI::HELPERS::set_cursor($main, 0);
221
222   if($opts->{'sign'}) {
223      $opts->{'reqfile'} = $reqfile;
224      $opts->{'passwd'}  = undef; # to sign request, ca-password is needed
225      $self->get_sign_req($main, $opts);
226   }
227
228   return;
229}
230
231#
232# get name of requestfile to delete
233#
234sub get_del_req {
235   my ($self, $main) = @_;
236
237   my($reqname, $req, $reqfile, $row, $ind, $ca, $cadir);
238
239   $ca    = $main->{'reqbrowser'}->selection_caname();
240   $cadir = $main->{'reqbrowser'}->selection_cadir();
241
242   if(not(defined($reqfile))) {
243      $req = $main->{'reqbrowser'}->selection_dn();
244
245
246      if(not defined($req)) {
247         GUI::HELPERS::print_info(_("Please select a Request first"));
248         return;
249      }
250
251      $reqname = HELPERS::enc_base64($req);
252      $reqfile = $cadir."/req/".$reqname.".pem";
253
254   }
255
256   if(not -s $reqfile) {
257      GUI::HELPERS::print_warning(_("Request file not found"));
258      return;
259   }
260
261   $main->show_del_confirm($reqfile, 'req');
262
263   return;
264}
265
266#
267# now really delete the requestfile
268#
269sub del_req {
270   my ($self, $main, $file) = @_;
271
272   my ($ca, $cadir);
273
274   GUI::HELPERS::set_cursor($main, 1);
275
276   unlink($file);
277
278   $ca    = $main->{'reqbrowser'}->selection_caname();
279   $cadir = $main->{'reqbrowser'}->selection_cadir();
280
281   $main->{'reqbrowser'}->update($cadir."/req",
282                                 $cadir."/crl/crl.pem",
283                                 $cadir."/index.txt",
284                                 0);
285
286   GUI::HELPERS::set_cursor($main, 0);
287
288   return;
289}
290
291sub read_reqlist {
292   my ($self, $reqdir, $crlfile, $indexfile, $force, $main) = @_;
293
294   my ($f, $modt, $d, $reqlist, $c, $p, $t);
295
296   GUI::HELPERS::set_cursor($main, 1);
297
298   $reqlist = [];
299
300   $modt = (stat($reqdir))[9];
301
302   if(defined($self->{'lastread'}) &&
303      $self->{'lastread'} >= $modt) {
304      GUI::HELPERS::set_cursor($main, 0);
305      return(0);
306   }
307
308   opendir(DIR, $reqdir) || do {
309      GUI::HELPERS::set_cursor($main, 0);
310      GUI::HELPERS::print_warning(_("Can't open Request directory"));
311      return(0);
312   };
313
314   while($f = readdir(DIR)) {
315      next if $f =~ /^\./;
316      $c++;
317   }
318   rewinddir(DIR);
319
320   $main->{'barbox'}->pack_start($main->{'progress'}, 0, 0, 0);
321   $main->{'progress'}->show();
322   while($f = readdir(DIR)) {
323      next if $f =~ /^\./;
324      $f =~ s/\.pem//;
325      $d = HELPERS::dec_base64($f);
326      next if not defined($d);
327      next if $d eq "";
328      push(@{$reqlist}, $d);
329
330      if(defined($main)) {
331         $t = sprintf(_("   Read Request: %s"), $d);
332         GUI::HELPERS::set_status($main, $t);
333         $p += 100/$c;
334         if($p/100 <= 1) {
335            $main->{'progress'}->set_fraction($p/100);
336            while(Gtk2->events_pending) {
337               Gtk2->main_iteration;
338            }
339         }
340         select(undef, undef, undef, 0.025);
341      }
342   }
343   @{$reqlist} = sort(@{$reqlist});
344   closedir(DIR);
345
346   delete($self->{'reqlist'});
347   $self->{'reqlist'} = $reqlist;
348
349   $self->{'lastread'} = time();
350
351   if(defined($main)) {
352      $main->{'progress'}->set_fraction(0);
353      $main->{'barbox'}->remove($main->{'progress'});
354      GUI::HELPERS::set_cursor($main, 0);
355   }
356
357   return(1);  # got new list
358}
359
360#
361# get name of request to sign
362#
363sub get_sign_req {
364   my ($self, $main, $opts, $box) = @_;
365
366   my($time, $parsed, $ca, $cadir, $ext, $ret, $t);
367
368   $box->destroy() if(defined($box));
369
370   $time  = time();
371   $ca    = $main->{'reqbrowser'}->selection_caname();
372   $cadir = $main->{'reqbrowser'}->selection_cadir();
373
374   if(not(defined($opts->{'reqfile'}))) {
375      $opts->{'req'} = $main->{'reqbrowser'}->selection_dn();
376
377      if(not defined($opts->{'req'})) {
378         GUI::HELPERS::print_info(_("Please select a Request first"));
379         return;
380      }
381
382      $opts->{'reqname'} = HELPERS::enc_base64($opts->{'req'});
383      $opts->{'reqfile'} = $cadir."/req/".$opts->{'reqname'}.".pem";
384   }
385
386   if(not -s $opts->{'reqfile'}) {
387         GUI::HELPERS::print_warning(_("Request file not found"));
388         return;
389   }
390
391   if((-s $cadir."/certs/".$opts->{'reqname'}.".pem") &&
392      (!(defined($opts->{'overwrite'})) || ($opts->{'overwrite'} ne 'true'))) {
393      $main->show_cert_overwrite_confirm($opts);
394      return;
395   }
396
397   $parsed = $main->{'CERT'}->parse_cert($main, 'CA');
398
399   defined($parsed) ||
400      GUI::HELPERS::print_error(_("Can't read CA certificate"));
401
402   if(!defined($opts->{'passwd'})) {
403      $opts->{'days'} =
404         $main->{'TCONFIG'}->{$opts->{'type'}."_ca"}->{'default_days'};
405
406      if($opts->{'days'} > (($parsed->{'EXPDATE'}/86400) - ($time/86400))) {
407         $opts->{'days'} = int(($parsed->{'EXPDATE'}/86400) - ($time/86400));
408      }
409
410      $main->show_req_sign_dialog($opts);
411      return;
412   }
413
414   if((($time + ($opts->{'days'} * 86400)) > $parsed->{'EXPDATE'}) &&
415      (!(defined($opts->{'ignoredate'})) ||
416       $opts->{'ignoredate'} ne 'true')){
417      $main->show_req_date_warning($opts);
418      return;
419   }
420
421   # try to find message digest used for the request
422   $parsed = undef;
423   $parsed = $self->parse_req($main, $opts->{'reqname'}, 1);
424   defined($parsed) ||
425      GUI::HELPERS::print_error(_("Can't read Request file"));
426
427   if(defined($parsed->{'SIG_ALGORITHM'})) {
428      $opts->{'digest'} = $parsed->{'SIG_ALGORITHM'};
429
430      if($opts->{'digest'} =~ /^md2/) {
431         $opts->{'digest'} = "md2";
432      } elsif ($opts->{'digest'} =~ /^mdc2/) {
433         $opts->{'digest'} = "mdc2";
434      } elsif ($opts->{'digest'} =~ /^md4/) {
435         $opts->{'digest'} = "md4";
436      } elsif ($opts->{'digest'} =~ /^md5/) {
437         $opts->{'digest'} = "md5";
438      } elsif ($opts->{'digest'} =~ /^sha1/) {
439         $opts->{'digest'} = "sha1";
440      } elsif ($opts->{'digest'} =~ /^sha256/) {
441         $opts->{'digest'} = "sha256";
442      } elsif ($opts->{'digest'} =~ /^sha512/) {
443         $opts->{'digest'} = "sha512";
444      } elsif ($opts->{'digest'} =~ /^ripemd160/) {
445         $opts->{'digest'} = "ripemd160";
446      } else {
447      }
448   } else {
449      $opts->{'digest'} = 0;
450   }
451
452   ($ret, $ext) = $self->sign_req($main, $opts);
453
454   return($ret, $ext);
455}
456
457#
458# now really sign the request
459#
460sub sign_req {
461   my ($self, $main, $opts) = @_;
462
463   my($serial, $certout, $certfile, $certfile2, $ca, $cadir, $ret, $t, $ext);
464
465   GUI::HELPERS::set_cursor($main, 1);
466
467   $ca    = $main->{'reqbrowser'}->selection_caname();
468   $cadir = $main->{'reqbrowser'}->selection_cadir();
469
470   $serial = $cadir."/serial";
471   open(IN, "<$serial") || do {
472      GUI::HELPERS::set_cursor($main, 0);
473      GUI::HELPERS::print_warning(_("Can't read serial"));
474      return;
475   };
476   $serial = <IN>;
477   chomp($serial);
478   close IN;
479
480   if(not defined($opts->{'nsSslServerName'})) {
481      $opts->{'nsSslServerName'} = 'none';
482   }
483   if(not defined($opts->{'nsRevocationUrl'})) {
484      $opts->{'nsRevocationUrl'} = 'none';
485   }
486   if(not defined($opts->{'nsRenewalUrl'})) {
487      $opts->{'nsRenewalUrl'} = 'none';
488   }
489   if(not defined($opts->{'subjectAltName'})) {
490      $opts->{'subjectAltName'}     = 'none';
491      $opts->{'subjectAltNameType'} = 'none';
492   } else {
493       $opts->{'subjectAltNameType'} =
494          $main->{TCONFIG}->{$opts->{'type'}.'_cert'}->{'subjectAltNameType'};
495   }
496   if(not defined($opts->{'extendedKeyUsage'})) {
497      $opts->{'extendedKeyUsage'}     = 'none';
498      $opts->{'extendedKeyUsageType'} = 'none';
499   } else {
500      $opts->{'extendedKeyUsageType'} =
501         $main->{TCONFIG}->{$opts->{'type'}.'_cert'}->{'extendedKeyUsageType'};
502   }
503
504   if(defined($opts->{'mode'}) && $opts->{'mode'} eq "sub") {
505      ($ret, $ext) = $self->{'OpenSSL'}->signreq(
506            'mode'                 => $opts->{'mode'},
507            'config'               => $main->{'CA'}->{$ca}->{'cnf'},
508            'reqfile'              => $opts->{'reqfile'},
509            'keyfile'              => $opts->{'keyfile'},
510            'cacertfile'           => $opts->{'cacertfile'},
511            'outdir'               => $opts->{'outdir'},
512            'days'                 => $opts->{'days'},
513            'parentpw'             => $opts->{'parentpw'},
514            'caname'               => "ca_ca",
515            'revocationurl'        => $opts->{'nsRevocationUrl'},
516            'renewalurl'           => $opts->{'nsRenewalUrl'},
517            'subjaltname'          => $opts->{'subjectAltName'},
518            'subjaltnametype'      => $opts->{'subjectAltNameType'},
519            'extendedkeyusage'     => $opts->{'extendedKeyUsage'},
520            'extendedkeyusagetype' => $opts->{'extendedKeyUsageType'},
521            'noemaildn'            => $opts->{'noemaildn'},
522            'digest'               => $opts->{'digest'}
523            );
524   } else {
525      ($ret, $ext) = $self->{'OpenSSL'}->signreq(
526            'config'               => $main->{'CA'}->{$ca}->{'cnf'},
527            'reqfile'              => $opts->{'reqfile'},
528            'days'                 => $opts->{'days'},
529            'pass'                 => $opts->{'passwd'},
530            'caname'               => $opts->{'type'}."_ca",
531            'sslservername'        => $opts->{'nsSslServerName'},
532            'revocationurl'        => $opts->{'nsRevocationUrl'},
533            'renewalurl'           => $opts->{'nsRenewalUrl'},
534            'subjaltname'          => $opts->{'subjectAltName'},
535            'subjaltnametype'      => $opts->{'subjectAltNameType'},
536            'extendedkeyusage'     => $opts->{'extendedKeyUsage'},
537            'extendedkeyusagetype' => $opts->{'extendedKeyUsageType'},
538            'noemaildn'            => $opts->{'noemaildn'},
539            'digest'               => $opts->{'digest'}
540            );
541   }
542
543   GUI::HELPERS::set_cursor($main, 0);
544
545   if($ret eq 1) {
546      $t = _("Wrong CA password given\nSigning of the Request failed");
547      GUI::HELPERS::print_warning($t, $ext);
548      delete($opts->{$_}) foreach(keys(%$opts));
549      $opts = undef;
550      return;
551   } elsif($ret eq 2) {
552      $t = _("CA Key not found\nSigning of the Request failed");
553      GUI::HELPERS::print_warning($t, $ext);
554      delete($opts->{$_}) foreach(keys(%$opts));
555      $opts = undef;
556      return;
557   } elsif($ret eq 3) {
558      $t = _("Certificate already existing\nSigning of the Request failed");
559      GUI::HELPERS::print_warning($t, $ext);
560      delete($opts->{$_}) foreach(keys(%$opts));
561      $opts = undef;
562      return;
563   } elsif($ret eq 4) {
564      $t = _("Invalid IP Address given\nSigning of the Request failed");
565      GUI::HELPERS::print_warning($t, $ext);
566      delete($opts->{$_}) foreach(keys(%$opts));
567      $opts = undef;
568      return;
569   } elsif($ret) {
570      GUI::HELPERS::print_warning(
571            _("Signing of the Request failed"), $ext);
572      delete($opts->{$_}) foreach(keys(%$opts));
573      $opts = undef;
574      return($ret, $ext);
575   }
576
577   if(defined($opts->{'mode'}) && $opts->{'mode'} eq "sub") {
578      $certout  = $cadir."/newcerts/".$serial.".pem";
579      $certfile = $opts->{'outfile'};
580      $certfile2 = $cadir."/certs/".$opts->{'reqname'}.".pem";
581   } else {
582      $certout  = $cadir."/newcerts/".$serial.".pem";
583      $certfile = $cadir."/certs/".$opts->{'reqname'}.".pem";
584      #print STDERR "DEBUG: write certificate to: ".$cadir."/certs/".$opts->{'reqname'}.".pem";
585   }
586
587   if (not -s $certout) {
588         GUI::HELPERS::print_warning(
589               _("Signing of the Request failed"), $ext);
590         delete($opts->{$_}) foreach(keys(%$opts));
591         $opts = undef;
592         return;
593   }
594
595   open(IN, "<$certout") || do {
596      GUI::HELPERS::print_warning(_("Can't read Certificate file"));
597      delete($opts->{$_}) foreach(keys(%$opts));
598      $opts = undef;
599      return;
600   };
601   open(OUT, ">$certfile") || do {
602      GUI::HELPERS::print_warning(_("Can't write Certificate file"));
603      delete($opts->{$_}) foreach(keys(%$opts));
604      $opts = undef;
605      return;
606   };
607   print OUT while(<IN>);
608
609   if(defined($opts->{'mode'}) && $opts->{'mode'} eq "sub") {
610      close OUT;
611      open(OUT, ">$certfile2") || do {
612         GUI::HELPERS::print_warning(_("Can't write Certificate file"));
613         delete($opts->{$_}) foreach(keys(%$opts));
614         $opts = undef;
615         return;
616      };
617      seek(IN, 0, 0);
618      print OUT while(<IN>);
619   }
620
621   close IN; close OUT;
622
623   GUI::HELPERS::print_info(
624         _("Request signed succesfully.\nCertificate created"), $ext);
625
626   GUI::HELPERS::set_cursor($main, 1);
627
628   $main->{'CERT'}->reread_cert($main,
629         HELPERS::dec_base64($opts->{'reqname'}));
630
631   $main->{'certbrowser'}->update($cadir."/certs",
632                                  $cadir."/crl/crl.pem",
633                                  $cadir."/index.txt",
634                                  0);
635
636   delete($opts->{$_}) foreach(keys(%$opts));
637   $opts = undef;
638
639   GUI::HELPERS::set_cursor($main, 0);
640
641   return($ret, $ext);
642}
643
644#
645# get informations/verifications to import request from file
646#
647sub get_import_req {
648   my ($self, $main, $opts, $box) = @_;
649
650   my ($ret, $ext, $der);
651
652   $box->destroy() if(defined($box));
653
654   my($ca, $parsed, $file, $format);
655
656   $ca = $main->{'CA'}->{'actca'};
657
658   if(not defined($opts)) {
659      $main->show_req_import_dialog();
660      return;
661   }
662
663   if(not defined($opts->{'infile'})) {
664      $main->show_req_import_dialog();
665      GUI::HELPERS::print_warning(_("Please select a Request file first"));
666      return;
667   }
668   if(not -s $opts->{'infile'}) {
669      $main->show_req_import_dialog();
670      GUI::HELPERS::print_warning(
671            _("Can't find Request file: ").$opts->{'infile'});
672      return;
673   }
674
675   open(IN, "<$opts->{'infile'}") || do {
676      GUI::HELPERS::print_warning(
677            _("Can't read Request file:").$opts->{'infile'});
678      return;
679   };
680
681   $opts->{'in'} .= $_ while(<IN>);
682
683   if($opts->{'in'} =~ /-BEGIN[\s\w]+CERTIFICATE REQUEST-/i) {
684      $format = "PEM";
685      $file = $opts->{'infile'};
686   } else {
687      $format = "DER";
688   }
689
690   if($format eq "DER") {
691      ($ret, $der, $ext) = $opts->{'in'} = $self->{'OpenSSL'}->convdata(
692            'cmd'     => 'req',
693            'data'    => $opts->{'in'},
694            'inform'  => 'DER',
695            'outform' => 'PEM'
696            );
697
698      if($ret) {
699         GUI::HELPERS::print_warning(
700               _("Error converting Request"), $ext);
701         return;
702      }
703
704      $opts->{'tmpfile'} =
705         HELPERS::mktmp($self->{'OpenSSL'}->{'tmp'}."/import");
706
707      open(TMP, ">$opts->{'tmpfile'}") || do {
708         GUI::HELPERS::print_warning( _("Can't create temporary file: %s: %s"),
709               $opts->{'tmpfile'}, $!);
710         return;
711      };
712      print TMP $opts->{'in'};
713      close(TMP);
714      $file = $opts->{'tmpfile'};
715   }
716
717   $parsed = $self->{'OpenSSL'}->parsereq(
718			$main->{'CA'}->{$ca}->{'cnf'},
719			$file);
720
721   if(not defined($parsed)) {
722      unlink($opts->{'tmpfile'});
723      GUI::HELPERS::print_warning(_("Parsing Request failed"));
724      return;
725   }
726
727   $main->show_import_verification("req", $opts, $parsed);
728   return;
729}
730
731#
732# import request
733#
734sub import_req {
735   my ($self, $main, $opts, $parsed, $box) = @_;
736
737   my ($ca, $cadir);
738
739   $box->destroy() if(defined($box));
740
741   GUI::HELPERS::set_cursor($main, 1);
742
743   $ca    = $main->{'reqbrowser'}->selection_caname();
744   $cadir = $main->{'reqbrowser'}->selection_cadir();
745
746   $opts->{'name'} = HELPERS::gen_name($parsed);
747
748   $opts->{'reqname'} = HELPERS::enc_base64($opts->{'name'});
749
750   $opts->{'reqfile'} = $cadir."/req/".$opts->{'reqname'}.".pem";
751
752   open(OUT, ">$opts->{'reqfile'}") || do {
753      unlink($opts->{'tmpfile'});
754      GUI::HELPERS::set_cursor($main, 0);
755      GUI::HELPERS::print_warning(_("Can't open output file: %s: %s"),
756            $opts->{'reqfile'}, $!);
757      return;
758   };
759   print OUT $opts->{'in'};
760   close OUT;
761
762   $main->{'reqbrowser'}->update($cadir."/req",
763                                 $cadir."/crl/crl.pem",
764                                 $cadir."/index.txt",
765                                 0);
766
767   GUI::HELPERS::set_cursor($main, 0);
768
769   return;
770}
771
772sub parse_req {
773   my ($self, $main, $name, $force) = @_;
774
775   my ($parsed, $ca, $reqfile, $req);
776
777   GUI::HELPERS::set_cursor($main, 1);
778
779   $ca = $main->{'CA'}->{'actca'};
780
781   $reqfile = $main->{'CA'}->{$ca}->{'dir'}."/req/".$name.".pem";
782
783   $parsed = $self->{'OpenSSL'}->parsereq($main->{'CA'}->{$ca}->{'cnf'},
784         $reqfile, $force);
785
786   GUI::HELPERS::set_cursor($main, 0);
787
788   return($parsed);
789}
790
7911
792
793