Bugzilla Bug 252702

NSS needs to handle better token insertion and removal.

Applied from patch to NSS 3.9
This commit is contained in:
relyea%netscape.com 2004-07-29 23:38:14 +00:00
parent 4221b9c089
commit e715f98c50
15 changed files with 682 additions and 158 deletions

View File

@ -797,6 +797,15 @@ PK11_UnlinkGenericObject;
;+ local:
;+ *;
;+};
;+NSS_3.9.3 { # NSS 3.9.3 release
;+ global:
SECMOD_CancelWait;
SECMOD_HasRemovableSlots;
SECMOD_UpdateSlotList;
SECMOD_WaitForAnyTokenEvent;
;+ local:
;+ *;
;+};
;+NSS_3.10 { # NSS 3.10 release
;+ global:
CERT_DecodeAltNameExtension;

View File

@ -90,6 +90,7 @@ PK11_MapError(CK_RV rv) {
MAPERROR(CKR_KEY_TYPE_INCONSISTENT, SEC_ERROR_INVALID_KEY)
MAPERROR(CKR_MECHANISM_INVALID, SEC_ERROR_BAD_DATA)
MAPERROR(CKR_MECHANISM_PARAM_INVALID, SEC_ERROR_BAD_DATA)
MAPERROR(CKR_NO_EVENT, SEC_ERROR_NO_EVENT)
MAPERROR(CKR_OBJECT_HANDLE_INVALID, SEC_ERROR_BAD_DATA)
MAPERROR(CKR_OPERATION_ACTIVE, SEC_ERROR_LIBRARY_FAILURE)
MAPERROR(CKR_OPERATION_NOT_INITIALIZED,SEC_ERROR_LIBRARY_FAILURE )
@ -124,6 +125,7 @@ PK11_MapError(CK_RV rv) {
#ifdef PK11_ERROR_USE_ARRAY
};
int
PK11_MapError(CK_RV rv) {

View File

@ -43,37 +43,26 @@
#include "secmod.h"
#include "secmodi.h"
#include "secmodti.h"
#define ISREADING 1
#define ISWRITING 2
#define WANTWRITE 4
#define ISLOCKED 3
#include "nssrwlk.h"
/*
* create a new lock for a Module List
*/
SECMODListLock *SECMOD_NewListLock() {
SECMODListLock *modLock;
modLock = (SECMODListLock*)PORT_Alloc(sizeof(SECMODListLock));
SECMODListLock *SECMOD_NewListLock()
{
#ifdef PKCS11_USE_THREADS
modLock->mutex = NULL;
modLock->monitor = PZ_NewMonitor(nssILockList);
return (SECMODListLock *) NSSRWLock_New( 10, "moduleListLock");
#else
modLock->mutex = NULL;
modLock->monitor = NULL;
return (SECMODListLock *) 1;
#endif
modLock->state = 0;
modLock->count = 0;
return modLock;
}
/*
* destroy the lock
*/
void SECMOD_DestroyListLock(SECMODListLock *lock) {
PK11_USE_THREADS(PZ_DestroyMonitor(lock->monitor);)
PORT_Free(lock);
void SECMOD_DestroyListLock(SECMODListLock *lock)
{
PK11_USE_THREADS(NSSRWLock_Destroy((NSSRWLock *)lock);)
}
@ -81,52 +70,26 @@ void SECMOD_DestroyListLock(SECMODListLock *lock) {
* Lock the List for Read: NOTE: this assumes the reading isn't so common
* the writing will be starved.
*/
void SECMOD_GetReadLock(SECMODListLock *modLock) {
#ifdef PKCS11_USE_THREADS
if (modLock == NULL) return;
PZ_EnterMonitor(modLock->monitor);
while (modLock->state & ISWRITING) {
PZ_Wait(modLock->monitor,PR_INTERVAL_NO_TIMEOUT); /* wait until woken up */
}
modLock->state |= ISREADING;
modLock->count++;
PZ_ExitMonitor(modLock->monitor);
#endif
void SECMOD_GetReadLock(SECMODListLock *modLock)
{
PK11_USE_THREADS(NSSRWLock_LockRead((NSSRWLock *)modLock);)
}
/*
* Release the Read lock
*/
void SECMOD_ReleaseReadLock(SECMODListLock *modLock) {
#ifdef PKCS11_USE_THREADS
if (modLock == NULL) return;
PZ_EnterMonitor(modLock->monitor);
modLock->count--;
if (modLock->count == 0) {
modLock->state &= ~ISREADING;
if (modLock->state & WANTWRITE) {
PZ_Notify(modLock->monitor); /* only one writer at a time */
}
}
PZ_ExitMonitor(modLock->monitor);
#endif
void SECMOD_ReleaseReadLock(SECMODListLock *modLock)
{
PK11_USE_THREADS(NSSRWLock_UnlockRead((NSSRWLock *)modLock);)
}
/*
* lock the list for Write
*/
void SECMOD_GetWriteLock(SECMODListLock *modLock) {
#ifdef PKCS11_USE_THREADS
if (modLock == NULL) return;
PZ_EnterMonitor(modLock->monitor);
while (modLock->state & ISLOCKED) {
modLock->state |= WANTWRITE;
PZ_Wait(modLock->monitor,PR_INTERVAL_NO_TIMEOUT); /* wait until woken up */
}
modLock->state = ISWRITING;
PZ_ExitMonitor(modLock->monitor);
#endif
void SECMOD_GetWriteLock(SECMODListLock *modLock)
{
PK11_USE_THREADS(NSSRWLock_LockWrite((NSSRWLock *)modLock);)
}
@ -134,14 +97,9 @@ void SECMOD_GetWriteLock(SECMODListLock *modLock) {
* Release the Write Lock: NOTE, this code is pretty inefficient if you have
* lots of write collisions.
*/
void SECMOD_ReleaseWriteLock(SECMODListLock *modLock) {
#ifdef PKCS11_USE_THREADS
if (modLock == NULL) return;
PZ_EnterMonitor(modLock->monitor);
modLock->state = 0;
PR_NotifyAll(modLock->monitor); /* enable all the readers */
PZ_ExitMonitor(modLock->monitor);
#endif
void SECMOD_ReleaseWriteLock(SECMODListLock *modLock)
{
PK11_USE_THREADS(NSSRWLock_UnlockWrite((NSSRWLock *)modLock);)
}
@ -149,7 +107,8 @@ void SECMOD_ReleaseWriteLock(SECMODListLock *modLock) {
* must Hold the Write lock
*/
void
SECMOD_RemoveList(SECMODModuleList **parent, SECMODModuleList *child) {
SECMOD_RemoveList(SECMODModuleList **parent, SECMODModuleList *child)
{
*parent = child->next;
child->next = NULL;
}
@ -159,7 +118,8 @@ SECMOD_RemoveList(SECMODModuleList **parent, SECMODModuleList *child) {
*/
void
SECMOD_AddList(SECMODModuleList *parent, SECMODModuleList *child,
SECMODListLock *lock) {
SECMODListLock *lock)
{
if (lock) { SECMOD_GetWriteLock(lock); }
child->next = parent->next;

View File

@ -90,6 +90,41 @@ static const CK_C_INITIALIZE_ARGS secmodLockFunctions = {
,NULL
};
/*
* collect the steps we need to initialize a module in a single function
*/
SECStatus
secmod_ModuleInit(SECMODModule *mod)
{
CK_C_INITIALIZE_ARGS moduleArgs;
CK_VOID_PTR pInitArgs;
CK_RV crv;
if (mod->isThreadSafe == PR_FALSE) {
pInitArgs = NULL;
} else if (mod->libraryParams == NULL) {
pInitArgs = (void *) &secmodLockFunctions;
} else {
moduleArgs = secmodLockFunctions;
moduleArgs.LibraryParameters = (void *) mod->libraryParams;
pInitArgs = &moduleArgs;
}
crv = PK11_GETTAB(mod)->C_Initialize(pInitArgs);
if (crv != CKR_OK) {
if (pInitArgs == NULL) {
PORT_SetError(PK11_MapError(crv));
return SECFailure;
}
mod->isThreadSafe = PR_FALSE;
crv = PK11_GETTAB(mod)->C_Initialize(NULL);
if (crv != CKR_OK) {
PORT_SetError(PK11_MapError(crv));
return SECFailure;
}
}
return SECSuccess;
}
/*
* set the hasRootCerts flags in the module so it can be stored back
* into the database.
@ -142,8 +177,7 @@ SECMOD_LoadPKCS11Module(SECMODModule *mod) {
char * full_name;
CK_INFO info;
CK_ULONG slotCount = 0;
CK_C_INITIALIZE_ARGS moduleArgs;
CK_VOID_PTR pInitArgs;
SECStatus rv;
if (mod->loaded) return SECSuccess;
@ -228,17 +262,11 @@ SECMOD_LoadPKCS11Module(SECMODModule *mod) {
#endif
mod->isThreadSafe = PR_TRUE;
/* Now we initialize the module */
if (mod->libraryParams) {
moduleArgs = secmodLockFunctions;
moduleArgs.LibraryParameters = (void *) mod->libraryParams;
pInitArgs = &moduleArgs;
} else {
pInitArgs = (void *) &secmodLockFunctions;
}
if (PK11_GETTAB(mod)->C_Initialize(pInitArgs) != CKR_OK) {
mod->isThreadSafe = PR_FALSE;
if (PK11_GETTAB(mod)->C_Initialize(NULL) != CKR_OK) goto fail;
rv = secmod_ModuleInit(mod);
if (rv != SECSuccess) {
goto fail;
}
/* check the version number */
@ -260,7 +288,7 @@ SECMOD_LoadPKCS11Module(SECMODModule *mod) {
if (PK11_GETTAB(mod)->C_GetSlotList(CK_FALSE, NULL, &slotCount) == CKR_OK) {
CK_SLOT_ID *slotIDs;
int i;
CK_RV rv;
CK_RV crv;
mod->slots = (PK11SlotInfo **)PORT_ArenaAlloc(mod->arena,
sizeof(PK11SlotInfo *) * slotCount);
@ -270,8 +298,8 @@ SECMOD_LoadPKCS11Module(SECMODModule *mod) {
if (slotIDs == NULL) {
goto fail2;
}
rv = PK11_GETTAB(mod)->C_GetSlotList(CK_FALSE, slotIDs, &slotCount);
if (rv != CKR_OK) {
crv = PK11_GETTAB(mod)->C_GetSlotList(CK_FALSE, slotIDs, &slotCount);
if (crv != CKR_OK) {
PORT_Free(slotIDs);
goto fail2;
}

View File

@ -97,6 +97,7 @@ secmod_NewModule(void)
newMod->moduleDBOnly = PR_FALSE;
newMod->trustOrder = 0;
newMod->cipherOrder = 0;
newMod->evControlMask = 0;
#ifdef PKCS11_USE_THREADS
newMod->refLock = (void *)PZ_NewLock(nssILockRefLock);
if (newMod->refLock == NULL) {
@ -163,9 +164,12 @@ pk11_mkModuleSpec(SECMODModule * module)
{
char *nss = NULL, *modSpec = NULL, **slotStrings = NULL;
int slotCount, i, si;
SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
/* allocate target slot info strings */
slotCount = 0;
SECMOD_GetReadLock(moduleLock);
if (module->slotCount) {
for (i=0; i < module->slotCount; i++) {
if (module->slots[i]->defaultFlags !=0) {
@ -178,6 +182,7 @@ pk11_mkModuleSpec(SECMODModule * module)
slotStrings = (char **)PORT_ZAlloc(slotCount*sizeof(char *));
if (slotStrings == NULL) {
SECMOD_ReleaseReadLock(moduleLock);
goto loser;
}
@ -208,6 +213,7 @@ pk11_mkModuleSpec(SECMODModule * module)
}
}
SECMOD_ReleaseReadLock(moduleLock);
nss = pk11_mkNSS(slotStrings,slotCount,module->internal, module->isFIPS,
module->isModuleDB, module->moduleDBOnly, module->isCritical,
module->trustOrder,module->cipherOrder,module->ssl[0],module->ssl[1]);
@ -386,8 +392,12 @@ SECMOD_LoadUserModule(char *modulespec,SECMODModule *parent, PRBool recurse)
{
SECStatus rv = SECSuccess;
SECMODModule * newmod = SECMOD_LoadModule(modulespec, parent, recurse);
SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
if (newmod) {
SECMOD_GetReadLock(moduleLock);
rv = STAN_AddModuleToDefaultTrustDomain(newmod);
SECMOD_ReleaseReadLock(moduleLock);
if (SECSuccess != rv) {
SECMOD_DestroyModule(newmod);
return NULL;
@ -404,10 +414,14 @@ SECStatus SECMOD_UnloadUserModule(SECMODModule *mod)
{
SECStatus rv = SECSuccess;
int atype = 0;
SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
if (!mod) {
return SECFailure;
}
SECMOD_GetReadLock(moduleLock);
rv = STAN_RemoveModuleFromDefaultTrustDomain(mod);
SECMOD_ReleaseReadLock(moduleLock);
if (SECSuccess != rv) {
return SECFailure;
}

View File

@ -62,7 +62,8 @@ extern int num_pk11_default_mechanisms;
void
SECMOD_Init() {
SECMOD_Init()
{
/* don't initialize twice */
if (moduleLock) return;
@ -72,7 +73,8 @@ SECMOD_Init() {
SECStatus
SECMOD_Shutdown() {
SECMOD_Shutdown()
{
/* destroy the lock */
if (moduleLock) {
SECMOD_DestroyListLock(moduleLock);
@ -128,13 +130,15 @@ SECMOD_Shutdown() {
* retrieve the internal module
*/
SECMODModule *
SECMOD_GetInternalModule(void) {
SECMOD_GetInternalModule(void)
{
return internalModule;
}
SECStatus
secmod_AddModuleToList(SECMODModuleList **moduleList,SECMODModule *newModule) {
secmod_AddModuleToList(SECMODModuleList **moduleList,SECMODModule *newModule)
{
SECMODModuleList *mlp, *newListElement, *last = NULL;
newListElement = SECMOD_NewModuleListElement();
@ -162,7 +166,8 @@ secmod_AddModuleToList(SECMODModuleList **moduleList,SECMODModule *newModule) {
}
SECStatus
SECMOD_AddModuleToList(SECMODModule *newModule) {
SECMOD_AddModuleToList(SECMODModule *newModule)
{
if (newModule->internal && !internalModule) {
internalModule = SECMOD_ReferenceModule(newModule);
}
@ -170,7 +175,8 @@ SECMOD_AddModuleToList(SECMODModule *newModule) {
}
SECStatus
SECMOD_AddModuleToDBOnlyList(SECMODModule *newModule) {
SECMOD_AddModuleToDBOnlyList(SECMODModule *newModule)
{
if (defaultDBModule == NULL) {
defaultDBModule = SECMOD_ReferenceModule(newModule);
}
@ -178,16 +184,29 @@ SECMOD_AddModuleToDBOnlyList(SECMODModule *newModule) {
}
SECStatus
SECMOD_AddModuleToUnloadList(SECMODModule *newModule) {
SECMOD_AddModuleToUnloadList(SECMODModule *newModule)
{
return secmod_AddModuleToList(&modulesUnload,newModule);
}
/*
* get the list of PKCS11 modules that are available.
*/
SECMODModuleList *SECMOD_GetDefaultModuleList() { return modules; }
SECMODModuleList * SECMOD_GetDefaultModuleList() { return modules; }
SECMODModuleList *SECMOD_GetDeadModuleList() { return modulesUnload; }
SECMODModuleList *SECMOD_GetDBModuleList() { return modulesDB; }
/*
* This lock protects the global module lists.
* it also protects changes to the slot array (module->slots[]) and slot count
* (module->slotCount) in each module. It is a read/write lock with multiple
* readers or one writer. Writes are uncommon.
* Because of legacy considerations protection of the slot array and count is
* only necessary in applications if the application calls
* SECMOD_UpdateSlotList() or SECMOD_WaitForAnyTokenEvent(), though all new
* applications are encouraged to acquire this lock when reading the
* slot array information directly.
*/
SECMODListLock *SECMOD_GetDefaultModuleListLock() { return moduleLock; }
@ -196,7 +215,9 @@ SECMODListLock *SECMOD_GetDefaultModuleListLock() { return moduleLock; }
* find a module by name, and add a reference to it.
* return that module.
*/
SECMODModule *SECMOD_FindModule(const char *name) {
SECMODModule *
SECMOD_FindModule(const char *name)
{
SECMODModuleList *mlp;
SECMODModule *module = NULL;
@ -229,7 +250,9 @@ found:
* find a module by ID, and add a reference to it.
* return that module.
*/
SECMODModule *SECMOD_FindModuleByID(SECMODModuleID id) {
SECMODModule *
SECMOD_FindModuleByID(SECMODModuleID id)
{
SECMODModuleList *mlp;
SECMODModule *module = NULL;
@ -242,30 +265,53 @@ SECMODModule *SECMOD_FindModuleByID(SECMODModuleID id) {
}
}
SECMOD_ReleaseReadLock(moduleLock);
if (module == NULL) {
PORT_SetError(SEC_ERROR_NO_MODULE);
}
return module;
}
/*
* Find the Slot based on ID and the module.
*/
PK11SlotInfo *
SECMOD_FindSlotByID(SECMODModule *module, CK_SLOT_ID slotID)
{
int i;
PK11SlotInfo *slot = NULL;
SECMOD_GetReadLock(moduleLock);
for (i=0; i < module->slotCount; i++) {
PK11SlotInfo *cSlot = module->slots[i];
if (cSlot->slotID == slotID) {
slot = PK11_ReferenceSlot(cSlot);
break;
}
}
SECMOD_ReleaseReadLock(moduleLock);
if (slot == NULL) {
PORT_SetError(SEC_ERROR_NO_SLOT_SELECTED);
}
return slot;
}
/*
* lookup the Slot module based on it's module ID and slot ID.
*/
PK11SlotInfo *SECMOD_LookupSlot(SECMODModuleID moduleID,CK_SLOT_ID slotID) {
int i;
PK11SlotInfo *
SECMOD_LookupSlot(SECMODModuleID moduleID,CK_SLOT_ID slotID)
{
SECMODModule *module;
PK11SlotInfo *slot;
module = SECMOD_FindModuleByID(moduleID);
if (module == NULL) return NULL;
for (i=0; i < module->slotCount; i++) {
PK11SlotInfo *slot = module->slots[i];
if (slot->slotID == slotID) {
SECMOD_DestroyModule(module);
return PK11_ReferenceSlot(slot);
}
}
slot = SECMOD_FindSlotByID(module, slotID);
SECMOD_DestroyModule(module);
return NULL;
return slot;
}
@ -338,7 +384,8 @@ found:
* find a module by name and delete it off the module list
*/
SECStatus
SECMOD_DeleteModule(const char *name, int *type) {
SECMOD_DeleteModule(const char *name, int *type)
{
return SECMOD_DeleteModuleEx(name, NULL, type, PR_TRUE);
}
@ -346,7 +393,8 @@ SECMOD_DeleteModule(const char *name, int *type) {
* find a module by name and delete it off the module list
*/
SECStatus
SECMOD_DeleteInternalModule(const char *name) {
SECMOD_DeleteInternalModule(const char *name)
{
SECMODModuleList *mlp;
SECMODModuleList **mlpp;
SECStatus rv = SECFailure;
@ -418,7 +466,8 @@ SECMOD_DeleteInternalModule(const char *name) {
}
SECStatus
SECMOD_AddModule(SECMODModule *newModule) {
SECMOD_AddModule(SECMODModule *newModule)
{
SECStatus rv;
SECMODModule *oldModule;
@ -450,10 +499,14 @@ SECMOD_AddModule(SECMODModule *newModule) {
return rv;
}
PK11SlotInfo *SECMOD_FindSlot(SECMODModule *module,const char *name) {
PK11SlotInfo *
SECMOD_FindSlot(SECMODModule *module,const char *name)
{
int i;
char *string;
PK11SlotInfo *retSlot = NULL;
SECMOD_GetReadLock(moduleLock);
for (i=0; i < module->slotCount; i++) {
PK11SlotInfo *slot = module->slots[i];
@ -463,10 +516,17 @@ PK11SlotInfo *SECMOD_FindSlot(SECMODModule *module,const char *name) {
string = PK11_GetSlotName(slot);
}
if (PORT_Strcmp(name,string) == 0) {
return PK11_ReferenceSlot(slot);
retSlot = PK11_ReferenceSlot(slot);
break;
}
}
SECMOD_ReleaseReadLock(moduleLock);
if (retSlot == NULL) {
PORT_SetError(SEC_ERROR_NO_SLOT_SELECTED);
}
return NULL;
return retSlot;
}
SECStatus
@ -501,11 +561,12 @@ PK11_IsFIPS(void)
/* combines NewModule() & AddModule */
/* give a string for the module name & the full-path for the dll, */
/* installs the PKCS11 module & update registry */
SECStatus SECMOD_AddNewModuleEx(const char* moduleName, const char* dllPath,
SECStatus
SECMOD_AddNewModuleEx(const char* moduleName, const char* dllPath,
unsigned long defaultMechanismFlags,
unsigned long cipherEnableFlags,
char* modparms,
char* nssparms) {
char* modparms, char* nssparms)
{
SECMODModule *module;
SECStatus result = SECFailure;
int s,i;
@ -526,26 +587,28 @@ SECStatus SECMOD_AddNewModuleEx(const char* moduleName, const char* dllPath,
/* turn on SSL cipher enable flags */
module->ssl[0] = cipherEnableFlags;
SECMOD_GetReadLock(moduleLock);
/* check each slot to turn on appropriate mechanisms */
for (s = 0; s < module->slotCount; s++) {
slot = (module->slots)[s];
/* for each possible mechanism */
for (i=0; i < num_pk11_default_mechanisms; i++) {
/* we are told to turn it on by default ? */
if (PK11_DefaultArray[i].flag & defaultMechanismFlags) {
/* it ignores if slot attribute update failes */
result = PK11_UpdateSlotAttribute(slot, &(PK11_DefaultArray[i]), PR_TRUE);
} else { /* turn this mechanism of the slot off by default */
result = PK11_UpdateSlotAttribute(slot, &(PK11_DefaultArray[i]), PR_FALSE);
}
PRBool add =
(PK11_DefaultArray[i].flag & defaultMechanismFlags) ?
PR_TRUE: PR_FALSE;
result = PK11_UpdateSlotAttribute(slot,
&(PK11_DefaultArray[i]), add);
} /* for each mechanism */
/* disable each slot if the defaultFlags say so */
if (defaultMechanismFlags & PK11_DISABLE_FLAG) {
PK11_UserDisableSlot(slot);
}
} /* for each slot of this module */
SECMOD_ReleaseReadLock(moduleLock);
/* delete and re-add module in order to save changes to the module */
/* delete and re-add module in order to save changes
* to the module */
result = SECMOD_UpdateModule(module);
}
}
@ -554,7 +617,8 @@ SECStatus SECMOD_AddNewModuleEx(const char* moduleName, const char* dllPath,
return result;
}
SECStatus SECMOD_AddNewModule(const char* moduleName, const char* dllPath,
SECStatus
SECMOD_AddNewModule(const char* moduleName, const char* dllPath,
unsigned long defaultMechanismFlags,
unsigned long cipherEnableFlags)
{
@ -563,7 +627,8 @@ SECStatus SECMOD_AddNewModule(const char* moduleName, const char* dllPath,
NULL, NULL); /* don't pass module or nss params */
}
SECStatus SECMOD_UpdateModule(SECMODModule *module)
SECStatus
SECMOD_UpdateModule(SECMODModule *module)
{
SECStatus result;
@ -582,7 +647,9 @@ SECStatus SECMOD_UpdateModule(SECMODModule *module)
* puts RANDOM_FLAG at bit 31 (Most-significant bit), but
* public representation puts this bit at bit 28
*/
unsigned long SECMOD_PubMechFlagstoInternal(unsigned long publicFlags) {
unsigned long
SECMOD_PubMechFlagstoInternal(unsigned long publicFlags)
{
unsigned long internalFlags = publicFlags;
if (publicFlags & PUBLIC_MECH_RANDOM_FLAG) {
@ -592,7 +659,9 @@ unsigned long SECMOD_PubMechFlagstoInternal(unsigned long publicFlags) {
return internalFlags;
}
unsigned long SECMOD_InternaltoPubMechFlags(unsigned long internalFlags) {
unsigned long
SECMOD_InternaltoPubMechFlags(unsigned long internalFlags)
{
unsigned long publicFlags = internalFlags;
if (internalFlags & SECMOD_RANDOM_FLAG) {
@ -606,11 +675,15 @@ unsigned long SECMOD_InternaltoPubMechFlags(unsigned long internalFlags) {
/* Public & Internal(Security Library) representation of */
/* cipher flags conversion */
/* Note: currently they are just stubs */
unsigned long SECMOD_PubCipherFlagstoInternal(unsigned long publicFlags) {
unsigned long
SECMOD_PubCipherFlagstoInternal(unsigned long publicFlags)
{
return publicFlags;
}
unsigned long SECMOD_InternaltoPubCipherFlags(unsigned long internalFlags) {
unsigned long
SECMOD_InternaltoPubCipherFlags(unsigned long internalFlags)
{
return internalFlags;
}
@ -624,7 +697,8 @@ SECMOD_IsModulePresent( unsigned long int pubCipherEnableFlags )
for ( ; mods != NULL; mods = mods->next) {
if (mods->module->ssl[0] & SECMOD_PubCipherFlagstoInternal(pubCipherEnableFlags)) {
if (mods->module->ssl[0] &
SECMOD_PubCipherFlagstoInternal(pubCipherEnableFlags)) {
result = PR_TRUE;
}
}
@ -634,7 +708,8 @@ SECMOD_IsModulePresent( unsigned long int pubCipherEnableFlags )
}
/* create a new ModuleListElement */
SECMODModuleList *SECMOD_NewModuleListElement(void) {
SECMODModuleList *SECMOD_NewModuleListElement(void)
{
SECMODModuleList *newModList;
newModList= (SECMODModuleList *) PORT_Alloc(sizeof(SECMODModuleList));
@ -644,11 +719,13 @@ SECMODModuleList *SECMOD_NewModuleListElement(void) {
}
return newModList;
}
/*
* make a new reference to a module so It doesn't go away on us
*/
SECMODModule *
SECMOD_ReferenceModule(SECMODModule *module) {
SECMOD_ReferenceModule(SECMODModule *module)
{
PK11_USE_THREADS(PZ_Lock((PZLock *)module->refLock);)
PORT_Assert(module->refCount > 0);
@ -660,7 +737,8 @@ SECMOD_ReferenceModule(SECMODModule *module) {
/* destroy an existing module */
void
SECMOD_DestroyModule(SECMODModule *module) {
SECMOD_DestroyModule(SECMODModule *module)
{
PRBool willfree = PR_FALSE;
int slotCount;
int i;
@ -707,7 +785,8 @@ SECMOD_DestroyModule(SECMODModule *module) {
/* we can only get here if we've destroyed the module, or some one has
* erroneously freed a slot that wasn't referenced. */
void
SECMOD_SlotDestroyModule(SECMODModule *module, PRBool fromSlot) {
SECMOD_SlotDestroyModule(SECMODModule *module, PRBool fromSlot)
{
PRBool willfree = PR_FALSE;
if (fromSlot) {
PORT_Assert(module->refCount == 0);
@ -737,7 +816,8 @@ SECMOD_SlotDestroyModule(SECMODModule *module, PRBool fromSlot) {
* on the chain. It makes it easy to implement for loops to delete
* the chain. It also make deleting a single element easy */
SECMODModuleList *
SECMOD_DestroyModuleListElement(SECMODModuleList *element) {
SECMOD_DestroyModuleListElement(SECMODModuleList *element)
{
SECMODModuleList *next = element->next;
if (element->module) {
@ -753,7 +833,8 @@ SECMOD_DestroyModuleListElement(SECMODModuleList *element) {
* Destroy an entire module list
*/
void
SECMOD_DestroyModuleList(SECMODModuleList *list) {
SECMOD_DestroyModuleList(SECMODModuleList *list)
{
SECMODModuleList *lp;
for ( lp = list; lp != NULL; lp = SECMOD_DestroyModuleListElement(lp)) ;
@ -764,3 +845,330 @@ SECMOD_CanDeleteInternalModule(void)
{
return (PRBool) (pendingModule == NULL);
}
/*
* check to see if the module has added new slots. PKCS 11 v2.20 allows for
* modules to add new slots, but never remove them. Slots cannot be added
* between a call to C_GetSlotLlist(Flag, NULL, &count) and the subsequent
* C_GetSlotList(flag, &data, &count) so that the array doesn't accidently
* grow on the caller. It is permissible for the slots to increase between
* successive calls with NULL to get the size.
*/
SECStatus
SECMOD_UpdateSlotList(SECMODModule *mod)
{
CK_RV crv;
int count,i, oldCount;
PRBool freeRef = PR_FALSE;
void *mark;
CK_ULONG *slotIDs = NULL;
PK11SlotInfo **newSlots = NULL;
PK11SlotInfo **oldSlots = NULL;
/* C_GetSlotList is not a session function, make sure
* calls are serialized */
PZ_Lock(mod->refLock);
freeRef = PR_TRUE;
/* see if the number of slots have changed */
crv = PK11_GETTAB(mod)->C_GetSlotList(PR_FALSE, NULL, &count);
if (crv != CKR_OK) {
PORT_SetError(PK11_MapError(crv));
goto loser;
}
/* nothing new, blow out early, we want this function to be quick
* and cheap in the normal case */
if (count == mod->slotCount) {
PZ_Unlock(mod->refLock);
return SECSuccess;
}
if (count < mod->slotCount) {
/* shouldn't happen with a properly functioning PKCS #11 module */
PORT_SetError( SEC_ERROR_INCOMPATIBLE_PKCS11 );
goto loser;
}
/* get the new slot list */
slotIDs = PORT_NewArray(CK_SLOT_ID, count);
if (slotIDs == NULL) {
goto loser;
}
crv = PK11_GETTAB(mod)->C_GetSlotList(PR_FALSE, slotIDs, &count);
if (crv != CKR_OK) {
PORT_SetError(PK11_MapError(crv));
goto loser;
}
freeRef = PR_FALSE;
PZ_Unlock(mod->refLock);
mark = PORT_ArenaMark(mod->arena);
if (mark == NULL) {
goto loser;
}
newSlots = PORT_ArenaZNewArray(mod->arena,PK11SlotInfo *,count);
/* walk down the new slot ID list returned from the module. We keep
* the old slots which match a returned ID, and we initialize the new
* slots. */
for (i=0; i < count; i++) {
PK11SlotInfo *slot = SECMOD_FindSlotByID(mod,slotIDs[i]);
if (!slot) {
/* we have a new slot create a new slot data structure */
slot = PK11_NewSlotInfo(mod);
if (!slot) {
goto loser;
}
PK11_InitSlot(mod, slotIDs[i], slot);
STAN_InitTokenForSlotInfo(NULL, slot);
}
newSlots[i] = slot;
}
STAN_ResetTokenInterator(NULL);
PORT_Free(slotIDs);
slotIDs = NULL;
PORT_ArenaUnmark(mod->arena, mark);
/* until this point we're still using the old slot list. Now we update
* module slot list. We update the slots (array) first then the count,
* since we've already guarrenteed that count has increased (just in case
* someone is looking at the slots field of module without holding the
* moduleLock */
SECMOD_GetWriteLock(moduleLock);
oldCount =mod->slotCount;
oldSlots = mod->slots;
mod->slots = newSlots; /* typical arena 'leak'... old mod->slots is
* allocated out of the module arena and won't
* be freed until the module is freed */
mod->slotCount = count;
SECMOD_ReleaseWriteLock(moduleLock);
/* free our old references before forgetting about oldSlot*/
for (i=0; i < oldCount; i++) {
PK11_FreeSlot(oldSlots[i]);
}
return SECSuccess;
loser:
if (freeRef) {
PZ_Unlock(mod->refLock);
}
if (slotIDs) {
PORT_Free(slotIDs);
}
/* free all the slots we allocated. newSlots are part of the
* mod arena. NOTE: the newSlots array contain both new and old
* slots, but we kept a reference to the old slots when we built the new
* array, so we need to free all the slots in newSlots array. */
if (newSlots) {
for (i=0; i < count; i++) {
if (newSlots[i] == NULL) {
break; /* hit the last one */
}
PK11_FreeSlot(newSlots[i]);
}
}
/* must come after freeing newSlots */
if (mark) {
PORT_ArenaRelease(mod->arena, mark);
}
return SECFailure;
}
/*
* this handles modules that do not support C_WaitForSlotEvent().
* The internal flags are stored. Note that C_WaitForSlotEvent() does not
* have a timeout, so we don't have one for handleWaitForSlotEvent() either.
*/
PK11SlotInfo *
secmod_HandleWaitForSlotEvent(SECMODModule *mod, unsigned long flags,
PRIntervalTime latency)
{
PRBool removableSlotsFound = PR_FALSE;
int i;
int error = SEC_ERROR_NO_EVENT;
PZ_Lock(mod->refLock);
if (mod->evControlMask & SECMOD_END_WAIT) {
mod->evControlMask &= ~SECMOD_END_WAIT;
PZ_Unlock(mod->refLock);
PORT_SetError(SEC_ERROR_NO_EVENT);
return NULL;
}
mod->evControlMask |= SECMOD_WAIT_SIMULATED_EVENT;
while (mod->evControlMask & SECMOD_WAIT_SIMULATED_EVENT) {
PZ_Unlock(mod->refLock);
/* now is a good time to see if new slots have been added */
SECMOD_UpdateSlotList(mod);
/* loop through all the slots on a module */
SECMOD_GetReadLock(moduleLock);
for (i=0; i < mod->slotCount; i++) {
PK11SlotInfo *slot = mod->slots[i];
uint16 series;
PRBool present;
/* perm modules do not change */
if (slot->isPerm) {
continue;
}
removableSlotsFound = PR_TRUE;
/* simulate the PKCS #11 module flags. are the flags different
* from the last time we called? */
series = slot->series;
present = PK11_IsPresent(slot);
if ((slot->flagSeries != series) || (slot->flagState != present)) {
slot->flagState = present;
slot->flagSeries = series;
SECMOD_ReleaseReadLock(moduleLock);
PZ_Lock(mod->refLock);
mod->evControlMask &= ~SECMOD_END_WAIT;
PZ_Unlock(mod->refLock);
return PK11_ReferenceSlot(slot);
}
}
SECMOD_ReleaseReadLock(moduleLock);
/* if everything was perm modules, don't lock up forever */
if (!removableSlotsFound) {
error =SEC_ERROR_NO_SLOT_SELECTED;
PZ_Lock(mod->refLock);
break;
}
if (flags & CKF_DONT_BLOCK) {
PZ_Lock(mod->refLock);
break;
}
PR_Sleep(latency);
PZ_Lock(mod->refLock);
}
mod->evControlMask &= ~SECMOD_END_WAIT;
PZ_Unlock(mod->refLock);
PORT_SetError(error);
return NULL;
}
/*
* this function waits for a token event on any slot of a given module
* This function should not be called from more than one thread of the
* same process (though other threads can make other library calls
* on this module while this call is blocked).
*/
PK11SlotInfo *
SECMOD_WaitForAnyTokenEvent(SECMODModule *mod, unsigned long flags,
PRIntervalTime latency)
{
CK_SLOT_ID id;
CK_RV crv;
PK11SlotInfo *slot;
/* first the the PKCS #11 call */
PZ_Lock(mod->refLock);
if (mod->evControlMask & SECMOD_END_WAIT) {
goto end_wait;
}
mod->evControlMask |= SECMOD_WAIT_PKCS11_EVENT;
PZ_Unlock(mod->refLock);
crv = PK11_GETTAB(mod)->C_WaitForSlotEvent(flags, &id, NULL);
PZ_Lock(mod->refLock);
mod->evControlMask &= ~SECMOD_WAIT_PKCS11_EVENT;
/* if we are in end wait, short circuit now, don't even risk
* going into secmod_HandleWaitForSlotEvent */
if (mod->evControlMask & SECMOD_END_WAIT) {
goto end_wait;
}
PZ_Unlock(mod->refLock);
if (crv == CKR_FUNCTION_NOT_SUPPORTED) {
/* module doesn't support that call, simulate it */
return secmod_HandleWaitForSlotEvent(mod, flags, latency);
}
if (crv != CKR_OK) {
/* we can get this error if finalize was called while we were
* still running. This is the only way to force a C_WaitForSlotEvent()
* to return in PKCS #11. In this case, just return that there
* was no event. */
if (crv == CKR_CRYPTOKI_NOT_INITIALIZED) {
PORT_SetError(SEC_ERROR_NO_EVENT);
} else {
PORT_SetError(PK11_MapError(crv));
}
return NULL;
}
slot = SECMOD_FindSlotByID(mod, id);
if (slot == NULL) {
/* possibly a new slot that was added? */
SECMOD_UpdateSlotList(mod);
slot = SECMOD_FindSlotByID(mod, id);
}
return slot;
/* must be called with the lock on. */
end_wait:
mod->evControlMask &= ~SECMOD_END_WAIT;
PZ_Unlock(mod->refLock);
PORT_SetError(SEC_ERROR_NO_EVENT);
return NULL;
}
/*
* This function "wakes up" WaitForAnyTokenEvent. It's a pretty drastic
* function, possibly bringing down the pkcs #11 module in question. This
* should be OK because 1) it does reinitialize, and 2) it should only be
* called when we are on our way to tear the whole system down anyway.
*/
SECStatus
SECMOD_CancelWait(SECMODModule *mod)
{
unsigned long controlMask = mod->evControlMask;
SECStatus rv = SECSuccess;
CK_RV crv;
PZ_Lock(mod->refLock);
mod->evControlMask |= SECMOD_END_WAIT;
controlMask = mod->evControlMask;
if (controlMask & SECMOD_WAIT_PKCS11_EVENT) {
/* NOTE: this call will drop all transient keys, in progress
* operations, and any authentication. This is the only documented
* way to get WaitForSlotEvent to return. Also note: for non-thread
* safe tokens, we need to hold the module lock, this is not yet at
* system shutdown/starup time, so we need to protect these calls */
crv = PK11_GETTAB(mod)->C_Finalize(NULL);
/* ok, we slammed the module down, now we need to reinit it in case
* we intend to use it again */
if (crv = CKR_OK) {
secmod_ModuleInit(mod);
} else {
/* Finalized failed for some reason, notify the application
* so maybe it has a prayer of recovering... */
PORT_SetError(PK11_MapError(crv));
rv = SECFailure;
}
} else if (controlMask & SECMOD_WAIT_SIMULATED_EVENT) {
mod->evControlMask &= ~SECMOD_WAIT_SIMULATED_EVENT;
/* Simulated events will eventually timeout
* and wake up in the loop */
}
PZ_Unlock(mod->refLock);
return rv;
}
/*
* check to see if the module has removable slots that we may need to
* watch for.
*/
PRBool
SECMOD_HasRemovableSlots(SECMODModule *mod)
{
int i;
PRBool ret = PR_FALSE;
SECMOD_GetReadLock(moduleLock);
for (i=0; i < mod->slotCount; i++) {
PK11SlotInfo *slot = mod->slots[i];
/* perm modules are not inserted or removed */
if (slot->isPerm) {
continue;
}
ret = PR_TRUE;
break;
}
SECMOD_ReleaseReadLock(moduleLock);
return ret;
}

View File

@ -37,6 +37,7 @@
#define _SEDMOD_H_
#include "seccomon.h"
#include "secmodt.h"
#include "prinrval.h"
#define PKCS11_USE_THREADS
@ -148,6 +149,25 @@ PRBool SECMOD_IsModulePresent( unsigned long int pubCipherEnableFlags );
extern unsigned long SECMOD_PubMechFlagstoInternal(unsigned long publicFlags);
extern unsigned long SECMOD_PubCipherFlagstoInternal(unsigned long publicFlags);
PRBool SECMOD_HasRemovableSlots(SECMODModule *mod);
PK11SlotInfo *SECMOD_WaitForAnyTokenEvent(SECMODModule *mod,
unsigned long flags, PRIntervalTime latency);
/*
* Warning: the SECMOD_CancelWait function is highly destructive, potentially
* finalizing the module 'mod' (causing inprogress operations to fail,
* and session key material to disappear). It should only be called when
* shutting down the module.
*/
SECStatus SECMOD_CancelWait(SECMODModule *mod);
/*
* check to see if the module has added new slots. PKCS 11 v2.20 allows for
* modules to add new slots, but never remove them. Slots not be added between
* a call to C_GetSlotLlist(Flag, NULL, &count) and the corresponding
* C_GetSlotList(flag, &data, &count) so that the array doesn't accidently
* grow on the caller. It is permissible for the slots to increase between
* corresponding calls with NULL to get the size.
*/
SECStatus SECMOD_UpdateSlotList(SECMODModule *mod);
SEC_END_PROTOS
#endif

View File

@ -65,6 +65,7 @@ void nss_DumpModuleLog(void);
extern int secmod_PrivateModuleCount;
extern void SECMOD_Init(void);
SECStatus secmod_ModuleInit(SECMODModule *mod);
/* list managment */
extern SECStatus SECMOD_AddModuleToList(SECMODModule *newModule);

View File

@ -93,8 +93,26 @@ struct SECMODModuleStr {
PRBool moduleDBOnly; /* this module only has lists of PKCS #11 modules */
int trustOrder; /* order for this module's certificate trust rollup */
int cipherOrder; /* order for cipher operations */
unsigned long evControlMask; /* control the running and shutdown of slot
* events (SECMOD_WaitForAnyTokenEvent) */
};
/* evControlMask flags */
/*
* These bits tell the current state of a SECMOD_WaitForAnyTokenEvent.
*
* SECMOD_WAIT_PKCS11_EVENT - we're waiting in the PKCS #11 module in
* C_WaitForSlotEvent().
* SECMOD_WAIT_SIMULATED_EVENT - we're waiting in the NSS simulation code
* which polls for token insertion and removal events.
* SECMOD_END_WAIT - SECMOD_CancelWait has been called while the module is
* waiting in SECMOD_WaitForAnyTokenEvent. SECMOD_WaitForAnyTokenEvent
* should return immediately to it's caller.
*/
#define SECMOD_END_WAIT 0x01
#define SECMOD_WAIT_SIMULATED_EVENT 0x02
#define SECMOD_WAIT_PKCS11_EVENT 0x04
struct SECMODModuleListStr {
SECMODModuleList *next;
SECMODModule *module;

View File

@ -122,6 +122,10 @@ struct PK11SlotInfoStr {
uint16 series; /* break up the slot info into various groups of
* inserted tokens so that keys and certs can be
* invalidated */
uint16 flagSeries; /* record the last series for the last event
* returned for this slot */
PRBool flagState; /* record the state of the last event returned for this
* slot. */
uint16 wrapKey; /* current wrapping key for SSL master secrets */
CK_MECHANISM_TYPE wrapMechanism;
/* current wrapping mechanism for current wrapKey */

View File

@ -35,7 +35,7 @@
* ***** END LICENSE BLOCK ***** */
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: pki3hack.c,v $ $Revision: 1.82 $ $Date: 2004/07/21 18:18:05 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: pki3hack.c,v $ $Revision: 1.83 $ $Date: 2004/07/29 23:38:14 $ $Name: $";
#endif /* DEBUG */
/*
@ -93,13 +93,40 @@ STAN_GetDefaultCryptoContext()
extern const NSSError NSS_ERROR_ALREADY_INITIALIZED;
extern const NSSError NSS_ERROR_INTERNAL_ERROR;
NSS_IMPLEMENT PRStatus
STAN_InitTokenForSlotInfo(NSSTrustDomain *td, PK11SlotInfo *slot)
{
NSSToken *token;
if (!td) {
td = g_default_trust_domain;
}
token = nssToken_CreateFromPK11SlotInfo(td, slot);
PK11Slot_SetNSSToken(slot, token);
NSSRWLock_LockWrite(td->tokensLock);
nssList_Add(td->tokenList, token);
NSSRWLock_UnlockWrite(td->tokensLock);
return PR_SUCCESS;
}
NSS_IMPLEMENT PRStatus
STAN_ResetTokenInterator(NSSTrustDomain *td)
{
if (!td) {
td = g_default_trust_domain;
}
NSSRWLock_LockWrite(td->tokensLock);
nssListIterator_Destroy(td->tokens);
td->tokens = nssList_CreateIterator(td->tokenList);
NSSRWLock_UnlockWrite(td->tokensLock);
return PR_SUCCESS;
}
NSS_IMPLEMENT PRStatus
STAN_LoadDefaultNSS3TrustDomain (
void
)
{
NSSTrustDomain *td;
NSSToken *token;
SECMODModuleList *mlp;
SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock();
int i;
@ -113,41 +140,48 @@ STAN_LoadDefaultNSS3TrustDomain (
if (!td) {
return PR_FAILURE;
}
td->tokenList = nssList_Create(td->arena, PR_TRUE);
/*
* Deadlock warning: we should never acquire the moduleLock while
* we hold the tokensLock. We can use the NSSRWLock Rank feature to
* guarrentee this. tokensLock have a higher rank than module lock.
*/
SECMOD_GetReadLock(moduleLock);
NSSRWLock_LockWrite(td->tokensLock);
td->tokenList = nssList_Create(td->arena, PR_TRUE);
for (mlp = SECMOD_GetDefaultModuleList(); mlp != NULL; mlp=mlp->next) {
for (i=0; i < mlp->module->slotCount; i++) {
token = nssToken_CreateFromPK11SlotInfo(td, mlp->module->slots[i]);
PK11Slot_SetNSSToken(mlp->module->slots[i], token);
nssList_Add(td->tokenList, token);
STAN_InitTokenForSlotInfo(td, mlp->module->slots[i]);
}
}
SECMOD_ReleaseReadLock(moduleLock);
td->tokens = nssList_CreateIterator(td->tokenList);
NSSRWLock_UnlockWrite(td->tokensLock);
SECMOD_ReleaseReadLock(moduleLock);
g_default_trust_domain = td;
g_default_crypto_context = NSSTrustDomain_CreateCryptoContext(td, NULL);
return PR_SUCCESS;
}
/*
* must be called holding the ModuleListLock (either read or write).
*/
NSS_IMPLEMENT SECStatus
STAN_AddModuleToDefaultTrustDomain (
SECMODModule *module
)
{
NSSToken *token;
NSSTrustDomain *td;
int i;
td = STAN_GetDefaultTrustDomain();
for (i=0; i<module->slotCount; i++) {
token = nssToken_CreateFromPK11SlotInfo(td, module->slots[i]);
PK11Slot_SetNSSToken(module->slots[i], token);
nssList_Add(td->tokenList, token);
STAN_InitTokenForSlotInfo(td, module->slots[i]);
}
nssListIterator_Destroy(td->tokens);
td->tokens = nssList_CreateIterator(td->tokenList);
STAN_ResetTokenInterator(td);
return SECSuccess;
}
/*
* must be called holding the ModuleListLock (either read or write).
*/
NSS_IMPLEMENT SECStatus
STAN_RemoveModuleFromDefaultTrustDomain (
SECMODModule *module
@ -157,6 +191,7 @@ STAN_RemoveModuleFromDefaultTrustDomain (
NSSTrustDomain *td;
int i;
td = STAN_GetDefaultTrustDomain();
NSSRWLock_LockWrite(td->tokensLock);
for (i=0; i<module->slotCount; i++) {
token = PK11Slot_GetNSSToken(module->slots[i]);
if (token) {
@ -168,6 +203,7 @@ STAN_RemoveModuleFromDefaultTrustDomain (
}
nssListIterator_Destroy(td->tokens);
td->tokens = nssList_CreateIterator(td->tokenList);
NSSRWLock_UnlockWrite(td->tokensLock);
return SECSuccess;
}
@ -1015,9 +1051,11 @@ STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust)
tok = stan_GetTrustToken(c);
moving_object = PR_FALSE;
if (tok && PK11_IsReadOnly(tok->pk11slot)) {
NSSRWLock_LockRead(td->tokensLock);
tokens = nssList_CreateIterator(td->tokenList);
if (!tokens) {
nssrv = PR_FAILURE;
NSSRWLock_UnlockRead(td->tokensLock);
goto done;
}
for (tok = (NSSToken *)nssListIterator_Start(tokens);
@ -1028,6 +1066,7 @@ STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust)
}
nssListIterator_Finish(tokens);
nssListIterator_Destroy(tokens);
NSSRWLock_UnlockRead(td->tokensLock);
moving_object = PR_TRUE;
}
if (tok) {

View File

@ -38,7 +38,7 @@
#define PKINSS3HACK_H
#ifdef DEBUG
static const char PKINSS3HACK_CVS_ID[] = "@(#) $RCSfile: pki3hack.h,v $ $Revision: 1.17 $ $Date: 2004/07/21 18:18:05 $ $Name: $";
static const char PKINSS3HACK_CVS_ID[] = "@(#) $RCSfile: pki3hack.h,v $ $Revision: 1.18 $ $Date: 2004/07/29 23:38:14 $ $Name: $";
#endif /* DEBUG */
#ifndef NSSDEVT_H
@ -74,25 +74,22 @@ NSS_EXTERN NSSCryptoContext *
STAN_GetDefaultCryptoContext();
NSS_EXTERN PRStatus
STAN_LoadDefaultNSS3TrustDomain
(
void
);
STAN_InitTokenForSlotInfo(NSSTrustDomain *td, PK11SlotInfo *slot);
NSS_EXTERN PRStatus
STAN_ResetTokenInterator(NSSTrustDomain *td);
NSS_EXTERN PRStatus
STAN_LoadDefaultNSS3TrustDomain(void);
NSS_EXTERN PRStatus
STAN_Shutdown();
NSS_EXTERN SECStatus
STAN_AddModuleToDefaultTrustDomain
(
SECMODModule *module
);
STAN_AddModuleToDefaultTrustDomain(SECMODModule *module);
NSS_EXTERN SECStatus
STAN_RemoveModuleFromDefaultTrustDomain
(
SECMODModule *module
);
STAN_RemoveModuleFromDefaultTrustDomain(SECMODModule *module);
NSS_EXTERN CERTCertificate *
STAN_ForceCERTCertificateUpdate(NSSCertificate *c);

View File

@ -38,7 +38,7 @@
#define PKIT_H
#ifdef DEBUG
static const char PKIT_CVS_ID[] = "@(#) $RCSfile: pkit.h,v $ $Revision: 1.15 $ $Date: 2004/05/17 20:08:37 $ $Name: $";
static const char PKIT_CVS_ID[] = "@(#) $RCSfile: pkit.h,v $ $Revision: 1.16 $ $Date: 2004/07/29 23:38:14 $ $Name: $";
#endif /* DEBUG */
/*
@ -72,6 +72,10 @@ static const char PKIT_CVS_ID[] = "@(#) $RCSfile: pkit.h,v $ $Revision: 1.15 $ $
#include "devt.h"
#endif /* DEVT_H */
#ifndef nssrwlkt_h__
#include "nssrwlkt.h"
#endif /* nssrwlkt_h__ */
PR_BEGIN_EXTERN_C
/*
@ -174,6 +178,7 @@ struct NSSTrustDomainStr {
nssList *tokenList;
nssListIterator *tokens;
nssTDCertificateCache *cache;
NSSRWLock *tokensLock;
#ifdef NSS_3_4_CODE
void *spkDigestInfo;
CERTStatusConfig *statusConfig;

View File

@ -35,7 +35,7 @@
* ***** END LICENSE BLOCK ***** */
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: trustdomain.c,v $ $Revision: 1.49 $ $Date: 2004/04/25 15:03:14 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: trustdomain.c,v $ $Revision: 1.50 $ $Date: 2004/07/29 23:38:14 $ $Name: $";
#endif /* DEBUG */
#ifndef DEV_H
@ -55,6 +55,8 @@ static const char CVS_ID[] = "@(#) $RCSfile: trustdomain.c,v $ $Revision: 1.49 $
#include "pki3hack.h"
#endif
#include "nssrwlk.h"
#define NSSTRUSTDOMAIN_DEFAULT_CACHE_SIZE 32
#ifdef PURE_STAN_BUILD
@ -93,6 +95,11 @@ NSSTrustDomain_Create (
if (!rvTD) {
goto loser;
}
/* protect the token list and the token iterator */
rvTD->tokensLock = NSSRWLock_New(100, "tokens");
if (!rvTD->tokensLock) {
goto loser;
}
nssTrustDomain_InitializeCache(rvTD, NSSTRUSTDOMAIN_DEFAULT_CACHE_SIZE);
rvTD->arena = arena;
rvTD->refCount = 1;
@ -101,6 +108,9 @@ NSSTrustDomain_Create (
#endif
return rvTD;
loser:
if (rvTD && rvTD->tokensLock) {
NSSRWLock_Destroy(rvTD->tokensLock);
}
nssArena_Destroy(arena);
return (NSSTrustDomain *)NULL;
}
@ -127,6 +137,7 @@ NSSTrustDomain_Destroy (
nssList_Clear(td->tokenList, token_destructor);
nssList_Destroy(td->tokenList);
}
NSSRWLock_Destroy(td->tokensLock);
status = nssTrustDomain_DestroyCache(td);
if (status == PR_FAILURE) {
return status;
@ -148,17 +159,21 @@ nssTrustDomain_GetActiveSlots (
NSSSlot **slots = NULL;
NSSToken **tp, **tokens;
*updateLevel = 1;
NSSRWLock_LockRead(td->tokensLock);
count = nssList_Count(td->tokenList);
tokens = nss_ZNEWARRAY(NULL, NSSToken *, count + 1);
if (!tokens) {
NSSRWLock_UnlockRead(td->tokensLock);
return NULL;
}
slots = nss_ZNEWARRAY(NULL, NSSSlot *, count + 1);
if (!slots) {
NSSRWLock_UnlockRead(td->tokensLock);
nss_ZFreeIf(tokens);
return NULL;
}
nssList_GetArray(td->tokenList, (void **)tokens, count);
NSSRWLock_UnlockRead(td->tokensLock);
count = 0;
for (tp = tokens; *tp; tp++) {
slots[count++] = nssToken_GetSlot(*tp);
@ -275,6 +290,7 @@ NSSTrustDomain_FindTokenByName (
PRStatus nssrv;
NSSUTF8 *myName;
NSSToken *tok = NULL;
NSSRWLock_LockRead(td->tokensLock);
for (tok = (NSSToken *)nssListIterator_Start(td->tokens);
tok != (NSSToken *)NULL;
tok = (NSSToken *)nssListIterator_Next(td->tokens))
@ -285,6 +301,7 @@ NSSTrustDomain_FindTokenByName (
}
}
nssListIterator_Finish(td->tokens);
NSSRWLock_UnlockRead(td->tokensLock);
return tok;
}

View File

@ -200,7 +200,9 @@ SEC_ERROR_REVOKED_CERTIFICATE_OCSP = (SEC_ERROR_BASE + 146),
SEC_ERROR_CRL_INVALID_VERSION = (SEC_ERROR_BASE + 147),
SEC_ERROR_CRL_V1_CRITICAL_EXTENSION = (SEC_ERROR_BASE + 148),
SEC_ERROR_CRL_UNKNOWN_CRITICAL_EXTENSION = (SEC_ERROR_BASE + 149),
SEC_ERROR_UNKNOWN_OBJECT_TYPE = (SEC_ERROR_BASE + 150)
SEC_ERROR_UNKNOWN_OBJECT_TYPE = (SEC_ERROR_BASE + 150),
SEC_ERROR_INCOMPATIBLE_PKCS11 = (SEC_ERROR_BASE + 151),
SEC_ERROR_NO_EVENT = (SEC_ERROR_BASE + 152)
} SECErrorCodes;
#endif /* NO_SECURITY_ERROR_ENUM */