589 lines
21 KiB
Diff
589 lines
21 KiB
Diff
diff --git a/lib/softoken/lgglue.c b/lib/softoken/lgglue.c
|
|
--- a/lib/softoken/lgglue.c
|
|
+++ b/lib/softoken/lgglue.c
|
|
@@ -179,23 +179,23 @@ sftkdb_encrypt_stub(PLArenaPool *arena,
|
|
}
|
|
|
|
/* if we aren't the key handle, try the other handle */
|
|
if (handle->type != SFTK_KEYDB_TYPE) {
|
|
handle = handle->peerDB;
|
|
}
|
|
|
|
/* not a key handle */
|
|
- if (handle == NULL || handle->passwordLock == NULL) {
|
|
+ if (handle == NULL || !sftkdb_passwordLockIsInited(handle)) {
|
|
return SECFailure;
|
|
}
|
|
|
|
- PZ_Lock(handle->passwordLock);
|
|
+ sftkdb_passwordReaderLock(handle);
|
|
if (handle->passwordKey.data == NULL) {
|
|
- PZ_Unlock(handle->passwordLock);
|
|
+ sftkdb_passwordReaderUnlock(handle);
|
|
/* PORT_SetError */
|
|
return SECFailure;
|
|
}
|
|
key = handle->newKey ? handle->newKey : &handle->passwordKey;
|
|
if (sftk_isLegacyIterationCountAllowed()) {
|
|
if (handle->newKey) {
|
|
iterationCount = handle->newDefaultIterationCount;
|
|
} else {
|
|
@@ -203,17 +203,17 @@ sftkdb_encrypt_stub(PLArenaPool *arena,
|
|
}
|
|
} else {
|
|
iterationCount = 1;
|
|
}
|
|
|
|
rv = sftkdb_EncryptAttribute(arena, handle, sdb, key, iterationCount,
|
|
CK_INVALID_HANDLE, CKT_INVALID_TYPE,
|
|
plainText, cipherText);
|
|
- PZ_Unlock(handle->passwordLock);
|
|
+ sftkdb_passwordReaderUnlock(handle);
|
|
|
|
return rv;
|
|
}
|
|
|
|
/*
|
|
* stub files for legacy db's to be able to encrypt and decrypt
|
|
* various keys and attributes.
|
|
*/
|
|
@@ -230,31 +230,31 @@ sftkdb_decrypt_stub(SDB *sdb, SECItem *c
|
|
|
|
/* if we aren't the key handle, try the other handle */
|
|
oldKey = handle->oldKey;
|
|
if (handle->type != SFTK_KEYDB_TYPE) {
|
|
handle = handle->peerDB;
|
|
}
|
|
|
|
/* not a key handle */
|
|
- if (handle == NULL || handle->passwordLock == NULL) {
|
|
+ if (handle == NULL || !sftkdb_passwordLockIsInited(handle)) {
|
|
return SECFailure;
|
|
}
|
|
|
|
- PZ_Lock(handle->passwordLock);
|
|
+ sftkdb_passwordReaderLock(handle);
|
|
if (handle->passwordKey.data == NULL) {
|
|
- PZ_Unlock(handle->passwordLock);
|
|
+ sftkdb_passwordReaderUnlock(handle);
|
|
/* PORT_SetError */
|
|
return SECFailure;
|
|
}
|
|
rv = sftkdb_DecryptAttribute(NULL, oldKey ? oldKey : &handle->passwordKey,
|
|
CK_INVALID_HANDLE,
|
|
CKT_INVALID_TYPE,
|
|
cipherText, plainText);
|
|
- PZ_Unlock(handle->passwordLock);
|
|
+ sftkdb_passwordReaderUnlock(handle);
|
|
|
|
return rv;
|
|
}
|
|
|
|
static const char *LEGACY_LIB_NAME =
|
|
SHLIB_PREFIX "nssdbm" SHLIB_VERSION "." SHLIB_SUFFIX;
|
|
/*
|
|
* 2 bools to tell us if we've check the legacy library successfully or
|
|
diff --git a/lib/softoken/sftkdb.c b/lib/softoken/sftkdb.c
|
|
--- a/lib/softoken/sftkdb.c
|
|
+++ b/lib/softoken/sftkdb.c
|
|
@@ -376,29 +376,29 @@ sftkdb_fixupTemplateOut(CK_ATTRIBUTE *te
|
|
/* This code depends on the fact that the cipherText is bigger
|
|
* than the plain text */
|
|
SECItem cipherText;
|
|
SECItem *plainText;
|
|
SECStatus rv;
|
|
|
|
cipherText.data = ntemplate[i].pValue;
|
|
cipherText.len = ntemplate[i].ulValueLen;
|
|
- PZ_Lock(handle->passwordLock);
|
|
+ sftkdb_passwordReaderLock(handle);
|
|
if (handle->passwordKey.data == NULL) {
|
|
- PZ_Unlock(handle->passwordLock);
|
|
+ sftkdb_passwordReaderUnlock(handle);
|
|
template[i].ulValueLen = -1;
|
|
crv = CKR_USER_NOT_LOGGED_IN;
|
|
continue;
|
|
}
|
|
rv = sftkdb_DecryptAttribute(handle,
|
|
&handle->passwordKey,
|
|
objectID,
|
|
ntemplate[i].type,
|
|
&cipherText, &plainText);
|
|
- PZ_Unlock(handle->passwordLock);
|
|
+ sftkdb_passwordReaderUnlock(handle);
|
|
if (rv != SECSuccess) {
|
|
PORT_Memset(template[i].pValue, 0, template[i].ulValueLen);
|
|
template[i].ulValueLen = -1;
|
|
crv = CKR_GENERAL_ERROR;
|
|
continue;
|
|
}
|
|
PORT_Assert(template[i].ulValueLen >= plainText->len);
|
|
if (template[i].ulValueLen < plainText->len) {
|
|
@@ -441,30 +441,30 @@ sftkdb_fixupTemplateOut(CK_ATTRIBUTE *te
|
|
|
|
plainText.data = ntemplate[i].pValue;
|
|
plainText.len = ntemplate[i].ulValueLen;
|
|
|
|
/*
|
|
* we do a second check holding the lock just in case the user
|
|
* loggout while we were trying to get the signature.
|
|
*/
|
|
- PZ_Lock(keyHandle->passwordLock);
|
|
+ sftkdb_passwordReaderLock(keyHandle);
|
|
if (keyHandle->passwordKey.data == NULL) {
|
|
/* if we are no longer logged in, no use checking the other
|
|
* Signatures either. */
|
|
checkSig = PR_FALSE;
|
|
- PZ_Unlock(keyHandle->passwordLock);
|
|
+ sftkdb_passwordReaderUnlock(keyHandle);
|
|
continue;
|
|
}
|
|
|
|
rv = sftkdb_VerifyAttribute(keyHandle,
|
|
&keyHandle->passwordKey,
|
|
objectID, ntemplate[i].type,
|
|
&plainText, &signText);
|
|
- PZ_Unlock(keyHandle->passwordLock);
|
|
+ sftkdb_passwordReaderUnlock(keyHandle);
|
|
if (rv != SECSuccess) {
|
|
PORT_Memset(template[i].pValue, 0, template[i].ulValueLen);
|
|
template[i].ulValueLen = -1;
|
|
crv = CKR_SIGNATURE_INVALID; /* better error code? */
|
|
}
|
|
/* This Attribute is fine */
|
|
}
|
|
}
|
|
@@ -553,28 +553,28 @@ sftk_signTemplate(PLArenaPool *arena, SF
|
|
for (i = 0; i < count; i++) {
|
|
if (sftkdb_isAuthenticatedAttribute(template[i].type)) {
|
|
SECStatus rv;
|
|
SECItem *signText;
|
|
SECItem plainText;
|
|
|
|
plainText.data = template[i].pValue;
|
|
plainText.len = template[i].ulValueLen;
|
|
- PZ_Lock(keyHandle->passwordLock);
|
|
+ sftkdb_passwordReaderLock(keyHandle);
|
|
if (keyHandle->passwordKey.data == NULL) {
|
|
- PZ_Unlock(keyHandle->passwordLock);
|
|
+ sftkdb_passwordReaderUnlock(keyHandle);
|
|
crv = CKR_USER_NOT_LOGGED_IN;
|
|
goto loser;
|
|
}
|
|
rv = sftkdb_SignAttribute(arena, keyHandle, keyTarget,
|
|
&keyHandle->passwordKey,
|
|
keyHandle->defaultIterationCount,
|
|
objectID, template[i].type,
|
|
&plainText, &signText);
|
|
- PZ_Unlock(keyHandle->passwordLock);
|
|
+ sftkdb_passwordReaderUnlock(keyHandle);
|
|
if (rv != SECSuccess) {
|
|
crv = CKR_GENERAL_ERROR; /* better error code here? */
|
|
goto loser;
|
|
}
|
|
crv = sftkdb_PutAttributeSignature(handle, keyTarget, objectID,
|
|
template[i].type, signText);
|
|
if (crv != CKR_OK) {
|
|
goto loser;
|
|
@@ -733,29 +733,29 @@ sftk_ExtractTemplate(PLArenaPool *arena,
|
|
if (doEnc && sftkdb_isPrivateAttribute(tp->type)) {
|
|
/* we have a private attribute */
|
|
SECItem *cipherText;
|
|
SECItem plainText;
|
|
SECStatus rv;
|
|
|
|
plainText.data = tp->pValue;
|
|
plainText.len = tp->ulValueLen;
|
|
- PZ_Lock(handle->passwordLock);
|
|
+ sftkdb_passwordReaderLock(handle);
|
|
if (handle->passwordKey.data == NULL) {
|
|
- PZ_Unlock(handle->passwordLock);
|
|
+ sftkdb_passwordReaderUnlock(handle);
|
|
*crv = CKR_USER_NOT_LOGGED_IN;
|
|
break;
|
|
}
|
|
rv = sftkdb_EncryptAttribute(arena, handle, db,
|
|
&handle->passwordKey,
|
|
handle->defaultIterationCount,
|
|
objectID,
|
|
tp->type,
|
|
&plainText, &cipherText);
|
|
- PZ_Unlock(handle->passwordLock);
|
|
+ sftkdb_passwordReaderUnlock(handle);
|
|
if (rv == SECSuccess) {
|
|
tp->pValue = cipherText->data;
|
|
tp->ulValueLen = cipherText->len;
|
|
} else {
|
|
*crv = CKR_GENERAL_ERROR; /* better error code here? */
|
|
break;
|
|
}
|
|
PORT_Memset(plainText.data, 0, plainText.len);
|
|
@@ -1604,18 +1604,18 @@ sftkdb_CloseDB(SFTKDBHandle *handle)
|
|
if (handle->db->sdb_SetForkState) {
|
|
(*handle->db->sdb_SetForkState)(parentForkedAfterC_Initialize);
|
|
}
|
|
(*handle->db->sdb_Close)(handle->db);
|
|
}
|
|
if (handle->passwordKey.data) {
|
|
SECITEM_ZfreeItem(&handle->passwordKey, PR_FALSE);
|
|
}
|
|
- if (handle->passwordLock) {
|
|
- SKIP_AFTER_FORK(PZ_DestroyLock(handle->passwordLock));
|
|
+ if (sftkdb_passwordLockIsInited(handle)) {
|
|
+ SKIP_AFTER_FORK(sftkdb_passwordLockDestroy(handle));
|
|
}
|
|
if (handle->updatePasswordKey) {
|
|
SECITEM_ZfreeItem(handle->updatePasswordKey, PR_TRUE);
|
|
}
|
|
if (handle->updateID) {
|
|
PORT_Free(handle->updateID);
|
|
}
|
|
PORT_Free(handle);
|
|
@@ -2665,18 +2665,20 @@ sftk_NewDBHandle(SDB *sdb, int type, PRB
|
|
handle->oldKey = NULL;
|
|
handle->updatePasswordKey = NULL;
|
|
handle->updateID = NULL;
|
|
handle->type = type;
|
|
handle->usesLegacyStorage = legacy;
|
|
handle->passwordKey.data = NULL;
|
|
handle->passwordKey.len = 0;
|
|
handle->passwordLock = NULL;
|
|
+ handle->passwordWriterCond = NULL;
|
|
+ handle->passwordReaderCond = NULL;
|
|
if (type == SFTK_KEYDB_TYPE) {
|
|
- handle->passwordLock = PZ_NewLock(nssILockAttribute);
|
|
+ (void) sftkdb_passwordLockInit(handle);
|
|
}
|
|
sdb->app_private = handle;
|
|
return handle;
|
|
}
|
|
|
|
/*
|
|
* reset the key database to it's uninitialized state. This call
|
|
* will clear all the key entried.
|
|
diff --git a/lib/softoken/sftkdbti.h b/lib/softoken/sftkdbti.h
|
|
--- a/lib/softoken/sftkdbti.h
|
|
+++ b/lib/softoken/sftkdbti.h
|
|
@@ -1,29 +1,35 @@
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#ifndef SFTKDBTI_H
|
|
#define SFTKDBTI_H 1
|
|
+#include <prcvar.h>
|
|
|
|
/*
|
|
* private defines
|
|
*/
|
|
struct SFTKDBHandleStr {
|
|
SDB *db;
|
|
PRInt32 ref;
|
|
CK_OBJECT_HANDLE type;
|
|
SECItem passwordKey;
|
|
int defaultIterationCount;
|
|
SECItem *newKey;
|
|
int newDefaultIterationCount;
|
|
SECItem *oldKey;
|
|
SECItem *updatePasswordKey;
|
|
PZLock *passwordLock;
|
|
+ PRCondVar *passwordWriterCond;
|
|
+ PRCondVar *passwordReaderCond;
|
|
+ PRBool passwordWriterActive;
|
|
+ int passwordWriters;
|
|
+ int passwordReaders;
|
|
SFTKDBHandle *peerDB;
|
|
SDB *update;
|
|
char *updateID;
|
|
PRBool updateDBIsInit;
|
|
PRBool usesLegacyStorage;
|
|
};
|
|
|
|
#define SFTK_KEYDB_TYPE 0x40000000
|
|
@@ -74,9 +80,18 @@ CK_RV sftkdb_GetAttributeSignature(SFTKD
|
|
CK_OBJECT_HANDLE objectID,
|
|
CK_ATTRIBUTE_TYPE type,
|
|
SECItem *signText);
|
|
CK_RV
|
|
sftkdb_DestroyAttributeSignature(SFTKDBHandle *handle, SDB *db,
|
|
CK_OBJECT_HANDLE objectID,
|
|
CK_ATTRIBUTE_TYPE type);
|
|
|
|
+/* password lock functions */
|
|
+SECStatus sftkdb_passwordLockInit(SFTKDBHandle *keydb);
|
|
+void sftkdb_passwordLockDestroy(SFTKDBHandle *keydb);
|
|
+PRBool sftkdb_passwordLockIsInited(SFTKDBHandle *keydb);
|
|
+void sftkdb_passwordReaderLock(SFTKDBHandle *keydb);
|
|
+void sftkdb_passwordWriterLock(SFTKDBHandle *keydb);
|
|
+void sftkdb_passwordReaderUnlock(SFTKDBHandle *keydb);
|
|
+void sftkdb_passwordWriterUnlock(SFTKDBHandle *keydb);
|
|
+
|
|
#endif
|
|
diff --git a/lib/softoken/sftkpwd.c b/lib/softoken/sftkpwd.c
|
|
--- a/lib/softoken/sftkpwd.c
|
|
+++ b/lib/softoken/sftkpwd.c
|
|
@@ -627,44 +627,164 @@ sftkdb_SignAttribute(PLArenaPool *arena,
|
|
loser:
|
|
PORT_Memset(signData, 0, sizeof signData);
|
|
if (param) {
|
|
nsspkcs5_DestroyPBEParameter(param);
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
+SECStatus
|
|
+sftkdb_passwordLockInit(SFTKDBHandle *keydb)
|
|
+{
|
|
+ keydb->passwordLock = PZ_NewLock(nssILockAttribute);
|
|
+ if (keydb->passwordLock == NULL) {
|
|
+ return SECFailure;
|
|
+ }
|
|
+ keydb->passwordWriterCond = PR_NewCondVar(keydb->passwordLock);
|
|
+ if (keydb->passwordWriterCond == NULL) {
|
|
+ PZ_DestroyLock(keydb->passwordLock);
|
|
+ keydb->passwordLock = NULL;
|
|
+ return SECFailure;
|
|
+ }
|
|
+ keydb->passwordReaderCond = PR_NewCondVar(keydb->passwordLock);
|
|
+ if (keydb->passwordReaderCond == NULL) {
|
|
+ PR_DestroyCondVar(keydb->passwordWriterCond);
|
|
+ PZ_DestroyLock(keydb->passwordLock);
|
|
+ keydb->passwordWriterCond = NULL;
|
|
+ keydb->passwordLock = NULL;
|
|
+ return SECFailure;
|
|
+ }
|
|
+ keydb->passwordWriters = 0;
|
|
+ keydb->passwordReaders = 0;
|
|
+ keydb->passwordWriterActive = PR_FALSE;
|
|
+ return SECSuccess;
|
|
+}
|
|
+
|
|
+void
|
|
+sftkdb_passwordLockDestroy(SFTKDBHandle *keydb)
|
|
+{
|
|
+ PR_DestroyCondVar(keydb->passwordWriterCond);
|
|
+ keydb->passwordWriterCond = NULL;
|
|
+ PR_DestroyCondVar(keydb->passwordReaderCond);
|
|
+ keydb->passwordReaderCond = NULL;
|
|
+ PZ_DestroyLock(keydb->passwordLock);
|
|
+ keydb->passwordLock = NULL;
|
|
+}
|
|
+
|
|
+PRBool
|
|
+sftkdb_passwordLockIsInited(SFTKDBHandle *keydb)
|
|
+{
|
|
+ return (keydb->passwordLock) && (keydb->passwordWriterCond)
|
|
+ && (keydb->passwordReaderCond);
|
|
+}
|
|
+
|
|
+/* we need reader/writer locks for the database because we have servers
|
|
+ * that use the database key in their transactions on multi-cpu systems.
|
|
+ * This means that all the other cpus doing private key operations become
|
|
+ * effectively single threaded. We implement our specific reader/writer
|
|
+ * locks because we want writer locks to interrupt reader streams to
|
|
+ * prevent starvation on the writer side. */
|
|
+void
|
|
+sftkdb_passwordReaderLock(SFTKDBHandle *keydb)
|
|
+{
|
|
+ PZ_Lock(keydb->passwordLock);
|
|
+ /* if there is a writer waiting or running wait until the
|
|
+ * writer has completed before we continue. This prevents
|
|
+ * writer starvation in a loaded system */
|
|
+ while (keydb->passwordWriters) {
|
|
+ PR_WaitCondVar(keydb->passwordReaderCond, PR_INTERVAL_NO_TIMEOUT);
|
|
+ }
|
|
+ /* allow multiple readers */
|
|
+ keydb->passwordReaders++;
|
|
+ PORT_Assert(keydb->passwordWriterActive == PR_FALSE);
|
|
+ PZ_Unlock(keydb->passwordLock);
|
|
+}
|
|
+
|
|
+/* We can only have 1 active writer or multiple active readers.
|
|
+ * Readers will wait for an active writer. This means lots of write
|
|
+ * operations can stall the readers. Write operations are rare, though and
|
|
+ * only happen on database update, or on initial login.
|
|
+ */
|
|
+void
|
|
+sftkdb_passwordWriterLock(SFTKDBHandle *keydb)
|
|
+{
|
|
+ PZ_Lock(keydb->passwordLock);
|
|
+ keydb->passwordWriters++;
|
|
+ /* if we have any readers or writers, wait for the writer condition */
|
|
+ while (keydb->passwordReaders || keydb->passwordWriterActive) {
|
|
+ PR_WaitCondVar(keydb->passwordWriterCond, PR_INTERVAL_NO_TIMEOUT);
|
|
+ }
|
|
+ /* only one writer allowed at a time */
|
|
+ keydb->passwordWriterActive = PR_TRUE;
|
|
+ PZ_Unlock(keydb->passwordLock);
|
|
+}
|
|
+
|
|
+/* unlock, decrements the reader counter, and if we have not active readers,
|
|
+ * notify any waiting writers. */
|
|
+void
|
|
+sftkdb_passwordReaderUnlock(SFTKDBHandle *keydb)
|
|
+{
|
|
+ PZ_Lock(keydb->passwordLock);
|
|
+ PORT_Assert(keydb->passwordReaders);
|
|
+ keydb->passwordReaders--;
|
|
+ if (keydb->passwordReaders == 0) {
|
|
+ if (keydb->passwordWriters) {
|
|
+ PR_NotifyCondVar(keydb->passwordWriterCond);
|
|
+ }
|
|
+ }
|
|
+ PZ_Unlock(keydb->passwordLock);
|
|
+}
|
|
+
|
|
+/* unlock, if there are more writers, wake one of them up. If there or no more
|
|
+ * writers but readers, wake up all the readers. */
|
|
+void
|
|
+sftkdb_passwordWriterUnlock(SFTKDBHandle *keydb)
|
|
+{
|
|
+ PZ_Lock(keydb->passwordLock);
|
|
+ PORT_Assert(keydb->passwordWriters);
|
|
+ PORT_Assert(keydb->passwordWriterActive);
|
|
+ keydb->passwordWriterActive = PR_FALSE;
|
|
+ keydb->passwordWriters--;
|
|
+ if (keydb->passwordWriters) {
|
|
+ PR_NotifyCondVar(keydb->passwordWriterCond);
|
|
+ } else {
|
|
+ PR_NotifyAllCondVar(keydb->passwordReaderCond);
|
|
+ }
|
|
+ PZ_Unlock(keydb->passwordLock);
|
|
+}
|
|
+
|
|
/*
|
|
* safely swith the passed in key for the one caches in the keydb handle
|
|
*
|
|
* A key attached to the handle tells us the the token is logged in.
|
|
* We can used the key attached to the handle in sftkdb_EncryptAttribute
|
|
* and sftkdb_DecryptAttribute calls.
|
|
*/
|
|
static void
|
|
sftkdb_switchKeys(SFTKDBHandle *keydb, SECItem *passKey, int iterationCount)
|
|
{
|
|
unsigned char *data;
|
|
int len;
|
|
|
|
- if (keydb->passwordLock == NULL) {
|
|
+ if (!sftkdb_passwordLockIsInited(keydb)) {
|
|
PORT_Assert(keydb->type != SFTK_KEYDB_TYPE);
|
|
return;
|
|
}
|
|
|
|
/* an atomic pointer set would be nice */
|
|
- SKIP_AFTER_FORK(PZ_Lock(keydb->passwordLock));
|
|
+ SKIP_AFTER_FORK(sftkdb_passwordWriterLock(keydb));
|
|
data = keydb->passwordKey.data;
|
|
len = keydb->passwordKey.len;
|
|
keydb->passwordKey.data = passKey->data;
|
|
keydb->passwordKey.len = passKey->len;
|
|
keydb->defaultIterationCount = iterationCount;
|
|
passKey->data = data;
|
|
passKey->len = len;
|
|
- SKIP_AFTER_FORK(PZ_Unlock(keydb->passwordLock));
|
|
+ SKIP_AFTER_FORK(sftkdb_passwordWriterUnlock(keydb));
|
|
}
|
|
|
|
/*
|
|
* returns true if we are in a middle of a merge style update.
|
|
*/
|
|
PRBool
|
|
sftkdb_InUpdateMerge(SFTKDBHandle *keydb)
|
|
{
|
|
@@ -700,21 +820,21 @@ sftkdb_GetUpdatePasswordKey(SFTKDBHandle
|
|
handle = handle->peerDB;
|
|
}
|
|
|
|
/* don't have one */
|
|
if (!handle) {
|
|
return NULL;
|
|
}
|
|
|
|
- PZ_Lock(handle->passwordLock);
|
|
+ sftkdb_passwordReaderLock(handle);
|
|
if (handle->updatePasswordKey) {
|
|
key = SECITEM_DupItem(handle->updatePasswordKey);
|
|
}
|
|
- PZ_Unlock(handle->passwordLock);
|
|
+ sftkdb_passwordReaderUnlock(handle);
|
|
|
|
return key;
|
|
}
|
|
|
|
/*
|
|
* free the update password key from a handle.
|
|
*/
|
|
void
|
|
@@ -727,22 +847,22 @@ sftkdb_FreeUpdatePasswordKey(SFTKDBHandl
|
|
return;
|
|
}
|
|
|
|
/* if we're a cert db, we don't have one */
|
|
if (handle->type == SFTK_CERTDB_TYPE) {
|
|
return;
|
|
}
|
|
|
|
- PZ_Lock(handle->passwordLock);
|
|
+ sftkdb_passwordWriterLock(handle);
|
|
if (handle->updatePasswordKey) {
|
|
key = handle->updatePasswordKey;
|
|
handle->updatePasswordKey = NULL;
|
|
}
|
|
- PZ_Unlock(handle->passwordLock);
|
|
+ sftkdb_passwordWriterUnlock(handle);
|
|
|
|
if (key) {
|
|
SECITEM_ZfreeItem(key, PR_TRUE);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
@@ -999,25 +1119,25 @@ sftkdb_finishPasswordCheck(SFTKDBHandle
|
|
* 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);
|
|
+ sftkdb_passwordWriterLock(keydb);
|
|
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);
|
|
+ sftkdb_passwordWriterUnlock(keydb);
|
|
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. */
|
|
@@ -1072,17 +1192,17 @@ sftkdb_finishPasswordCheck(SFTKDBHandle
|
|
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);
|
|
+ sftkdb_passwordWriterUnlock(keydb);
|
|
}
|
|
/* load the keys, so the keydb can parse it's key set */
|
|
sftkdb_switchKeys(keydb, key, iterationCount);
|
|
|
|
/* we need to update, do it now */
|
|
if (((keydb->db->sdb_flags & SDB_RDONLY) == 0) && keydb->update) {
|
|
/* update the peer certdb if it exists */
|
|
if (keydb->peerDB) {
|