зеркало из https://github.com/mozilla/gecko-dev.git
reuse old key structures on a given token rather than building it up and
tearing it down every time.
This commit is contained in:
Родитель
78671954d3
Коммит
d43393b11b
|
@ -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);
|
||||
|
||||
|
||||
|
||||
/************************************************************
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче