pk11slot.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 2,388 行 · 第 1/5 页
C
2,388 行
if (slot->sessionLock) { 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 */ PORT_Free(slot);}/* We're all done with the slot, free it */voidPK11_FreeSlot(PK11SlotInfo *slot){ PRBool freeit = PR_FALSE; PK11_USE_THREADS(PR_Lock(slot->refLock);) if (slot->refCount-- == 1) freeit = PR_TRUE; PK11_USE_THREADS(PR_Unlock(slot->refLock);) if (freeit) PK11_DestroySlot(slot);}voidPK11_EnterSlotMonitor(PK11SlotInfo *slot) { PR_Lock(slot->sessionLock);}voidPK11_ExitSlotMonitor(PK11SlotInfo *slot) { PR_Unlock(slot->sessionLock);}/*********************************************************** * Functions to find specific slots. ***********************************************************/PK11SlotInfo *PK11_FindSlotByName(char *name){ SECMODModuleList *mlp; SECMODModuleList *modules = SECMOD_GetDefaultModuleList(); SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock(); int i; PK11SlotInfo *slot = NULL; if ((name == NULL) || (*name == 0)) { return PK11_GetInternalKeySlot(); } /* work through all the slots */ SECMOD_GetReadLock(moduleLock); for(mlp = modules; mlp != NULL; mlp = mlp->next) { for (i=0; i < mlp->module->slotCount; i++) { PK11SlotInfo *tmpSlot = mlp->module->slots[i]; if (PK11_IsPresent(tmpSlot)) { if (PORT_Strcmp(tmpSlot->token_name,name) == 0) { slot = PK11_ReferenceSlot(tmpSlot); break; } } } if (slot != NULL) break; } SECMOD_ReleaseReadLock(moduleLock); if (slot == NULL) { PORT_SetError(SEC_ERROR_NO_TOKEN); } return slot;}PK11SlotInfo *PK11_FindSlotBySerial(char *serial){ SECMODModuleList *mlp; SECMODModuleList *modules = SECMOD_GetDefaultModuleList(); SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock(); int i; PK11SlotInfo *slot = NULL; /* work through all the slots */ SECMOD_GetReadLock(moduleLock); for(mlp = modules; mlp != NULL; mlp = mlp->next) { for (i=0; i < mlp->module->slotCount; i++) { PK11SlotInfo *tmpSlot = mlp->module->slots[i]; if (PK11_IsPresent(tmpSlot)) { if (PORT_Memcmp(tmpSlot->serial,serial, sizeof(tmpSlot->serial)) == 0) { slot = PK11_ReferenceSlot(tmpSlot); break; } } } if (slot != NULL) break; } SECMOD_ReleaseReadLock(moduleLock); if (slot == NULL) { PORT_SetError(SEC_ERROR_NO_TOKEN); } return slot;}/*********************************************************** * Password Utilities ***********************************************************//* * Check the user's password. Log into the card if it's correct. * succeed if the user is already logged in. */SECStatuspk11_CheckPassword(PK11SlotInfo *slot,char *pw){ int len = PORT_Strlen(pw); CK_RV crv; SECStatus rv; int64 currtime = PR_Now(); PK11_EnterSlotMonitor(slot); crv = PK11_GETTAB(slot)->C_Login(slot->session,CKU_USER, (unsigned char *)pw,len); PK11_ExitSlotMonitor(slot); switch (crv) { /* if we're already logged in, we're good to go */ case CKR_OK: slot->authTransact = PK11_Global.transaction; case CKR_USER_ALREADY_LOGGED_IN: slot->authTime = currtime; rv = SECSuccess; break; case CKR_PIN_INCORRECT: PORT_SetError(SEC_ERROR_BAD_PASSWORD); rv = SECWouldBlock; /* everything else is ok, only the pin is bad */ break; default: PORT_SetError(PK11_MapError(crv)); rv = SECFailure; /* some failure we can't fix by retrying */ } return rv;}/* * Check the user's password. Logout before hand to make sure that * we are really checking the password. */SECStatusPK11_CheckUserPassword(PK11SlotInfo *slot,char *pw){ int len = PORT_Strlen(pw); CK_RV crv; SECStatus rv; int64 currtime = PR_Now(); /* force a logout */ PK11_EnterSlotMonitor(slot); PK11_GETTAB(slot)->C_Logout(slot->session); crv = PK11_GETTAB(slot)->C_Login(slot->session,CKU_USER, (unsigned char *)pw,len); PK11_ExitSlotMonitor(slot); switch (crv) { /* if we're already logged in, we're good to go */ case CKR_OK: slot->authTransact = PK11_Global.transaction; slot->authTime = currtime; rv = SECSuccess; break; case CKR_PIN_INCORRECT: PORT_SetError(SEC_ERROR_BAD_PASSWORD); rv = SECWouldBlock; /* everything else is ok, only the pin is bad */ break; default: PORT_SetError(PK11_MapError(crv)); rv = SECFailure; /* some failure we can't fix by retrying */ } return rv;}SECStatusPK11_Logout(PK11SlotInfo *slot){ CK_RV crv; /* force a logout */ PK11_EnterSlotMonitor(slot); crv = PK11_GETTAB(slot)->C_Logout(slot->session); PK11_ExitSlotMonitor(slot); if (crv != CKR_OK) { PORT_SetError(PK11_MapError(crv)); return SECFailure; } return SECSuccess;}/* * transaction stuff is for when we test for the need to do every * time auth to see if we already did it for this slot/transaction */void PK11_StartAuthTransaction(void){PK11_Global.transaction++;PK11_Global.inTransaction = PR_TRUE;}void PK11_EndAuthTransaction(void){PK11_Global.transaction++;PK11_Global.inTransaction = PR_FALSE;}/* * before we do a private key op, we check to see if we * need to reauthenticate. */voidPK11_HandlePasswordCheck(PK11SlotInfo *slot,void *wincx){ int askpw = slot->askpw; PRBool NeedAuth = PR_FALSE; if (!slot->needLogin) return; if ((slot->defaultFlags & PK11_OWN_PW_DEFAULTS) == 0) { PK11SlotInfo *def_slot = PK11_GetInternalKeySlot(); if (def_slot) { askpw = def_slot->askpw; PK11_FreeSlot(def_slot); } } /* timeouts are handled by isLoggedIn */ if (!PK11_IsLoggedIn(slot,wincx)) { NeedAuth = PR_TRUE; } else if (slot->askpw == -1) { if (!PK11_Global.inTransaction || (PK11_Global.transaction != slot->authTransact)) { PK11_EnterSlotMonitor(slot); PK11_GETTAB(slot)->C_Logout(slot->session); PK11_ExitSlotMonitor(slot); NeedAuth = PR_TRUE; } } if (NeedAuth) PK11_DoPassword(slot,PR_TRUE,wincx);}voidPK11_SlotDBUpdate(PK11SlotInfo *slot){ SECMOD_AddPermDB(slot->module);}/* * set new askpw and timeout values */voidPK11_SetSlotPWValues(PK11SlotInfo *slot,int askpw, int timeout){ slot->askpw = askpw; slot->timeout = timeout; slot->defaultFlags |= PK11_OWN_PW_DEFAULTS; PK11_SlotDBUpdate(slot);}/* * Get the askpw and timeout values for this slot */voidPK11_GetSlotPWValues(PK11SlotInfo *slot,int *askpw, int *timeout){ *askpw = slot->askpw; *timeout = slot->timeout; if ((slot->defaultFlags & PK11_OWN_PW_DEFAULTS) == 0) { PK11SlotInfo *def_slot = PK11_GetInternalKeySlot(); if (def_slot) { *askpw = def_slot->askpw; *timeout = def_slot->timeout; PK11_FreeSlot(def_slot); } }}/* * make sure a slot is authenticated... */SECStatusPK11_Authenticate(PK11SlotInfo *slot, PRBool loadCerts, void *wincx) { if (slot->needLogin && !PK11_IsLoggedIn(slot,wincx)) { return PK11_DoPassword(slot,loadCerts,wincx); } return SECSuccess;}/* * notification stub. If we ever get interested in any events that * the pkcs11 functions may pass back to use, we can catch them here... * currently pdata is a slotinfo structure. */CK_RV pk11_notify(CK_SESSION_HANDLE session, CK_NOTIFICATION event, CK_VOID_PTR pdata){ return CKR_OK;}/* * grab a new RW session * !!! has a side effect of grabbing the Monitor if either the slot's default * session is RW or the slot is not thread safe. Monitor is release in function * below */CK_SESSION_HANDLE PK11_GetRWSession(PK11SlotInfo *slot){ CK_SESSION_HANDLE rwsession; CK_RV crv; if (!slot->isThreadSafe || slot->defRWSession) PK11_EnterSlotMonitor(slot); if (slot->defRWSession) return slot->session; crv = PK11_GETTAB(slot)->C_OpenSession(slot->slotID, CKF_RW_SESSION|CKF_SERIAL_SESSION, slot, pk11_notify,&rwsession); if (crv == CKR_SESSION_COUNT) { PK11_GETTAB(slot)->C_CloseSession(slot->session); slot->session = CK_INVALID_SESSION; crv = PK11_GETTAB(slot)->C_OpenSession(slot->slotID, CKF_RW_SESSION|CKF_SERIAL_SESSION, slot,pk11_notify,&rwsession); } if (crv != CKR_OK) { PORT_SetError(PK11_MapError(crv)); if (slot->session == CK_INVALID_SESSION) { PK11_GETTAB(slot)->C_OpenSession(slot->slotID,CKF_SERIAL_SESSION, slot,pk11_notify,&slot->session); } if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot); return CK_INVALID_SESSION; } return rwsession;}PRBoolPK11_RWSessionHasLock(PK11SlotInfo *slot,CK_SESSION_HANDLE session_handle) { return (PRBool)(!slot->isThreadSafe || slot->defRWSession);}/* * close the rwsession and restore our readonly session * !!! has a side effect of releasing the Monitor if either the slot's default * session is RW or the slot is not thread safe. */voidPK11_RestoreROSession(PK11SlotInfo *slot,CK_SESSION_HANDLE rwsession){ if (slot->defRWSession) { PK11_ExitSlotMonitor(slot); return; } PK11_GETTAB(slot)->C_CloseSession(rwsession); if (slot->session == CK_INVALID_SESSION) { PK11_GETTAB(slot)->C_OpenSession(slot->slotID,CKF_SERIAL_SESSION, slot,pk11_notify,&slot->session); } if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);}/* * NOTE: this assumes that we are logged out of the card before hand */SECStatusPK11_CheckSSOPassword(PK11SlotInfo *slot, char *ssopw){ CK_SESSION_HANDLE rwsession; CK_RV crv; SECStatus rv = SECFailure; int len = PORT_Strlen(ssopw); /* get a rwsession */ rwsession = PK11_GetRWSession(slot); if (rwsession == CK_INVALID_SESSION) return rv; /* check the password */ crv = PK11_GETTAB(slot)->C_Login(rwsession,CKU_SO, (unsigned char *)ssopw,len); switch (crv) { /* if we're already logged in, we're good to go */ case CKR_OK: rv = SECSuccess; break; case CKR_PIN_INCORRECT: PORT_SetError(SEC_ERROR_BAD_PASSWORD); rv = SECWouldBlock; /* everything else is ok, only the pin is bad */ break; default: PORT_SetError(PK11_MapError(crv)); rv = SECFailure; /* some failure we can't fix by retrying */ } PK11_GETTAB(slot)->C_Logout(rwsession); /* release rwsession */ PK11_RestoreROSession(slot,rwsession); return rv;}/* * make sure the password conforms to your token's requirements. */SECStatusPK11_VerifyPW(PK11SlotInfo *slot,char *pw){ int len = PORT_Strlen(pw); if ((slot->minPassword > len) || (slot->maxPassword < len)) { PORT_SetError(SEC_ERROR_BAD_DATA); return SECFailure; } return SECSuccess;}/* * initialize a user PIN Value */SECStatusPK11_InitPin(PK11SlotInfo *slot,char *ssopw, char *userpw){ CK_SESSION_HANDLE rwsession = CK_INVALID_SESSION; CK_RV crv; SECStatus rv = SECFailure; int len; int ssolen; if (userpw == NULL) userpw = ""; if (ssopw == NULL) ssopw = ""; len = PORT_Strlen(userpw); ssolen = PORT_Strlen(ssopw); /* get a rwsession */ rwsession = PK11_GetRWSession(slot); if (rwsession == CK_INVALID_SESSION) goto done; /* check the password */ crv = PK11_GETTAB(slot)->C_Login(rwsession,CKU_SO, (unsigned char *)ssopw,ssolen); if (crv != CKR_OK) { PORT_SetError(PK11_MapError(crv)); goto done; } crv = PK11_GETTAB(slot)->C_InitPIN(rwsession,(unsigned char *)userpw,len); if (crv != CKR_OK) { PORT_SetError(PK11_MapError(crv)); } else { rv = SECSuccess; }done: PK11_GETTAB(slot)->C_Logout(rwsession); PK11_RestoreROSession(slot,rwsession); if (rv == SECSuccess) { /* update our view of the world */ PK11_InitToken(slot,PR_TRUE); PK11_EnterSlotMonitor(slot); PK11_GETTAB(slot)->C_Login(slot->session,CKU_USER, (unsigned char *)userpw,len);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?