rpms/crypto-utils/devel keyutil.c,1.6,1.7

Elio Maldonado emaldonado at fedoraproject.org
Sun Oct 19 05:09:23 UTC 2008


Author: emaldonado

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

Modified Files:
	keyutil.c 
Log Message:
Added support for CA cert renewal


Index: keyutil.c
===================================================================
RCS file: /cvs/extras/rpms/crypto-utils/devel/keyutil.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- keyutil.c	11 Oct 2008 19:45:12 -0000	1.6
+++ keyutil.c	19 Oct 2008 05:08:53 -0000	1.7
@@ -204,26 +204,29 @@
 }
 
 /*
- * Loads the key from the specified file into the module at
- * the specified slot and returns a key object.
+ * Loads the cert from the specified file into the module at
+ * the specified slot.
+ *
+ * This function is modelled after the one in libcurl.
+ *
+ * @param slot the slot to load the cert into
+ * @param cacert true if the cert is for a ca, false otherwise
+ * @param certfile pem encoded file with the certificate
+ * @param nickname the certificate niskanme
  */
-#if(0)
 static SECStatus loadCert(
     PK11SlotInfo *slot, 
+    PRBool cacert,
     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 {
@@ -246,7 +249,6 @@
         	rv = PR_GetError();
         	PR_fprintf(PR_STDERR, "%s: unable to Create object for cert, (%s)\n", 
                     progName, SECU_Strerror(rv));
-
             break;
         }
         if (!cacert) {
@@ -264,7 +266,7 @@
         	}
         } else {
         	rv = SECSuccess;
-        }    	
+        }
   	
     } while (0);
     
@@ -272,38 +274,34 @@
     	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.
+ * Loads the key from the specified file into the module at
+ * the specified slot.
+ *
+ * function is modelled after the one in libcurl.
+ * @param slot the slot into which the key will be loaded
+ * @param keyfile the file from which the key will be read
+ * @param nickname the nickname of the matching certificate
  */
-#if(0)
 static SECStatus loadKey(
 		PK11SlotInfo *slot, 
 		const char *keyfile, 
 		const char *nickname,
-		CERTCertificate **keycert) 
+		secuPWData *pwdata) 
 {
 	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++;
@@ -312,10 +310,11 @@
 
         /* 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", 
+        if (!object) {
+        	rv = SEC_ERROR_BAD_KEY;
+        	PR_SetError(rv, 0);
+            PR_fprintf(PR_STDERR,
+                    "%s: unable to create key object (%s)\n", 
                     progName, SECU_Strerror(rv));
         	break;
         }
@@ -331,6 +330,10 @@
             break;
         }
 
+        /* must find it again because "reinsertion" */
+        cert = PK11_FindCertFromNickname((char *)nickname, NULL);
+        assert(cert);
+
         /* Can we find the key? */
 
         privkey = PK11_FindPrivateKeyFromCert(slot, cert, pwdata->data);
@@ -348,9 +351,7 @@
     	CERT_DestroyCertificate(cert);
     	
     return rv;
-
 }
-#endif
 
 /*
  * Loads the certificate and private key from the specified files into 
@@ -364,119 +365,40 @@
  */
 static SECStatus loadCertAndKey(
 		PK11SlotInfo *slot, 
+		PRBool cacert,
 		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);
-    	
+    /* 
+     * Load the certificate first 
+    */
+    rv = loadCert(slot, cacert, certfile, nickname);
+    if (rv != SECSuccess) return rv;
+ 
+    /* 
+     * Load the private key next
+     */
+    rv = loadKey(slot, keyfile, nickname, pwdata);
+        	
     return rv;
 }
 
+/*
+ * Extract the public and private keys and the subject
+ * distinguished from the cert with the given nickname 
+ * in the given slot.
+ * 
+ * @param nickname the certificate nickname
+ * @param slot the slot where keys it was loaded
+ * @param pwdat password to authenication into slot
+ * @param privkey private key out
+ * @param pubkey public key out
+ * @param subject subject out
+ */
 static SECStatus extractRSAKeysAndSubject(
 	const char *nickname,
 	PK11SlotInfo *slot,
@@ -532,7 +454,7 @@
 }
 
 /*
- * Modelled after the one in certutil
+ * Modeled after the one in certutil
  */
 static CERTCertificateRequest *
 GetCertRequest(PRFileDesc *inFile, PRBool ascii)
@@ -594,6 +516,9 @@
     return certReq;
 }
 
+/*
+ * Modeled after the one in certutil
+ */
 static SECStatus
 CertReq(SECKEYPrivateKey *privk, SECKEYPublicKey *pubk, KeyType keyType,
         SECOidTag hashAlgTag, CERTName *subject, char *phone, int ascii, 
@@ -718,6 +643,9 @@
     return SECSuccess;
 }
 
+/*
+ * Modeled after the one in certutil
+ */
 static CERTCertificate *
 MakeV1Cert(CERTCertDBHandle *   handle, 
         CERTCertificateRequest *req,
@@ -769,6 +697,9 @@
     return(cert);
 }
 
+/*
+ * Modelled after the one in certutil
+ */
 static SECItem *
 SignCert(CERTCertDBHandle *handle, CERTCertificate *cert, PRBool selfsign, 
          SECOidTag hashAlgTag,
@@ -847,6 +778,9 @@
     return result;
 }
 
+/*
+ * Modelled after the one in certutil
+ */
 static SECStatus
 CreateCert(
     CERTCertDBHandle *handle, 
@@ -1413,6 +1347,7 @@
         const char       *key_pwd_file,
         const char       *cert_to_renew,
         const char       *input_key_file,
+        PRBool           cacert,
         const char       *subjectstr,
         int              keysize, 
         int              warpmonths,
@@ -1442,7 +1377,7 @@
          * This certificate request is for a renewal,
          * using existing keys.
          */
-    	CK_SLOT_ID slotID = 1;
+    	CK_SLOT_ID slotID = cacert ? 0 : 1;
     	char slotname[32];
     	char nickname[256];
     	CERTCertificate *keycert = NULL;
@@ -1464,7 +1399,7 @@
             goto shutdown;
         }
                
-        rv = loadCertAndKey(slot,
+        rv = loadCertAndKey(slot, cacert,
                             cert_to_renew, nickname, input_key_file, 
                             &pwdata);
 
@@ -1686,6 +1621,7 @@
         { "output",     required_argument, NULL, 'o' }, /* reg, cert, enckey */
         { "keyout",     required_argument, NULL, 'k' }, /* plaintext key */
         { "ascii",      no_argument,       NULL, 'a' }, /* ascii */
+        { "cacert",     no_argument,       NULL, 't' }, /* ca cert to renew */
         { "help",       no_argument,       NULL, 'h' },
         { NULL }
     };
@@ -1703,16 +1639,20 @@
     char *digestAlgorithm = "md5";
     char *keyoutfile = 0;
     PRBool ascii = PR_FALSE;
+    PRBool cacert = PR_FALSE;
     CERTCertDBHandle *certHandle = 0;
     SECStatus status = 0;
     CommandType cmd = cmd_CertReq;
     PRBool initialized = PR_FALSE;
       
-    while ((optc = getopt_long(argc, argv, "ac:rs:g:v:e:f:d:z:i:p:o:k:h", options, NULL)) != -1) {
+    while ((optc = getopt_long(argc, argv, "atc:rs:g:v:e:f:d:z:i:p:o:k:h", options, NULL)) != -1) {
         switch (optc) {
         case 'a':
             ascii = PR_TRUE;
             break;
+        case 't':
+            cacert = PR_TRUE;
+            break;
         case 'c':
             cmdstr = strdup(optarg);
             printf("cmdstr: %s\n", cmdstr);
@@ -1793,7 +1733,6 @@
     }
     if (cert_to_renew) {
         char *configstring = NULL;
-    	//PK11_SetPasswordFunc(SECU_FilePasswd);    	
         /* Load our PKCS#11 module */
         configstring = (char *)malloc(4096);   
         PR_snprintf(configstring, 4096,
@@ -1819,14 +1758,14 @@
         /* certfile NULL signals only the request is needed */
         rv = keyutil_main(certHandle,
                 noisefile, access_pwd_file, key_pwd_file,
-                cert_to_renew, keyfile, 
+                cert_to_renew, keyfile, cacert,
                 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,
+                NULL, NULL, cacert, /* ignored */
                 subject, keysize, warpmonths, validity_months,
                 ascii, "tmprequest", outfile, keyoutfile);
         break;




More information about the fedora-extras-commits mailing list