From 054411e9e54c5f51b078c20d79390352362970fa Mon Sep 17 00:00:00 2001 From: Elio Maldonado Date: Wed, 1 Oct 2008 21:31:14 +0000 Subject: [PATCH] Added support for true cert renewal, depends on recent upstream patch to certutil targeted for nss 3.12.2, will patch downstream for now. --- genkey.pl | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 180 insertions(+), 14 deletions(-) diff --git a/genkey.pl b/genkey.pl index 9a697d3..6bc7ed1 100644 --- a/genkey.pl +++ b/genkey.pl @@ -70,9 +70,11 @@ sub usage print STDERR < \$test_mode, 'genreq' => \$genreq_mode, 'days=i' => \$cert_days, + 'renew' => \$renew, + 'isca' => \$isca, 'nss|n' => \$nss, 'makeca' => \$ca_mode) or usage(); usage() unless @ARGV != 0; @@ -176,16 +182,29 @@ if ($nss) { # if (!$nss) { -if (!$genreq_mode && -f $keyfile && !$overwrite_key) { - Newt::newtWinMessage("Error", "Close", + if (!$genreq_mode && -f $keyfile && !$overwrite_key) { + Newt::newtWinMessage("Error", "Close", "You already have a key file for this host in file:\n\n" . $keyfile . "\n\n" . "This script will not overwrite an existing key.\n" . "You will need to remove or rename this file in order to" . "generate a new key for this host, then rerun the command"); - Newt::Finished(); - exit 1; -} + Newt::Finished(); + exit 1; + } +} else { + # check for the key in the database + if (!$genreq_mode && keyInDatabase($nssNickname,$modNssDbDir) && + !$renew && !$overwrite_key) { + Newt::newtWinMessage("Error", "Close", + "You already have a key file for this host in the datatabase:\n\n" . + "$modNssDbDir" ." with nickname ". "$nssNickname" . "\n\n" . + "This script will not overwrite an existing key.\n" . + "You will need to remove or rename the database in order to" . + "generate a new key for this host, then rerun the command"); + Newt::Finished(); + exit 1; + } } ###################################################################### @@ -204,13 +223,14 @@ if (!$genreq_mode && -f $keyfile && !$overwrite_key) { my @windows; if ($genreq_mode) { $useca = 1; - @windows = ( - getkeysizeWindow, + @windows = $renew + ? (passwordWindow,genReqWindow,) + : (getkeysizeWindow, customKeySizeWindow, getRandomDataWindow, passwordWindow, genReqWindow, - ); + ); $doingwhat="CSR generation"; } elsif ($ca_mode) { @windows = (CAwelcomeWindow, @@ -393,6 +413,36 @@ sub clearSensitiveData { } } +# Remove a directory and its contents +sub removeDirectory { + my ($dir) = @_; + if (-f $dir) { + opendir(DOOMED, $dir) || die("Cannot open directory"); + my @thefiles= readdir(DOOMED); + foreach my $file (@thefiles) { + unlink @file; + } + closedir(DOOMED); + rmdir $dir; + } +} + +# Print error message +sub printError { + my ($msg) = @_; + Newt::Suspend(); + print STDERR "$msg\n"; + Newt::Resume(); +} + +# Is the given key in the database? +sub keyInDatabase { + my ($nickname, $dbdir) = @_; + my $tmp = "tmp"; + my $answer = `$bindir/certutil -L -d $dbdir | grep $nickname`; + return $answer; +} + ###################################################################### # The window functions @@ -735,7 +785,8 @@ EOT # module acces password instead. sub passwordWindow { - return moduleAccesPasswordWindow() if $nss; + return moduleAccesPasswordWindow() if $nss; + return "Next" if $renew; my $message = <Add(0, 0, + Newt::TextboxReflowed(60, 10, 10, 0, + "Would you like to send a Certificate Request" . + "for\n\n$servername". + "\nto a Certificate Authority (CA)?")); + + $panel->Add(0, 1, DoubleButton("Yes", "No")); + $ret = &RunForm($panel); + $panel->Hide(); + undef $panel; + + return "Cancel" if $ret eq "Cancel"; + + # Cert to renew could be in the nss database or in a pem file + + if ($nss) { + # Renew cert in the nss database + renewCertNSS( + $csrfile, + $modNssDbDir, + $nssDBPrefix, + $nssNickname, + $days, + $tmpPasswordFile); + + } else { + # Renew cert in a PEM file + renewCertOpenSSL( + $csrfile, + $certfile, # contains cert to renew + $keyfile, # contains encrypted private key + $days, + $isca); + + ## FIXME don't harcode password - keypwdfile and I + ## though it was the p12 file pwd + } +} + sub genReqWindow { return "Skip" unless $useca; $keyfile = $ssltop."/private/".$servername.".key"; - $certfile = $ssltop."/certs/".$servername.".cert"; + $certfile = $ssltop."/certs/".$servername.".crt"; $num = 0; while (-f $ssltop."/certs/".$servername.".$num.csr") { @@ -1206,6 +1370,8 @@ sub genReqWindow } $csrfile = $ssltop."/certs/".$servername.".$num.csr"; + return renewCert($csrfile) if $renew; + my $msg = "You are about to be asked to enter information that will be ". "incorporated into your certificate request to a CA. What you are about to ". "enter is what is called a Distinguished Name or a DN. There are ".