diff options
author | relyea%netscape.com <devnull@localhost> | 2000-06-13 21:37:28 +0000 |
---|---|---|
committer | relyea%netscape.com <devnull@localhost> | 2000-06-13 21:37:28 +0000 |
commit | eaa056d41046b41fee0c3b8d6fa93714a6e5474a (patch) | |
tree | c26321ca40d30c3d906bafb42aa56dc637ec81fe | |
parent | 930f5c5e6a7609ec639cc700ba7d5c33036ed07c (diff) | |
download | nss-hg-eaa056d41046b41fee0c3b8d6fa93714a6e5474a.tar.gz |
reuse old key structures on a given token rather than building it up and
tearing it down every time.
-rw-r--r-- | security/nss/lib/pk11wrap/pk11func.h | 2 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11skey.c | 82 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11slot.c | 28 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/secmodti.h | 5 |
4 files changed, 106 insertions, 11 deletions
diff --git a/security/nss/lib/pk11wrap/pk11func.h b/security/nss/lib/pk11wrap/pk11func.h index 21003d1ce..99310d48d 100644 --- a/security/nss/lib/pk11wrap/pk11func.h +++ b/security/nss/lib/pk11wrap/pk11func.h @@ -89,6 +89,8 @@ SECStatus PK11_Logout(PK11SlotInfo *slot); void PK11_LogoutAll(void); void PK11_EnterSlotMonitor(PK11SlotInfo *); void PK11_ExitSlotMonitor(PK11SlotInfo *); +void PK11_CleanKeyList(PK11SlotInfo *slot); + /************************************************************ diff --git a/security/nss/lib/pk11wrap/pk11skey.c b/security/nss/lib/pk11wrap/pk11skey.c index 52f2ce30d..e48c88a6d 100644 --- a/security/nss/lib/pk11wrap/pk11skey.c +++ b/security/nss/lib/pk11wrap/pk11skey.c @@ -154,6 +154,54 @@ pk11_ExitKeyMonitor(PK11SymKey *symKey) { PK11_ExitSlotMonitor(symKey->slot); } + +static PK11SymKey *pk11SymKeyHead = NULL; +static PK11SymKey * +pk11_getKeyFromList(PK11SlotInfo *slot) { + PK11SymKey *symKey; + + + PK11_USE_THREADS(PR_Lock(slot->freeListLock);) + if (slot->freeSymKeysHead) { + symKey = slot->freeSymKeysHead; + slot->freeSymKeysHead = symKey->next; + slot->keyCount--; + } + PK11_USE_THREADS(PR_Unlock(slot->freeListLock);) + if (symKey) { + symKey->next = NULL; + return symKey; + } + + symKey = (PK11SymKey *)PORT_ZAlloc(sizeof(PK11SymKey)); + if (symKey == NULL) { + return NULL; + } + symKey->refLock = PR_NewLock(); + if (symKey->refLock == NULL) { + PORT_Free(symKey); + return NULL; + } + symKey->session = pk11_GetNewSession(slot,&symKey->sessionOwner); + symKey->next = NULL; + return symKey; +} + +void +PK11_CleanKeyList(PK11SlotInfo *slot) +{ + PK11SymKey *symKey = NULL; + + while (slot->freeSymKeysHead) { + symKey = slot->freeSymKeysHead; + slot->freeSymKeysHead = symKey->next; + pk11_CloseSession(symKey->slot, symKey->session,symKey->sessionOwner); + PK11_USE_THREADS(PR_DestroyLock(symKey->refLock);) + PORT_Free(symKey); + }; + return; +} + /* * create a symetric key: * Slot is the slot to create the key in. @@ -163,15 +211,13 @@ PK11SymKey * PK11_CreateSymKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, void *wincx) { - PK11SymKey *symKey = (PK11SymKey *)PORT_Alloc(sizeof(PK11SymKey)); + PK11SymKey *symKey = pk11_getKeyFromList(slot); + + if (symKey == NULL) { return NULL; } - symKey->refLock = PR_NewLock(); - if (symKey->refLock == NULL) { - PORT_Free(symKey); - return NULL; - } + symKey->type = type; symKey->data.data = NULL; symKey->data.len = 0; @@ -183,7 +229,6 @@ PK11_CreateSymKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, void *wincx) symKey->size = 0; symKey->refCount = 1; symKey->origin = PK11_OriginNULL; - symKey->session = pk11_GetNewSession(slot,&symKey->sessionOwner); symKey->origin = PK11_OriginNULL; PK11_ReferenceSlot(slot); return symKey; @@ -196,6 +241,8 @@ void PK11_FreeSymKey(PK11SymKey *symKey) { PRBool destroy = PR_FALSE; + PK11SlotInfo *slot; + PRBool freeit = PR_TRUE; PK11_USE_THREADS(PR_Lock(symKey->refLock);) if (symKey->refCount-- == 1) { @@ -209,14 +256,27 @@ PK11_FreeSymKey(PK11SymKey *symKey) C_DestroyObject(symKey->session, symKey->objectID); pk11_ExitKeyMonitor(symKey); } - pk11_CloseSession(symKey->slot, symKey->session,symKey->sessionOwner); if (symKey->data.data) { PORT_Memset(symKey->data.data, 0, symKey->data.len); PORT_Free(symKey->data.data); } - PK11_USE_THREADS(PR_DestroyLock(symKey->refLock);) - PK11_FreeSlot(symKey->slot); - PORT_Free(symKey); + slot = symKey->slot; + PK11_USE_THREADS(PR_Lock(slot->freeListLock);) + if (slot->keyCount < slot->maxKeyCount) { + symKey->next = slot->freeSymKeysHead; + slot->freeSymKeysHead = symKey; + slot->keyCount++; + symKey->slot = NULL; + freeit = PR_FALSE; + } + PK11_USE_THREADS(PR_Unlock(slot->freeListLock);) + if (freeit) { + pk11_CloseSession(symKey->slot, symKey->session, + symKey->sessionOwner); + PK11_USE_THREADS(PR_DestroyLock(symKey->refLock);) + PORT_Free(symKey); + } + PK11_FreeSlot(slot); } } diff --git a/security/nss/lib/pk11wrap/pk11slot.c b/security/nss/lib/pk11wrap/pk11slot.c index 82d7466d4..6c7cb4296 100644 --- a/security/nss/lib/pk11wrap/pk11slot.c +++ b/security/nss/lib/pk11wrap/pk11slot.c @@ -385,10 +385,21 @@ PK11_NewSlotInfo(void) PORT_Free(slot); return slot; } + slot->freeListLock = PR_NewLock(); + if (slot->freeListLock == NULL) { + PR_DestroyLock(slot->sessionLock); + PR_DestroyLock(slot->refLock); + PORT_Free(slot); + return slot; + } #else slot->sessionLock = NULL; slot->refLock = NULL; + slot->freeListLock = NULL; #endif + slot->freeSymKeysHead = NULL; + slot->keyCount = 0; + slot->maxKeyCount = 0; slot->functionList = NULL; slot->needTest = PR_TRUE; slot->isPerm = PR_FALSE; @@ -449,6 +460,9 @@ PK11_DestroySlot(PK11SlotInfo *slot) /* now free up all the certificates we grabbed on this slot */ PK11_FreeSlotCerts(slot); + /* free up the cached keys and sessions */ + PK11_CleanKeyList(slot); + /* finally Tell our parent module that we've gone away so it can unload */ if (slot->module) { SECMOD_SlotDestroyModule(slot->module,PR_TRUE); @@ -462,6 +476,10 @@ PK11_DestroySlot(PK11SlotInfo *slot) PR_DestroyLock(slot->sessionLock); slot->sessionLock = NULL; } + if (slot->freeListLock) { + PR_DestroyLock(slot->freeListLock); + slot->freeListLock = NULL; + } #endif /* ok, well not quit finally... now we free the memory */ @@ -1587,6 +1605,16 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts) slot->hasRSAInfo = PR_FALSE; slot->RSAInfoFlags = 0; + /* initialize the maxKeyCount value */ + if (tokenInfo.ulMaxSessionCount == 0) { + slot->maxKeyCount = 300; /* should be #define or a config param */ + } else if (tokenInfo.ulMaxSessionCount < 20) { + /* don't have enough sessions to keep that many keys around */ + slot->maxKeyCount = 0; + } else { + slot->maxKeyCount = tokenInfo.ulMaxSessionCount/2; + } + /* Make sure our session handle is valid */ if (slot->session == CK_INVALID_SESSION) { /* we know we don't have a valid session, go get one */ diff --git a/security/nss/lib/pk11wrap/secmodti.h b/security/nss/lib/pk11wrap/secmodti.h index c7028641c..d97059a9b 100644 --- a/security/nss/lib/pk11wrap/secmodti.h +++ b/security/nss/lib/pk11wrap/secmodti.h @@ -83,6 +83,10 @@ struct PK11SlotInfoStr { * still in use */ int refCount; PRLock *refLock; + PRLock *freeListLock; + PK11SymKey *freeSymKeysHead; + int keyCount; + int maxKeyCount; /* Password control functions for this slot. many of these are only * active if the appropriate flag is on in defaultFlags */ int askpw; /* what our password options are */ @@ -133,6 +137,7 @@ struct PK11SymKeyStr { CK_OBJECT_HANDLE objectID; /* object id of this key in the slot */ PK11SlotInfo *slot; /* Slot this key is loaded into */ void *cx; /* window context in case we need to loggin */ + PK11SymKey *next; PRBool owner; SECItem data; /* raw key data if available */ CK_SESSION_HANDLE session; |