rpms/crypto-utils/devel keyutil.c,1.4,1.5

Elio Maldonado emaldonado at fedoraproject.org
Wed Oct 1 21:23:20 UTC 2008


Author: emaldonado

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

Modified Files:
	keyutil.c 
Log Message:
Added support for true cert renew, this may move to certutil in nss


Index: keyutil.c
===================================================================
RCS file: /cvs/extras/rpms/crypto-utils/devel/keyutil.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- keyutil.c	11 May 2008 02:53:02 -0000	1.4
+++ keyutil.c	1 Oct 2008 21:22:49 -0000	1.5
@@ -65,11 +65,15 @@
  * ***** END LICENSE BLOCK ***** */
 
 /*
-** keyutil.c
-**
-** utility for managing certificates and the cert database
-**
-*/
+ * keyutil.c
+ *
+ * Utility for managing certificates and the cert database
+ *
+ * Key generation, encryption, and certificate utility code, based on
+ * code from NSS's security utilities and the certutil application.  
+ * Elio Maldonado <emaldona at redhat.com> 
+ *
+ */
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
@@ -165,6 +169,15 @@
 #include "secerr.h"
 #include "sslerr.h"
 
+#ifndef PK11_SETATTRS
+#define PK11_SETATTRS(x,id,v,l) (x)->type = (id); \
+		(x)->pValue=(v); (x)->ulValueLen = (l);
+#endif
+
+SECMODModule* mod = NULL; /* the pem module */
+static const char* pem_library = "libnsspem.so";
+/* will use this slot only */
+CK_SLOT_ID slotID = 1;
 
 char *progName;
 
@@ -173,7 +186,8 @@
 {
     fprintf(stderr, "Usage: %s [options] arguments\n", progName);
     fprintf(stderr, "-h print this help message");
-    fprintf(stderr, "-c command one of [genreq|makecert]");
+    fprintf(stderr, "-c command, one of [genreq|makecert]");
+    fprintf(stderr, "-r the cert to renew");
     fprintf(stderr, "-s subject subject distinguished name");
     fprintf(stderr, "-g keysize in bits");
     fprintf(stderr, "-v validity in months");
@@ -181,7 +195,7 @@
     fprintf(stderr, "-f key encryption password file");
     fprintf(stderr, "-f module access password file");
     fprintf(stderr, "-d digest algorithm");
-    fprintf(stderr, "-i input (key to encrypt)");
+    fprintf(stderr, "-i input (key to encrypt or to sign a request with)");
     fprintf(stderr, "-k key out, when csr or cert generation");
     fprintf(stderr, "-o output (a csr or cert)");
     fprintf(stderr, "-p passout, the pbe password");
@@ -190,6 +204,334 @@
 }
 
 /*
+ * Loads the key from the specified file into the module at
+ * the specified slot and returns a key object.
+ */
+#if(0)
+static SECStatus loadCert(
+    PK11SlotInfo *slot, 
+    const char *certfile,
+    const char *nickname) 
+{
+	SECStatus rv = SECSuccess;
+    PRBool cacert = PR_FALSE;             /* only server certs for now */
+    PK11GenericObject *genericObjCert;
+    CK_ATTRIBUTE theCertTemplate[20];
+    CK_ATTRIBUTE *attrs = NULL;
+    CK_BBOOL cktrue = CK_TRUE;
+    CK_BBOOL ckfalse = CK_FALSE;
+    CK_OBJECT_CLASS certObjClass = CKO_CERTIFICATE;
+	PRBool isPresent;
+    PK11GenericObject *object;
+    CK_ATTRIBUTE theTemplate[20];
+    CERTCertificate *cert = NULL;
+
+    do {
+        /*
+         * Load the certificate
+         */
+    	attrs = theCertTemplate;
+        PK11_SETATTRS(attrs, CKA_CLASS, &certObjClass, sizeof(certObjClass)); attrs++;
+        PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL)); attrs++;
+        PK11_SETATTRS(attrs, CKA_LABEL, (unsigned char *)certfile, strlen(certfile)+1); attrs++;
+        if (cacert) {
+            PK11_SETATTRS(attrs, CKA_TRUST, &cktrue, sizeof(CK_BBOOL) ); attrs++;
+        } else {
+            PK11_SETATTRS(attrs, CKA_TRUST, &ckfalse, sizeof(CK_BBOOL) ); attrs++;
+        }
+
+        /* Load the certificate in our PEM module into the appropriate slot. */
+        genericObjCert = PK11_CreateGenericObject(slot, theCertTemplate, 4, PR_FALSE /* isPerm */);
+        if (!genericObjCert) {
+        	rv = PR_GetError();
+        	PR_fprintf(PR_STDERR, "%s: unable to Create object for cert, (%s)\n", 
+                    progName, SECU_Strerror(rv));
+
+            break;
+        }
+        if (!cacert) {
+            /* Double-check that the certificate or nickname requested exists in
+             * either the token or the NSS certificate database.
+             */
+            cert = PK11_FindCertFromNickname((char *)nickname, NULL);
+        	if (!cert) {
+        		PR_fprintf(PR_STDERR, "%s: Can't find cert named (%s), bailing out\n", 
+        				   progName, nickname);
+        		rv = 255;
+        		break;
+        	} else {
+        	   rv = SECSuccess;
+        	}
+        } else {
+        	rv = SECSuccess;
+        }    	
+  	
+    } while (0);
+    
+    if (cert)
+    	CERT_DestroyCertificate(cert);
+    	
+    return rv;
+
+}
+#endif
+
+/*
+ * Loads the certificate from the specified file into the module at
+ * the specified slot and returns a certificate object.
+ */
+#if(0)
+static SECStatus loadKey(
+		PK11SlotInfo *slot, 
+		const char *keyfile, 
+		const char *nickname,
+		CERTCertificate **keycert) 
+{
+	SECStatus rv = SECSuccess;
+    CK_ATTRIBUTE *attrs = NULL;
+    CK_BBOOL cktrue = CK_TRUE;
+    CK_BBOOL ckfalse = CK_FALSE;
+
+	PRBool isPresent;
+    PK11GenericObject *object;
+    CK_ATTRIBUTE theTemplate[20];
+    CK_OBJECT_CLASS objClass = CKO_PRIVATE_KEY;
+    CERTCertificate *cert = NULL;
+    SECKEYPrivateKey *privkey = NULL;
+    int retryCount = 0;
+
+    do {   	
+        
+        /* must find it again because "reinsertion" */
+        cert = PK11_FindCertFromNickname((char *)nickname, NULL);
+
+        attrs = theTemplate;
+        PK11_SETATTRS(attrs, CKA_CLASS, &objClass, sizeof(objClass) ); attrs++;
+        PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL) ); attrs++;
+        PK11_SETATTRS(attrs, CKA_LABEL, (unsigned char *)keyfile, strlen(keyfile)+1); attrs++;
+
+        /* When adding an encrypted key the PKCS#11 will be set as removed */
+        object = PK11_CreateGenericObject(slot, theTemplate, 3, PR_FALSE /* isPerm */);
+        if (!object) {  	
+            rv = PR_GetError();
+            PR_fprintf(PR_STDERR, 
+            		"%s: unable to create key object (%s)\n", 
+                    progName, SECU_Strerror(rv));
+        	break;
+        }
+
+        /* This will force the token to be seen as re-inserted */
+        (void) SECMOD_WaitForAnyTokenEvent(mod, 0, 0);
+        isPresent = PK11_IsPresent(slot);
+        assert(isPresent);
+
+        rv = PK11_Authenticate(slot, PR_TRUE, pwdata->data);
+        if (rv != SECSuccess) { 
+        	PR_fprintf(PR_STDERR, "Can't authenticate\n"); 
+            break;
+        }
+
+        /* Can we find the key? */
+
+        privkey = PK11_FindPrivateKeyFromCert(slot, cert, pwdata->data);
+        if (!privkey) {
+        	rv = PR_GetError();
+        	PR_fprintf(PR_STDERR, "%s: unable to find the key for cert, (%s)\n", 
+                    progName, SECU_Strerror(rv));
+            GEN_BREAK(SECFailure);
+        }
+        rv = SECSuccess;
+  	
+    } while (0);
+    
+    if (cert)
+    	CERT_DestroyCertificate(cert);
+    	
+    return rv;
+
+}
+#endif
+
+/*
+ * Loads the certificate and private key from the specified files into 
+ * the PEM the module at the specified slot.
+ * 
+ * @param slot the slot to load into
+ * @param certfile the certificate file
+ * @param nickname the certificate nickname
+ * @param keyfile the key file
+ * @param pwdata access password
+ */
+static SECStatus loadCertAndKey(
+		PK11SlotInfo *slot, 
+		const char *certfile, 
+		const char *nickname,
+		const char *keyfile,
+		secuPWData *pwdata)
+{
+	SECStatus rv = SECSuccess;
+    PRBool cacert = PR_FALSE;             /* only server certs for now */
+    PK11GenericObject *genericObjCert;
+    CK_ATTRIBUTE theCertTemplate[20];
+    CK_ATTRIBUTE *attrs = NULL;
+    CK_BBOOL cktrue = CK_TRUE;
+    CK_BBOOL ckfalse = CK_FALSE;
+    CK_OBJECT_CLASS certObjClass = CKO_CERTIFICATE;
+	PRBool isPresent;
+    PK11GenericObject *object;
+    CK_ATTRIBUTE theTemplate[20];
+    CK_OBJECT_CLASS objClass = CKO_PRIVATE_KEY;
+    CERTCertificate *cert = NULL;
+    SECKEYPrivateKey *privkey = NULL;
+    /*int retryCount = 0;*/
+
+    do {
+        /*
+         * Load the certificate
+         */
+    	attrs = theCertTemplate;
+        PK11_SETATTRS(attrs, CKA_CLASS, &certObjClass, sizeof(certObjClass)); attrs++;
+        PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL)); attrs++;
+        PK11_SETATTRS(attrs, CKA_LABEL, (unsigned char *)certfile, strlen(certfile)+1); attrs++;
+        if (cacert) {
+            PK11_SETATTRS(attrs, CKA_TRUST, &cktrue, sizeof(CK_BBOOL) ); attrs++;
+        } else {
+            PK11_SETATTRS(attrs, CKA_TRUST, &ckfalse, sizeof(CK_BBOOL) ); attrs++;
+        }
+
+        /* Load the certificate in our PEM module into the appropriate slot. */
+        genericObjCert = PK11_CreateGenericObject(slot, theCertTemplate, 4, PR_FALSE /* isPerm */);
+        if (!genericObjCert) {
+        	rv = PR_GetError();
+        	PR_fprintf(PR_STDERR, "%s: unable to Create object for cert, (%s)\n", 
+                    progName, SECU_Strerror(rv));
+
+            break;
+        }
+        if (!cacert) {
+            /* Double-check that the certificate or nickname requested exists in
+             * either the token or the NSS certificate database.
+             */
+            cert = PK11_FindCertFromNickname((char *)nickname, NULL);
+        	if (!cert) {
+        		PR_fprintf(PR_STDERR, "%s: Can't find cert named (%s), bailing out\n", 
+        				   progName, nickname);
+        		rv = 255;
+        		break;
+        	} else {
+        	   rv = SECSuccess;
+        	}
+        } else {
+        	rv = SECSuccess;
+        }    	
+
+        /*
+         * Load the private key
+         */
+        
+        attrs = theTemplate;
+
+        PK11_SETATTRS(attrs, CKA_CLASS, &objClass, sizeof(objClass) ); attrs++;
+        PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL) ); attrs++;
+        PK11_SETATTRS(attrs, CKA_LABEL, (unsigned char *)keyfile, strlen(keyfile)+1); attrs++;
+
+        /* When adding an encrypted key the PKCS#11 will be set as removed */
+        object = PK11_CreateGenericObject(slot, theTemplate, 3, PR_FALSE /* isPerm */);
+        if (!object) {  	
+            rv = PR_GetError();
+            PR_fprintf(PR_STDERR, 
+            		"%s: unable to create key object (%s)\n", 
+                    progName, SECU_Strerror(rv));
+        	break;
+        }
+        /* This will force the token to be seen as re-inserted */
+        (void) SECMOD_WaitForAnyTokenEvent(mod, 0, 0);
+        isPresent = PK11_IsPresent(slot);
+        assert(isPresent);
+
+        rv = PK11_Authenticate(slot, PR_TRUE, pwdata->data);
+        if (rv != SECSuccess) { 
+        	PR_fprintf(PR_STDERR, "Can't authenticate\n"); 
+            break;
+        }
+        
+        /* must find it again because "reinsertion" */
+        cert = PK11_FindCertFromNickname((char *)nickname, NULL);
+
+        /* Can we find the key? */
+        assert(cert);
+        privkey = PK11_FindPrivateKeyFromCert(slot, cert, pwdata->data);
+        if (!privkey) {
+        	rv = PR_GetError();
+        	PR_fprintf(PR_STDERR, "%s: unable to find the key for cert, (%s)\n", 
+                    progName, SECU_Strerror(rv));
+            GEN_BREAK(SECFailure);
+        }
+        rv = SECSuccess;
+  	
+    } while (0);
+    
+    if (cert)
+    	CERT_DestroyCertificate(cert);
+    	
+    return rv;
+}
+
+static SECStatus extractRSAKeysAndSubject(
+	const char *nickname,
+	PK11SlotInfo *slot,
+	void *pwdata,
+    SECKEYPrivateKey **privkey,
+    SECKEYPublicKey **pubkey,
+    CERTName **subject)
+{
+	SECStatus rv = SECSuccess;
+	CERTCertificate *cert = NULL;
+	
+    do {
+    	
+    	cert = PK11_FindCertFromNickname((char *)nickname, NULL);
+    	if (!cert) {
+    		GEN_BREAK(SECFailure);
+    	}
+ 
+        *pubkey = CERT_ExtractPublicKey(cert);
+        if (!*pubkey) {
+        	PR_fprintf(PR_STDERR, "%s: Could not get public key from cert, (%s)\n", 
+                       progName, SECU_Strerror(PR_GetError()));
+		    GEN_BREAK(SECFailure);
+        }
+
+        *privkey = PK11_FindKeyByDERCert(slot, cert, &pwdata);
+        if (!*privkey) {
+        	rv = PR_GetError();
+        	PR_fprintf(PR_STDERR, "%s: unable to find the key with PK11_FindKeyByDERCert, (%s)\n", 
+                       progName, SECU_Strerror(rv));
+        	*privkey= PK11_FindKeyByAnyCert(cert, &pwdata);
+        	rv = PR_GetError();
+        	PR_fprintf(PR_STDERR, "%s: unable to find the key with PK11_FindKeyByAnyCert, (%s)\n", 
+                       progName, SECU_Strerror(rv));
+       	
+            GEN_BREAK(SECFailure);
+        }
+
+	    assert(((*privkey)->keyType) == rsaKey);
+        *subject = CERT_AsciiToName(cert->subjectName);
+        
+ 		if (!*subject) {
+		    PR_fprintf(PR_STDERR, "%s -s: improperly formatted name: \"%s\"\n", 
+		    		   progName, cert->subjectName);
+		    GEN_BREAK(SECFailure);
+		 }
+         rv = SECSuccess;
+    } while (0);
+   
+    if (cert)
+        CERT_DestroyCertificate(cert);
+    return rv;
+}
+
+/*
  * Modelled after the one in certutil
  */
 static CERTCertificateRequest *
@@ -767,7 +1109,7 @@
     int publicExponent,
     char *noise, 
     SECKEYPublicKey **pubkeyp,
-    secuPWData *accessPassword)
+    secuPWData *pwdata)
 {
     CK_MECHANISM_TYPE  mechanism;
     PK11RSAGenParams   rsaparams;
@@ -776,7 +1118,7 @@
     if (slot == NULL) 
         return NULL;
 
-    if (PK11_Authenticate(slot, PR_TRUE, accessPassword) != SECSuccess)
+    if (PK11_Authenticate(slot, PR_TRUE, pwdata) != SECSuccess)
         return NULL;
 
     /*
@@ -808,7 +1150,7 @@
             mechanism, &rsaparams, pubkeyp,
             PR_FALSE /* isPerm */, 
             PR_TRUE  /* isSensitive*/, 
-            accessPassword   /* wincx */
+            pwdata   /* wincx */
             );
     
     assert(privKey);
@@ -823,7 +1165,7 @@
     SECKEYEncryptedPrivateKeyInfo *epki,    
     SECOidTag algTag,
     SECItem *pwitem, 
-    secuPWData *accessPassword,
+    secuPWData *pwdata,
     SECItem *derPKI)
 {
     SECItem  *cryptoParam = NULL;
@@ -856,7 +1198,7 @@
         	ERROR_BREAK;
         }
         
-        symKey = PK11_PBEKeyGen(slot, &algid, pwitem, PR_FALSE, accessPassword);
+        symKey = PK11_PBEKeyGen(slot, &algid, pwitem, PR_FALSE, pwdata);
         if (symKey == NULL) {
             ERROR_BREAK;
         }
@@ -903,7 +1245,7 @@
        SECKEYPrivateKey *privkey,
        SECKEYPublicKey *pubkey,
        SECOidTag algTag,
-       secuPWData *accessPassword,
+       secuPWData *pwdata,
        PRBool ascii)
 {
     
@@ -950,7 +1292,7 @@
         }
 
         epki = PK11_ExportEncryptedPrivKeyInfo(NULL,
-                algTag, &pwitem, privkey, 1000, accessPassword);
+                algTag, &pwitem, privkey, 1000, pwdata);
         if (!epki) {
             rv = PORT_GetError();
             SECU_PrintError(progName, 
@@ -983,7 +1325,7 @@
             derPKI.len = epki->encryptedData.len;
             derPKI.type = siBuffer;
 
-            rv = DecryptKey(epki, algTag, &pwitem, accessPassword, &derPKI);
+            rv = DecryptKey(epki, algTag, &pwitem, pwdata, &derPKI);
             if (rv) {
                 GEN_BREAK(rv);
             }
@@ -1069,6 +1411,8 @@
         const char       *noisefile, 
         const char       *access_pwd_file,
         const char       *key_pwd_file,
+        const char       *cert_to_renew,
+        const char       *input_key_file,
         const char       *subjectstr,
         int              keysize, 
         int              warpmonths,
@@ -1086,30 +1430,65 @@
     CERTName   *subject         = NULL;
     SECKEYPrivateKey *privkey   = NULL;
     SECKEYPublicKey *pubkey     = NULL;
-                               /* PK11_GetInternalSlot() ? */
-    PK11SlotInfo *slot          = PK11_GetInternalKeySlot();
-    secuPWData  accessPassword  = { PW_NONE, 0 };
+    PK11SlotInfo *slot          = NULL;
+    secuPWData  pwdata          = { PW_NONE, 0 };
     KeyType     keytype         = rsaKey;
     SECOidTag   hashAlgTag      = SEC_OID_UNKNOWN;
     PRBool      doCert          = certfile != NULL;
     int         rv;
+    
+    if (cert_to_renew && input_key_file) {
+    	CK_SLOT_ID slotID = 1;
+    	char slotname[32];
+    	char nickname[256];
+    	CERTCertificate *keycert = NULL;
+    	const char *n = cert_to_renew;
+ 
+    	/* Remove the path part */
+        n = strrchr(cert_to_renew, '/');
+        if (!n) 
+        	n = cert_to_renew;
+        else 
+        	n++;
+
+        snprintf(slotname, 32, "PEM Token #%ld", slotID);
+        snprintf(nickname, 256, "PEM Token #%ld:%s", slotID, n);
+        slot = PK11_FindSlotByName(slotname);
+        if (!slot) {
+        	printf("%s: Can't find slot for %s\n", progName, slotname);
+        	rv = 255;
+        	goto shutdown;
+        }
+               
+        rv = loadCertAndKey(slot,
+                            cert_to_renew, nickname, input_key_file, 
+                            &pwdata);
 
-    outFile = PR_Open(certreqfile, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE, 00660);
-    if (!outFile) {
-        PR_fprintf(PR_STDERR, 
-               "%s -o: unable to open \"%s\" for writing (%ld, %ld)\n",
-               progName, certreqfile,
-               PR_GetError(), PR_GetOSError());
-        return 255;
-    }
-    printf("Opened %s for writing\n", certreqfile);
-    if (access_pwd_file) {
-        accessPassword.source = PW_FROMFILE;
-        accessPassword.data = (char *)access_pwd_file;
-    }
+        if (rv != SECSuccess) {
+	        printf("%s: Can't load the key or cert, bailing out\n", progName);
+	        goto shutdown;
+        }
+        
+        rv = extractRSAKeysAndSubject(nickname, 
+                slot, &pwdata, &privkey, &pubkey, &subject);
+        
+        if (rv != SECSuccess) {
+            if (keycert) {
+            	CERT_DestroyCertificate(keycert);
+            }
+          goto shutdown;
+        }
+
+        assert(privkey);
+        assert(pubkey);
+        assert(subject);
+
+    } else {
+    	
+   slot = PK11_GetInternalKeySlot(); /* PK11_GetInternalSlot() ? */
 
     privkey = GenerateRSAPrivateKey(keytype, slot, 
-            keysize, 65537L, (char *)noisefile, &pubkey, &accessPassword);
+            keysize, 65537L, (char *)noisefile, &pubkey, &pwdata);
     
     if (!privkey) {
         PR_fprintf(PR_STDERR,
@@ -1118,10 +1497,6 @@
         rv = 255;
         goto shutdown;
     }
-    PR_fprintf(PR_STDOUT, "%s Got a key\n", progName);
-    /*
-     *  Certificate request
-     */
     subject = CERT_AsciiToName((char *)subjectstr);
     if (!subject) {
         PR_fprintf(PR_STDERR, "%s -s: improperly formatted name: \"%s\"\n",
@@ -1129,9 +1504,30 @@
         rv = 255;
         goto shutdown;
     }
+
+    }
+    PR_fprintf(PR_STDOUT, "%s Got a key\n", progName);
     
-    hashAlgTag = SEC_OID_MD5;
+    outFile = PR_Open(certreqfile, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE, 00660);
+    if (!outFile) {
+        PR_fprintf(PR_STDERR, 
+               "%s -o: unable to open \"%s\" for writing (%ld, %ld)\n",
+               progName, certreqfile,
+               PR_GetError(), PR_GetOSError());
+        return 255;
+    }
+    printf("Opened %s for writing\n", certreqfile);
+    if (access_pwd_file) {
+        pwdata.source = PW_FROMFILE;
+        pwdata.data = (char *)access_pwd_file;
+    }
+
+    /*
+     *  Certificate request
+     */
     
+    hashAlgTag = SEC_OID_MD5;
+ 
     /*  Make a cert request */
     rv = CertReq(privkey, pubkey, rsaKey, hashAlgTag, subject,
                  NULL,         /* PhoneNumber */
@@ -1164,7 +1560,7 @@
         LL_USHR(now, now, 19);
         LL_L2UI(serialNumber, now);
         
-        privkey->wincx = &accessPassword;
+        privkey->wincx = &pwdata;
         PR_Close(outFile);
        
         inFile  = PR_Open(certreqfile, PR_RDONLY, 0);
@@ -1190,7 +1586,7 @@
         /* issuerName == subject */
         rv = CreateCert(certHandle, 
             "tempnickname", inFile, outFile,
-            privkey, &accessPassword, hashAlgTag,
+            privkey, &pwdata, hashAlgTag,
             serialNumber, warpmonths, validityMonths,
             NULL, NULL, ascii, PR_TRUE, NULL,
             &cert);
@@ -1210,7 +1606,7 @@
     
          /* for fips - must log in to get private key */
         if (slot && PK11_NeedLogin(slot)) {
-            SECStatus newrv = PK11_Authenticate(slot, PR_TRUE, &accessPassword);
+            SECStatus newrv = PK11_Authenticate(slot, PR_TRUE, &pwdata);
             if (newrv != SECSuccess) {
                 SECU_PrintError(progName, "could not authenticate to token %s.",
                             PK11_GetTokenName(slot));
@@ -1226,7 +1622,7 @@
          */
         rv = KeyOut(keyoutfile, key_pwd_file,
                 privkey, pubkey, SEC_OID_DES_EDE3_CBC, 
-                &accessPassword, ascii);
+                &pwdata, ascii);
         if (rv != SECSuccess) {
             SECU_PrintError(progName, "Failed to write the key");
         } else {
@@ -1250,6 +1646,10 @@
     if (pubkey) {
         SECKEY_DestroyPublicKey(pubkey);
     }
+    if (mod) {
+        rv = SECMOD_UnloadUserModule(mod);
+        mod = NULL;
+    }
 
     return rv == SECSuccess ? 0 : 255;
 }
@@ -1267,6 +1667,7 @@
     int optc, rv = 0;
     static const struct option options[] = {
         { "command",    required_argument, NULL, 'c' },
+        { "renew",      required_argument, NULL, 'r' },
         { "subject",    required_argument, NULL, 's' },
         { "gkeysize",   required_argument, NULL, 'g' },
         { "validity",   required_argument, NULL, 'v' },
@@ -1289,6 +1690,7 @@
     int  validity_months = 24;
     char *keyfile = NULL;
     char *outfile = NULL;
+    char *cert_to_renew = NULL;
     char *subject = NULL;
     char *access_pwd_file = NULL;
     char *key_pwd_file = NULL;
@@ -1299,8 +1701,8 @@
     SECStatus status = 0;
     CommandType cmd = cmd_CertReq;
     PRBool initialized = PR_FALSE;
-  
-    while ((optc = getopt_long(argc, argv, "ac:s:g:v:e:f:d:z:i:p:o:k:h", options, NULL)) != -1) {
+      
+    while ((optc = getopt_long(argc, argv, "ac:rs:g:v:e:f:d:z:i:p:o:k:h", options, NULL)) != -1) {
         switch (optc) {
         case 'a':
             ascii = PR_TRUE;
@@ -1320,6 +1722,9 @@
             }
             printf("command:  %s\n", cmdstr);
             break;
+        case 'r':
+            cert_to_renew = strdup(optarg);
+            break;
         case 's':
             subject = strdup(optarg);
             printf("subject = %s\n", subject);
@@ -1380,6 +1785,24 @@
         printf("NSS initialization failed\n");
         return EXIT_FAILURE;
     }
+    if (cert_to_renew) {
+        char *configstring = NULL;
+    	//PK11_SetPasswordFunc(SECU_FilePasswd);    	
+        /* Load our PKCS#11 module */
+        configstring = (char *)malloc(4096);   
+        PR_snprintf(configstring, 4096,
+                    "library=%s name=PEM parameters=\"\"", pem_library);
+        mod = SECMOD_LoadUserModule(configstring, NULL, PR_FALSE);
+        if (!mod || !mod->loaded) {
+            printf("%s: Failed to load %s\n", progName, pem_library);
+        }
+        free(configstring);
+    	if (!mod) {
+            NSS_Shutdown();
+            PR_Cleanup();
+            return EXIT_FAILURE;
+    	}
+    }
     initialized = PR_TRUE;
     
     certHandle = CERT_GetDefaultCertDB();
@@ -1390,12 +1813,14 @@
         /* certfile NULL signals only the request is needed */
         rv = keyutil_main(certHandle,
                 noisefile, access_pwd_file, key_pwd_file,
+                cert_to_renew, keyfile, 
                 subject, keysize, warpmonths, validity_months,
                 ascii, outfile, NULL, keyoutfile);
         break;
     case cmd_CreateNewCert:
         rv = keyutil_main(certHandle,
                 noisefile, access_pwd_file, key_pwd_file,
+                NULL, NULL,
                 subject, keysize, warpmonths, validity_months,
                 ascii, "tmprequest", outfile, keyoutfile);
         break;




More information about the scm-commits mailing list