Bug 391296 â Need an update helper for Shared Databases
r=nelson. git-svn-id: svn://10.0.0.236/trunk@247495 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
dcdde8bd96
commit
ef7b124a1b
@ -942,6 +942,15 @@ Usage(char *progName)
|
||||
progName);
|
||||
#endif /* NSS_ENABLE_ECC */
|
||||
FPS "\t\t [-f pwfile] [-X] [-d certdir] [-P dbprefix]\n");
|
||||
FPS "\t%s --upgrade-merge --source-dir upgradeDir --upgrade-id uniqueID\n",
|
||||
progName);
|
||||
FPS "\t\t [--upgrade-token-name tokenName] [-d targetDBDir]\n");
|
||||
FPS "\t\t [-P targetDBPrefix] [--source-prefix upgradeDBPrefix]\n");
|
||||
FPS "\t\t [-f targetPWfile] [-@ upgradePWFile]\n");
|
||||
FPS "\t%s --merge --source-dir sourceDBDir [-d targetDBdir]\n",
|
||||
progName);
|
||||
FPS "\t\t [-P targetDBPrefix] [--source-prefix sourceDBPrefix]\n");
|
||||
FPS "\t\t [-f targetPWfile] [-@ sourcePWFile]\n");
|
||||
FPS "\t%s -L [-n cert-name] [-X] [-d certdir] [-P dbprefix] [-r] [-a]\n", progName);
|
||||
FPS "\t%s -M -n cert-name -t trustargs [-d certdir] [-P dbprefix]\n",
|
||||
progName);
|
||||
@ -1259,6 +1268,42 @@ static void LongUsage(char *progName)
|
||||
" -X");
|
||||
FPS "\n");
|
||||
|
||||
FPS "%-15s Upgrade an old database and merge it into a new one\n",
|
||||
"--upgrade-merge");
|
||||
FPS "%-20s Cert database directory to merge into (default is ~/.netscape)\n",
|
||||
" -d certdir");
|
||||
FPS "%-20s Cert & Key database prefix of the target database\n",
|
||||
" -P dbprefix");
|
||||
FPS "%-20s Specify the password file for the target database\n",
|
||||
" -f pwfile");
|
||||
FPS "%-20s \n%-20s Cert database directory to upgrade from\n",
|
||||
" --source-dir certdir", "");
|
||||
FPS "%-20s \n%-20s Cert & Key database prefix of the upgrade database\n",
|
||||
" --soruce-prefix dbprefix", "");
|
||||
FPS "%-20s \n%-20s Unique identifier for the upgrade database\n",
|
||||
" --upgrade-id uniqueID", "");
|
||||
FPS "%-20s \n%-20s Name of the token while it is in upgrade state\n",
|
||||
" --upgrade-token-name name", "");
|
||||
FPS "%-20s Specify the password file for the upgrade database\n",
|
||||
" -@ pwfile");
|
||||
FPS "\n");
|
||||
|
||||
FPS "%-15s Merge source database into the target database\n",
|
||||
"--merge");
|
||||
FPS "%-20s Cert database directory of target (default is ~/.netscape)\n",
|
||||
" -d certdir");
|
||||
FPS "%-20s Cert & Key database prefix of the target database\n",
|
||||
" -P dbprefix");
|
||||
FPS "%-20s Specify the password file for the target database\n",
|
||||
" -f pwfile");
|
||||
FPS "%-20s \n%-20s Cert database directory of the source database\n",
|
||||
" --source-dir certdir", "");
|
||||
FPS "%-20s \n%-20s Cert & Key database prefix of the source database\n",
|
||||
" --source-prefix dbprefix", "");
|
||||
FPS "%-20s Specify the password file for the source database\n",
|
||||
" -@ pwfile");
|
||||
FPS "\n");
|
||||
|
||||
FPS "%-15s Make a certificate and add to database\n",
|
||||
"-S");
|
||||
FPS "%-20s Specify the nickname of the cert\n",
|
||||
@ -1567,6 +1612,99 @@ CreateCert(
|
||||
return (rv);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* map a class to a user presentable string
|
||||
*/
|
||||
static const char *objClassArray[] = {
|
||||
"Data",
|
||||
"Certificate",
|
||||
"Public Key",
|
||||
"Private Key",
|
||||
"Secret Key",
|
||||
"Hardware Feature",
|
||||
"Domain Parameters",
|
||||
"Mechanism"
|
||||
};
|
||||
|
||||
static const char *objNSSClassArray[] = {
|
||||
"CKO_NSS",
|
||||
"Crl",
|
||||
"SMIME Record",
|
||||
"Trust",
|
||||
"Builtin Root List"
|
||||
};
|
||||
|
||||
|
||||
const char *
|
||||
getObjectClass(CK_ULONG classType)
|
||||
{
|
||||
static char buf[sizeof(CK_ULONG)*2+3];
|
||||
|
||||
if (classType <= CKO_MECHANISM) {
|
||||
return objClassArray[classType];
|
||||
}
|
||||
if (classType >= CKO_NSS && classType <= CKO_NSS_BUILTIN_ROOT_LIST) {
|
||||
return objNSSClassArray[classType - CKO_NSS];
|
||||
}
|
||||
sprintf(buf, "0x%lx", classType);
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *mkNickname(unsigned char *data, int len)
|
||||
{
|
||||
char *nick = PORT_Alloc(len+1);
|
||||
if (!nick) {
|
||||
return nick;
|
||||
}
|
||||
PORT_Memcpy(nick, data, len);
|
||||
nick[len] = 0;
|
||||
return nick;
|
||||
}
|
||||
|
||||
/*
|
||||
* dump a PK11_MergeTokens error log to the console
|
||||
*/
|
||||
void
|
||||
DumpMergeLog(const char *progname, PK11MergeLog *log)
|
||||
{
|
||||
PK11MergeLogNode *node;
|
||||
|
||||
for (node = log->head; node; node = node->next) {
|
||||
SECItem attrItem;
|
||||
char *nickname = NULL;
|
||||
const char *objectClass = NULL;
|
||||
SECStatus rv;
|
||||
|
||||
attrItem.data = NULL;
|
||||
rv = PK11_ReadRawAttribute(PK11_TypeGeneric, node->object,
|
||||
CKA_LABEL, &attrItem);
|
||||
if (rv == SECSuccess) {
|
||||
nickname = mkNickname(attrItem.data, attrItem.len);
|
||||
PORT_Free(attrItem.data);
|
||||
}
|
||||
attrItem.data = NULL;
|
||||
rv = PK11_ReadRawAttribute(PK11_TypeGeneric, node->object,
|
||||
CKA_CLASS, &attrItem);
|
||||
if (rv == SECSuccess) {
|
||||
if (attrItem.len == sizeof(CK_ULONG)) {
|
||||
objectClass = getObjectClass(*(CK_ULONG *)attrItem.data);
|
||||
}
|
||||
PORT_Free(attrItem.data);
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s: Could not merge object %s (type %s): %s\n",
|
||||
progName,
|
||||
nickname ? nickname : "unnamed",
|
||||
objectClass ? objectClass : "unknown",
|
||||
SECU_Strerror(node->error));
|
||||
|
||||
if (nickname) {
|
||||
PORT_Free(nickname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Certutil commands */
|
||||
enum {
|
||||
cmd_AddCert = 0,
|
||||
@ -1588,7 +1726,9 @@ enum {
|
||||
cmd_CheckCertValidity,
|
||||
cmd_ChangePassword,
|
||||
cmd_Version,
|
||||
cmd_Batch
|
||||
cmd_Batch,
|
||||
cmd_Merge,
|
||||
cmd_UpgradeMerge, /* test only */
|
||||
};
|
||||
|
||||
/* Certutil options */
|
||||
@ -1638,7 +1778,11 @@ enum certutilOpts {
|
||||
opt_AddPolicyMapExt,
|
||||
opt_AddPolicyConstrExt,
|
||||
opt_AddInhibAnyExt,
|
||||
opt_AddSubjectKeyIDExt
|
||||
opt_AddSubjectKeyIDExt,
|
||||
opt_SourceDir,
|
||||
opt_SourcePrefix,
|
||||
opt_UpgradeID,
|
||||
opt_UpgradeTokenName
|
||||
};
|
||||
|
||||
static const
|
||||
@ -1663,7 +1807,10 @@ secuCommandFlag commands_init[] =
|
||||
{ /* cmd_CheckCertValidity */ 'V', PR_FALSE, 0, PR_FALSE },
|
||||
{ /* cmd_ChangePassword */ 'W', PR_FALSE, 0, PR_FALSE },
|
||||
{ /* cmd_Version */ 'Y', PR_FALSE, 0, PR_FALSE },
|
||||
{ /* cmd_Batch */ 'B', PR_FALSE, 0, PR_FALSE }
|
||||
{ /* cmd_Batch */ 'B', PR_FALSE, 0, PR_FALSE },
|
||||
{ /* cmd_Merge */ 0, PR_FALSE, 0, PR_FALSE, "merge" },
|
||||
{ /* cmd_UpgradeMerge */ 0, PR_FALSE, 0, PR_FALSE,
|
||||
"upgrade-merge" }
|
||||
};
|
||||
#define NUM_COMMANDS ((sizeof commands_init) / (sizeof commands_init[0]))
|
||||
|
||||
@ -1715,7 +1862,16 @@ secuCommandFlag options_init[] =
|
||||
{ /* opt_AddPolicyMapExt */ 0, PR_FALSE, 0, PR_FALSE, "extPM" },
|
||||
{ /* opt_AddPolicyConstrExt */ 0, PR_FALSE, 0, PR_FALSE, "extPC" },
|
||||
{ /* opt_AddInhibAnyExt */ 0, PR_FALSE, 0, PR_FALSE, "extIA" },
|
||||
{ /* opt_AddSubjectKeyIDExt */ 0, PR_FALSE, 0, PR_FALSE, "extSKID" }
|
||||
{ /* opt_AddSubjectKeyIDExt */ 0, PR_FALSE, 0, PR_FALSE,
|
||||
"extSKID" },
|
||||
{ /* opt_SourceDir */ 0, PR_TRUE, 0, PR_FALSE,
|
||||
"source-dir"},
|
||||
{ /* opt_SourcePrefix */ 0, PR_TRUE, 0, PR_FALSE,
|
||||
"source-prefix"},
|
||||
{ /* opt_UpgradeID */ 0, PR_TRUE, 0, PR_FALSE,
|
||||
"upgrade-id"},
|
||||
{ /* opt_UpgradeTokenName */ 0, PR_TRUE, 0, PR_FALSE,
|
||||
"upgrade-token-name"},
|
||||
};
|
||||
#define NUM_OPTIONS ((sizeof options_init) / (sizeof options_init[0]))
|
||||
|
||||
@ -1743,6 +1899,10 @@ certutil_main(int argc, char **argv, PRBool initialize)
|
||||
char * certreqfile = "tempcertreq";
|
||||
char * slotname = "internal";
|
||||
char * certPrefix = "";
|
||||
char * sourceDir = "";
|
||||
char * srcCertPrefix = "";
|
||||
char * upgradeID = "";
|
||||
char * upgradeTokenName = "";
|
||||
KeyType keytype = rsaKey;
|
||||
char * name = NULL;
|
||||
char * keysource = NULL;
|
||||
@ -1755,6 +1915,7 @@ certutil_main(int argc, char **argv, PRBool initialize)
|
||||
int commandsEntered = 0;
|
||||
char commandToRun = '\0';
|
||||
secuPWData pwdata = { PW_NONE, 0 };
|
||||
secuPWData pwdata2 = { PW_NONE, 0 };
|
||||
PRBool readOnly = PR_FALSE;
|
||||
PRBool initialized = PR_FALSE;
|
||||
|
||||
@ -1781,10 +1942,23 @@ certutil_main(int argc, char **argv, PRBool initialize)
|
||||
pwdata.source = PW_FROMFILE;
|
||||
pwdata.data = certutil.options[opt_PasswordFile].arg;
|
||||
}
|
||||
if (certutil.options[opt_NewPasswordFile].arg) {
|
||||
pwdata2.source = PW_FROMFILE;
|
||||
pwdata2.data = certutil.options[opt_NewPasswordFile].arg;
|
||||
}
|
||||
|
||||
if (certutil.options[opt_CertDir].activated)
|
||||
SECU_ConfigDirectory(certutil.options[opt_CertDir].arg);
|
||||
|
||||
if (certutil.options[opt_SourceDir].activated)
|
||||
sourceDir = certutil.options[opt_SourceDir].arg;
|
||||
|
||||
if (certutil.options[opt_UpgradeID].activated)
|
||||
upgradeID = certutil.options[opt_UpgradeID].arg;
|
||||
|
||||
if (certutil.options[opt_UpgradeTokenName].activated)
|
||||
upgradeTokenName = certutil.options[opt_UpgradeTokenName].arg;
|
||||
|
||||
if (certutil.options[opt_KeySize].activated) {
|
||||
keysize = PORT_Atoi(certutil.options[opt_KeySize].arg);
|
||||
if ((keysize < MIN_KEY_BITS) || (keysize > MAX_KEY_BITS)) {
|
||||
@ -1862,6 +2036,15 @@ certutil_main(int argc, char **argv, PRBool initialize)
|
||||
}
|
||||
}
|
||||
|
||||
/* --source-prefix certdb name prefix */
|
||||
if (certutil.options[opt_SourcePrefix].activated) {
|
||||
if (certutil.options[opt_SourcePrefix].arg) {
|
||||
srcCertPrefix = strdup(certutil.options[opt_SourcePrefix].arg);
|
||||
} else {
|
||||
Usage(progName);
|
||||
}
|
||||
}
|
||||
|
||||
/* -q PQG file or curve name */
|
||||
if (certutil.options[opt_PQGFile].activated) {
|
||||
#ifdef NSS_ENABLE_ECC
|
||||
@ -2034,6 +2217,32 @@ certutil_main(int argc, char **argv, PRBool initialize)
|
||||
progName);
|
||||
return 255;
|
||||
}
|
||||
|
||||
/* Upgrade/Merge needs a source database and a upgrade id. */
|
||||
if (certutil.commands[cmd_UpgradeMerge].activated &&
|
||||
!(certutil.options[opt_SourceDir].activated &&
|
||||
certutil.options[opt_UpgradeID].activated)) {
|
||||
|
||||
PR_fprintf(PR_STDERR,
|
||||
"%s --upgrade-merge: specify an upgrade database directory "
|
||||
"(--source-dir) and\n"
|
||||
" an upgrade ID (--upgrade-id).\n",
|
||||
progName);
|
||||
return 255;
|
||||
}
|
||||
|
||||
/* Merge needs a source database */
|
||||
if (certutil.commands[cmd_Merge].activated &&
|
||||
!certutil.options[opt_SourceDir].activated) {
|
||||
|
||||
|
||||
PR_fprintf(PR_STDERR,
|
||||
"%s --merge: specify an source database directory "
|
||||
"(--source-dir)\n",
|
||||
progName);
|
||||
return 255;
|
||||
}
|
||||
|
||||
|
||||
/* To make a cert, need either a issuer or to self-sign it. */
|
||||
if (certutil.commands[cmd_CreateAndAddCert].activated &&
|
||||
@ -2109,8 +2318,17 @@ certutil_main(int argc, char **argv, PRBool initialize)
|
||||
if (PR_TRUE == initialize) {
|
||||
/* Initialize NSPR and NSS. */
|
||||
PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
|
||||
rv = NSS_Initialize(SECU_ConfigDirectory(NULL), certPrefix, certPrefix,
|
||||
if (!certutil.commands[cmd_UpgradeMerge].activated) {
|
||||
rv = NSS_Initialize(SECU_ConfigDirectory(NULL),
|
||||
certPrefix, certPrefix,
|
||||
"secmod.db", readOnly ? NSS_INIT_READONLY: 0);
|
||||
} else {
|
||||
rv = NSS_InitWithMerge(SECU_ConfigDirectory(NULL),
|
||||
certPrefix, certPrefix, "secmod.db",
|
||||
sourceDir, srcCertPrefix, srcCertPrefix,
|
||||
upgradeID, upgradeTokenName,
|
||||
readOnly ? NSS_INIT_READONLY: 0);
|
||||
}
|
||||
if (rv != SECSuccess) {
|
||||
SECU_PrintPRandOSError(progName);
|
||||
rv = SECFailure;
|
||||
@ -2130,6 +2348,8 @@ certutil_main(int argc, char **argv, PRBool initialize)
|
||||
else if (slotname != NULL)
|
||||
slot = PK11_FindSlotByName(slotname);
|
||||
|
||||
|
||||
|
||||
|
||||
if ( !slot && (certutil.commands[cmd_NewDBs].activated ||
|
||||
certutil.commands[cmd_ModifyCertTrust].activated ||
|
||||
@ -2137,6 +2357,8 @@ certutil_main(int argc, char **argv, PRBool initialize)
|
||||
certutil.commands[cmd_TokenReset].activated ||
|
||||
certutil.commands[cmd_CreateAndAddCert].activated ||
|
||||
certutil.commands[cmd_AddCert].activated ||
|
||||
certutil.commands[cmd_Merge].activated ||
|
||||
certutil.commands[cmd_UpgradeMerge].activated ||
|
||||
certutil.commands[cmd_AddEmailCert].activated)) {
|
||||
|
||||
SECU_PrintError(progName, "could not find the slot %s",slotname);
|
||||
@ -2150,6 +2372,132 @@ certutil_main(int argc, char **argv, PRBool initialize)
|
||||
certutil.options[opt_NewPasswordFile].arg);
|
||||
}
|
||||
|
||||
/* walk through the upgrade merge if necessary.
|
||||
* This option is more to test what some applications will want to do
|
||||
* to do an automatic upgrade. The --merge command is more useful for
|
||||
* the general case where 2 database need to be merged together.
|
||||
*/
|
||||
if (certutil.commands[cmd_UpgradeMerge].activated) {
|
||||
if (*upgradeTokenName == 0) {
|
||||
upgradeTokenName = upgradeID;
|
||||
}
|
||||
if (!PK11_IsInternal(slot)) {
|
||||
fprintf(stderr, "Only internal DB's can be upgraded\n");
|
||||
rv = SECSuccess;
|
||||
goto shutdown;
|
||||
}
|
||||
if (!PK11_IsRemovable(slot)) {
|
||||
printf("database already upgraded.\n");
|
||||
rv = SECSuccess;
|
||||
goto shutdown;
|
||||
}
|
||||
if (!PK11_NeedLogin(slot)) {
|
||||
printf("upgrade complete!\n");
|
||||
rv = SECSuccess;
|
||||
goto shutdown;
|
||||
}
|
||||
/* authenticate to the old DB if necessary */
|
||||
if (PORT_Strcmp(PK11_GetTokenName(slot), upgradeTokenName) == 0) {
|
||||
/* if we need a password, supply it. This will be the password
|
||||
* for the old database */
|
||||
rv = PK11_Authenticate(slot, PR_FALSE, &pwdata2);
|
||||
if (rv != SECSuccess) {
|
||||
SECU_PrintError(progName, "Could not get password for %s",
|
||||
upgradeTokenName);
|
||||
goto shutdown;
|
||||
}
|
||||
/*
|
||||
* if we succeeded above, but still aren't logged in, that means
|
||||
* we just supplied the password for the old database. We may
|
||||
* need the password for the new database. NSS will automatically
|
||||
* change the token names at this point
|
||||
*/
|
||||
if (PK11_IsLoggedIn(slot, &pwdata)) {
|
||||
printf("upgrade complete!\n");
|
||||
rv = SECSuccess;
|
||||
goto shutdown;
|
||||
}
|
||||
}
|
||||
|
||||
/* call PK11_IsPresent to update our cached token information */
|
||||
if (!PK11_IsPresent(slot)) {
|
||||
/* this shouldn't happen. We call isPresent to force a token
|
||||
* info update */
|
||||
fprintf(stderr, "upgrade/merge internal error\n");
|
||||
rv = SECFailure;
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* the token is now set to the state of the source database,
|
||||
* if we need a password for it, PK11_Authenticate will
|
||||
* automatically prompt us */
|
||||
rv = PK11_Authenticate(slot, PR_FALSE, &pwdata);
|
||||
if (rv == SECSuccess) {
|
||||
printf("upgrade complete!\n");
|
||||
} else {
|
||||
SECU_PrintError(progName, "Could not get password for %s",
|
||||
PK11_GetTokenName(slot));
|
||||
}
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/*
|
||||
* merge 2 databases.
|
||||
*/
|
||||
if (certutil.commands[cmd_Merge].activated) {
|
||||
PK11SlotInfo *sourceSlot = NULL;
|
||||
PK11MergeLog *log;
|
||||
char *modspec = PR_smprintf(
|
||||
"configDir='%s' certPrefix='%s' tokenDescription='%s'",
|
||||
sourceDir, srcCertPrefix,
|
||||
*upgradeTokenName ? upgradeTokenName : "Source Database");
|
||||
|
||||
if (!modspec) {
|
||||
rv = SECFailure;
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
sourceSlot = SECMOD_OpenUserDB(modspec);
|
||||
PR_smprintf_free(modspec);
|
||||
if (!sourceSlot) {
|
||||
SECU_PrintError(progName, "couldn't open source database");
|
||||
rv = SECFailure;
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
rv = PK11_Authenticate(slot, PR_FALSE, &pwdata);
|
||||
if (rv != SECSuccess) {
|
||||
SECU_PrintError(progName, "Couldn't get password for %s",
|
||||
PK11_GetTokenName(slot));
|
||||
goto merge_fail;
|
||||
}
|
||||
|
||||
rv = PK11_Authenticate(sourceSlot, PR_FALSE, &pwdata2);
|
||||
if (rv != SECSuccess) {
|
||||
SECU_PrintError(progName, "Couldn't get password for %s",
|
||||
PK11_GetTokenName(sourceSlot));
|
||||
goto merge_fail;
|
||||
}
|
||||
|
||||
log = PK11_CreateMergeLog();
|
||||
if (!log) {
|
||||
rv = SECFailure;
|
||||
SECU_PrintError(progName, "couldn't create error log");
|
||||
goto merge_fail;
|
||||
}
|
||||
|
||||
rv = PK11_MergeTokens(slot, sourceSlot, log, &pwdata, &pwdata2);
|
||||
if (rv != SECSuccess) {
|
||||
DumpMergeLog(progName, log);
|
||||
}
|
||||
PK11_DestroyMergeLog(log);
|
||||
|
||||
merge_fail:
|
||||
SECMOD_CloseUserDB(sourceSlot);
|
||||
PK11_FreeSlot(sourceSlot);
|
||||
goto shutdown;
|
||||
}
|
||||
|
||||
/* The following 8 options are mutually exclusive with all others. */
|
||||
|
||||
/* List certs (-L) */
|
||||
|
||||
@ -106,7 +106,7 @@ static CERTSignedCrl *FindCRL
|
||||
return (crl);
|
||||
}
|
||||
|
||||
static void DisplayCRL (CERTCertDBHandle *certHandle, char *nickName, int crlType)
|
||||
static SECStatus DisplayCRL (CERTCertDBHandle *certHandle, char *nickName, int crlType)
|
||||
{
|
||||
CERTSignedCrl *crl = NULL;
|
||||
|
||||
@ -115,7 +115,9 @@ static void DisplayCRL (CERTCertDBHandle *certHandle, char *nickName, int crlTyp
|
||||
if (crl) {
|
||||
SECU_PrintCRLInfo (stdout, &crl->crl, "CRL Info:\n", 0);
|
||||
SEC_DestroyCrl (crl);
|
||||
return SECSuccess;
|
||||
}
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
static void ListCRLNames (CERTCertDBHandle *certHandle, int crlType, PRBool deletecrls)
|
||||
@ -211,12 +213,14 @@ static void ListCRLNames (CERTCertDBHandle *certHandle, int crlType, PRBool dele
|
||||
PORT_FreeArena (arena, PR_FALSE);
|
||||
}
|
||||
|
||||
static void ListCRL (CERTCertDBHandle *certHandle, char *nickName, int crlType)
|
||||
static SECStatus ListCRL (CERTCertDBHandle *certHandle, char *nickName, int crlType)
|
||||
{
|
||||
if (nickName == NULL)
|
||||
if (nickName == NULL) {
|
||||
ListCRLNames (certHandle, crlType, PR_FALSE);
|
||||
else
|
||||
DisplayCRL (certHandle, nickName, crlType);
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
return DisplayCRL (certHandle, nickName, crlType);
|
||||
}
|
||||
|
||||
|
||||
@ -1041,7 +1045,7 @@ int main(int argc, char **argv)
|
||||
if (deleteCRL)
|
||||
DeleteCRL (certHandle, nickName, crlType);
|
||||
else if (listCRL) {
|
||||
ListCRL (certHandle, nickName, crlType);
|
||||
rv = ListCRL (certHandle, nickName, crlType);
|
||||
}
|
||||
else if (importCRL) {
|
||||
rv = ImportCRL (certHandle, url, crlType, inFile, importOptions,
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
/*
|
||||
* Test program for SDR (Secret Decoder Ring) functions.
|
||||
*
|
||||
* $Id: sdrtest.c,v 1.13 2004-04-25 15:02:52 gerv%gerv.net Exp $
|
||||
* $Id: sdrtest.c,v 1.14 2008-03-10 20:16:44 rrelyea%redhat.com Exp $
|
||||
*/
|
||||
|
||||
#include "nspr.h"
|
||||
@ -61,8 +61,9 @@ static void
|
||||
synopsis (char *program_name)
|
||||
{
|
||||
PR_fprintf (pr_stderr,
|
||||
"Usage: %s [-d <dir>] [-v] [-t <text>] [-a] -i <input-file>\n"
|
||||
" %s [-d <dir>] [-v] [-t <text>] [-a] -o <output-file>\n",
|
||||
"Usage: %s [<common>] -i <input-file>\n"
|
||||
" %s [<common>] -o <output-file>\n"
|
||||
" <common> [-d dir] [-v] [-t text] [-a] [-f pwfile | -p pwd]\n",
|
||||
program_name, program_name);
|
||||
}
|
||||
|
||||
@ -93,6 +94,12 @@ long_usage (char *program_name)
|
||||
PR_fprintf (pr_stderr,
|
||||
" %-13s Find security databases in \"dbdir\"\n",
|
||||
"-d dbdir");
|
||||
PR_fprintf (pr_stderr,
|
||||
" %-13s read the password from \"pwfile\"\n",
|
||||
"-f pwfile");
|
||||
PR_fprintf (pr_stderr,
|
||||
" %-13s supply \"password\" on the command line\n",
|
||||
"-p password");
|
||||
}
|
||||
|
||||
int
|
||||
@ -180,6 +187,7 @@ main (int argc, char **argv)
|
||||
SECItem result = {0, 0, 0};
|
||||
SECItem text;
|
||||
PRBool ascii = PR_FALSE;
|
||||
secuPWData pwdata = { PW_NONE, 0 };
|
||||
|
||||
pr_stderr = PR_STDERR;
|
||||
result.data = 0;
|
||||
@ -188,7 +196,7 @@ main (int argc, char **argv)
|
||||
program_name = PL_strrchr(argv[0], '/');
|
||||
program_name = program_name ? (program_name + 1) : argv[0];
|
||||
|
||||
optstate = PL_CreateOptState (argc, argv, "?Had:i:o:t:v");
|
||||
optstate = PL_CreateOptState (argc, argv, "?Had:i:o:t:vf:p:");
|
||||
if (optstate == NULL) {
|
||||
SECU_PrintError (program_name, "PL_CreateOptState failed");
|
||||
return -1;
|
||||
@ -224,6 +232,26 @@ main (int argc, char **argv)
|
||||
value = optstate->value;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
if (pwdata.data) {
|
||||
PORT_Free(pwdata.data);
|
||||
short_usage(program_name);
|
||||
return -1;
|
||||
}
|
||||
pwdata.source = PW_FROMFILE;
|
||||
pwdata.data = PORT_Strdup(optstate->value);
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
if (pwdata.data) {
|
||||
PORT_Free(pwdata.data);
|
||||
short_usage(program_name);
|
||||
return -1;
|
||||
}
|
||||
pwdata.source = PW_PLAINTEXT;
|
||||
pwdata.data = PORT_Strdup(optstate->value);
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
verbose = PR_TRUE;
|
||||
break;
|
||||
@ -298,7 +326,17 @@ main (int argc, char **argv)
|
||||
/* sigh, initialize the key database */
|
||||
slot = PK11_GetInternalKeySlot();
|
||||
if (slot && PK11_NeedUserInit(slot)) {
|
||||
rv = SECU_ChangePW(slot, "", 0);
|
||||
switch (pwdata.source) {
|
||||
case PW_FROMFILE:
|
||||
rv = SECU_ChangePW(slot, 0, pwdata.data);
|
||||
break;
|
||||
case PW_PLAINTEXT:
|
||||
rv = SECU_ChangePW(slot, pwdata.data, 0);
|
||||
break;
|
||||
default:
|
||||
rv = SECU_ChangePW(slot, "", 0);
|
||||
break;
|
||||
}
|
||||
if (rv != SECSuccess) {
|
||||
SECU_PrintError(program_name, "Failed to initialize slot \"%s\"",
|
||||
PK11_GetSlotName(slot));
|
||||
@ -309,7 +347,7 @@ main (int argc, char **argv)
|
||||
PK11_FreeSlot(slot);
|
||||
}
|
||||
|
||||
rv = PK11SDR_Encrypt(&keyid, &data, &result, 0);
|
||||
rv = PK11SDR_Encrypt(&keyid, &data, &result, &pwdata);
|
||||
if (rv != SECSuccess) {
|
||||
if (verbose)
|
||||
SECU_PrintError(program_name, "Encrypt operation failed\n");
|
||||
@ -380,7 +418,7 @@ main (int argc, char **argv)
|
||||
}
|
||||
|
||||
/* Decrypt the value */
|
||||
rv = PK11SDR_Decrypt(&result, &text, 0);
|
||||
rv = PK11SDR_Decrypt(&result, &text, &pwdata);
|
||||
if (rv != SECSuccess) {
|
||||
if (verbose) SECU_PrintError(program_name, "Decrypt operation failed\n");
|
||||
retval = -1;
|
||||
@ -406,5 +444,8 @@ loser:
|
||||
|
||||
prdone:
|
||||
PR_Cleanup ();
|
||||
if (pwdata.data) {
|
||||
PORT_Free(pwdata.data);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -926,11 +926,16 @@ CERT_NewTempCertificate;
|
||||
CERT_SetOCSPTimeout;
|
||||
CERT_PKIXVerifyCert;
|
||||
HASH_GetType;
|
||||
NSS_InitWithMerge;
|
||||
PK11_CreateMergeLog;
|
||||
PK11_CreateGenericObject;
|
||||
PK11_CreatePBEV2AlgorithmID;
|
||||
PK11_DestroyMergeLog;
|
||||
PK11_GenerateKeyPairWithOpFlags;
|
||||
PK11_GetAllSlotsForCert;
|
||||
PK11_GetPBECryptoMechanism;
|
||||
PK11_IsRemovable;
|
||||
PK11_MergeTokens;
|
||||
PK11_WriteRawAttribute;
|
||||
SECKEY_ECParamsToBasePointOrderLen;
|
||||
SECKEY_ECParamsToKeySize;
|
||||
|
||||
@ -36,7 +36,7 @@
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* $Id: nss.h,v 1.51 2007-05-04 05:15:43 nelson%bolyard.com Exp $ */
|
||||
/* $Id: nss.h,v 1.52 2008-03-10 20:16:45 rrelyea%redhat.com Exp $ */
|
||||
|
||||
#ifndef __nss_h_
|
||||
#define __nss_h_
|
||||
@ -196,6 +196,21 @@ extern SECStatus NSS_Initialize(const char *configdir,
|
||||
const char *certPrefix, const char *keyPrefix,
|
||||
const char *secmodName, PRUint32 flags);
|
||||
|
||||
/*
|
||||
* same as NSS_Init, but checks to see if we need to merge an
|
||||
* old database in.
|
||||
* updatedir is the directory where the old database lives.
|
||||
* updCertPrefix is the certPrefix for the old database.
|
||||
* updKeyPrefix is the keyPrefix for the old database.
|
||||
* updateID is a unique identifier chosen by the application for
|
||||
* the specific database.
|
||||
* updatName is the name the user will be prompted for when
|
||||
* asking to authenticate to the old database */
|
||||
extern SECStatus NSS_InitWithMerge(const char *configdir,
|
||||
const char *certPrefix, const char *keyPrefix, const char *secmodName,
|
||||
const char *updatedir, const char *updCertPrefix,
|
||||
const char *updKeyPrefix, const char *updateID,
|
||||
const char *updateName, PRUint32 flags);
|
||||
/*
|
||||
* initialize NSS without a creating cert db's, key db's, or secmod db's.
|
||||
*/
|
||||
|
||||
@ -36,7 +36,7 @@
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* $Id: nssinit.c,v 1.91 2008-02-23 05:29:39 nelson%bolyard.com Exp $ */
|
||||
/* $Id: nssinit.c,v 1.92 2008-03-10 20:16:45 rrelyea%redhat.com Exp $ */
|
||||
|
||||
#include <ctype.h>
|
||||
#include "seccomon.h"
|
||||
@ -421,7 +421,10 @@ static CERTCertificate dummyCert;
|
||||
|
||||
static SECStatus
|
||||
nss_Init(const char *configdir, const char *certPrefix, const char *keyPrefix,
|
||||
const char *secmodName, PRBool readOnly, PRBool noCertDB,
|
||||
const char *secmodName, const char *updateDir,
|
||||
const char *updCertPrefix, const char *updKeyPrefix,
|
||||
const char *updateID, const char *updateName,
|
||||
PRBool readOnly, PRBool noCertDB,
|
||||
PRBool noModDB, PRBool forceOpen, PRBool noRootInit,
|
||||
PRBool optimizeSpace, PRBool noSingleThreadedModules,
|
||||
PRBool allowAlreadyInitializedModules,
|
||||
@ -434,6 +437,11 @@ nss_Init(const char *configdir, const char *certPrefix, const char *keyPrefix,
|
||||
char *lcertPrefix = NULL;
|
||||
char *lkeyPrefix = NULL;
|
||||
char *lsecmodName = NULL;
|
||||
char *lupdateDir = NULL;
|
||||
char *lupdCertPrefix = NULL;
|
||||
char *lupdKeyPrefix = NULL;
|
||||
char *lupdateID = NULL;
|
||||
char *lupdateName = NULL;
|
||||
PKIX_UInt32 actualMinorVersion = 0;
|
||||
PKIX_Error *pkixError = NULL;;
|
||||
|
||||
@ -480,6 +488,26 @@ nss_Init(const char *configdir, const char *certPrefix, const char *keyPrefix,
|
||||
if (lsecmodName == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
lupdateDir = nss_doubleEscape(updateDir);
|
||||
if (lupdateDir == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
lupdCertPrefix = nss_doubleEscape(updCertPrefix);
|
||||
if (lupdCertPrefix == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
lupdKeyPrefix = nss_doubleEscape(updKeyPrefix);
|
||||
if (lupdKeyPrefix == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
lupdateID = nss_doubleEscape(updateID);
|
||||
if (lupdateID == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
lupdateName = nss_doubleEscape(updateName);
|
||||
if (lupdateName == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
if (noSingleThreadedModules || allowAlreadyInitializedModules ||
|
||||
dontFinalizeModules) {
|
||||
pk11_setGlobalOptions(noSingleThreadedModules,
|
||||
@ -487,10 +515,15 @@ nss_Init(const char *configdir, const char *certPrefix, const char *keyPrefix,
|
||||
dontFinalizeModules);
|
||||
}
|
||||
|
||||
moduleSpec = PR_smprintf("name=\"%s\" parameters=\"configdir='%s' certPrefix='%s' keyPrefix='%s' secmod='%s' flags=%s %s\" NSS=\"flags=internal,moduleDB,moduleDBOnly,critical\"",
|
||||
moduleSpec = PR_smprintf(
|
||||
"name=\"%s\" parameters=\"configdir='%s' certPrefix='%s' keyPrefix='%s' "
|
||||
"secmod='%s' flags=%s updatedir='%s' updateCertPrefix='%s' "
|
||||
"updateKeyPrefix='%s' updateid='%s' updateTokenDescription='%s' %s\" "
|
||||
"NSS=\"flags=internal,moduleDB,moduleDBOnly,critical\"",
|
||||
pk11_config_name ? pk11_config_name : NSS_DEFAULT_MOD_NAME,
|
||||
lconfigdir,lcertPrefix,lkeyPrefix,lsecmodName,flags,
|
||||
pk11_config_strings ? pk11_config_strings : "");
|
||||
lupdateDir, lupdCertPrefix, lupdKeyPrefix, lupdateID,
|
||||
lupdateName, pk11_config_strings ? pk11_config_strings : "");
|
||||
|
||||
loser:
|
||||
PORT_Free(flags);
|
||||
@ -498,6 +531,11 @@ loser:
|
||||
if (lcertPrefix) PORT_Free(lcertPrefix);
|
||||
if (lkeyPrefix) PORT_Free(lkeyPrefix);
|
||||
if (lsecmodName) PORT_Free(lsecmodName);
|
||||
if (lupdateDir) PORT_Free(lupdateDir);
|
||||
if (lupdCertPrefix) PORT_Free(lupdCertPrefix);
|
||||
if (lupdKeyPrefix) PORT_Free(lupdKeyPrefix);
|
||||
if (lupdateID) PORT_Free(lupdateID);
|
||||
if (lupdateName) PORT_Free(lupdateName);
|
||||
|
||||
if (moduleSpec) {
|
||||
SECMODModule *module = SECMOD_LoadModule(moduleSpec,NULL,PR_TRUE);
|
||||
@ -555,15 +593,17 @@ loser:
|
||||
SECStatus
|
||||
NSS_Init(const char *configdir)
|
||||
{
|
||||
return nss_Init(configdir, "", "", SECMOD_DB, PR_TRUE,
|
||||
PR_FALSE, PR_FALSE, PR_FALSE, PR_FALSE, PR_TRUE, PR_FALSE, PR_FALSE, PR_FALSE);
|
||||
return nss_Init(configdir, "", "", SECMOD_DB, "", "", "", "", "",
|
||||
PR_TRUE, PR_FALSE, PR_FALSE, PR_FALSE, PR_FALSE,
|
||||
PR_TRUE, PR_FALSE, PR_FALSE, PR_FALSE);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
NSS_InitReadWrite(const char *configdir)
|
||||
{
|
||||
return nss_Init(configdir, "", "", SECMOD_DB, PR_FALSE,
|
||||
PR_FALSE, PR_FALSE, PR_FALSE, PR_FALSE, PR_TRUE, PR_FALSE, PR_FALSE, PR_FALSE);
|
||||
return nss_Init(configdir, "", "", SECMOD_DB, "", "", "", "", "",
|
||||
PR_FALSE, PR_FALSE, PR_FALSE, PR_FALSE, PR_FALSE,
|
||||
PR_TRUE, PR_FALSE, PR_FALSE, PR_FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -618,7 +658,28 @@ SECStatus
|
||||
NSS_Initialize(const char *configdir, const char *certPrefix,
|
||||
const char *keyPrefix, const char *secmodName, PRUint32 flags)
|
||||
{
|
||||
return nss_Init(configdir, certPrefix, keyPrefix, secmodName,
|
||||
return nss_Init(configdir, certPrefix, keyPrefix, secmodName,
|
||||
"", "", "", "", "",
|
||||
((flags & NSS_INIT_READONLY) == NSS_INIT_READONLY),
|
||||
((flags & NSS_INIT_NOCERTDB) == NSS_INIT_NOCERTDB),
|
||||
((flags & NSS_INIT_NOMODDB) == NSS_INIT_NOMODDB),
|
||||
((flags & NSS_INIT_FORCEOPEN) == NSS_INIT_FORCEOPEN),
|
||||
((flags & NSS_INIT_NOROOTINIT) == NSS_INIT_NOROOTINIT),
|
||||
((flags & NSS_INIT_OPTIMIZESPACE) == NSS_INIT_OPTIMIZESPACE),
|
||||
((flags & NSS_INIT_PK11THREADSAFE) == NSS_INIT_PK11THREADSAFE),
|
||||
((flags & NSS_INIT_PK11RELOAD) == NSS_INIT_PK11RELOAD),
|
||||
((flags & NSS_INIT_NOPK11FINALIZE) == NSS_INIT_NOPK11FINALIZE));
|
||||
}
|
||||
|
||||
SECStatus
|
||||
NSS_InitWithMerge(const char *configdir, const char *certPrefix,
|
||||
const char *keyPrefix, const char *secmodName,
|
||||
const char *updateDir, const char *updCertPrefix,
|
||||
const char *updKeyPrefix, const char *updateID,
|
||||
const char *updateName, PRUint32 flags)
|
||||
{
|
||||
return nss_Init(configdir, certPrefix, keyPrefix, secmodName,
|
||||
updateDir, updCertPrefix, updKeyPrefix, updateID, updateName,
|
||||
((flags & NSS_INIT_READONLY) == NSS_INIT_READONLY),
|
||||
((flags & NSS_INIT_NOCERTDB) == NSS_INIT_NOCERTDB),
|
||||
((flags & NSS_INIT_NOMODDB) == NSS_INIT_NOMODDB),
|
||||
@ -636,7 +697,7 @@ NSS_Initialize(const char *configdir, const char *certPrefix,
|
||||
SECStatus
|
||||
NSS_NoDB_Init(const char * configdir)
|
||||
{
|
||||
return nss_Init("","","","",
|
||||
return nss_Init("","","","", "", "", "", "", "",
|
||||
PR_TRUE,PR_TRUE,PR_TRUE,PR_TRUE,PR_TRUE,PR_TRUE,
|
||||
PR_FALSE,PR_FALSE,PR_FALSE);
|
||||
}
|
||||
|
||||
@ -66,6 +66,7 @@ CSRCS = \
|
||||
pk11list.c \
|
||||
pk11load.c \
|
||||
pk11mech.c \
|
||||
pk11merge.c \
|
||||
pk11nobj.c \
|
||||
pk11obj.c \
|
||||
pk11pars.c \
|
||||
|
||||
@ -87,6 +87,12 @@ pk11_MakeIDFromPublicKey(SECKEYPublicKey *pubKey)
|
||||
|
||||
/*
|
||||
* import a public key into the desired slot
|
||||
*
|
||||
* This function takes a public key structure and creates a public key in a
|
||||
* given slot. If isToken is set, then a persistant public key is created.
|
||||
*
|
||||
* Note: it is possible for this function to return a handle for a key which
|
||||
* is persistant, even if isToken is not set.
|
||||
*/
|
||||
CK_OBJECT_HANDLE
|
||||
PK11_ImportPublicKey(PK11SlotInfo *slot, SECKEYPublicKey *pubKey,
|
||||
@ -113,10 +119,12 @@ PK11_ImportPublicKey(PK11SlotInfo *slot, SECKEYPublicKey *pubKey,
|
||||
/* free the existing key */
|
||||
if (pubKey->pkcs11Slot != NULL) {
|
||||
PK11SlotInfo *oSlot = pubKey->pkcs11Slot;
|
||||
PK11_EnterSlotMonitor(oSlot);
|
||||
(void) PK11_GETTAB(oSlot)->C_DestroyObject(oSlot->session,
|
||||
if (!PK11_IsPermObject(pubKey->pkcs11Slot,pubKey->pkcs11ID)) {
|
||||
PK11_EnterSlotMonitor(oSlot);
|
||||
(void) PK11_GETTAB(oSlot)->C_DestroyObject(oSlot->session,
|
||||
pubKey->pkcs11ID);
|
||||
PK11_ExitSlotMonitor(oSlot);
|
||||
PK11_ExitSlotMonitor(oSlot);
|
||||
}
|
||||
PK11_FreeSlot(oSlot);
|
||||
pubKey->pkcs11Slot = NULL;
|
||||
}
|
||||
@ -1889,6 +1897,15 @@ PK11_MakeIDFromPubKey(SECItem *pubKeyData)
|
||||
SECItem *certCKA_ID;
|
||||
SECStatus rv;
|
||||
|
||||
if (pubKeyData->len <= SHA1_LENGTH) {
|
||||
/* probably an already hashed value. The strongest known public
|
||||
* key values <= 160 bits would be less than 40 bit symetric in
|
||||
* strength. Don't hash them, just return the value. There are
|
||||
* none at the time of this writing supported by previous versions
|
||||
* of NSS, so change is binary compatible safe */
|
||||
return SECITEM_DupItem(pubKeyData);
|
||||
}
|
||||
|
||||
context = PK11_CreateDigestContext(SEC_OID_SHA1);
|
||||
if (context == NULL) {
|
||||
return NULL;
|
||||
|
||||
1329
mozilla/security/nss/lib/pk11wrap/pk11merge.c
Normal file
1329
mozilla/security/nss/lib/pk11wrap/pk11merge.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -114,6 +114,7 @@ char * PK11_GetSlotName(PK11SlotInfo *slot);
|
||||
PRBool PK11_NeedLogin(PK11SlotInfo *slot);
|
||||
PRBool PK11_IsFriendly(PK11SlotInfo *slot);
|
||||
PRBool PK11_IsHW(PK11SlotInfo *slot);
|
||||
PRBool PK11_IsRemovable(PK11SlotInfo *slot);
|
||||
PRBool PK11_NeedUserInit(PK11SlotInfo *slot);
|
||||
PRBool PK11_ProtectedAuthenticationPath(PK11SlotInfo *slot);
|
||||
int PK11_GetSlotSeries(PK11SlotInfo *slot);
|
||||
@ -183,6 +184,7 @@ PK11SlotInfo *PK11_GetBestSlotMultiple(CK_MECHANISM_TYPE *type, int count,
|
||||
PK11SlotInfo *PK11_GetBestSlot(CK_MECHANISM_TYPE type, void *wincx);
|
||||
CK_MECHANISM_TYPE PK11_GetBestWrapMechanism(PK11SlotInfo *slot);
|
||||
int PK11_GetBestKeyLength(PK11SlotInfo *slot, CK_MECHANISM_TYPE type);
|
||||
|
||||
/*
|
||||
* Open a new database using the softoken. The caller is responsible for making
|
||||
* sure the module spec is correct and usable. The caller should ask for one
|
||||
@ -235,6 +237,20 @@ int PK11_GetBestKeyLength(PK11SlotInfo *slot, CK_MECHANISM_TYPE type);
|
||||
PK11SlotInfo *SECMOD_OpenUserDB(const char *moduleSpec);
|
||||
SECStatus SECMOD_CloseUserDB(PK11SlotInfo *slot);
|
||||
|
||||
/*
|
||||
* merge the permanent objects from on token to another
|
||||
*/
|
||||
SECStatus PK11_MergeTokens(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
|
||||
PK11MergeLog *log, void *targetPwArg, void *sourcePwArg);
|
||||
|
||||
/*
|
||||
* create and destroy merge logs needed by PK11_MergeTokens
|
||||
*/
|
||||
PK11MergeLog * PK11_CreateMergeLog();
|
||||
void PK11_DestroyMergeLog(PK11MergeLog *log);
|
||||
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
* Mechanism Mapping functions
|
||||
*********************************************************************/
|
||||
@ -288,6 +304,15 @@ PK11SymKey *PK11_GetWrapKey(PK11SlotInfo *slot, int wrap,
|
||||
*/
|
||||
void PK11_SetWrapKey(PK11SlotInfo *slot, int wrap, PK11SymKey *wrapKey);
|
||||
CK_MECHANISM_TYPE PK11_GetMechanism(PK11SymKey *symKey);
|
||||
/*
|
||||
* import a public key into the desired slot
|
||||
*
|
||||
* This function takes a public key structure and creates a public key in a
|
||||
* given slot. If isToken is set, then a persistant public key is created.
|
||||
*
|
||||
* Note: it is possible for this function to return a handle for a key which
|
||||
* is persistant, even if isToken is not set.
|
||||
*/
|
||||
CK_OBJECT_HANDLE PK11_ImportPublicKey(PK11SlotInfo *slot,
|
||||
SECKEYPublicKey *pubKey, PRBool isToken);
|
||||
PK11SymKey *PK11_KeyGen(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
|
||||
|
||||
@ -252,6 +252,41 @@ loser:
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* decrypt a block */
|
||||
static SECStatus
|
||||
pk11Decrypt(PK11SlotInfo *slot, PLArenaPool *arena,
|
||||
CK_MECHANISM_TYPE type, PK11SymKey *key,
|
||||
SECItem *params, SECItem *in, SECItem *result)
|
||||
{
|
||||
PK11Context *ctx = 0;
|
||||
SECItem paddedResult;
|
||||
SECStatus rv;
|
||||
|
||||
paddedResult.len = 0;
|
||||
paddedResult.data = 0;
|
||||
|
||||
ctx = PK11_CreateContextBySymKey(type, CKA_DECRYPT, key, params);
|
||||
if (!ctx) { rv = SECFailure; goto loser; }
|
||||
|
||||
paddedResult.len = in->len;
|
||||
paddedResult.data = PORT_ArenaAlloc(arena, paddedResult.len);
|
||||
|
||||
rv = PK11_CipherOp(ctx, paddedResult.data,
|
||||
(int*)&paddedResult.len, paddedResult.len,
|
||||
in->data, in->len);
|
||||
if (rv != SECSuccess) goto loser;
|
||||
|
||||
PK11_Finalize(ctx);
|
||||
|
||||
/* Remove the padding */
|
||||
rv = unpadBlock(&paddedResult, PK11_GetBlockSize(type, 0), result);
|
||||
if (rv) goto loser;
|
||||
|
||||
loser:
|
||||
if (ctx) PK11_DestroyContext(ctx, PR_TRUE);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* PK11SDR_Decrypt
|
||||
* Decrypt a block of data produced by PK11SDR_Encrypt. The key used is identified
|
||||
@ -263,15 +298,11 @@ PK11SDR_Decrypt(SECItem *data, SECItem *result, void *cx)
|
||||
SECStatus rv = SECSuccess;
|
||||
PK11SlotInfo *slot = 0;
|
||||
PK11SymKey *key = 0;
|
||||
PK11Context *ctx = 0;
|
||||
CK_MECHANISM_TYPE type;
|
||||
SDRResult sdrResult;
|
||||
SECItem *params = 0;
|
||||
SECItem paddedResult;
|
||||
PLArenaPool *arena = 0;
|
||||
|
||||
paddedResult.len = 0;
|
||||
paddedResult.data = 0;
|
||||
|
||||
arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
|
||||
if (!arena) { rv = SECFailure; goto loser; }
|
||||
@ -288,35 +319,48 @@ PK11SDR_Decrypt(SECItem *data, SECItem *result, void *cx)
|
||||
rv = PK11_Authenticate(slot, PR_TRUE, cx);
|
||||
if (rv != SECSuccess) goto loser;
|
||||
|
||||
/* Use triple-DES (Should look up the algorithm) */
|
||||
type = CKM_DES3_CBC;
|
||||
key = PK11_FindFixedKey(slot, type, &sdrResult.keyid, cx);
|
||||
if (!key) { rv = SECFailure; goto loser; }
|
||||
|
||||
/* Get the parameter values from the data */
|
||||
params = PK11_ParamFromAlgid(&sdrResult.alg);
|
||||
if (!params) { rv = SECFailure; goto loser; }
|
||||
|
||||
ctx = PK11_CreateContextBySymKey(type, CKA_DECRYPT, key, params);
|
||||
if (!ctx) { rv = SECFailure; goto loser; }
|
||||
/* Use triple-DES (Should look up the algorithm) */
|
||||
type = CKM_DES3_CBC;
|
||||
key = PK11_FindFixedKey(slot, type, &sdrResult.keyid, cx);
|
||||
if (!key) {
|
||||
rv = SECFailure;
|
||||
} else {
|
||||
rv = pk11Decrypt(slot, arena, type, key, params,
|
||||
&sdrResult.data, result);
|
||||
}
|
||||
/*
|
||||
* handle the case where your key indicies may have been broken
|
||||
*/
|
||||
if (rv != SECSuccess) {
|
||||
PK11SymKey *keyList = PK11_ListFixedKeysInSlot(slot, NULL, cx);
|
||||
PK11SymKey *testKey = NULL;
|
||||
PK11SymKey *nextKey = NULL;
|
||||
|
||||
paddedResult.len = sdrResult.data.len;
|
||||
paddedResult.data = PORT_ArenaAlloc(arena, paddedResult.len);
|
||||
for (testKey = keyList; testKey;
|
||||
testKey = PK11_GetNextSymKey(testKey)) {
|
||||
rv = pk11Decrypt(slot, arena, type, testKey, params,
|
||||
&sdrResult.data, result);
|
||||
if (rv == SECSuccess) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rv = PK11_CipherOp(ctx, paddedResult.data, (int*)&paddedResult.len, paddedResult.len,
|
||||
sdrResult.data.data, sdrResult.data.len);
|
||||
if (rv != SECSuccess) goto loser;
|
||||
/* free the list */
|
||||
for (testKey = keyList; testKey; testKey = nextKey) {
|
||||
nextKey = PK11_GetNextSymKey(testKey);
|
||||
PK11_FreeSymKey(testKey);
|
||||
}
|
||||
}
|
||||
|
||||
PK11_Finalize(ctx);
|
||||
|
||||
/* Remove the padding */
|
||||
rv = unpadBlock(&paddedResult, PK11_GetBlockSize(type, 0), result);
|
||||
if (rv) goto loser;
|
||||
|
||||
loser:
|
||||
/* SECITEM_ZfreeItem(&paddedResult, PR_FALSE); */
|
||||
if (arena) PORT_FreeArena(arena, PR_TRUE);
|
||||
if (ctx) PK11_DestroyContext(ctx, PR_TRUE);
|
||||
if (key) PK11_FreeSymKey(key);
|
||||
if (params) SECITEM_ZfreeItem(params, PR_TRUE);
|
||||
if (slot) PK11_FreeSlot(slot);
|
||||
|
||||
@ -1494,6 +1494,12 @@ PK11_IsHW(PK11SlotInfo *slot)
|
||||
return slot->isHW;
|
||||
}
|
||||
|
||||
PRBool
|
||||
PK11_IsRemovable(PK11SlotInfo *slot)
|
||||
{
|
||||
return !slot->isPerm;
|
||||
}
|
||||
|
||||
PRBool
|
||||
PK11_IsInternal(PK11SlotInfo *slot)
|
||||
{
|
||||
|
||||
@ -164,6 +164,8 @@ CK_OBJECT_HANDLE pk11_FindPrivateKeyFromCertID(PK11SlotInfo *slot,
|
||||
SECItem *keyID);
|
||||
SECKEYPrivateKey *PK11_MakePrivKey(PK11SlotInfo *slot, KeyType keyType,
|
||||
PRBool isTemp, CK_OBJECT_HANDLE privID, void *wincx);
|
||||
CERTCertificate *PK11_MakeCertFromHandle(PK11SlotInfo *slot,
|
||||
CK_OBJECT_HANDLE certID, CK_ATTRIBUTE *privateLabel);
|
||||
|
||||
SECItem *pk11_GenerateNewParamWithKeyLen(CK_MECHANISM_TYPE type, int keyLen);
|
||||
SECItem *pk11_ParamFromIVWithLen(CK_MECHANISM_TYPE type,
|
||||
|
||||
@ -465,4 +465,38 @@ typedef enum {
|
||||
#define CRL_IMPORT_DEFAULT_OPTIONS 0x00000000
|
||||
#define CRL_IMPORT_BYPASS_CHECKS 0x00000001
|
||||
|
||||
|
||||
/*
|
||||
* Merge Error Log
|
||||
*/
|
||||
typedef struct PK11MergeLogStr PK11MergeLog;
|
||||
typedef struct PK11MergeLogNodeStr PK11MergeLogNode;
|
||||
|
||||
/* These need to be global, leave some open fields so we can 'expand'
|
||||
* these without breaking binary compatibility */
|
||||
struct PK11MergeLogNodeStr {
|
||||
PK11MergeLogNode *next; /* next entry in the list */
|
||||
PK11MergeLogNode *prev; /* last entry in the list */
|
||||
PK11GenericObject *object; /* object that failed */
|
||||
int error; /* what the error was */
|
||||
CK_RV reserved1;
|
||||
unsigned long reserved2; /* future flags */
|
||||
unsigned long reserved3; /* future scalar */
|
||||
void *reserved4; /* future pointer */
|
||||
void *reserved5; /* future expansion pointer */
|
||||
};
|
||||
|
||||
struct PK11MergeLogStr {
|
||||
PK11MergeLogNode *head;
|
||||
PK11MergeLogNode *tail;
|
||||
PRArenaPool *arena;
|
||||
int version;
|
||||
unsigned long reserved1;
|
||||
unsigned long reserved2;
|
||||
unsigned long reserved3;
|
||||
void *reserverd4;
|
||||
void *reserverd5;
|
||||
};
|
||||
|
||||
|
||||
#endif /*_SECMODT_H_ */
|
||||
|
||||
@ -638,10 +638,12 @@ lg_FindPublicKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
|
||||
case CKA_MODIFIABLE:
|
||||
case CKA_EXTRACTABLE:
|
||||
return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr);
|
||||
case CKA_SUBJECT:
|
||||
return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
|
||||
case CKA_LABEL:
|
||||
label = lg_FindKeyNicknameByPublicKey(obj->sdb, &obj->dbKey);
|
||||
if (label == NULL) {
|
||||
return LG_CLONE_ATTR(attribute,type,lg_StaticOneAttr);
|
||||
return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
|
||||
}
|
||||
crv = lg_CopyAttribute(attribute,type,label,PORT_Strlen(label));
|
||||
PORT_Free(label);
|
||||
@ -652,6 +654,9 @@ lg_FindPublicKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
|
||||
|
||||
key = lg_GetPublicKey(obj);
|
||||
if (key == NULL) {
|
||||
if (type == CKA_ID) {
|
||||
return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
|
||||
}
|
||||
return CKR_OBJECT_HANDLE_INVALID;
|
||||
}
|
||||
|
||||
@ -1602,6 +1607,19 @@ done:
|
||||
return crv;
|
||||
}
|
||||
|
||||
static CK_RV
|
||||
lg_SetPublicKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
|
||||
const void *value, unsigned int len,
|
||||
PRBool *writePrivate)
|
||||
{
|
||||
/* we can't change the ID and we don't store the subject, but let the
|
||||
* upper layers feel better about the fact we tried to set these */
|
||||
if ((type == CKA_ID) || (type == CKA_SUBJECT) || (type == CKA_LABEL)) {
|
||||
return CKR_OK;
|
||||
}
|
||||
return CKR_ATTRIBUTE_READ_ONLY;
|
||||
}
|
||||
|
||||
static CK_RV
|
||||
lg_SetTrustAttribute(LGObjectCache *obj, const CK_ATTRIBUTE *attr)
|
||||
{
|
||||
@ -1613,11 +1631,15 @@ lg_SetTrustAttribute(LGObjectCache *obj, const CK_ATTRIBUTE *attr)
|
||||
SECStatus rv;
|
||||
CK_RV crv;
|
||||
|
||||
if (attr->type == CKA_LABEL) {
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
crv = lg_GetULongAttribute(attr->type, attr, 1, &trust);
|
||||
if (crv != CKR_OK) {
|
||||
return crv;
|
||||
}
|
||||
flags = lg_MapTrust(trust, (PRBool) (attr->type == CKA_TRUST_SERVER_AUTH));
|
||||
flags = lg_MapTrust(trust, (PRBool) (attr->type == CKA_TRUST_CLIENT_AUTH));
|
||||
|
||||
certHandle = lg_getCertDB(obj->sdb);
|
||||
|
||||
@ -1704,6 +1726,10 @@ lg_SetSingleAttribute(LGObjectCache *obj, const CK_ATTRIBUTE *attr,
|
||||
crv = lg_SetPrivateKeyAttribute(obj,attr->type,
|
||||
attr->pValue,attr->ulValueLen, writePrivate);
|
||||
break;
|
||||
case CKO_PUBLIC_KEY:
|
||||
crv = lg_SetPublicKeyAttribute(obj,attr->type,
|
||||
attr->pValue,attr->ulValueLen, writePrivate);
|
||||
break;
|
||||
}
|
||||
return crv;
|
||||
}
|
||||
|
||||
@ -205,7 +205,7 @@ sftkdb_encrypt_stub(PRArenaPool *arena, SDB *sdb, SECItem *plainText,
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* if we aren't th handle, try the other handle */
|
||||
/* if we aren't the key handle, try the other handle */
|
||||
if (handle->type != SFTK_KEYDB_TYPE) {
|
||||
handle = handle->peerDB;
|
||||
}
|
||||
@ -239,12 +239,14 @@ sftkdb_decrypt_stub(SDB *sdb, SECItem *cipherText, SECItem **plainText)
|
||||
{
|
||||
SFTKDBHandle *handle = sdb->app_private;
|
||||
SECStatus rv;
|
||||
SECItem *oldKey = NULL;
|
||||
|
||||
if (handle == NULL) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* if we aren't th handle, try the other handle */
|
||||
oldKey = handle->oldKey;
|
||||
if (handle->type != SFTK_KEYDB_TYPE) {
|
||||
handle = handle->peerDB;
|
||||
}
|
||||
@ -260,7 +262,8 @@ sftkdb_decrypt_stub(SDB *sdb, SECItem *cipherText, SECItem **plainText)
|
||||
/* PORT_SetError */
|
||||
return SECFailure;
|
||||
}
|
||||
rv = sftkdb_DecryptAttribute(&handle->passwordKey, cipherText, plainText);
|
||||
rv = sftkdb_DecryptAttribute( oldKey ? oldKey : &handle->passwordKey,
|
||||
cipherText, plainText);
|
||||
PZ_Unlock(handle->passwordLock);
|
||||
|
||||
return rv;
|
||||
|
||||
@ -478,11 +478,11 @@ void ForkedChild(void)
|
||||
#endif
|
||||
|
||||
static char *
|
||||
sftk_setStringName(const char *inString, char *buffer, int buffer_length)
|
||||
sftk_setStringName(const char *inString, char *buffer, int buffer_length, PRBool nullTerminate)
|
||||
{
|
||||
int full_length, string_length;
|
||||
|
||||
full_length = buffer_length -1;
|
||||
full_length = nullTerminate ? buffer_length -1 : buffer_length;
|
||||
string_length = PORT_Strlen(inString);
|
||||
/*
|
||||
* shorten the string, respecting utf8 encoding
|
||||
@ -522,7 +522,9 @@ sftk_setStringName(const char *inString, char *buffer, int buffer_length)
|
||||
}
|
||||
}
|
||||
PORT_Memset(buffer,' ',full_length);
|
||||
buffer[full_length] = 0;
|
||||
if (nullTerminate) {
|
||||
buffer[full_length] = 0;
|
||||
}
|
||||
PORT_Memcpy(buffer,inString,string_length);
|
||||
return buffer;
|
||||
}
|
||||
@ -536,11 +538,12 @@ sftk_configure(const char *man, const char *libdes)
|
||||
/* make sure the internationalization was done correctly... */
|
||||
if (man) {
|
||||
manufacturerID = sftk_setStringName(man,manufacturerID_space,
|
||||
sizeof(manufacturerID_space));
|
||||
sizeof(manufacturerID_space), PR_TRUE);
|
||||
}
|
||||
if (libdes) {
|
||||
libraryDescription = sftk_setStringName(libdes,
|
||||
libraryDescription_space, sizeof(libraryDescription_space));
|
||||
libraryDescription_space, sizeof(libraryDescription_space),
|
||||
PR_TRUE);
|
||||
}
|
||||
|
||||
return CKR_OK;
|
||||
@ -554,13 +557,13 @@ sftk_configure(const char *man, const char *libdes)
|
||||
* see if the key DB password is enabled
|
||||
*/
|
||||
static PRBool
|
||||
sftk_hasNullPassword(SFTKDBHandle *keydb)
|
||||
sftk_hasNullPassword(SFTKSlot *slot, SFTKDBHandle *keydb)
|
||||
{
|
||||
PRBool pwenabled;
|
||||
|
||||
pwenabled = PR_FALSE;
|
||||
if (sftkdb_HasPasswordSet(keydb) == SECSuccess) {
|
||||
return (sftkdb_CheckPassword(keydb, "") == SECSuccess);
|
||||
return (sftkdb_CheckPassword(slot, keydb, "") == SECSuccess);
|
||||
}
|
||||
|
||||
return pwenabled;
|
||||
@ -2028,8 +2031,8 @@ sftk_RegisterSlot(SFTKSlot *slot, int moduleIndex)
|
||||
*
|
||||
*/
|
||||
CK_RV
|
||||
SFTK_SlotReInit(SFTKSlot *slot,
|
||||
char *configdir,sftk_token_parameters *params, int moduleIndex)
|
||||
SFTK_SlotReInit(SFTKSlot *slot, char *configdir, char *updatedir,
|
||||
char *updateID, sftk_token_parameters *params, int moduleIndex)
|
||||
{
|
||||
PRBool needLogin = !params->noKeyDB;
|
||||
CK_RV crv;
|
||||
@ -2048,15 +2051,21 @@ SFTK_SlotReInit(SFTKSlot *slot,
|
||||
slot->readOnly = params->readOnly;
|
||||
sftk_setStringName(params->tokdes ? params->tokdes :
|
||||
sftk_getDefTokName(slot->slotID), slot->tokDescription,
|
||||
sizeof(slot->tokDescription));
|
||||
sizeof(slot->tokDescription),PR_TRUE);
|
||||
sftk_setStringName(params->updtokdes ? params->updtokdes : " ",
|
||||
slot->updateTokDescription,
|
||||
sizeof(slot->updateTokDescription),PR_TRUE);
|
||||
|
||||
if ((!params->noCertDB) || (!params->noKeyDB)) {
|
||||
SFTKDBHandle * certHandle = NULL;
|
||||
SFTKDBHandle *keyHandle = NULL;
|
||||
crv = sftk_DBInit(params->configdir ? params->configdir : configdir,
|
||||
params->certPrefix, params->keyPrefix, params->readOnly,
|
||||
params->noCertDB, params->noKeyDB, params->forceOpen,
|
||||
&certHandle, &keyHandle);
|
||||
params->certPrefix, params->keyPrefix,
|
||||
params->updatedir ? params->updatedir : updatedir,
|
||||
params->updCertPrefix, params->updKeyPrefix,
|
||||
params->updateID ? params->updateID : updateID,
|
||||
params->readOnly, params->noCertDB, params->noKeyDB,
|
||||
params->forceOpen, &certHandle, &keyHandle);
|
||||
if (crv != CKR_OK) {
|
||||
goto loser;
|
||||
}
|
||||
@ -2067,7 +2076,7 @@ SFTK_SlotReInit(SFTKSlot *slot,
|
||||
if (needLogin) {
|
||||
/* if the data base is initialized with a null password,remember that */
|
||||
slot->needLogin =
|
||||
(PRBool)!sftk_hasNullPassword(slot->keyDB);
|
||||
(PRBool)!sftk_hasNullPassword(slot, slot->keyDB);
|
||||
if ((params->minPW >= 0) && (params->minPW <= SFTK_MAX_PIN)) {
|
||||
slot->minimumPinLen = params->minPW;
|
||||
}
|
||||
@ -2092,7 +2101,8 @@ loser:
|
||||
* initialize one of the slot structures. figure out which by the ID
|
||||
*/
|
||||
CK_RV
|
||||
SFTK_SlotInit(char *configdir,sftk_token_parameters *params, int moduleIndex)
|
||||
SFTK_SlotInit(char *configdir, char *updatedir, char *updateID,
|
||||
sftk_token_parameters *params, int moduleIndex)
|
||||
{
|
||||
unsigned int i;
|
||||
CK_SLOT_ID slotID = params->slotID;
|
||||
@ -2155,11 +2165,12 @@ SFTK_SlotInit(char *configdir,sftk_token_parameters *params, int moduleIndex)
|
||||
slot->slotID = slotID;
|
||||
sftk_setStringName(params->slotdes ? params->slotdes :
|
||||
sftk_getDefSlotName(slotID), slot->slotDescription,
|
||||
sizeof(slot->slotDescription));
|
||||
sizeof(slot->slotDescription), PR_TRUE);
|
||||
|
||||
/* call the reinit code to set everything that changes between token
|
||||
* init calls */
|
||||
crv = SFTK_SlotReInit(slot, configdir, params, moduleIndex);
|
||||
crv = SFTK_SlotReInit(slot, configdir, updatedir, updateID,
|
||||
params, moduleIndex);
|
||||
if (crv != CKR_OK) {
|
||||
goto loser;
|
||||
}
|
||||
@ -2177,7 +2188,7 @@ loser:
|
||||
}
|
||||
|
||||
|
||||
static CK_RV sft_CloseAllSession(SFTKSlot *slot)
|
||||
CK_RV sftk_CloseAllSessions(SFTKSlot *slot)
|
||||
{
|
||||
SFTKSession *session;
|
||||
unsigned int i;
|
||||
@ -2268,7 +2279,7 @@ SFTK_ShutdownSlot(SFTKSlot *slot)
|
||||
* the sessHashSize variable guarentees we have all the session
|
||||
* mechanism set up */
|
||||
if (slot->head) {
|
||||
sft_CloseAllSession(slot);
|
||||
sftk_CloseAllSessions(slot);
|
||||
}
|
||||
|
||||
/* clear all objects.. session objects are cleared as a result of
|
||||
@ -2518,8 +2529,8 @@ CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS)
|
||||
|
||||
for (i=0; i < paramStrings.token_count; i++) {
|
||||
crv = SFTK_SlotInit(paramStrings.configdir,
|
||||
¶mStrings.tokens[i],
|
||||
moduleIndex);
|
||||
paramStrings.updatedir, paramStrings.updateID,
|
||||
¶mStrings.tokens[i], moduleIndex);
|
||||
if (crv != CKR_OK) {
|
||||
nscFreeAllSlots(moduleIndex);
|
||||
break;
|
||||
@ -2660,13 +2671,28 @@ CK_RV NSC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
|
||||
pInfo->firmwareVersion.major = 0;
|
||||
pInfo->firmwareVersion.minor = 0;
|
||||
|
||||
PORT_Memcpy(pInfo->manufacturerID,manufacturerID,32);
|
||||
PORT_Memcpy(pInfo->slotDescription,slot->slotDescription,64);
|
||||
PORT_Memcpy(pInfo->manufacturerID,manufacturerID,
|
||||
sizeof(pInfo->manufacturerID));
|
||||
PORT_Memcpy(pInfo->slotDescription,slot->slotDescription,
|
||||
sizeof(pInfo->slotDescription));
|
||||
pInfo->flags = (slot->present) ? CKF_TOKEN_PRESENT : 0;
|
||||
|
||||
/* all user defined slots are defined as removable */
|
||||
if (slotID >= SFTK_MIN_USER_SLOT_ID) {
|
||||
pInfo->flags |= CKF_REMOVABLE_DEVICE;
|
||||
} else {
|
||||
/* In the case where we are doing a merge update, we need
|
||||
* the DB slot to be removable so the token name can change
|
||||
* appropriately. */
|
||||
SFTKDBHandle *handle = sftk_getKeyDB(slot);
|
||||
if (handle) {
|
||||
if (sftkdb_InUpdateMerge(handle)) {
|
||||
pInfo->flags |= CKF_REMOVABLE_DEVICE;
|
||||
}
|
||||
sftk_freeDB(handle);
|
||||
}
|
||||
}
|
||||
|
||||
/* ok we really should read it out of the keydb file. */
|
||||
/* pInfo->hardwareVersion.major = NSSLOWKEY_DB_FILE_VERSION; */
|
||||
pInfo->hardwareVersion.major = SOFTOKEN_VMAJOR;
|
||||
@ -2684,10 +2710,22 @@ sftk_checkNeedLogin(SFTKSlot *slot, SFTKDBHandle *keyHandle)
|
||||
if (sftkdb_PWCached(keyHandle) == SECSuccess) {
|
||||
return slot->needLogin;
|
||||
}
|
||||
slot->needLogin = (PRBool)!sftk_hasNullPassword(keyHandle);
|
||||
slot->needLogin = (PRBool)!sftk_hasNullPassword(slot, keyHandle);
|
||||
return (slot->needLogin);
|
||||
}
|
||||
|
||||
static PRBool
|
||||
sftk_isBlank(const char *s, int len)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i < len; i++) {
|
||||
if (s[i] != ' ') {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
/* NSC_GetTokenInfo obtains information about a particular token in
|
||||
* the system. */
|
||||
CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)
|
||||
@ -2711,7 +2749,7 @@ CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)
|
||||
pInfo->ulRwSessionCount = slot->rwSessionCount;
|
||||
pInfo->firmwareVersion.major = 0;
|
||||
pInfo->firmwareVersion.minor = 0;
|
||||
PORT_Memcpy(pInfo->label,slot->tokDescription,32);
|
||||
PORT_Memcpy(pInfo->label,slot->tokDescription,sizeof(pInfo->label));
|
||||
handle = sftk_getKeyDB(slot);
|
||||
pInfo->flags = CKF_RNG | CKF_DUAL_CRYPTO_OPERATIONS;
|
||||
if (handle == NULL) {
|
||||
@ -2740,6 +2778,27 @@ CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)
|
||||
pInfo->flags |= CKF_USER_PIN_INITIALIZED;
|
||||
} else {
|
||||
pInfo->flags |= CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED;
|
||||
/*
|
||||
* if we are doing a merge style update, and we need to get the password
|
||||
* of our source database (the database we are updating from), make sure we
|
||||
* return a token name that will match the database we are prompting for.
|
||||
*/
|
||||
if (sftkdb_NeedUpdateDBPassword(handle)) {
|
||||
/* if we have an update tok description, use it. otherwise
|
||||
* use the updateID for this database */
|
||||
if (!sftk_isBlank(slot->updateTokDescription,
|
||||
sizeof(pInfo->label))) {
|
||||
PORT_Memcpy(pInfo->label,slot->updateTokDescription,
|
||||
sizeof(pInfo->label));
|
||||
} else {
|
||||
/* build from updateID */
|
||||
const char *updateID = sftkdb_GetUpdateID(handle);
|
||||
if (updateID) {
|
||||
sftk_setStringName(updateID, (char *)pInfo->label,
|
||||
sizeof(pInfo->label), PR_FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pInfo->ulMaxPinLen = SFTK_MAX_PIN;
|
||||
pInfo->ulMinPinLen = (CK_ULONG)slot->minimumPinLen;
|
||||
@ -2988,7 +3047,7 @@ CK_RV NSC_InitPIN(CK_SESSION_HANDLE hSession,
|
||||
/* build the hashed pins which we pass around */
|
||||
|
||||
/* change the data base */
|
||||
rv = sftkdb_ChangePassword(handle, NULL, newPinStr);
|
||||
rv = sftkdb_ChangePassword(slot, handle, NULL, newPinStr);
|
||||
sftk_freeDB(handle);
|
||||
handle = NULL;
|
||||
|
||||
@ -3067,7 +3126,7 @@ CK_RV NSC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin,
|
||||
|
||||
/* change the data base password */
|
||||
PR_Lock(slot->pwCheckLock);
|
||||
rv = sftkdb_ChangePassword(handle, oldPinStr, newPinStr);
|
||||
rv = sftkdb_ChangePassword(slot, handle, oldPinStr, newPinStr);
|
||||
sftk_freeDB(handle);
|
||||
handle = NULL;
|
||||
if ((rv != SECSuccess) && (slot->slotID == FIPS_SLOT_ID)) {
|
||||
@ -3205,7 +3264,7 @@ CK_RV NSC_CloseAllSessions (CK_SLOT_ID slotID)
|
||||
slot = sftk_SlotFromID(slotID, PR_FALSE);
|
||||
if (slot == NULL) return CKR_SLOT_ID_INVALID;
|
||||
|
||||
return sft_CloseAllSession(slot);
|
||||
return sftk_CloseAllSessions(slot);
|
||||
}
|
||||
|
||||
|
||||
@ -3313,18 +3372,22 @@ CK_RV NSC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
|
||||
|
||||
/* build the hashed pins which we pass around */
|
||||
PR_Lock(slot->pwCheckLock);
|
||||
rv = sftkdb_CheckPassword(handle,pinStr);
|
||||
sftk_freeDB(handle);
|
||||
handle = NULL;
|
||||
rv = sftkdb_CheckPassword(slot,handle,pinStr);
|
||||
if ((rv != SECSuccess) && (slot->slotID == FIPS_SLOT_ID)) {
|
||||
PR_Sleep(loginWaitTime);
|
||||
}
|
||||
PR_Unlock(slot->pwCheckLock);
|
||||
if (rv == SECSuccess) {
|
||||
PZ_Lock(slot->slotLock);
|
||||
slot->isLoggedIn = PR_TRUE;
|
||||
/* make sure the login state matches the underlying
|
||||
* database state */
|
||||
slot->isLoggedIn = sftkdb_PWCached(handle) == SECSuccess ?
|
||||
PR_TRUE : PR_FALSE;
|
||||
PZ_Unlock(slot->slotLock);
|
||||
|
||||
sftk_freeDB(handle);
|
||||
handle = NULL;
|
||||
|
||||
/* update all sessions */
|
||||
sftk_update_all_states(slot);
|
||||
return CKR_OK;
|
||||
@ -3450,9 +3513,11 @@ static CK_RV sftk_CreateNewSlot(SFTKSlot *slot, CK_OBJECT_CLASS class,
|
||||
|
||||
if (newSlot) {
|
||||
crv = SFTK_SlotReInit(newSlot, paramStrings.configdir,
|
||||
paramStrings.updatedir, paramStrings.updateID,
|
||||
¶mStrings.tokens[0], moduleIndex);
|
||||
} else {
|
||||
crv = SFTK_SlotInit(paramStrings.configdir,
|
||||
paramStrings.updatedir, paramStrings.updateID,
|
||||
¶mStrings.tokens[0], moduleIndex);
|
||||
}
|
||||
if (crv != CKR_OK) {
|
||||
|
||||
@ -376,7 +376,8 @@ struct SFTKSlotStr {
|
||||
SFTKSession **head; /* variable -reset */
|
||||
unsigned int sessHashSize; /* invariant */
|
||||
char tokDescription[33]; /* per load */
|
||||
char slotDescription[64]; /* invariant */
|
||||
char updateTokDescription[33]; /* per load */
|
||||
char slotDescription[65]; /* invariant */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -530,8 +531,13 @@ typedef struct sftk_token_parametersStr {
|
||||
char *configdir;
|
||||
char *certPrefix;
|
||||
char *keyPrefix;
|
||||
char *updatedir;
|
||||
char *updCertPrefix;
|
||||
char *updKeyPrefix;
|
||||
char *updateID;
|
||||
char *tokdes;
|
||||
char *slotdes;
|
||||
char *updtokdes;
|
||||
int minPW;
|
||||
PRBool readOnly;
|
||||
PRBool noCertDB;
|
||||
@ -543,6 +549,8 @@ typedef struct sftk_token_parametersStr {
|
||||
|
||||
typedef struct sftk_parametersStr {
|
||||
char *configdir;
|
||||
char *updatedir;
|
||||
char *updateID;
|
||||
char *secmodName;
|
||||
char *man;
|
||||
char *libdes;
|
||||
@ -580,12 +588,14 @@ extern CK_RV nsc_CommonGetSlotList(CK_BBOOL tokPresent,
|
||||
CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount, int moduleIndex);
|
||||
|
||||
/* slot initialization, reinit, shutdown and destruction */
|
||||
extern CK_RV SFTK_SlotInit(char *configdir,
|
||||
extern CK_RV SFTK_SlotInit(char *configdir, char *updatedir, char *updateID,
|
||||
sftk_token_parameters *params, int moduleIndex);
|
||||
extern CK_RV SFTK_SlotReInit(SFTKSlot *slot, char *configdir,
|
||||
char *updatedir, char *updateID,
|
||||
sftk_token_parameters *params, int moduleIndex);
|
||||
extern CK_RV SFTK_DestroySlotData(SFTKSlot *slot);
|
||||
extern CK_RV SFTK_ShutdownSlot(SFTKSlot *slot);
|
||||
extern CK_RV sftk_CloseAllSessions(SFTKSlot *slot);
|
||||
|
||||
|
||||
/* internal utility functions used by pkcs11.c */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -71,12 +71,18 @@ SECStatus sftkdb_AddSecmodDB(SDBType dbType, const char *appName,
|
||||
/* keydb functions */
|
||||
|
||||
SECStatus sftkdb_PWIsInitialized(SFTKDBHandle *keydb);
|
||||
SECStatus sftkdb_CheckPassword(SFTKDBHandle *keydb, const char *pw);
|
||||
SECStatus sftkdb_CheckPassword(SFTKSlot * slot, SFTKDBHandle *keydb, const char *pw);
|
||||
SECStatus sftkdb_PWCached(SFTKDBHandle *keydb);
|
||||
SECStatus sftkdb_HasPasswordSet(SFTKDBHandle *keydb);
|
||||
SECStatus sftkdb_ResetKeyDB(SFTKDBHandle *keydb);
|
||||
SECStatus sftkdb_ChangePassword(SFTKDBHandle *keydb, char *oldPin, char *newPin);
|
||||
SECStatus sftkdb_ChangePassword(SFTKSlot *slot, SFTKDBHandle *keydb,
|
||||
char *oldPin, char *newPin);
|
||||
SECStatus sftkdb_ClearPassword(SFTKDBHandle *keydb);
|
||||
SECStatus sftkdb_InUpdateMerge(SFTKDBHandle *keydb);
|
||||
SECStatus sftkdb_NeedUpdateDBPassword(SFTKDBHandle *keydb);
|
||||
const char *sftkdb_GetUpdateID(SFTKDBHandle *keydb);
|
||||
SECItem *sftkdb_GetUpdatePasswordKey(SFTKDBHandle *keydb);
|
||||
void sftkdb_FreeUpdatePasswordKey(SFTKDBHandle *keydb);
|
||||
|
||||
/* Utility functions */
|
||||
/*
|
||||
@ -96,8 +102,10 @@ SECStatus sftkdb_ClearPassword(SFTKDBHandle *keydb);
|
||||
* forceOpen - Continue to force initializations even if the databases cannot
|
||||
* be opened.
|
||||
*/
|
||||
CK_RV sftk_DBInit(const char *configdir, const char *certPrefix,
|
||||
const char *keyPrefix, PRBool readOnly, PRBool noCertDB,
|
||||
CK_RV sftk_DBInit(const char *configdir, const char *certPrefix,
|
||||
const char *keyPrefix, const char *updatedir,
|
||||
const char *updCertPrefix, const char *updKeyPrefix,
|
||||
const char *updateID, PRBool readOnly, PRBool noCertDB,
|
||||
PRBool noKeyDB, PRBool forceOpen,
|
||||
SFTKDBHandle **certDB, SFTKDBHandle **keyDB);
|
||||
CK_RV sftkdb_Shutdown(void);
|
||||
|
||||
@ -46,9 +46,13 @@ struct SFTKDBHandleStr {
|
||||
CK_OBJECT_HANDLE type;
|
||||
SECItem passwordKey;
|
||||
SECItem *newKey;
|
||||
SECItem *oldKey;
|
||||
SECItem *updatePasswordKey;
|
||||
PZLock *passwordLock;
|
||||
SFTKDBHandle *peerDB;
|
||||
SDB *update;
|
||||
char *updateID;
|
||||
PRBool updateDBIsInit;
|
||||
};
|
||||
|
||||
#define SFTK_KEYDB_TYPE 0x40000000
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
* Portions created by the Initial Developer are Copyright (C) 1994-2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
@ -344,9 +344,15 @@ sftk_parseTokenParameters(char *param, sftk_token_parameters *parsed)
|
||||
|
||||
while (*index) {
|
||||
SFTK_HANDLE_STRING_ARG(index,parsed->configdir,"configDir=",;)
|
||||
SFTK_HANDLE_STRING_ARG(index,parsed->updatedir,"updateDir=",;)
|
||||
SFTK_HANDLE_STRING_ARG(index,parsed->updCertPrefix,"updateCertPrefix=",;)
|
||||
SFTK_HANDLE_STRING_ARG(index,parsed->updKeyPrefix,"updateKeyPrefix=",;)
|
||||
SFTK_HANDLE_STRING_ARG(index,parsed->updateID,"updateID=",;)
|
||||
SFTK_HANDLE_STRING_ARG(index,parsed->certPrefix,"certPrefix=",;)
|
||||
SFTK_HANDLE_STRING_ARG(index,parsed->keyPrefix,"keyPrefix=",;)
|
||||
SFTK_HANDLE_STRING_ARG(index,parsed->tokdes,"tokenDescription=",;)
|
||||
SFTK_HANDLE_STRING_ARG(index,parsed->updtokdes,
|
||||
"updateTokenDescription=",;)
|
||||
SFTK_HANDLE_STRING_ARG(index,parsed->slotdes,"slotDescription=",;)
|
||||
SFTK_HANDLE_STRING_ARG(index,tmp,"minPWLen=",
|
||||
if(tmp) { parsed->minPW=atoi(tmp); PORT_Free(tmp); })
|
||||
@ -410,9 +416,9 @@ sftk_parseParameters(char *param, sftk_parameters *parsed, PRBool isFIPS)
|
||||
char *tmp;
|
||||
char *index;
|
||||
char *certPrefix = NULL, *keyPrefix = NULL;
|
||||
char *tokdes = NULL, *ptokdes = NULL;
|
||||
char *tokdes = NULL, *ptokdes = NULL, *pupdtokdes = NULL;
|
||||
char *slotdes = NULL, *pslotdes = NULL;
|
||||
char *fslotdes = NULL, *fpslotdes = NULL;
|
||||
char *fslotdes = NULL, *ftokdes = NULL, *fupdtokdes = NULL;
|
||||
char *minPW = NULL;
|
||||
index = sftk_argStrip(param);
|
||||
|
||||
@ -420,6 +426,8 @@ sftk_parseParameters(char *param, sftk_parameters *parsed, PRBool isFIPS)
|
||||
|
||||
while (*index) {
|
||||
SFTK_HANDLE_STRING_ARG(index,parsed->configdir,"configDir=",;)
|
||||
SFTK_HANDLE_STRING_ARG(index,parsed->updatedir,"updateDir=",;)
|
||||
SFTK_HANDLE_STRING_ARG(index,parsed->updateID,"updateID=",;)
|
||||
SFTK_HANDLE_STRING_ARG(index,parsed->secmodName,"secmod=",;)
|
||||
SFTK_HANDLE_STRING_ARG(index,parsed->man,"manufacturerID=",;)
|
||||
SFTK_HANDLE_STRING_ARG(index,parsed->libdes,"libraryDescription=",;)
|
||||
@ -431,7 +439,8 @@ sftk_parseParameters(char *param, sftk_parameters *parsed, PRBool isFIPS)
|
||||
SFTK_HANDLE_STRING_ARG(index,slotdes,"cryptoSlotDescription=",;)
|
||||
SFTK_HANDLE_STRING_ARG(index,pslotdes,"dbSlotDescription=",;)
|
||||
SFTK_HANDLE_STRING_ARG(index,fslotdes,"FIPSSlotDescription=",;)
|
||||
SFTK_HANDLE_STRING_ARG(index,fpslotdes,"FIPSTokenDescription=",;)
|
||||
SFTK_HANDLE_STRING_ARG(index,ftokdes,"FIPSTokenDescription=",;)
|
||||
SFTK_HANDLE_STRING_ARG(index,pupdtokdes, "updateTokenDescription=",;)
|
||||
SFTK_HANDLE_STRING_ARG(index,minPW,"minPWLen=",;)
|
||||
|
||||
SFTK_HANDLE_STRING_ARG(index,tmp,"flags=",
|
||||
@ -466,18 +475,22 @@ sftk_parseParameters(char *param, sftk_parameters *parsed, PRBool isFIPS)
|
||||
certPrefix = NULL;
|
||||
keyPrefix = NULL;
|
||||
if (isFIPS) {
|
||||
tokens[index].tokdes = fslotdes;
|
||||
tokens[index].slotdes = fpslotdes;
|
||||
tokens[index].tokdes = ftokdes;
|
||||
tokens[index].updtokdes = pupdtokdes;
|
||||
tokens[index].slotdes = fslotdes;
|
||||
fslotdes = NULL;
|
||||
fpslotdes = NULL;
|
||||
ftokdes = NULL;
|
||||
fupdtokdes = NULL;
|
||||
} else {
|
||||
tokens[index].tokdes = ptokdes;
|
||||
tokens[index].updtokdes = pupdtokdes;
|
||||
tokens[index].slotdes = pslotdes;
|
||||
tokens[0].slotID = NETSCAPE_SLOT_ID;
|
||||
tokens[0].tokdes = tokdes;
|
||||
tokens[0].slotdes = slotdes;
|
||||
tokens[0].noCertDB = PR_TRUE;
|
||||
tokens[0].noKeyDB = PR_TRUE;
|
||||
pupdtokdes = NULL;
|
||||
ptokdes = NULL;
|
||||
pslotdes = NULL;
|
||||
tokdes = NULL;
|
||||
@ -490,10 +503,12 @@ loser:
|
||||
FREE_CLEAR(keyPrefix);
|
||||
FREE_CLEAR(tokdes);
|
||||
FREE_CLEAR(ptokdes);
|
||||
FREE_CLEAR(pupdtokdes);
|
||||
FREE_CLEAR(slotdes);
|
||||
FREE_CLEAR(pslotdes);
|
||||
FREE_CLEAR(fslotdes);
|
||||
FREE_CLEAR(fpslotdes);
|
||||
FREE_CLEAR(ftokdes);
|
||||
FREE_CLEAR(fupdtokdes);
|
||||
FREE_CLEAR(minPW);
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
@ -550,6 +550,114 @@ sftkdb_switchKeys(SFTKDBHandle *keydb, SECItem *passKey)
|
||||
PZ_Unlock(keydb->passwordLock);
|
||||
}
|
||||
|
||||
/*
|
||||
* returns true if we are in a middle of a merge style update.
|
||||
*/
|
||||
PRBool
|
||||
sftkdb_InUpdateMerge(SFTKDBHandle *keydb)
|
||||
{
|
||||
return keydb->updateID ? PR_TRUE : PR_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* returns true if we are looking for the password for the user's old source
|
||||
* database as part of a merge style update.
|
||||
*/
|
||||
PRBool
|
||||
sftkdb_NeedUpdateDBPassword(SFTKDBHandle *keydb)
|
||||
{
|
||||
if (!sftkdb_InUpdateMerge(keydb)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
if (keydb->updateDBIsInit && !keydb->updatePasswordKey) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* fetch an update password key from a handle.
|
||||
*/
|
||||
SECItem *
|
||||
sftkdb_GetUpdatePasswordKey(SFTKDBHandle *handle)
|
||||
{
|
||||
SECItem *key = NULL;
|
||||
|
||||
/* if we're a cert db, fetch it from our peer key db */
|
||||
if (handle->type == SFTK_CERTDB_TYPE) {
|
||||
handle = handle->peerDB;
|
||||
}
|
||||
|
||||
/* don't have one */
|
||||
if (!handle) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PZ_Lock(handle->passwordLock);
|
||||
if (handle->updatePasswordKey) {
|
||||
key = SECITEM_DupItem(handle->updatePasswordKey);
|
||||
}
|
||||
PZ_Unlock(handle->passwordLock);
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
/*
|
||||
* free the update password key from a handle.
|
||||
*/
|
||||
void
|
||||
sftkdb_FreeUpdatePasswordKey(SFTKDBHandle *handle)
|
||||
{
|
||||
SECItem *key = NULL;
|
||||
|
||||
/* if we're a cert db, we don't have one */
|
||||
if (handle->type == SFTK_CERTDB_TYPE) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* don't have one */
|
||||
if (!handle) {
|
||||
return;
|
||||
}
|
||||
|
||||
PZ_Lock(handle->passwordLock);
|
||||
if (handle->updatePasswordKey) {
|
||||
key = handle->updatePasswordKey;
|
||||
handle->updatePasswordKey = NULL;
|
||||
}
|
||||
PZ_Unlock(handle->passwordLock);
|
||||
|
||||
if (key) {
|
||||
SECITEM_ZfreeItem(key, PR_TRUE);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* what password db we use depends heavily on the update state machine
|
||||
*
|
||||
* 1) no update db, return the normal database.
|
||||
* 2) update db and no merge return the update db.
|
||||
* 3) update db and in merge:
|
||||
* return the update db if we need the update db's password,
|
||||
* otherwise return our normal datbase.
|
||||
*/
|
||||
static SDB *
|
||||
sftk_getPWSDB(SFTKDBHandle *keydb)
|
||||
{
|
||||
if (!keydb->update) {
|
||||
return keydb->db;
|
||||
}
|
||||
if (!sftkdb_InUpdateMerge(keydb)) {
|
||||
return keydb->update;
|
||||
}
|
||||
if (sftkdb_NeedUpdateDBPassword(keydb)) {
|
||||
return keydb->update;
|
||||
}
|
||||
return keydb->db;
|
||||
}
|
||||
|
||||
/*
|
||||
* return success if we have a valid password entry.
|
||||
* This is will show up outside of PKCS #11 as CKF_USER_PIN_INIT
|
||||
@ -568,7 +676,7 @@ sftkdb_HasPasswordSet(SFTKDBHandle *keydb)
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
db = SFTK_GET_SDB(keydb);
|
||||
db = sftk_getPWSDB(keydb);
|
||||
if (db == NULL) {
|
||||
return SECFailure;
|
||||
}
|
||||
@ -588,7 +696,7 @@ sftkdb_HasPasswordSet(SFTKDBHandle *keydb)
|
||||
* check if the supplied password is valid
|
||||
*/
|
||||
SECStatus
|
||||
sftkdb_CheckPassword(SFTKDBHandle *keydb, const char *pw)
|
||||
sftkdb_CheckPassword(SFTKSlot *slot, SFTKDBHandle *keydb, const char *pw)
|
||||
{
|
||||
SECStatus rv;
|
||||
SECItem salt, value;
|
||||
@ -603,7 +711,7 @@ sftkdb_CheckPassword(SFTKDBHandle *keydb, const char *pw)
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
db = SFTK_GET_SDB(keydb);
|
||||
db = sftk_getPWSDB(keydb);
|
||||
if (db == NULL) {
|
||||
return SECFailure;
|
||||
}
|
||||
@ -621,27 +729,133 @@ sftkdb_CheckPassword(SFTKDBHandle *keydb, const char *pw)
|
||||
crv = (*db->sdb_GetMetaData)(db, "password", &salt, &value);
|
||||
if (crv != CKR_OK) {
|
||||
rv = SECFailure;
|
||||
goto loser;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* get our intermediate key based on the entry salt value */
|
||||
rv = sftkdb_passwordToKey(keydb, &salt, pw, &key);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* decrypt the entry value */
|
||||
rv = sftkdb_DecryptAttribute(&key, &value, &result);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* if it's what we expect, update our key in the database handle and
|
||||
* return Success */
|
||||
if ((result->len == SFTK_PW_CHECK_LEN) &&
|
||||
PORT_Memcmp(result->data, SFTK_PW_CHECK_STRING, SFTK_PW_CHECK_LEN) == 0){
|
||||
/*
|
||||
* We have a password, now lets handle any potential update cases..
|
||||
*
|
||||
* First, the normal case: no update. In this case we only need the
|
||||
* the password for our only DB, which we now have, we switch
|
||||
* the keys and fall through.
|
||||
* Second regular (non-merge) update: The target DB does not yet have
|
||||
* a password initialized, we now have the password for the source DB,
|
||||
* so we can switch the keys and simply update the target database.
|
||||
* Merge update case: This one is trickier.
|
||||
* 1) If we need the source DB password, then we just got it here.
|
||||
* We need to save that password,
|
||||
* then we need to check to see if we need or have the target
|
||||
* database password.
|
||||
* If we have it (it's the same as the source), or don't need
|
||||
* it (it's not set or is ""), we can start the update now.
|
||||
* If we don't have it, we need the application to get it from
|
||||
* the user. Clear our sessions out to simulate a token
|
||||
* removal. C_GetTokenInfo will change the token description
|
||||
* and the token will still appear to be logged out.
|
||||
* 2) If we already have the source DB password, this password is
|
||||
* for the target database. We can now move forward with the
|
||||
* update, as we now have both required passwords.
|
||||
*
|
||||
*/
|
||||
PZ_Lock(keydb->passwordLock);
|
||||
if (sftkdb_NeedUpdateDBPassword(keydb)) {
|
||||
/* Squirrel this special key away.
|
||||
* This has the side effect of turning sftkdb_NeedLegacyPW off,
|
||||
* as well as changing which database is returned from
|
||||
* SFTK_GET_PW_DB (thus effecting both sftkdb_CheckPassword()
|
||||
* and sftkdb_HasPasswordSet()) */
|
||||
keydb->updatePasswordKey = SECITEM_DupItem(&key);
|
||||
PZ_Unlock(keydb->passwordLock);
|
||||
if (keydb->updatePasswordKey == NULL) {
|
||||
/* PORT_Error set by SECITEM_DupItem */
|
||||
rv = SECFailure;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Simulate a token removal -- we need to do this any
|
||||
* any case at this point so the token name is correct. NOTE: if
|
||||
* slot is NULL, then we were called from the database init code,
|
||||
* there are no sessions, so there is no need to close them. */
|
||||
if (slot) {
|
||||
sftk_CloseAllSessions(slot);
|
||||
}
|
||||
|
||||
/*
|
||||
* OK, we got the update DB password, see if we need a password
|
||||
* for the target...
|
||||
*/
|
||||
if (sftkdb_HasPasswordSet(keydb) == SECSuccess) {
|
||||
/* We have a password, do we know what the password is?
|
||||
* check 1) for the password the user supplied for the
|
||||
* update DB,
|
||||
* and 2) for the null password.
|
||||
*
|
||||
* RECURSION NOTE: we are calling ourselves here. This means
|
||||
* any updates, switchKeys, etc will have been completed
|
||||
* if these functions return successfully, in those cases
|
||||
* just exit returning Success. We don't recurse infinitely
|
||||
* because we are making this call from a NeedUpdateDBPassword
|
||||
* block and we've already set that update password at this
|
||||
* point. */
|
||||
rv = sftkdb_CheckPassword(slot, keydb, pw);
|
||||
if (rv == SECSuccess) {
|
||||
/* source and target databases have the same password, we
|
||||
* are good to go */
|
||||
goto done;
|
||||
}
|
||||
sftkdb_CheckPassword(slot, keydb, "");
|
||||
|
||||
/*
|
||||
* Important 'NULL' code here. At this point either we
|
||||
* succeeded in logging in with "" or we didn't.
|
||||
*
|
||||
* If we did succeed at login, our machine state will be set
|
||||
* to logged in appropriately. The application will find that
|
||||
* it's logged in as soon as it opens a new session. We have
|
||||
* also completed the update. Life is good.
|
||||
*
|
||||
* If we did not succeed, well the user still successfully
|
||||
* logged into the update database, since we faked the token
|
||||
* removal it's just like the user logged into his smart card
|
||||
* then removed it. the actual login work, so we report that
|
||||
* success back to the user, but we won't actually be
|
||||
* logged in. The application will find this out when it
|
||||
* checks it's login state, thus triggering another password
|
||||
* prompt so we can get the real target DB password.
|
||||
*
|
||||
* summary, we exit from here with SECSuccess no matter what.
|
||||
*/
|
||||
rv = SECSuccess;
|
||||
goto done;
|
||||
} else {
|
||||
/* there is no password, just fall through to update.
|
||||
* update will write the source DB's password record
|
||||
* into the target DB just like it would in a non-merge
|
||||
* update case. */
|
||||
}
|
||||
} else {
|
||||
PZ_Unlock(keydb->passwordLock);
|
||||
}
|
||||
/* load the keys, so the keydb can parse it's key set */
|
||||
sftkdb_switchKeys(keydb, &key);
|
||||
|
||||
/* we need to update, do it now */
|
||||
if (keydb->update) {
|
||||
/* update the peer certdb if it exists */
|
||||
if (keydb->peerDB) {
|
||||
@ -654,7 +868,7 @@ sftkdb_CheckPassword(SFTKDBHandle *keydb, const char *pw)
|
||||
/*PORT_SetError( bad password); */
|
||||
}
|
||||
|
||||
loser:
|
||||
done:
|
||||
if (key.data) {
|
||||
PORT_ZFree(key.data,key.len);
|
||||
}
|
||||
@ -951,7 +1165,8 @@ sftkdb_convertObjects(SFTKDBHandle *handle, CK_ATTRIBUTE *template,
|
||||
* change the database password.
|
||||
*/
|
||||
SECStatus
|
||||
sftkdb_ChangePassword(SFTKDBHandle *keydb, char *oldPin, char *newPin)
|
||||
sftkdb_ChangePassword(SFTKSlot *slot, SFTKDBHandle *keydb,
|
||||
char *oldPin, char *newPin)
|
||||
{
|
||||
SECStatus rv = SECSuccess;
|
||||
SECItem plainText;
|
||||
@ -987,7 +1202,7 @@ sftkdb_ChangePassword(SFTKDBHandle *keydb, char *oldPin, char *newPin)
|
||||
value.len = sizeof(valueData);
|
||||
crv = (*db->sdb_GetMetaData)(db, "password", &salt, &value);
|
||||
if (crv == CKR_OK) {
|
||||
rv = sftkdb_CheckPassword(keydb, oldPin);
|
||||
rv = sftkdb_CheckPassword(slot, keydb, oldPin);
|
||||
if (rv == SECFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
@ -97,7 +97,7 @@ run_tests()
|
||||
done
|
||||
}
|
||||
|
||||
tests="cipher perf libpkix cert dbtests tools fips sdr crmf smime ssl ocsp"
|
||||
tests="cipher perf libpkix cert dbtests tools fips sdr crmf smime ssl ocsp merge"
|
||||
if [ -z "$BUILD_LIBPKIX_TESTS" ] ; then
|
||||
tests=`echo "${tests}" | sed -e "s/libpkix//"`
|
||||
fi
|
||||
@ -132,6 +132,7 @@ env_backup > ${ENV_BACKUP}
|
||||
|
||||
# standard tests, no pkix, no sharedb
|
||||
if [ -z "$NSS_TEST_DISABLE_STANDARD" ] ; then
|
||||
TEST_MODE=STANDARD
|
||||
run_tests
|
||||
fi
|
||||
|
||||
@ -152,6 +153,7 @@ if [ -z "$NSS_TEST_DISABLE_PKIX" ] ; then
|
||||
|
||||
TESTS=`echo "${ALL_TESTS}" | sed -e "s/cipher//" -e "s/libpkix//" \
|
||||
-e "s/dbupgrade//"`
|
||||
TEST_MODE=PKIX
|
||||
run_tests
|
||||
|
||||
. ${ENV_BACKUP}
|
||||
@ -161,6 +163,7 @@ fi
|
||||
if [ -z "$NSS_TEST_DISABLE_UPGRADE_DB" ] ; then
|
||||
# upgrade certs dbs to shared db
|
||||
TESTS="dbupgrade"
|
||||
TEST_MODE=UPGRADE_DB
|
||||
run_tests
|
||||
|
||||
TABLE_ARGS="bgcolor=pink"
|
||||
@ -193,6 +196,7 @@ if [ -z "$NSS_TEST_DISABLE_SHARED_DB" ] ; then
|
||||
|
||||
# run the tests for native sharedb support
|
||||
TESTS=`echo "${ALL_TESTS}" | sed -e "s/libpkix//" -e "s/dbupgrade//"`
|
||||
TEST_MODE=SHARED_DB
|
||||
run_tests
|
||||
|
||||
. ${ENV_BACKUP}
|
||||
|
||||
251
mozilla/security/nss/tests/merge/merge.sh
Executable file
251
mozilla/security/nss/tests/merge/merge.sh
Executable file
@ -0,0 +1,251 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is the Netscape security libraries.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
########################################################################
|
||||
#
|
||||
# mozilla/security/nss/tests/merge/merge.sh
|
||||
#
|
||||
# Script to test NSS merge
|
||||
#
|
||||
# needs to work on all Unix and Windows platforms
|
||||
#
|
||||
# special strings
|
||||
# ---------------
|
||||
# FIXME ... known problems, search for this string
|
||||
# NOTE .... unexpected behavior
|
||||
#
|
||||
########################################################################
|
||||
|
||||
############################## merge_init ##############################
|
||||
# local shell function to initialize this script
|
||||
########################################################################
|
||||
merge_init()
|
||||
{
|
||||
SCRIPTNAME=merge.sh # sourced - $0 would point to all.sh
|
||||
|
||||
|
||||
if [ -z "${CLEANUP}" ] ; then # if nobody else is responsible for
|
||||
CLEANUP="${SCRIPTNAME}" # cleaning this script will do it
|
||||
fi
|
||||
|
||||
if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then
|
||||
cd ../common
|
||||
. ./init.sh
|
||||
fi
|
||||
if [ ! -r $CERT_LOG_FILE ]; then # we need certificates here
|
||||
cd ${QADIR}/cert
|
||||
. ./cert.sh
|
||||
fi
|
||||
|
||||
if [ ! -d ${HOSTDIR}/SDR ]; then
|
||||
cd ${QADIR}/sdr
|
||||
. ./sdr.sh
|
||||
fi
|
||||
SCRIPTNAME=merge.sh
|
||||
|
||||
html_head "Merge Tests"
|
||||
|
||||
# need the SSL & SMIME directories from cert.sh
|
||||
grep "SUCCESS: SMIME passed" $CERT_LOG_FILE >/dev/null || {
|
||||
Exit 11 "Fatal - S/MIME of cert.sh needs to pass first"
|
||||
}
|
||||
grep "SUCCESS: SSL passed" $CERT_LOG_FILE >/dev/null || {
|
||||
Exit 8 "Fatal - SSL of cert.sh needs to pass first"
|
||||
}
|
||||
|
||||
#temporary files for SDR tests
|
||||
VALUE1=$HOSTDIR/tests.v1.$$
|
||||
VALUE3=$HOSTDIR/tests.v3.$$
|
||||
|
||||
# local directories used in this test.
|
||||
MERGEDIR=${HOSTDIR}/merge
|
||||
R_MERGEDIR=../merge
|
||||
D_MERGE="merge.$version"
|
||||
# SDR not initialized in common/init
|
||||
P_R_SDR=../SDR
|
||||
D_SDR="SDR.$version"
|
||||
mkdir -p ${MERGEDIR}
|
||||
|
||||
PROFILE=.
|
||||
if [ -n "${MULTIACCESS_DBM}" ]; then
|
||||
PROFILE="multiaccess:${D_MERGE}"
|
||||
P_R_SDR="multiaccess:${D_SDR}"
|
||||
fi
|
||||
|
||||
cd ${MERGEDIR}
|
||||
|
||||
# clear out any existing databases, potentially from a previous run.
|
||||
rm -f *.db
|
||||
|
||||
# copy alicedir over as a seed database.
|
||||
cp ${R_ALICEDIR}/* .
|
||||
# copy the smime text samples
|
||||
cp ${QADIR}/smime/*.txt .
|
||||
|
||||
#
|
||||
# allow all the tests to run in standalone mode.
|
||||
# in standalone mode, TEST_MODE is not set.
|
||||
# if NSS_DEFAULT_DB_TYPE is dbm, then test merge with dbm
|
||||
# if NSS_DEFAULT_DB_TYPE is sql, then test merge with sql
|
||||
# if NSS_DEFAULT_DB_TYPE is not set, then test database upgrade merge
|
||||
# from dbm databases (created above) into a new sql db.
|
||||
if [ -z "${TEST_MODE}" ] && [ -z "${NSS_DEFAULT_DB_TYPE}" ]; then
|
||||
echo "*** Using Standalone Upgrade DB mode"
|
||||
export NSS_DEFAULT_DB_TYPE=sql
|
||||
echo certutil --upgrade-merge --source-dir ${P_R_ALICEDIR} --upgrade-id local -d ${PROFILE} -f ${R_PWFILE} -@ ${R_PWFILE}
|
||||
#gdb `which certutil`
|
||||
certutil --upgrade-merge --source-dir ${P_R_ALICEDIR} --upgrade-id local -d ${PROFILE} -f ${R_PWFILE} -@ ${R_PWFILE}
|
||||
TEST_MODE=UPGRADE_DB
|
||||
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
#
|
||||
# this allows us to run this test for both merge and upgrade-merge cases.
|
||||
# merge_cmd takes the potential upgrade-id and the rest of the certutil
|
||||
# arguments.
|
||||
#
|
||||
merge_cmd()
|
||||
{
|
||||
MERGE_CMD=--merge
|
||||
if [ "${TEST_MODE}" = "UPGRADE_DB" ]; then
|
||||
MERGE_CMD="--upgrade-merge --upgrade-token-name OldDB --upgrade-id ${1}"
|
||||
fi
|
||||
shift
|
||||
echo certutil ${MERGE_CMD} $*
|
||||
${PROFTOOL} certutil ${MERGE_CMD} $*
|
||||
}
|
||||
|
||||
|
||||
merge_main()
|
||||
{
|
||||
# first create a local sdr key and encrypt some data with it
|
||||
# This will cause a colision with the SDR key in ../SDR.
|
||||
echo "$SCRIPTNAME: Creating an SDR key & Encrypt"
|
||||
echo "sdrtest -d ${PROFILE} -o ${VALUE3} -t Test2 -f ${R_PWFILE}"
|
||||
${PROFTOOL} sdrtest -d ${PROFILE} -o ${VALUE3} -t Test2 -f ${R_PWFILE}
|
||||
html_msg $? 0 "Creating SDR Key"
|
||||
|
||||
# Now merge in Dave
|
||||
# Dave's cert is already in alicedir, but his key isn't. This will make
|
||||
# sure we are updating the keys and CKA_ID's on the certificate properly.
|
||||
MERGE_ID=dave
|
||||
echo "$SCRIPTNAME: Merging in Key for Existing user"
|
||||
merge_cmd dave --source-dir ${P_R_DAVEDIR} -d ${PROFILE} -f ${R_PWFILE} -@ ${R_PWFILE}
|
||||
html_msg $? 0 "Merging Dave"
|
||||
|
||||
# Merge in server
|
||||
# contains a CRL and new user certs
|
||||
MERGE_ID=server
|
||||
echo "$SCRIPTNAME: Merging in new user "
|
||||
merge_cmd server --source-dir ${P_R_SERVERDIR} -d ${PROFILE} -f ${R_PWFILE} -@ ${R_PWFILE}
|
||||
html_msg $? 0 "Merging server"
|
||||
|
||||
# Merge in ext_client
|
||||
# contains a new certificate chain and additional trust flags
|
||||
MERGE_ID=ext_client
|
||||
echo "$SCRIPTNAME: Merging in new chain "
|
||||
merge_cmd ext_client --source-dir ${P_R_EXT_CLIENTDIR} -d ${PROFILE} -f ${R_PWFILE} -@ ${R_PWFILE}
|
||||
html_msg $? 0 "Merging ext_client"
|
||||
|
||||
# Merge in SDR
|
||||
# contains a secret SDR key
|
||||
MERGE_ID=SDR
|
||||
echo "$SCRIPTNAME: Merging in SDR "
|
||||
merge_cmd sdr --source-dir ${P_R_SDR} -d ${PROFILE} -f ${R_PWFILE} -@ ${R_PWFILE}
|
||||
html_msg $? 0 "Merging SDR"
|
||||
|
||||
# insert a listing of the database into the log for diagonic purposes
|
||||
certutil -L -d ${PROFILE}
|
||||
crlutil -L -d ${PROFILE}
|
||||
|
||||
# Make sure we can decrypt with our original SDR key generated above
|
||||
echo "$SCRIPTNAME: Decrypt - With Original SDR Key"
|
||||
${PROFTOOL} echo "sdrtest -d ${PROFILE} -i ${VALUE3} -t Test2 -f ${R_PWFILE}"
|
||||
sdrtest -d ${PROFILE} -i ${VALUE3} -t Test2 -f ${R_PWFILE}
|
||||
html_msg $? 0 "Decrypt - Value 3"
|
||||
|
||||
# Make sure we can decrypt with our the SDR key merged in from ../SDR
|
||||
echo "$SCRIPTNAME: Decrypt - With Merged SDR Key"
|
||||
echo "sdrtest -d ${PROFILE} -i ${VALUE1} -t Test1 -f ${R_PWFILE}"
|
||||
${PROFTOOL} sdrtest -d ${PROFILE} -i ${VALUE1} -t Test1 -f ${R_PWFILE}
|
||||
html_msg $? 0 "Decrypt - Value 1"
|
||||
|
||||
# Make sure we can sign with merge certificate
|
||||
echo "$SCRIPTNAME: Signing with merged key ------------------"
|
||||
echo "cmsutil -S -T -N Dave -H SHA1 -i alice.txt -d ${PROFILE} -p nss -o dave.dsig"
|
||||
${PROFTOOL} cmsutil -S -T -N Dave -H SHA1 -i alice.txt -d ${PROFILE} -p nss -o dave.dsig
|
||||
html_msg $? 0 "Create Detached Signature Dave" "."
|
||||
|
||||
echo "cmsutil -D -i dave.dsig -c alice.txt -d ${PROFILE} "
|
||||
${PROFTOOL} cmsutil -D -i dave.dsig -c alice.txt -d ${PROFILE}
|
||||
html_msg $? 0 "Verifying Dave's Detached Signature"
|
||||
|
||||
# Make sure that trust objects were properly merged
|
||||
echo "$SCRIPTNAME: verifying merged cert ------------------"
|
||||
echo "certutil -V -n ExtendedSSLUser -u C -d ${PROFILE}"
|
||||
${PROFTOOL} certutil -V -n ExtendedSSLUser -u C -d ${PROFILE}
|
||||
html_msg $? 0 "Verifying ExtendedSSL User Cert"
|
||||
|
||||
# Make sure that the crl got properly copied in
|
||||
echo "$SCRIPTNAME: verifying merged crl ------------------"
|
||||
echo "crlutil -L -n TestCA -d ${PROFILE}"
|
||||
${PROFTOOL} crlutil -L -n TestCA -d ${PROFILE}
|
||||
html_msg $? 0 "Verifying TestCA CRL"
|
||||
|
||||
}
|
||||
|
||||
############################## smime_cleanup ###########################
|
||||
# local shell function to finish this script (no exit since it might be
|
||||
# sourced)
|
||||
########################################################################
|
||||
merge_cleanup()
|
||||
{
|
||||
html "</TABLE><BR>"
|
||||
cd ${QADIR}
|
||||
. common/cleanup.sh
|
||||
}
|
||||
|
||||
################## main #################################################
|
||||
|
||||
merge_init
|
||||
merge_main
|
||||
merge_cleanup
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user