rpms/crypto-utils/devel keyutil.c,1.10,1.11

Elio Maldonado emaldonado at fedoraproject.org
Tue Nov 4 04:07:58 UTC 2008


Author: emaldonado

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

Modified Files:
	keyutil.c 
Log Message:
Per code review, preauthenticate to modules using specially formatted password file, fix a memory deallocation bug


Index: keyutil.c
===================================================================
RCS file: /cvs/extras/rpms/crypto-utils/devel/keyutil.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- keyutil.c	26 Oct 2008 23:50:45 -0000	1.10
+++ keyutil.c	4 Nov 2008 04:07:28 -0000	1.11
@@ -190,7 +190,7 @@
     { "subject",    required_argument, NULL, 's' },
     { "gkeysize",   required_argument, NULL, 'g' },
     { "validity",   required_argument, NULL, 'v' },
-    { "encpwdfile", required_argument, NULL, 'e' },
+    { "encpwd",     required_argument, NULL, 'e' },
     { "filepwdnss", required_argument, NULL, 'f' },
     { "digest",     required_argument, NULL, 'd' },
     { "znoisefile", required_argument, NULL, 'z' },
@@ -214,7 +214,7 @@
     fprintf(stderr, "{-g|--gsize} key_size          size in bitsof the rsa key to generate");
     fprintf(stderr, "{-v|--validity} months         cert validity in months");
     fprintf(stderr, "{-z|--znoisefile} noisefile    seed file for use in key gneration");
-    fprintf(stderr, "{-e|--filepwdnss} keypwdfile   file with the key encryption_password");
+    fprintf(stderr, "{-e|--encpwd} keypwd           key encryption_password");
     fprintf(stderr, "{-f|--filepwdnss} modpwdfile   file with the module access_password");
     fprintf(stderr, "{-d|--digest} digest-algorithm digest algorithm");
     fprintf(stderr, "{-i|--input} inputkey-file     file with key with which to encrypt or to sign a request");
@@ -227,8 +227,6 @@
     exit(1);
 }
 
-
-#if(0)
 /*
  * Authenticates to any token that may require it.
  * It also checks that the NSS database ahs been initialized.
@@ -254,7 +252,7 @@
 
         if (PK11_NeedLogin(slot) && PK11_NeedUserInit(slot)) {
             if (slot == PK11_GetInternalKeySlot()) {
-                SECU_PrintError(progName,
+                SECU_PrintError(progName ? progName : "keyutil",
                     "The NSS database has not been initialized\n");
             } else {
             	SECU_PrintError(progName,
@@ -268,7 +266,7 @@
         ret = PK11_Authenticate(slot, PR_TRUE, &pwdata);
         if (SECSuccess != ret) {
             if (PR_GetError() == SEC_ERROR_BAD_PASSWORD) {
-        	    SECU_PrintError(progName,
+        	    SECU_PrintError(progName ? progName : "keyutil",
         	    "%s: The password for token '%s' is incorrect\n",
         	    PK11_GetTokenName(slot));
             }
@@ -280,7 +278,6 @@
 
     return status;
 }
-#endif
 
 /*
  * Loads the cert from the specified file into the module at
@@ -336,7 +333,7 @@
              */
             cert = PK11_FindCertFromNickname((char *)nickname, NULL);
             if (!cert) {
-            	SECU_PrintError(progName,
+            	SECU_PrintError(progName ? progName : "keyutil",
                     "%s: Can't find cert named (%s), bailing out\n", nickname);
                 rv = 255;
         	    break;
@@ -391,7 +388,7 @@
         if (!object) {
             rv = SEC_ERROR_BAD_KEY;
             PR_SetError(rv, 0);
-            SECU_PrintError(progName,
+            SECU_PrintError(progName ? progName : "keyutil",
                 "Unable to create key object (%s)\n", SECU_Strerror(rv));
             break;
         }
@@ -403,7 +400,7 @@
 
         rv = PK11_Authenticate(slot, PR_TRUE, pwdata);
         if (rv != SECSuccess) {
-            SECU_PrintError(progName,
+            SECU_PrintError(progName ? progName : "keyutil",
                 "Can't authenticate\n", SECU_Strerror(rv));
             break;
         }
@@ -417,7 +414,7 @@
         privkey = PK11_FindPrivateKeyFromCert(slot, cert, pwdata);
         if (!privkey) {
             rv = PR_GetError();
-            SECU_PrintError(progName,
+            SECU_PrintError(progName ? progName : "keyutil",
                 "Unable to find the key for cert, (%s)\n", SECU_Strerror(rv));
             GEN_BREAK(SECFailure);
         }
@@ -488,13 +485,13 @@
 {
     SECStatus rv = SECSuccess;
     CERTCertificate *cert = NULL;
-	
+    
     do {
         cert = PK11_FindCertFromNickname((char *)nickname, NULL);
         if (!cert) {
             GEN_BREAK(SECFailure);
         }
- 
+        
         *pubkey = CERT_ExtractPublicKey(cert);
         if (!*pubkey) {
             SECU_PrintError(progName,
@@ -523,7 +520,7 @@
         if (!*subject) {
             SECU_PrintError(progName,
                 "Improperly formatted name: \"%s\"\n",
-                progName, cert->subjectName);
+                cert->subjectName);
             GEN_BREAK(SECFailure);
         }
         rv = SECSuccess;
@@ -554,7 +551,7 @@
         if (arena == NULL) {
             GEN_BREAK(SECFailure);
         }
-    
+        
         rv = SECU_ReadDERFromFile(&reqDER, inFile, ascii);
         if (rv) {
         	GEN_BREAK(rv);
@@ -724,7 +721,7 @@
 }
 
 static CERTCertificate *
-MakeV1Cert(CERTCertDBHandle *   handle, 
+MakeV1Cert(CERTCertDBHandle *handle,
         CERTCertificateRequest *req,
         char *issuerNickName, 
         PRBool selfsign, 
@@ -781,7 +778,7 @@
 {
     SECItem der;
     SECItem *result = NULL;
-    SECKEYPrivateKey *caPrivateKey = NULL;    
+    SECKEYPrivateKey *caPrivateKey = NULL;
     SECStatus rv;
     PRArenaPool *arena;
     SECOidTag algID;
@@ -852,12 +849,9 @@
     return result;
 }
 
-/*
- * Modelled after the one in certutil
- */
 static SECStatus
 CreateCert(
-    CERTCertDBHandle *handle, 
+    CERTCertDBHandle *handle,
     char             *issuerNickName, 
     PRFileDesc       *inFile,
     PRFileDesc       *outFile, 
@@ -889,7 +883,7 @@
         if (!arena) {
             GEN_BREAK (SECFailure);
         }
-    
+        
         /* Create a certrequest object from the input cert request der */
         certReq = GetCertRequest(inFile, ascii);
         if (certReq == NULL) {
@@ -970,42 +964,6 @@
     cmd_CreateNewCert
 } CommandType;
 
-/*
- * Get the key encryption password from a password file.
- * Stores the password from pwFile in pwitem.
- */
-PRBool GetKeyPassword(const char *pwFile, SECItem *pwitem)
-{
-    int i;
-    unsigned char phrase[200];
-    PRFileDesc *fd;
-    PRInt32 nb;
-
-    if (!pwFile) 
-        return PR_FALSE;
-    
-    fd = PR_Open(pwFile, PR_RDONLY, 0);
-    if (!fd) 
-        return PR_FALSE;
-
-    nb = PR_Read(fd, phrase, sizeof(phrase));
-    PR_Close(fd);
-    
-    /* handle the Windows EOL case */
-    i = 0;
-    while (phrase[i] != '\r' && phrase[i] != '\n' && i < nb)
-        i++;
-    phrase[i] = '\0';
-    if (nb == 0)
-        return PR_FALSE;
-
-    pwitem->data = (unsigned char *) PORT_Strdup((char*)phrase);
-    pwitem->len = (unsigned int) strlen((char*)phrase);
-    pwitem->type = siBuffer;
-    
-    return PR_TRUE;
-}
-
 /* returns 0 for success, -1 for failure (EOF encountered) */
 static int
 UpdateRNG(void)
@@ -1018,10 +976,10 @@
     cc_t           orig_cc_time;
     tcflag_t       orig_lflag;
     struct termios tio;
-    char meter[] = { 
+    char meter[] = {
       "\r|                                                            |" };
 
-#define FPS fprintf(stderr, 
+#define FPS fprintf(stderr,
     FPS "\n");
     FPS "A random seed must be generated that will be used in the\n");
     FPS "creation of your key.  One of the easiest ways to create a\n");
@@ -1070,7 +1028,7 @@
 
     while ((c = getc(stdin)) != '\n' && c != EOF)
         ;
-    if (c == EOF) 
+    if (c == EOF)
     rv = -1;
     FPS "\n");
 
@@ -1122,7 +1080,7 @@
     PK11RSAGenParams   rsaparams;
     SECKEYPrivateKey * privKey = NULL;
 
-    if (slot == NULL) 
+    if (slot == NULL)
         return NULL;
 
     if (PK11_Authenticate(slot, PR_TRUE, pwdata) != SECSuccess)
@@ -1169,7 +1127,7 @@
  * Decrypt the private key 
  */
 SECStatus DecryptKey(
-    SECKEYEncryptedPrivateKeyInfo *epki,    
+    SECKEYEncryptedPrivateKeyInfo *epki,
     SECOidTag algTag,
     SECItem *pwitem, 
     secuPWData *pwdata,
@@ -1212,10 +1170,10 @@
 
         ctx = PK11_CreateContextBySymKey(cryptoMechType, operation, symKey, cryptoParam);
         if (ctx == NULL) {
-             ERROR_BREAK;       
+             ERROR_BREAK;
         }
         
-        rv = PK11_CipherOp(ctx, 
+        rv = PK11_CipherOp(ctx,
         		derPKI->data,                  /* out     */
                 (int *)(&derPKI->len),         /* out len */
                 (int)epki->encryptedData.len,  /* max out */
@@ -1248,7 +1206,7 @@
 /* Output the private key to a file */
 static SECStatus
 KeyOut(const char *keyoutfile,
-       const char *key_pwd_file,
+       const char *keyEncPwd,
        SECKEYPrivateKey *privkey,
        SECKEYPublicKey *pubkey,
        SECOidTag algTag,
@@ -1272,16 +1230,15 @@
     int rv = SECSuccess;
 
     do {
-        /* Caller wants an encrypted key. Get
-         * the password from the file */
-        if (key_pwd_file) {
-            if (!GetKeyPassword(key_pwd_file, &pwitem)) {
-                return 255;
-            }
+        /* Caller wants an encrypted key. */
+        if (keyEncPwd) {
+            pwitem.data = (unsigned char *) PORT_Strdup((char*)keyEncPwd);
+            pwitem.len = (unsigned int) strlen((char*)keyEncPwd);
+            pwitem.type = siBuffer;
         } else {
             /* Caller wants clear keys. Make up a dummy
-             * password to get NSS to export an encrypted 
-             * key which we will decrypt. 
+             * password to get NSS to export an encrypted
+             * key which we will decrypt.
              */
             rv = PK11_GenerateRandom(randomPassword, RAND_PASS_LEN);
             if (rv != SECSuccess) GEN_BREAK(rv);
@@ -1307,19 +1264,20 @@
         arenaForEPKI = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
         assert(arenaForEPKI);
         
-        if (key_pwd_file) {
+        if (keyEncPwd) {
             /* NULL dest to let it allocate memory for us */
             derEPKI = SEC_ASN1EncodeItem(arenaForEPKI, NULL, epki,
                 SECKEY_EncryptedPrivateKeyInfoTemplate);
             if (!derEPKI) {
-            	SECU_PrintError(progName, "%s ASN1 Encode failed (%dl)\n",
-                    SECU_Strerror(PR_GetError()));
+                rv = PR_GetError();
+            	SECU_PrintError(progName, "ASN1 Encode failed (%s)\n",
+                    SECU_Strerror(rv));
                 GEN_BREAK(rv);
             }
-        
+            
         } else {
             /* Make a decrypted key the one to write out. */
-        	
+            
             arenaForPKI = PORT_NewArena(2048);
             if (!arenaForPKI) {
                 GEN_BREAK(PR_OUT_OF_MEMORY_ERROR);
@@ -1334,12 +1292,12 @@
                 GEN_BREAK(rv);
             }
         }
- 
+        
         if (ascii) {
             /* we could be exporting a clear or encrypted key */
-            SECItem *src  = key_pwd_file ? derEPKI : &derPKI;
-            char *header  = key_pwd_file ? ENCRYPTED_KEY_HEADER : KEY_HEADER;
-            char *trailer = key_pwd_file ? ENCRYPTED_KEY_TRAILER : KEY_TRAILER;
+            SECItem *src  = keyEncPwd ? derEPKI : &derPKI;
+            char *header  = keyEncPwd ? ENCRYPTED_KEY_HEADER : KEY_HEADER;
+            char *trailer = keyEncPwd ? ENCRYPTED_KEY_TRAILER : KEY_TRAILER;
             char *b64 = NULL;
             do {
                 
@@ -1348,7 +1306,7 @@
                 	break;
                 
                 total = PL_strlen(b64);
-            
+                
                 PR_fprintf(keyOutFile, "%s\n", header);
                 
                 numBytes = PR_Write(keyOutFile, b64, total);
@@ -1359,7 +1317,7 @@
                 }
 
                 PR_fprintf(keyOutFile, "\n%s\n", trailer);
-            	
+                
             } while (0);
             
             if (b64) {
@@ -1367,7 +1325,7 @@
             }
             
         } else {
-            if (key_pwd_file) {
+            if (keyEncPwd) {
             	/* Write out the encrypted key */
                 numBytes = PR_Write(keyOutFile, derEPKI, derEPKI->len);
             } else {
@@ -1388,9 +1346,6 @@
         PR_Close(keyOutFile);
     }
     
-    if (derEPKI != NULL)
-        PORT_Free(derEPKI);
-
     if (arenaForEPKI) {
         PORT_FreeArena(arenaForEPKI, PR_FALSE);
     }
@@ -1399,9 +1354,15 @@
         PORT_FreeArena(arenaForPKI, PR_FALSE);
     }
     
-    if (!key_pwd_file) {
+    if (!keyEncPwd) {
         /* paranoia, though stack-based object we clear it anyway */
     	memset(randomPassword, 0, RAND_PASS_LEN);
+    } else {
+    	if (pwitem.data) {
+    		memset(pwitem.data, 0, pwitem.len);
+    		PORT_Free(pwitem.data);
+    	}
+        memset(&pwitem, 0, sizeof(SECItem));
     }
     
     return rv;
@@ -1412,14 +1373,14 @@
  */
 static int keyutil_main(
         CERTCertDBHandle *certHandle,
-        const char       *noisefile, 
+        const char       *noisefile,
         const char       *access_pwd_file,
-        const char       *key_pwd_file,
+        const char       *keyEncPwd,
         const char       *cert_to_renew,
         const char       *input_key_file,
         PRBool           cacert,
         const char       *subjectstr,
-        int              keysize, 
+        int              keysize,
         int              warpmonths,
         int              validityMonths,
         PRBool           ascii,
@@ -1445,6 +1406,10 @@
     if (access_pwd_file) {
         pwdata.source = PW_FROMFILE;
         pwdata.data = (char *)access_pwd_file;
+        rv = nss_Init_Tokens(&pwdata);
+        if (SECSuccess != rv) {
+        	goto shutdown;
+        }
     }
 
     if (cert_to_renew && input_key_file) {
@@ -1457,12 +1422,12 @@
     	char nickname[256];
     	CERTCertificate *keycert = NULL;
     	const char *n = cert_to_renew;
- 
+        
     	/* Remove the path part */
         n = strrchr(cert_to_renew, '/');
-        if (!n) 
+        if (!n)
             n = cert_to_renew;
-        else 
+        else
             n++;
 
         snprintf(slotname, 32, "PEM Token #%ld", slotID);
@@ -1475,7 +1440,7 @@
         }
                
         rv = loadCertAndKey(slot, cacert,
-                            cert_to_renew, nickname, input_key_file, 
+                            cert_to_renew, nickname, input_key_file,
                             &pwdata);
 
         if (rv != SECSuccess) {
@@ -1483,9 +1448,8 @@
 	    goto shutdown;
         }
         
-        rv = extractRSAKeysAndSubject(nickname, 
+        rv = extractRSAKeysAndSubject(nickname,
                 slot, &pwdata, &privkey, &pubkey, &subject);
-        
         if (rv != SECSuccess) {
             if (keycert) {
             	CERT_DestroyCertificate(keycert);
@@ -1497,6 +1461,8 @@
         assert(pubkey);
         assert(subject);
 
+        printf("Read keys and subject from the cert to renew\n");
+
     } else {
         /*
          * This is a certificate signing request for a new cert,
@@ -1504,7 +1470,7 @@
          */
         slot = PK11_GetInternalKeySlot(); /* PK11_GetInternalSlot() ? */
 
-        privkey = GenerateRSAPrivateKey(keytype, slot, 
+        privkey = GenerateRSAPrivateKey(keytype, slot,
             keysize, 65537L, (char *)noisefile, &pubkey, &pwdata);
     
         if (!privkey) {
@@ -1520,9 +1486,9 @@
             rv = 255;
             goto shutdown;
         }
+        printf("Made a key\n");
     }
-    PR_fprintf(PR_STDOUT, "%s Got a key\n", progName);
-    
+
     outFile = PR_Open(certreqfile, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE, 00660);
     if (!outFile) {
         SECU_PrintError(progName,
@@ -1537,7 +1503,7 @@
      */
     
     hashAlgTag = SEC_OID_MD5;
- 
+    
     /*  Make a cert request */
     rv = CertReq(privkey, pubkey, rsaKey, hashAlgTag, subject,
                  NULL,         /* PhoneNumber */
@@ -1545,26 +1511,25 @@
                  NULL,         /* ExtendedEmailAddrs */
                  NULL,         /* ExtendedDNSNames */
                  nullextnlist, /* certutil_extns */
-                 outFile);       
+                 outFile);
     
     PR_Close(outFile);
     if (rv) {
-        PR_fprintf(PR_STDERR, "%s CertReq failed: \"%d\"\n", 
-                progName, PORT_GetError());
+        SECU_PrintError(progName ? progName : "keyutil",
+                "CertReq failed: \"%s\"\n", SECU_Strerror(rv));
         rv = 255;
         goto shutdown;
     }
 
-    PR_fprintf(PR_STDOUT, "%s Made a cert request\n", progName);
     if (doCert) {
     
         /* If making a cert, we already have a cert request file.
          * without any extensions, load it with any command line extensions
          * and output the cert to other file. Delete the request file.
-         */     
+         */
         PRFileDesc *inFile = NULL;
         unsigned int serialNumber;
-       
+        
         /*  Make a default serial number from the current time.  */
         PRTime now = PR_Now();
         LL_USHR(now, now, 19);
@@ -1572,7 +1537,7 @@
         
         privkey->wincx = &pwdata;
         PR_Close(outFile);
-       
+        
         inFile  = PR_Open(certreqfile, PR_RDONLY, 0);
         assert(inFile);
         if (!inFile) {
@@ -1581,18 +1546,17 @@
             rv = SECFailure;
             goto shutdown;
         }
-       
+        
         outFile = PR_Open(certfile, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE, 00660);
-       
         if (!outFile) {
             SECU_PrintError(progName, "Failed to open file \"%s\" (%ld, %ld).\n",
                        certfile, PR_GetError(), PR_GetOSError());
             rv = SECFailure;
             goto    shutdown;
         }
-    
+        
         /*  Create a certificate (-C or -S).  */
-    
+        
         /* issuerName == subject */
         rv = CreateCert(certHandle, 
             "tempnickname", inFile, outFile,
@@ -1608,10 +1572,10 @@
              SECU_PrintError(progName, "Failed to create certificate \"%s\" (%ld).\n",
                    outFile, PR_GetError());
              rv = SECFailure;
-             goto shutdown; 
+             goto shutdown;
          }
-         PR_fprintf(PR_STDOUT, "%s Created a cert\n", progName);
-    
+         printf("Created a certificate\n");
+
          /*  Sanity check: Check cert validity against current time. */
     
          /* for fips - must log in to get private key */
@@ -1622,21 +1586,24 @@
                             PK11_GetTokenName(slot));
                 goto shutdown;
             }
+            printf("Authenticated to token\n");
         }
-    }    
+    } else {
+    	printf("Wrote the CSR to %s\n", certreqfile);
+    }
 
     /* If the caller wants the private key extract it and save it to a file. */
     if (keyoutfile) {
         /* Two candidate tags to use: SEC_OID_DES_EDE3_CBC and
          * SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC
          */
-        rv = KeyOut(keyoutfile, key_pwd_file,
-                privkey, pubkey, SEC_OID_DES_EDE3_CBC, 
+        rv = KeyOut(keyoutfile, keyEncPwd,
+                privkey, pubkey, SEC_OID_DES_EDE3_CBC,
                 &pwdata, ascii);
         if (rv != SECSuccess) {
             SECU_PrintError(progName, "Failed to write the key");
         } else {
-            printf("%s Wrote the key to\n%s\n", progName, keyoutfile);  
+            printf("Wrote the key to:\n%s\n", keyoutfile);
         }
     }
 
@@ -1685,7 +1652,7 @@
     char *cert_to_renew = NULL;
     char *subject = NULL;
     char *access_pwd_file = NULL;
-    char *key_pwd_file = NULL;
+    char *keyEncPwd = NULL;
     char *digestAlgorithm = "md5";
     char *keyoutfile = 0;
     PRBool ascii = PR_FALSE;
@@ -1711,7 +1678,7 @@
                 printf("\ncmd_CertReq\n");
             } else if (strcmp(cmdstr, "makecert") == 0) {
                 cmd = cmd_CreateNewCert;
-                printf("\ncmd_CreateNewCert\n");          
+                printf("\ncmd_CreateNewCert\n");
             } else {
                 printf("\nInvalid argument: %s\n", cmdstr);
                 exit(2);
@@ -1734,12 +1701,12 @@
             printf("valid for %d months\n", validity_months);
             break;
         case 'e':
-            key_pwd_file = strdup(optarg);
-            printf("key encryption password from = %s\n", key_pwd_file);
+            keyPassword = strdup(optarg);
+            printf("key encryption password = ****\n");
             break;
         case 'f':
             access_pwd_file = strdup(optarg);
-            printf("module access password from = %s\n", access_pwd_file);
+            printf("module access password from %s\n", access_pwd_file);
             break;
         case 'd':
             digestAlgorithm = strdup(optarg);
@@ -1811,14 +1778,14 @@
     case cmd_CertReq:
         /* certfile NULL signals only the request is needed */
         rv = keyutil_main(certHandle,
-                noisefile, access_pwd_file, key_pwd_file,
+                noisefile, access_pwd_file, keyEncPwd,
                 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,
+                noisefile, access_pwd_file, keyEncPwd,
                 NULL, NULL, cacert, /* ignored */
                 subject, keysize, warpmonths, validity_months,
                 ascii, "tmprequest", outfile, keyoutfile);




More information about the fedora-extras-commits mailing list