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