pk11slot.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 2,388 行 · 第 1/5 页
C
2,388 行
}PRBool PK11_HasRootCerts(PK11SlotInfo *slot) { return slot->hasRootCerts;}/* Get the module this slot is attatched to */SECMODModule *PK11_GetModule(PK11SlotInfo *slot){ return slot->module;}/* returnt the default flags of a slot */unsigned longPK11_GetDefaultFlags(PK11SlotInfo *slot){ return slot->defaultFlags;}/* * we can initialize the password if 1) The toke is not inited * (need login == true and see need UserInit) or 2) the token has * a NULL password. (slot->needLogin = false & need user Init = false). */PRBool PK11_NeedPWInitForSlot(PK11SlotInfo *slot){ if (slot->needLogin && PK11_NeedUserInit(slot)) { return PR_TRUE; } if (!slot->needLogin && !PK11_NeedUserInit(slot)) { return PR_TRUE; } return PR_FALSE;}PRBool PK11_NeedPWInit(){ PK11SlotInfo *slot = PK11_GetInternalKeySlot(); PRBool ret = PK11_NeedPWInitForSlot(slot); PK11_FreeSlot(slot); return ret;}/* * The following wrapper functions allow us to export an opaque slot * function to the rest of libsec and the world... */PRBoolPK11_IsReadOnly(PK11SlotInfo *slot){ return slot->readOnly;}PRBoolPK11_IsHW(PK11SlotInfo *slot){ return slot->isHW;}PRBoolPK11_IsInternal(PK11SlotInfo *slot){ return slot->isInternal;}PRBoolPK11_NeedLogin(PK11SlotInfo *slot){ return slot->needLogin;}PRBoolPK11_IsFriendly(PK11SlotInfo *slot){ /* internal slot always has public readable certs */ return (PRBool)(slot->isInternal || ((slot->defaultFlags & SECMOD_FRIENDLY_FLAG) == SECMOD_FRIENDLY_FLAG));}char *PK11_GetTokenName(PK11SlotInfo *slot){ return slot->token_name;}char *PK11_GetSlotName(PK11SlotInfo *slot){ return slot->slot_name;}intPK11_GetSlotSeries(PK11SlotInfo *slot){ return slot->series;}intPK11_GetCurrentWrapIndex(PK11SlotInfo *slot){ return slot->wrapKey;}CK_SLOT_IDPK11_GetSlotID(PK11SlotInfo *slot){ return slot->slotID;}SECMODModuleIDPK11_GetModuleID(PK11SlotInfo *slot){ return slot->module->moduleID;}/* return the slot info structure */SECStatusPK11_GetSlotInfo(PK11SlotInfo *slot, CK_SLOT_INFO *info){ CK_RV crv; if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot); crv = PK11_GETTAB(slot)->C_GetSlotInfo(slot->slotID,info); if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot); if (crv != CKR_OK) { PORT_SetError(PK11_MapError(crv)); return SECFailure; } return SECSuccess;}/* return the token info structure */SECStatusPK11_GetTokenInfo(PK11SlotInfo *slot, CK_TOKEN_INFO *info){ CK_RV crv; if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot); crv = PK11_GETTAB(slot)->C_GetTokenInfo(slot->slotID,info); if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot); if (crv != CKR_OK) { PORT_SetError(PK11_MapError(crv)); return SECFailure; } return SECSuccess;}/* Find out if we need to initialize the user's pin */PRBoolPK11_NeedUserInit(PK11SlotInfo *slot){ return (PRBool)((slot->flags & CKF_USER_PIN_INITIALIZED) == 0);}/* get the internal key slot. FIPS has only one slot for both key slots and * default slots */PK11SlotInfo *PK11_GetInternalKeySlot(void){ SECMODModule *mod = SECMOD_GetInternalModule(); return PK11_ReferenceSlot(mod->isFIPS ? mod->slots[0] : mod->slots[1]);}/* get the internal default slot */PK11SlotInfo *PK11_GetInternalSlot(void) { return PK11_ReferenceSlot(SECMOD_GetInternalModule()->slots[0]);}/* * Determine if the token is logged in. We have to actually query the token, * because it's state can change without intervention from us. */PRBoolPK11_IsLoggedIn(PK11SlotInfo *slot,void *wincx){ CK_SESSION_INFO sessionInfo; int askpw = slot->askpw; int timeout = slot->timeout; CK_RV crv; /* If we don't have our own password default values, use the system * ones */ 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); } } if ((wincx != NULL) && (PK11_Global.isLoggedIn != NULL) && (*PK11_Global.isLoggedIn)(slot, wincx) == PR_FALSE) { return PR_FALSE; } /* forget the password if we've been inactive too long */ if (askpw == 1) { int64 currtime = PR_Now(); int64 result; int64 mult; LL_I2L(result, timeout); LL_I2L(mult, 60*1000*1000); LL_MUL(result,result,mult); LL_ADD(result, result, slot->authTime); if (LL_CMP(result, <, currtime) ) { PK11_EnterSlotMonitor(slot); PK11_GETTAB(slot)->C_Logout(slot->session); PK11_ExitSlotMonitor(slot); } else { slot->authTime = currtime; } } PK11_EnterSlotMonitor(slot); crv = PK11_GETTAB(slot)->C_GetSessionInfo(slot->session,&sessionInfo); PK11_ExitSlotMonitor(slot); /* if we can't get session info, something is really wrong */ if (crv != CKR_OK) { slot->session = CK_INVALID_SESSION; return PR_FALSE; } switch (sessionInfo.state) { case CKS_RW_PUBLIC_SESSION: case CKS_RO_PUBLIC_SESSION: default: break; /* fail */ case CKS_RW_USER_FUNCTIONS: case CKS_RW_SO_FUNCTIONS: case CKS_RO_USER_FUNCTIONS: return PR_TRUE; } return PR_FALSE; }/* * check if a given slot supports the requested mechanism */PRBoolPK11_DoesMechanism(PK11SlotInfo *slot, CK_MECHANISM_TYPE type){ int i; /* CKM_FAKE_RANDOM is not a real PKCS mechanism. It's a marker to * tell us we're looking form someone that has implemented get * random bits */ if (type == CKM_FAKE_RANDOM) { return slot->hasRandom; } for (i=0; i < (int) slot->mechanismCount; i++) { if (slot->mechanismList[i] == type) return PR_TRUE; } return PR_FALSE;}/* * Return true if a token that can do the desired mechanism exists. * This allows us to have hardware tokens that can do function XYZ magically * allow SSL Ciphers to appear if they are plugged in. */PRBoolPK11_TokenExists(CK_MECHANISM_TYPE type){ SECMODModuleList *mlp; SECMODModuleList *modules = SECMOD_GetDefaultModuleList(); SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock(); PK11SlotInfo *slot; PRBool found = PR_FALSE; int i; /* we only need to know if there is a token that does this mechanism. * check the internal module first because it's fast, and supports * almost everything. */ slot = PK11_GetInternalSlot(); if (slot) { found = PK11_DoesMechanism(slot,type); PK11_FreeSlot(slot); } if (found) return PR_TRUE; /* bypass getting module locks */ SECMOD_GetReadLock(moduleLock); for(mlp = modules; mlp != NULL && (!found); mlp = mlp->next) { for (i=0; i < mlp->module->slotCount; i++) { slot = mlp->module->slots[i]; if (PK11_IsPresent(slot)) { if (PK11_DoesMechanism(slot,type)) { found = PR_TRUE; break; } } } } SECMOD_ReleaseReadLock(moduleLock); return found;}/* * get all the currently available tokens in a list. * that can perform the given mechanism. If mechanism is CKM_INVALID_MECHANISM, * get all the tokens. Make sure tokens that need authentication are put at * the end of this list. */PK11SlotList *PK11_GetAllTokens(CK_MECHANISM_TYPE type, PRBool needRW, PRBool loadCerts, void *wincx){ PK11SlotList * list = PK11_NewSlotList(); PK11SlotList * loginList = PK11_NewSlotList(); PK11SlotList * friendlyList = PK11_NewSlotList(); SECMODModuleList * mlp; SECMODModuleList * modules = SECMOD_GetDefaultModuleList(); SECMODListLock * moduleLock = SECMOD_GetDefaultModuleListLock(); int i;#if defined( XP_WIN32 ) int j = 0; PRInt32 waste[16];#endif if ((list == NULL) || (loginList == NULL) || (friendlyList == NULL)) { if (list) PK11_FreeSlotList(list); if (loginList) PK11_FreeSlotList(loginList); if (friendlyList) PK11_FreeSlotList(friendlyList); return NULL; } SECMOD_GetReadLock(moduleLock); for(mlp = modules; mlp != NULL; mlp = mlp->next) {#if defined( XP_WIN32 ) /* This is works around some horrible cache/page thrashing problems ** on Win32. Without this, this loop can take up to 6 seconds at ** 100% CPU on a Pentium-Pro 200. The thing this changes is to ** increase the size of the stack frame and modify it. ** Moving the loop code itself seems to have no effect. ** Dunno why this combination makes a difference, but it does. */ waste[ j & 0xf] = j++; #endif for (i = 0; i < mlp->module->slotCount; i++) { PK11SlotInfo *slot = mlp->module->slots[i]; if (pk11_IsPresentCertLoad(slot, loadCerts)) { if (needRW && slot->readOnly) continue; if ((type == CKM_INVALID_MECHANISM) || PK11_DoesMechanism(slot, type)) { if (slot->needLogin && !PK11_IsLoggedIn(slot, wincx)) { if (PK11_IsFriendly(slot)) { PK11_AddSlotToList(friendlyList, slot); } else { PK11_AddSlotToList(loginList, slot); } } else { PK11_AddSlotToList(list, slot); } } } } } SECMOD_ReleaseReadLock(moduleLock); PK11_MoveListToList(list,friendlyList); PK11_FreeSlotList(friendlyList); PK11_MoveListToList(list,loginList); PK11_FreeSlotList(loginList); return list;}/* * NOTE: This routine is working from a private List generated by * PK11_GetAllTokens. That is why it does not need to lock. */PK11SlotList *PK11_GetPrivateKeyTokens(CK_MECHANISM_TYPE type,PRBool needRW,void *wincx){ PK11SlotList *list = PK11_GetAllTokens(type,needRW,PR_TRUE,wincx); PK11SlotListElement *le, *next ; SECStatus rv; if (list == NULL) return list; for (le = list->head ; le; le = next) { next = le->next; /* save the pointer here in case we have to * free the element later */ rv = PK11_Authenticate(le->slot,PR_TRUE,wincx); if (rv != SECSuccess) { PK11_DeleteSlotFromList(list,le); continue; } } return list;}/* * find the best slot which supports the given * Mechanism. In normal cases this should grab the first slot on the list * with no fuss. */PK11SlotInfo *PK11_GetBestSlotMultiple(CK_MECHANISM_TYPE *type, int mech_count, void *wincx){ PK11SlotList *list = NULL; PK11SlotListElement *le ; PK11SlotInfo *slot = NULL; PRBool freeit = PR_FALSE; PRBool listNeedLogin = PR_FALSE; int i; SECStatus rv; list = PK11_GetSlotList(type[0]); if ((list == NULL) || (list->head == NULL)) { /* We need to look up all the tokens for the mechanism */ list = PK11_GetAllTokens(type[0],PR_FALSE,PR_TRUE,wincx); freeit = PR_TRUE; } /* no one can do it! */ if (list == NULL) { PORT_SetError(SEC_ERROR_NO_TOKEN); return NULL; } PORT_SetError(0); listNeedLogin = PR_FALSE; for (i=0; i < mech_count; i++) { if ((type[i] != CKM_FAKE_RANDOM) && (type[i] != CKM_SHA_1) && (type[i] != CKM_MD5) && (type[i] != CKM_MD2)) { listNeedLogin = PR_TRUE; break; } } for (le = PK11_GetFirstSafe(list); le; le = PK11_GetNextSafe(list,le,PR_TRUE)) { if (PK11_IsPresent(le->slot)) { PRBool doExit = PR_FALSE; for (i=0; i < mech_count; i++) { if (!PK11_DoesMechanism(le->slot,type[i])) { doExit = PR_TRUE; break; } } if (doExit) continue; if (listNeedLogin && le->slot->needLogin) { rv = PK11_Authenticate(le->slot,PR_TRUE,wincx); if (rv != SECSuccess) continue; } slot = le->slot; PK11_ReferenceSlot(slot); pk11_FreeListElement(list,le); if (freeit) { PK11_FreeSlotList(list); } return slot; } } if (freeit) { PK11_FreeSlotList(list); } if (PORT_GetError() == 0) { PORT_SetError(SEC_ERROR_NO_TOKEN); } return NULL;}/* original get best slot now calls the multip
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?