@@ -518,10 +518,12 @@ SCARDHANDLE pcsc_card; int transaction_depth; int slot_reset; + + CK_FLAGS token_flags; }; typedef enum { CACKEY_TLV_APP_GENERIC = 0x01, CACKEY_TLV_APP_SKI = 0x02, @@ -2809,10 +2811,11 @@ for (idx = 0; idx < (sizeof(cackey_slots) / sizeof(cackey_slots[0])); idx++) { cackey_slots[idx].active = 0; cackey_slots[idx].pcsc_reader = NULL; cackey_slots[idx].transaction_depth = 0; cackey_slots[idx].slot_reset = 0; + cackey_slots[idx].token_flags = 0; } cackey_initialized = 1; if (!cackey_biglock_init) { @@ -3001,10 +3004,11 @@ cackey_slots[currslot].active = 1; cackey_slots[currslot].pcsc_reader = strdup(pcsc_readers); cackey_slots[currslot].pcsc_card_connected = 0; cackey_slots[currslot].transaction_depth = 0; cackey_slots[currslot].slot_reset = 1; + cackey_slots[currslot].token_flags = CKF_LOGIN_REQUIRED; } currslot++; pcsc_readers += curr_reader_len + 1; } @@ -3226,11 +3230,11 @@ pInfo->hardwareVersion.minor = (cackey_getversion() >> 8) & 0xff; pInfo->firmwareVersion.major = 0x00; pInfo->firmwareVersion.minor = 0x00; - pInfo->flags = CKF_WRITE_PROTECTED | CKF_USER_PIN_INITIALIZED | CKF_TOKEN_INITIALIZED | CKF_LOGIN_REQUIRED; + pInfo->flags = CKF_WRITE_PROTECTED | CKF_USER_PIN_INITIALIZED | CKF_TOKEN_INITIALIZED | cackey_slots[slotID].token_flags; pInfo->ulMaxSessionCount = (sizeof(cackey_sessions) / sizeof(cackey_sessions[0])) - 1; pInfo->ulSessionCount = CK_UNAVAILABLE_INFORMATION; pInfo->ulMaxRwSessionCount = 0; pInfo->ulRwSessionCount = CK_UNAVAILABLE_INFORMATION; @@ -3745,21 +3749,27 @@ cackey_mutex_unlock(cackey_biglock); if (login_ret == CACKEY_PCSC_E_LOCKED) { CACKEY_DEBUG_PRINTF("Error. Token is locked."); + cackey_slots[cackey_sessions[hSession].slotID].token_flags |= CKF_USER_PIN_LOCKED; + return(CKR_PIN_LOCKED); } else if (login_ret == CACKEY_PCSC_E_BADPIN) { CACKEY_DEBUG_PRINTF("Error. Invalid PIN."); + + cackey_slots[cackey_sessions[hSession].slotID].token_flags |= CKF_USER_PIN_COUNT_LOW; return(CKR_PIN_INCORRECT); } CACKEY_DEBUG_PRINTF("Error. Unknown error returned from cackey_login() (%i)", login_ret); return(CKR_GENERAL_ERROR); } + + cackey_slots[cackey_sessions[hSession].slotID].token_flags &= ~(CKF_USER_PIN_LOCKED | CKF_USER_PIN_COUNT_LOW | CKF_LOGIN_REQUIRED); cackey_sessions[hSession].state = CKS_RO_USER_FUNCTIONS; mutex_retval = cackey_mutex_unlock(cackey_biglock); if (mutex_retval != 0) { @@ -4059,10 +4069,11 @@ cackey_sessions[hSession].identities = NULL; cackey_sessions[hSession].identities_count = 0; } cackey_slots[cackey_sessions[hSession].slotID].slot_reset = 0; + cackey_slots[cackey_sessions[hSession].slotID].token_flags = CKF_LOGIN_REQUIRED; } if (cackey_sessions[hSession].identities == NULL) { cackey_sessions[hSession].identities = cackey_read_identities(&cackey_slots[cackey_sessions[hSession].slotID], &cackey_sessions[hSession].identities_count); } @@ -4918,11 +4929,11 @@ cackey_sessions[hSession].sign_bufused += ulPartLen; break; case CKM_SHA1_RSA_PKCS: - /* Accumulate into a SHA1 hash */ + /* XXX: Accumulate into a SHA1 hash */ cackey_mutex_unlock(cackey_biglock); CACKEY_DEBUG_PRINTF("Returning CKR_FUNCTION_NOT_SUPPORTED (%i)", CKR_FUNCTION_NOT_SUPPORTED); return(CKR_FUNCTION_NOT_SUPPORTED); @@ -5021,11 +5032,11 @@ retval = CKR_OK; } break; case CKM_SHA1_RSA_PKCS: - /* Accumulate into a SHA1 hash */ + /* XXX: Accumulate into a SHA1 hash */ cackey_mutex_unlock(cackey_biglock); CACKEY_DEBUG_PRINTF("Returning CKR_FUNCTION_NOT_SUPPORTED (%i)", CKR_FUNCTION_NOT_SUPPORTED); return(CKR_FUNCTION_NOT_SUPPORTED);