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