pk11slot.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 2,388 行 · 第 1/5 页

C
2,388
字号
	PK11_ExitSlotMonitor(slot);    }    return rv;}/* * Change an existing user password */SECStatusPK11_ChangePW(PK11SlotInfo *slot,char *oldpw, char *newpw){    CK_RV crv;    SECStatus rv = SECFailure;    int newLen;    int oldLen;    CK_SESSION_HANDLE rwsession;    if (newpw == NULL) newpw = "";    if (oldpw == NULL) oldpw = "";    newLen = PORT_Strlen(newpw);    oldLen = PORT_Strlen(oldpw);    /* get a rwsession */    rwsession = PK11_GetRWSession(slot);    crv = PK11_GETTAB(slot)->C_SetPIN(rwsession,		(unsigned char *)oldpw,oldLen,(unsigned char *)newpw,newLen);    if (crv == CKR_OK) {	rv = SECSuccess;    } else {	PORT_SetError(PK11_MapError(crv));    }    PK11_RestoreROSession(slot,rwsession);    /* update our view of the world */    PK11_InitToken(slot,PR_TRUE);    return rv;}static char *pk11_GetPassword(PK11SlotInfo *slot, PRBool retry, void * wincx){    if (PK11_Global.getPass == NULL) return NULL;    return (*PK11_Global.getPass)(slot, retry, wincx);}voidPK11_SetPasswordFunc(PK11PasswordFunc func){    PK11_Global.getPass = func;}voidPK11_SetVerifyPasswordFunc(PK11VerifyPasswordFunc func){    PK11_Global.verifyPass = func;}voidPK11_SetIsLoggedInFunc(PK11IsLoggedInFunc func){    PK11_Global.isLoggedIn = func;}/* * authenticate to a slot. This loops until we can't recover, the user * gives up, or we succeed. If we're already logged in and this function * is called we will still prompt for a password, but we will probably * succeed no matter what the password was (depending on the implementation * of the PKCS 11 module. */SECStatusPK11_DoPassword(PK11SlotInfo *slot, PRBool loadCerts, void *wincx){    SECStatus rv = SECFailure;    char * password;    PRBool attempt = PR_FALSE;    if (PK11_NeedUserInit(slot)) {	PORT_SetError(SEC_ERROR_IO);	return SECFailure;    }    /*     * Central server type applications which control access to multiple     * slave applications to single crypto devices need to virtuallize the     * login state. This is done by a callback out of PK11_IsLoggedIn and     * here. If we are actually logged in, then we got here because the     * higher level code told us that the particular client application may     * still need to be logged in. If that is the case, we simply tell the     * server code that it should now verify the clients password and tell us     * the results.     */    if (PK11_IsLoggedIn(slot,NULL) &&     			(PK11_Global.verifyPass != NULL)) {	if (!PK11_Global.verifyPass(slot,wincx)) {	    PORT_SetError(SEC_ERROR_BAD_PASSWORD);	    return SECFailure;	}	return SECSuccess;    }    /* get the password. This can drop out of the while loop     * for the following reasons:     * 	(1) the user refused to enter a password.      *			(return error to caller)     *	(2) the token user password is disabled [usually due to     *	   too many failed authentication attempts].     *			(return error to caller)     *	(3) the password was successful.     */    while ((password = pk11_GetPassword(slot, attempt, wincx)) != NULL) {	attempt = PR_TRUE;	rv = pk11_CheckPassword(slot,password);	PORT_Memset(password, 0, PORT_Strlen(password));	PORT_Free(password);	if (rv != SECWouldBlock) break;    }    if (rv == SECSuccess) {	if ((loadCerts) && (!slot->isInternal) && (slot->cert_count == 0)) {	    PK11_ReadSlotCerts(slot);	}	rv = pk11_CheckVerifyTest(slot);    } else if (!attempt) PORT_SetError(SEC_ERROR_BAD_PASSWORD);    return rv;}void PK11_LogoutAll(void){    SECMODListLock *lock = SECMOD_GetDefaultModuleListLock();    SECMODModuleList *modList = SECMOD_GetDefaultModuleList();    SECMODModuleList *mlp = NULL;    int i;    SECMOD_GetReadLock(lock);    /* find the number of entries */    for (mlp = modList; mlp != NULL; mlp = mlp->next) {	for (i=0; i < mlp->module->slotCount; i++) {	    PK11_Logout(mlp->module->slots[i]);	}    }    SECMOD_ReleaseReadLock(lock);}intPK11_GetMinimumPwdLength(PK11SlotInfo *slot){    return ((int)slot->minPassword);}/************************************************************ * Manage the built-In Slot Lists ************************************************************//* Init the static built int slot list (should actually integrate * with PK11_NewSlotList */static voidpk11_initSlotList(PK11SlotList *list){#ifdef PKCS11_USE_THREADS    list->lock = PR_NewLock();#else    list->lock = NULL;#endif    list->head = NULL;}/* initialize the system slotlists */SECStatusPK11_InitSlotLists(void){    pk11_initSlotList(&pk11_desSlotList);    pk11_initSlotList(&pk11_rc4SlotList);    pk11_initSlotList(&pk11_rc2SlotList);    pk11_initSlotList(&pk11_rc5SlotList);    pk11_initSlotList(&pk11_md5SlotList);    pk11_initSlotList(&pk11_md2SlotList);    pk11_initSlotList(&pk11_sha1SlotList);    pk11_initSlotList(&pk11_rsaSlotList);    pk11_initSlotList(&pk11_dsaSlotList);    pk11_initSlotList(&pk11_dhSlotList);    pk11_initSlotList(&pk11_ideaSlotList);    pk11_initSlotList(&pk11_sslSlotList);    pk11_initSlotList(&pk11_tlsSlotList);    pk11_initSlotList(&pk11_randomSlotList);    return SECSuccess;}/* return a system slot list based on mechanism */PK11SlotList *PK11_GetSlotList(CK_MECHANISM_TYPE type){/* XXX a workaround for Bugzilla bug #55267 */#if defined(HPUX) && defined(__LP64__)    if (CKM_INVALID_MECHANISM == type)        return NULL;#endif    switch (type) {    case CKM_DES_CBC:    case CKM_DES_ECB:    case CKM_DES3_ECB:    case CKM_DES3_CBC:	return &pk11_desSlotList;    case CKM_RC4:	return &pk11_rc4SlotList;    case CKM_RC5_CBC:	return &pk11_rc5SlotList;    case CKM_SHA_1:	return &pk11_sha1SlotList;    case CKM_MD5:	return &pk11_md5SlotList;    case CKM_MD2:	return &pk11_md2SlotList;    case CKM_RC2_ECB:    case CKM_RC2_CBC:	return &pk11_rc2SlotList;    case CKM_RSA_PKCS:    case CKM_RSA_PKCS_KEY_PAIR_GEN:    case CKM_RSA_X_509:	return &pk11_rsaSlotList;    case CKM_DSA:	return &pk11_dsaSlotList;    case CKM_DH_PKCS_KEY_PAIR_GEN:    case CKM_DH_PKCS_DERIVE:	return &pk11_dhSlotList;    case CKM_SSL3_PRE_MASTER_KEY_GEN:    case CKM_SSL3_MASTER_KEY_DERIVE:    case CKM_SSL3_SHA1_MAC:    case CKM_SSL3_MD5_MAC:	return &pk11_sslSlotList;    case CKM_TLS_MASTER_KEY_DERIVE:    case CKM_TLS_KEY_AND_MAC_DERIVE:	return &pk11_tlsSlotList;    case CKM_IDEA_CBC:    case CKM_IDEA_ECB:	return &pk11_ideaSlotList;    case CKM_FAKE_RANDOM:	return &pk11_randomSlotList;    }    return NULL;}/* * load the static SlotInfo structures used to select a PKCS11 slot. * preSlotInfo has a list of all the default flags for the slots on this * module. */voidPK11_LoadSlotList(PK11SlotInfo *slot, PK11PreSlotInfo *psi, int count){    int i;    for (i=0; i < count; i++) {	if (psi[i].slotID == slot->slotID)	    break;    }    if (i == count) return;    slot->defaultFlags = psi[i].defaultFlags;    slot->askpw = psi[i].askpw;    slot->timeout = psi[i].timeout;    slot->hasRootCerts = psi[i].hasRootCerts;    /* if the slot is already disabled, don't load them into the     * default slot lists. We get here so we can save the default     * list value. */    if (slot->disabled) return;    /* if the user has disabled us, don't load us in */    if (slot->defaultFlags & PK11_DISABLE_FLAG) {	slot->disabled = PR_TRUE;	slot->reason = PK11_DIS_USER_SELECTED;	/* free up sessions and things?? */	return;    }    for (i=0; i < sizeof(PK11_DefaultArray)/sizeof(PK11_DefaultArray[0]);								i++) {	if (slot->defaultFlags & PK11_DefaultArray[i].flag) {	    CK_MECHANISM_TYPE mechanism = PK11_DefaultArray[i].mechanism;	    PK11SlotList *slotList = PK11_GetSlotList(mechanism);	    if (slotList) PK11_AddSlotToList(slotList,slot);	}    }    return;}/* * update a slot to its new attribute according to the slot list * returns: SECSuccess if nothing to do or add/delete is successful */SECStatusPK11_UpdateSlotAttribute(PK11SlotInfo *slot, PK11DefaultArrayEntry *entry,                        PRBool add)                          /* add: PR_TRUE if want to turn on */{    SECStatus result = SECSuccess;    PK11SlotList *slotList = PK11_GetSlotList(entry->mechanism);    if (add) { /* trying to turn on a mechanism */                         /* turn on the default flag in the slot */        slot->defaultFlags |= entry->flag;                /* add this slot to the list */        if (slotList!=NULL)            result = PK11_AddSlotToList(slotList, slot);            } else { /* trying to turn off */                    /* turn OFF the flag in the slot */         slot->defaultFlags &= ~entry->flag;                if (slotList) {            /* find the element in the list & delete it */            PK11SlotListElement *le = PK11_FindSlotElement(slotList, slot);            /* remove the slot from the list */            if (le)                result = PK11_DeleteSlotFromList(slotList, le);        }    }    return result;}/* * clear a slot off of all of it's default list */voidPK11_ClearSlotList(PK11SlotInfo *slot){    int i;    if (slot->disabled) return;    if (slot->defaultFlags == 0) return;    for (i=0; i < sizeof(PK11_DefaultArray)/sizeof(PK11_DefaultArray[0]);								i++) {	if (slot->defaultFlags & PK11_DefaultArray[i].flag) {	    CK_MECHANISM_TYPE mechanism = PK11_DefaultArray[i].mechanism;	    PK11SlotList *slotList = PK11_GetSlotList(mechanism);	    PK11SlotListElement *le = NULL;	    if (slotList) le = PK11_FindSlotElement(slotList,slot);	    if (le) {		PK11_DeleteSlotFromList(slotList,le);		pk11_FreeListElement(slotList,le);	    }	}    }}/****************************************************************** *           Slot initialization ******************************************************************//* * turn a PKCS11 Static Label into a string */char *PK11_MakeString(PRArenaPool *arena,char *space,					char *staticString,int stringLen){	int i;	char *newString;	for(i=(stringLen-1); i >= 0; i--) {	  if (staticString[i] != ' ') break;	}	/* move i to point to the last space */	i++;	if (arena) {	    newString = (char*)PORT_ArenaAlloc(arena,i+1 /* space for NULL */);	} else if (space) {	    newString = space;	} else {	    newString = (char*)PORT_Alloc(i+1 /* space for NULL */);	}	if (newString == NULL) return NULL;	if (i) PORT_Memcpy(newString,staticString, i);	newString[i] = 0;	return newString;}/* * verify that slot implements Mechanism mech properly by checking against * our internal implementation */PRBoolPK11_VerifyMechanism(PK11SlotInfo *slot,PK11SlotInfo *intern,  CK_MECHANISM_TYPE mech, SECItem *data, SECItem *iv){    PK11Context *test = NULL, *reference = NULL;    PK11SymKey *symKey = NULL, *testKey = NULL;    SECItem *param = NULL;    unsigned char encTest[8];    unsigned char encRef[8];    int outLenTest,outLenRef;    int key_size = 0;    SECStatus rv;    if ((mech == CKM_RC2_CBC) || (mech == CKM_RC2_ECB) || (mech == CKM_RC4)) {	key_size = 16;    }    /* initialize the mechanism parameter */    param = PK11_ParamFromIV(mech,iv);    if (param == NULL) goto loser;    /* load the keys and contexts */    symKey = PK11_KeyGen(intern,mech,NULL, key_size, NULL);    if (symKey == NULL) goto loser;    reference = PK11_CreateContextBySymKey(mech, CKA_ENCRYPT, symKey, param);    if (reference == NULL) goto loser;    testKey = pk11_CopyToSlot(slot, mech, CKA_ENCRYPT, symKey);    if (testKey == NULL) goto loser;    test = PK11_CreateContextBySymKey(mech, CKA_ENCRYPT, testKey, param);    if (test == NULL) goto loser;    SECITEM_FreeItem(param,PR_TRUE); param = NULL;    /* encrypt the test data */    rv = PK11_CipherOp(test,encTest,&outLenTest,sizeof(encTest),							data->data,data->len);    if (rv != SECSuccess) goto loser;    rv = PK11_CipherOp(reference,encRef,&outLenRef,sizeof(encRef),							data->data,data->len);    if (rv != SECSuccess) goto loser;    PK11_DestroyContext(reference,PR_TRUE); reference = NULL;    PK11_DestroyContext(test,PR_TRUE); test = NULL;    if (outLenTest != outLenRef) goto loser;    if (PORT_Memcmp(encTest, encRef, outLenTest) != 0) goto loser;    return PR_TRUE;loser:    if (test) PK11_DestroyContext(test,PR_TRUE);    if (symKey) PK11_FreeSymKey(symKey);    if (testKey) PK11_FreeSymKey(testKey);    if (reference) PK11_DestroyContext(reference,PR_TRUE);    if (param) SECITEM_FreeItem(param,PR_TRUE);    return PR_FALSE;}/* * this code verifies that the advertised mechanisms are what they * seem to be. */#define MAX_MECH_LIST_SIZE 30	/* we only know of about 30 odd mechanisms */PRBoolPK11_VerifySlotMechanisms(PK11SlotInfo *slot){    CK_MECHANISM_TYPE mechListArray[MAX_MECH_LIST_SIZE];    CK_MECHANISM_TYPE *mechList = mechListArray;    static SECItem data;    static SECItem iv;    static SECItem key;    static unsigned char dataV[8];    static unsigned char ivV[8];    static unsigned char keyV[8];    static PRBool generated = PR_FALSE;    CK_ULONG count;    int i;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?