@@ -2872,11 +2872,11 @@ } /* End transaction */ cackey_end_transaction(slot); - if (respcode == 0x6982) { + if (respcode == 0x6982 || respcode == 0x6e00) { CACKEY_DEBUG_PRINTF("Security status not satisified. Returning NEEDLOGIN"); cackey_mark_slot_reset(slot); return(CACKEY_PCSC_E_NEEDLOGIN); @@ -5172,11 +5172,11 @@ CACKEY_DEBUG_PRINTF("Returning CKR_FUNCTION_NOT_SUPPORTED (%i)", CKR_FUNCTION_NOT_SUPPORTED); return(CKR_FUNCTION_NOT_SUPPORTED); } -CK_DEFINE_FUNCTION(CK_RV, C_Login)(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen) { +CK_DEFINE_FUNCTION(CK_RV, _C_LoginMutexArg)(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen, int lock_mutex) { CK_SLOT_ID slotID; FILE *pinfd; char *pincmd, pinbuf[64], *fgets_ret; int mutex_retval; int tries_remaining; @@ -5201,19 +5201,23 @@ CACKEY_DEBUG_PRINTF("Error. We only support USER mode, asked for %lu mode.", (unsigned long) userType) return(CKR_USER_TYPE_INVALID); } - mutex_retval = cackey_mutex_lock(cackey_biglock); - if (mutex_retval != 0) { - CACKEY_DEBUG_PRINTF("Error. Locking failed."); + if (lock_mutex) { + mutex_retval = cackey_mutex_lock(cackey_biglock); + if (mutex_retval != 0) { + CACKEY_DEBUG_PRINTF("Error. Locking failed."); - return(CKR_GENERAL_ERROR); + return(CKR_GENERAL_ERROR); + } } if (!cackey_sessions[hSession].active) { - cackey_mutex_unlock(cackey_biglock); + if (lock_mutex) { + cackey_mutex_unlock(cackey_biglock); + } CACKEY_DEBUG_PRINTF("Error. Session not active."); return(CKR_SESSION_HANDLE_INVALID); } @@ -5220,18 +5224,24 @@ slotID = cackey_sessions[hSession].slotID; if (slotID < 0 || slotID >= (sizeof(cackey_slots) / sizeof(cackey_slots[0]))) { CACKEY_DEBUG_PRINTF("Error. Invalid slot requested (%lu), outside of valid range", slotID); + + if (lock_mutex) { + cackey_mutex_unlock(cackey_biglock); + } return(CKR_GENERAL_ERROR); } if (cackey_slots[slotID].active == 0) { CACKEY_DEBUG_PRINTF("Error. Invalid slot requested (%lu), slot not currently active", slotID); - cackey_mutex_unlock(cackey_biglock); + if (lock_mutex) { + cackey_mutex_unlock(cackey_biglock); + } return(CKR_GENERAL_ERROR); } pincmd = cackey_pin_command; @@ -5244,11 +5254,13 @@ pinfd = popen(pincmd, "r"); if (pinfd == NULL) { CACKEY_DEBUG_PRINTF("Error. %s: Unable to run", pincmd); - cackey_mutex_unlock(cackey_biglock); + if (lock_mutex) { + cackey_mutex_unlock(cackey_biglock); + } CACKEY_DEBUG_PRINTF("Returning CKR_PIN_INCORRECT (%i)", (int) CKR_PIN_INCORRECT); return(CKR_PIN_INCORRECT); } @@ -5260,21 +5272,25 @@ pclose_ret = pclose(pinfd); if (pclose_ret != 0) { CACKEY_DEBUG_PRINTF("Error. %s: exited with non-zero status of %i", pincmd, pclose_ret); - cackey_mutex_unlock(cackey_biglock); + if (lock_mutex) { + cackey_mutex_unlock(cackey_biglock); + } CACKEY_DEBUG_PRINTF("Returning CKR_PIN_INCORRECT (%i)", (int) CKR_PIN_INCORRECT); return(CKR_PIN_INCORRECT); } if (strlen(pinbuf) < 1) { CACKEY_DEBUG_PRINTF("Error. %s: returned no data", pincmd); - cackey_mutex_unlock(cackey_biglock); + if (lock_mutex) { + cackey_mutex_unlock(cackey_biglock); + } CACKEY_DEBUG_PRINTF("Returning CKR_PIN_INCORRECT (%i)", (int) CKR_PIN_INCORRECT); return(CKR_PIN_INCORRECT); } @@ -5287,11 +5303,13 @@ ulPinLen = strlen(pinbuf); } login_ret = cackey_login(&cackey_slots[slotID], pPin, ulPinLen, &tries_remaining); if (login_ret != CACKEY_PCSC_S_OK) { - cackey_mutex_unlock(cackey_biglock); + if (lock_mutex) { + cackey_mutex_unlock(cackey_biglock); + } if (login_ret == CACKEY_PCSC_E_LOCKED) { CACKEY_DEBUG_PRINTF("Error. Token is locked."); cackey_slots[slotID].token_flags |= CKF_USER_PIN_LOCKED; @@ -5320,21 +5338,27 @@ cackey_slots[slotID].token_flags &= ~(CKF_USER_PIN_LOCKED | CKF_USER_PIN_COUNT_LOW | CKF_LOGIN_REQUIRED | CKF_USER_PIN_FINAL_TRY); cackey_sessions[hSession].state = CKS_RO_USER_FUNCTIONS; - mutex_retval = cackey_mutex_unlock(cackey_biglock); - if (mutex_retval != 0) { - CACKEY_DEBUG_PRINTF("Error. Unlocking failed."); + if (lock_mutex) { + mutex_retval = cackey_mutex_unlock(cackey_biglock); + if (mutex_retval != 0) { + CACKEY_DEBUG_PRINTF("Error. Unlocking failed."); - return(CKR_GENERAL_ERROR); + return(CKR_GENERAL_ERROR); + } } CACKEY_DEBUG_PRINTF("Returning CKR_OK (%i)", CKR_OK); return(CKR_OK); } + +CK_DEFINE_FUNCTION(CK_RV, C_Login)(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen) { + return(_C_LoginMutexArg(hSession, userType, pPin, ulPinLen, 1)); +} CK_DEFINE_FUNCTION(CK_RV, C_Logout)(CK_SESSION_HANDLE hSession) { CK_SLOT_ID slotID; int mutex_retval; @@ -6313,11 +6337,11 @@ case CKM_RSA_PKCS: /* Ask card to decrypt */ buflen = cackey_signdecrypt(&cackey_slots[slotID], cackey_sessions[hSession].decrypt_identity, pEncryptedPart, ulEncryptedPartLen, buf, sizeof(buf), 0, 1); if (buflen == CACKEY_PCSC_E_NEEDLOGIN && cackey_pin_command != NULL) { - if (C_Login(hSession, CKU_USER, NULL, 0) == CKR_OK) { + if (_C_LoginMutexArg(hSession, CKU_USER, NULL, 0, 0) == CKR_OK) { buflen = cackey_signdecrypt(&cackey_slots[slotID], cackey_sessions[hSession].decrypt_identity, pEncryptedPart, ulEncryptedPartLen, buf, sizeof(buf), 0, 1); } } if (buflen < 0) { @@ -6830,11 +6854,11 @@ /* Ask card to sign */ CACKEY_DEBUG_PRINTF("Asking to sign from identity %p in session %lu", (void *) cackey_sessions[hSession].sign_identity, (unsigned long) hSession); sigbuflen = cackey_signdecrypt(&cackey_slots[slotID], cackey_sessions[hSession].sign_identity, cackey_sessions[hSession].sign_buf, cackey_sessions[hSession].sign_bufused, sigbuf, sizeof(sigbuf), 1, 0); if (sigbuflen == CACKEY_PCSC_E_NEEDLOGIN && cackey_pin_command != NULL) { - if (C_Login(hSession, CKU_USER, NULL, 0) == CKR_OK) { + if (_C_LoginMutexArg(hSession, CKU_USER, NULL, 0, 0) == CKR_OK) { sigbuflen = cackey_signdecrypt(&cackey_slots[slotID], cackey_sessions[hSession].sign_identity, cackey_sessions[hSession].sign_buf, cackey_sessions[hSession].sign_bufused, sigbuf, sizeof(sigbuf), 1, 0); } } if (sigbuflen < 0) {