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 + -
显示快捷键?