pkcs11u.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 1,271 行 · 第 1/3 页
C
1,271 行
/* * release a reference to an object handle */PK11FreeStatuspk11_FreeObject(PK11Object *object){ PRBool destroy = PR_FALSE; CK_RV crv; PK11_USE_THREADS(PR_Lock(object->refLock);) if (object->refCount == 1) destroy = PR_TRUE; object->refCount--; PK11_USE_THREADS(PR_Unlock(object->refLock);) if (destroy) { crv = pk11_DestroyObject(object); if (crv != CKR_OK) { return PK11_DestroyFailure; } return PK11_Destroyed; } return PK11_Busy;} /* * add an object to a slot and session queue. These two functions * adopt the object. */voidpk11_AddSlotObject(PK11Slot *slot, PK11Object *object){ PK11_USE_THREADS(PR_Lock(slot->objectLock);) pk11queue_add(object,object->handle,slot->tokObjects,TOKEN_OBJECT_HASH_SIZE); PK11_USE_THREADS(PR_Unlock(slot->objectLock);)}voidpk11_AddObject(PK11Session *session, PK11Object *object){ PK11Slot *slot = pk11_SlotFromSession(session); if (!pk11_isToken(object->handle)) { PK11_USE_THREADS(PR_Lock(session->objectLock);) pk11queue_add(&object->sessionList,0,session->objects,0); object->session = session; PK11_USE_THREADS(PR_Unlock(session->objectLock);) } pk11_AddSlotObject(slot,object);} /* * add an object to a slot andsession queue */voidpk11_DeleteObject(PK11Session *session, PK11Object *object){ PK11Slot *slot = pk11_SlotFromSession(session); if (object->session) { PK11Session *session = object->session; PK11_USE_THREADS(PR_Lock(session->objectLock);) pk11queue_delete(&object->sessionList,0,session->objects,0); PK11_USE_THREADS(PR_Unlock(session->objectLock);) } PK11_USE_THREADS(PR_Lock(slot->objectLock);) pk11queue_delete(object,object->handle,slot->tokObjects, TOKEN_OBJECT_HASH_SIZE); PK11_USE_THREADS(PR_Unlock(slot->objectLock);) pk11_FreeObject(object);}/* * copy the attributes from one object to another. Don't overwrite existing * attributes. NOTE: This is a pretty expensive operation since it * grabs the attribute locks for the src object for a *long* time. */CK_RVpk11_CopyObject(PK11Object *destObject,PK11Object *srcObject){ PK11Attribute *attribute; int i; PK11_USE_THREADS(PR_Lock(srcObject->attributeLock);) for(i=0; i < ATTRIBUTE_HASH_SIZE; i++) { attribute = srcObject->head[i]; do { if (attribute) { if (!pk11_hasAttribute(destObject,attribute->handle)) { /* we need to copy the attribute since each attribute * only has one set of link list pointers */ PK11Attribute *newAttribute = pk11_NewAttribute( destObject,pk11_attr_expand(&attribute->attrib)); if (newAttribute == NULL) { PK11_USE_THREADS(PR_Unlock(srcObject->attributeLock);) return CKR_HOST_MEMORY; } pk11_AddAttribute(destObject,newAttribute); } attribute=attribute->next; } } while (attribute != NULL); } PK11_USE_THREADS(PR_Unlock(srcObject->attributeLock);) return CKR_OK;}/* * ******************** Search Utilities ******************************* *//* add an object to a search list */CK_RVAddToList(PK11ObjectListElement **list,PK11Object *object){ PK11ObjectListElement *newElem = (PK11ObjectListElement *)PORT_Alloc(sizeof(PK11ObjectListElement)); if (newElem == NULL) return CKR_HOST_MEMORY; newElem->next = *list; newElem->object = object; pk11_ReferenceObject(object); *list = newElem; return CKR_OK;}/* return true if the object matches the template */PRBoolpk11_objectMatch(PK11Object *object,CK_ATTRIBUTE_PTR theTemplate,int count){ int i; for (i=0; i < count; i++) { PK11Attribute *attribute = pk11_FindAttribute(object,theTemplate[i].type); if (attribute == NULL) { return PR_FALSE; } if (attribute->attrib.ulValueLen == theTemplate[i].ulValueLen) { if (PORT_Memcmp(attribute->attrib.pValue,theTemplate[i].pValue, theTemplate[i].ulValueLen) == 0) { pk11_FreeAttribute(attribute); continue; } } pk11_FreeAttribute(attribute); return PR_FALSE; } return PR_TRUE;}/* search through all the objects in the queue and return the template matches * in the object list. */CK_RVpk11_searchObjectList(PK11ObjectListElement **objectList,PK11Object **head, PRLock *lock, CK_ATTRIBUTE_PTR theTemplate, int count, PRBool isLoggedIn){ int i; PK11Object *object; CK_RV crv = CKR_OK; for(i=0; i < TOKEN_OBJECT_HASH_SIZE; i++) { /* We need to hold the lock to copy a consistant version of * the linked list. */ PK11_USE_THREADS(PR_Lock(lock);) for (object = head[i]; object != NULL; object= object->next) { if (pk11_objectMatch(object,theTemplate,count)) { /* don't return objects that aren't yet visible */ if ((!isLoggedIn) && pk11_isTrue(object,CKA_PRIVATE)) continue; crv = AddToList(objectList,object); if (crv != CKR_OK) { break; } } } PK11_USE_THREADS(PR_Unlock(lock);) } return crv;}/* * free a single list element. Return the Next object in the list. */PK11ObjectListElement *pk11_FreeObjectListElement(PK11ObjectListElement *objectList){ PK11ObjectListElement *ol = objectList->next; pk11_FreeObject(objectList->object); PORT_Free(objectList); return ol;}/* free an entire object list */voidpk11_FreeObjectList(PK11ObjectListElement *objectList){ PK11ObjectListElement *ol; for (ol= objectList; ol != NULL; ol = pk11_FreeObjectListElement(ol)) {}}/* * free a search structure */voidpk11_FreeSearch(PK11SearchResults *search){ if (search->handles) { PORT_Free(search->handles); } PORT_Free(search);}/* * ******************** Session Utilities ******************************* *//* update the sessions state based in it's flags and wether or not it's * logged in */voidpk11_update_state(PK11Slot *slot,PK11Session *session){ if (slot->isLoggedIn) { if (slot->ssoLoggedIn) { session->info.state = CKS_RW_SO_FUNCTIONS; } else if (session->info.flags & CKF_RW_SESSION) { session->info.state = CKS_RW_USER_FUNCTIONS; } else { session->info.state = CKS_RO_USER_FUNCTIONS; } } else { if (session->info.flags & CKF_RW_SESSION) { session->info.state = CKS_RW_PUBLIC_SESSION; } else { session->info.state = CKS_RO_PUBLIC_SESSION; } }}/* update the state of all the sessions on a slot */voidpk11_update_all_states(PK11Slot *slot){ int i; PK11Session *session; for (i=0; i < SESSION_HASH_SIZE; i++) { PK11_USE_THREADS(PR_Lock(slot->sessionLock);) for (session = slot->head[i]; session; session = session->next) { pk11_update_state(slot,session); } PK11_USE_THREADS(PR_Unlock(slot->sessionLock);) }}/* * context are cipher and digest contexts that are associated with a session */voidpk11_FreeContext(PK11SessionContext *context){ if (context->cipherInfo) { (*context->destroy)(context->cipherInfo,PR_TRUE); } if (context->hashInfo) { (*context->hashdestroy)(context->hashInfo,PR_TRUE); } PORT_Free(context);}/* look up a slot structure from the ID (used to be a macro when we only * had two slots) */PK11Slot *pk11_SlotFromID(CK_SLOT_ID slotID){ switch (slotID) { case NETSCAPE_SLOT_ID: return &pk11_slot[0]; case PRIVATE_KEY_SLOT_ID: return &pk11_slot[1]; case FIPS_SLOT_ID: return &pk11_slot[2]; default: break; /* fall through to NULL */ } return NULL;}PK11Slot *pk11_SlotFromSessionHandle(CK_SESSION_HANDLE handle){ if (handle & PK11_PRIVATE_KEY_FLAG) { return &pk11_slot[1]; } if (handle & PK11_FIPS_FLAG) { return &pk11_slot[2]; } return &pk11_slot[0];}/* * create a new nession. NOTE: The session handle is not set, and the * session is not added to the slot's session queue. */PK11Session *pk11_NewSession(CK_SLOT_ID slotID, CK_NOTIFY notify, CK_VOID_PTR pApplication, CK_FLAGS flags){ PK11Session *session; PK11Slot *slot = pk11_SlotFromID(slotID); if (slot == NULL) return NULL; session = (PK11Session*)PORT_Alloc(sizeof(PK11Session)); if (session == NULL) return NULL; session->next = session->prev = NULL; session->refCount = 1; session->enc_context = NULL; session->hash_context = NULL; session->sign_context = NULL; session->search = NULL; session->objectIDCount = 1;#ifdef PKCS11_USE_THREADS session->refLock = PR_NewLock(); if (session->refLock == NULL) { PORT_Free(session); return NULL; } session->objectLock = PR_NewLock(); if (session->objectLock == NULL) { PK11_USE_THREADS(PR_DestroyLock(session->refLock);) PORT_Free(session); return NULL; }#else session->refLock = NULL; session->objectLock = NULL;#endif session->objects[0] = NULL; session->slot = slot; session->notify = notify; session->appData = pApplication; session->info.flags = flags; session->info.slotID = slotID; pk11_update_state(slot,session); return session;}/* free all the data associated with a session. */static voidpk11_DestroySession(PK11Session *session){ PK11ObjectList *op,*next; PORT_Assert(session->refCount == 0); /* clean out the attributes */ /* since no one is referencing us, it's safe to walk the chain * without a lock */ for (op = session->objects[0]; op != NULL; op = next) { next = op->next; /* paranoia */ op->next = op->prev = NULL; pk11_DeleteObject(session,op->parent); } PK11_USE_THREADS(PR_DestroyLock(session->objectLock);) PK11_USE_THREADS(PR_DestroyLock(session->refLock);) if (session->enc_context) { pk11_FreeContext(session->enc_context); } if (session->hash_context) { pk11_FreeContext(session->hash_context); } if (session->sign_context) { pk11_FreeContext(session->sign_context); } if (session->search) { pk11_FreeSearch(session->search); } PORT_Free(session);}/* * look up a session structure from a session handle * generate a reference to it. */PK11Session *pk11_SessionFromHandle(CK_SESSION_HANDLE handle){ PK11Slot *slot = pk11_SlotFromSessionHandle(handle); PK11Session *session; PK11_USE_THREADS(PR_Lock(slot->sessionLock);) pk11queue_find(session,handle,slot->head,SESSION_HASH_SIZE); if (session) session->refCount++; PK11_USE_THREADS(PR_Unlock(slot->sessionLock);) return (session);}/* * release a reference to a session handle */voidpk11_FreeSession(PK11Session *session){ PRBool destroy = PR_FALSE; PK11_USE_THREADS(PK11Slot *slot = pk11_SlotFromSession(session);) PK11_USE_THREADS(PR_Lock(slot->sessionLock);) if (session->refCount == 1) destroy = PR_TRUE; session->refCount--; PK11_USE_THREADS(PR_Unlock(slot->sessionLock);) if (destroy) pk11_DestroySession(session);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?