rpms/crypto-utils/devel genkey.pl,1.17,1.18

Elio Maldonado emaldonado at fedoraproject.org
Wed Oct 1 21:31:44 UTC 2008


Author: emaldonado

Update of /cvs/extras/rpms/crypto-utils/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv26472

Modified Files:
	genkey.pl 
Log Message:
Added support for true cert renewal, depends on recent upstream patch to certutil targeted for nss 3.12.2, will patch downstream for now.


Index: genkey.pl
===================================================================
RCS file: /cvs/extras/rpms/crypto-utils/devel/genkey.pl,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- genkey.pl	27 May 2008 16:29:54 -0000	1.17
+++ genkey.pl	1 Oct 2008 21:31:14 -0000	1.18
@@ -70,9 +70,11 @@
     print STDERR <<EOH;
 Usage: genkey [options] servername
     --test   Test mode, faster seeding, overwrite existing key
-    --genreq Just generate a CSR from an existing key
-    --makeca Generate a private CA key instead
+    --genreq Generate a Certificate Signing Request (CSR)
+    --makeca Generate a self-signed certificate for a CA
     --days   Days until expiry of self-signed certificate (default 30)
+    --renew  CSR is for cert renewal, reusing existing key pair
+    --isca   Renewal is for a CA certificate
     --nss    Use the nss database for keys and certificates
 EOH
     exit 1;
@@ -121,12 +123,16 @@
 my $ca_mode = '';
 my $cert_days = 30;
 my $nss ='';
+my $renew = '';
+my $isca = '';
 my $modNssDbDir = '';
 my $nssNickname = '';
 my $nssDBPrefix = '';
 GetOptions('test|t' => \$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 (!$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 @@
 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 @@
     }
 }
 
+# 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 @@
 # module acces password instead.
 sub passwordWindow
 {
-	return moduleAccesPasswordWindow() if $nss;
+    return moduleAccesPasswordWindow() if $nss;
+    return "Next" if $renew;
 	
     my $message = <<EOT;
 At this stage you can set the passphrase on your private key. If you
@@ -869,7 +920,8 @@
     # If no days specified it's a ca so use 2 years
     use integer;
     my $months = $days / 30;      
-    my $trustargs = "\"" . "TCu,TCu,TCuw". "\"";
+    my $trustargs = $ca_mode ? "CT,," : "u,,";
+    $trustargs = "\"" . $trustargs. "\"";
     
     my $args = "-S ";
     $args .= "-n $nickname ";
@@ -991,7 +1043,7 @@
 
     use integer;
     my $months = $days ? $days / 30 : 24;
-            
+    
     # build the arguments for a gen request call
     my $args = "-c genreq ";
     $args   .= "-g $bits "; 
@@ -1032,6 +1084,69 @@
     }
 }
 
+# Renew a certificate which is stored in the nss database
+sub renewCertNSS
+{
+    my ($csrfile, $dbdir, $dbprefix, $nickname, $days, $pwdfile) = @_;
+
+    use integer;
+    my $months = $days ? $days / 30 : 24;
+    
+    # Build the arguments for a certificate renewal request
+    # This is a request where we reuse the existing key pair
+    
+    my $args = "-R ";
+    $args   .= "-d $dbdir ";
+    $args   .= "-p $dbprefix " if $dbprefix;
+    $args   .= "-a ";              ## using ascii 
+    $args   .= "-k $nickname ";    ## pass cert nickname as key id
+    $args   .= "-f $pwdfile "   if $pwdfile;
+    $args   .= "-v $months ";
+    $args   .= "-o $csrfile ";
+    
+    nssUtilCmd("$bindir/certutil", $args);
+    
+    if (!-f $csrfile) {
+        Newt::newtWinMessage("Error", "Close", 
+                 "Was not able to create a CSR for this ".
+                 "host:\n\nPress return to exit");
+        Newt::Finished();
+        exit 1; 
+    }
+}
+
+# Renew a certificate which is stored in a PEM file
+sub renewCertOpenSSL
+{
+    my ($csrfile, # output
+        $certfile,$keyfile,$days,$isca) = @_;
+
+    use integer;
+    my $months = $days ? $days / 30 : 24;
+    
+    # Build the arguments for a certificate renewal request
+    # This is a request where we reuse the existing key pair
+
+    my $args = "--command genreq ";
+    $args   .= "--renew $certfile "; 
+    $args   .= "--input $keyfile "; 
+    $args   .= "--validity $months "; 
+    $args   .= "--out $csrfile ";
+ 
+    nssUtilCmd("$bindir/keyutil", $args);
+         
+    unlink($noisefile);
+    Newt::Resume();
+    
+    if (!-f $csrfile) {
+        Newt::newtWinMessage("Error", "Close", 
+                 "Unable to create a cert signing request for this ".
+                 "host:\n\nPress return to exit");
+        Newt::Finished();
+        exit 1;
+    }
+}
+
 sub AddField
 {
     my ($panel, $row, $msg, $default, $width, $topspace, $flags) = (@_, 0, 0);
@@ -1193,12 +1308,61 @@
     return $ret;
 }
 
+# Cert signing request generation for renewal
+sub renewCert
+{
+    my ($csrfile) = @_;
+
+    my $tempDbDir = "/tmp/nss.".$$;
+
+    # Get a comfirmation
+    my $msg = "You are about to issue a certificate renewal";
+    my $panel = Newt::Panel(1, 2, "Certificate Renewal");
+    $panel->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 @@
     }
     $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 ".




More information about the fedora-extras-commits mailing list