Overview
Comment: | Updated to retry APDU in some cases
Updated to recognize when a card is logged out without being switched |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: | 9b8b8e3b4ad44774d04ca207013ae14af26833dc |
User & Date: | rkeene on 2010-05-23 02:59:54 |
Other Links: | manifest | tags |
Context
2010-05-23
| ||
03:42 |
Updated to retry if got NOT_TRANSACTED
Fixed issue with retry in APDU transmit check-in: 7cc9fb64cc user: rkeene tags: trunk | |
02:59 |
Updated to retry APDU in some cases
Updated to recognize when a card is logged out without being switched check-in: 9b8b8e3b4a user: rkeene tags: trunk | |
2010-05-22
| ||
21:31 |
Updated to set LOGIN_REQUIRED flag when C_Logout is called
Updated to check all references to a session's slot check-in: a08de24384 user: rkeene tags: trunk | |
Changes
Modified cackey.c from [26bb9837f1] to [6811fa6136].
549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 .... 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 .... 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 .... 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 .... 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 .... 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 .... 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 .... 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 |
CACKEY_TLV_OBJID_CAC_BENEFITS = 0x0202, CACKEY_TLV_OBJID_CAC_OTHERBENEFITS = 0x0203, CACKEY_TLV_OBJID_CAC_PERSONNEL = 0x0201, CACKEY_TLV_OBJID_CAC_PKICERT = 0x02FE } cackey_tlv_objectid; typedef enum { CACKEY_PCSC_S_TOKENPRESENT = 2, CACKEY_PCSC_S_TOKENABSENT = 1, CACKEY_PCSC_S_OK = 0, CACKEY_PCSC_E_GENERIC = -1, CACKEY_PCSC_E_BADPIN = -2, CACKEY_PCSC_E_LOCKED = -3, } cackey_ret; struct cackey_tlv_cardurl { unsigned char rid[5]; cackey_tlv_apptype apptype; cackey_tlv_objectid objectid; cackey_tlv_objectid appid; ................................................................................ CACKEY_DEBUG_PRINTF("Sending APDU: <<censored>>"); } else { CACKEY_DEBUG_PRINTBUF("Sending APDU:", xmit_buf, xmit_len); } recv_len = sizeof(recv_buf); scard_xmit_ret = SCardTransmit(slot->pcsc_card, SCARD_PCI_T0, xmit_buf, xmit_len, SCARD_PCI_T1, recv_buf, &recv_len); if (scard_xmit_ret != SCARD_S_SUCCESS) { CACKEY_DEBUG_PRINTF("Failed to send APDU to card (SCardTransmit() = %s/%lx)", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_xmit_ret), (unsigned long) scard_xmit_ret); CACKEY_DEBUG_PRINTF("Marking slot as having been reset"); slot->transaction_depth = 0; slot->slot_reset = 1; ................................................................................ SCardDisconnect(slot->pcsc_card, SCARD_RESET_CARD); slot->pcsc_card_connected = 0; /* End Smartcard Transaction */ slot->transaction_depth = 1; cackey_end_transaction(slot); return(CACKEY_PCSC_E_GENERIC); } } else { CACKEY_DEBUG_PRINTF("Disconnecting card"); SCardDisconnect(slot->pcsc_card, SCARD_RESET_CARD); slot->pcsc_card_connected = 0; /* End Smartcard Transaction */ slot->transaction_depth = 1; cackey_end_transaction(slot); CACKEY_DEBUG_PRINTF("Returning in failure"); return(CACKEY_PCSC_E_GENERIC); } } else { CACKEY_DEBUG_PRINTF("Disconnecting card"); SCardDisconnect(slot->pcsc_card, SCARD_RESET_CARD); slot->pcsc_card_connected = 0; /* End Smartcard Transaction */ slot->transaction_depth = 1; cackey_end_transaction(slot); CACKEY_DEBUG_PRINTF("Returning in failure"); return(CACKEY_PCSC_E_GENERIC); } } CACKEY_DEBUG_PRINTBUF("Returned Value:", recv_buf, recv_len); if (recv_len < 2) { /* Minimal response length is 2 bytes, returning in failure */ ................................................................................ tmpoutbuflen = outbuflen; send_ret = cackey_send_apdu(slot, GSCIS_CLASS_GLOBAL_PLATFORM, GSCIS_INSTR_SIGNDECRYPT, p1, 0x00, bytes_to_send, tmpbuf, le, &respcode, outbuf, &tmpoutbuflen); if (send_ret != CACKEY_PCSC_S_OK) { CACKEY_DEBUG_PRINTF("ADPU Sending Failed -- returning in error."); if (respcode == 0x6982) { CACKEY_DEBUG_PRINTF("Security status not satisified."); } if (free_tmpbuf) { if (tmpbuf_s) { free(tmpbuf_s); } } /* End transaction */ cackey_end_transaction(slot); return(-1); } tmpbuf += bytes_to_send; tmpbuflen -= bytes_to_send; ................................................................................ CACKEY_DEBUG_PRINTF("Called."); pcsc_connect_ret = cackey_connect_card(slot); if (pcsc_connect_ret != CACKEY_PCSC_S_OK) { CACKEY_DEBUG_PRINTF("Unable to connect to card, returning token absent"); return(CACKEY_PCSC_S_TOKENABSENT); } atr_len = sizeof(atr); status_ret = SCardStatus(slot->pcsc_card, NULL, &reader_len, &state, &protocol, atr, &atr_len); if (status_ret != SCARD_S_SUCCESS) { slot->slot_reset = 1; slot->token_flags = CKF_LOGIN_REQUIRED; ................................................................................ } CACKEY_DEBUG_PRINTF("Reset successful, requerying"); status_ret = SCardStatus(slot->pcsc_card, NULL, &reader_len, &state, &protocol, atr, &atr_len); if (status_ret != SCARD_S_SUCCESS) { CACKEY_DEBUG_PRINTF("Still unable to query card status, returning token absent. SCardStatus() = %s", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(status_ret)); return(CACKEY_PCSC_S_TOKENABSENT); } } else { CACKEY_DEBUG_PRINTF("Unable to reconnect to card, returning token absent. SCardReconnect() = %s", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_reconn_ret)); return(CACKEY_PCSC_S_TOKENABSENT); } } else { CACKEY_DEBUG_PRINTF("Unable to query card status, returning token absent. SCardStatus() = %s", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(status_ret)); return(CACKEY_PCSC_S_TOKENABSENT); } } if ((state & SCARD_ABSENT) == SCARD_ABSENT) { CACKEY_DEBUG_PRINTF("Card is absent, returning token absent"); return(CACKEY_PCSC_S_TOKENABSENT); } CACKEY_DEBUG_PRINTF("Returning token present."); return(CACKEY_PCSC_S_TOKENPRESENT); } ................................................................................ switch (cackey_sessions[hSession].decrypt_mechanism) { 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 < 0) { /* Decryption failed. */ retval = CKR_GENERAL_ERROR; } else if (((unsigned long) buflen) > *pulPartLen && pPart) { /* Decrypted data too large */ retval = CKR_BUFFER_TOO_SMALL; } else { if (pPart) { memcpy(pPart, buf, buflen); } ................................................................................ case CKM_RSA_PKCS: /* Ask card to sign */ CACKEY_DEBUG_PRINTF("Asking to sign from identity %p in session %lu", 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 < 0) { /* Signing failed. */ retval = CKR_GENERAL_ERROR; } else if (((unsigned long) sigbuflen) > *pulSignatureLen && pSignature) { /* Signed data too large */ CACKEY_DEBUG_PRINTF("retval = CKR_BUFFER_TOO_SMALL; sigbuflen = %lu, pulSignatureLen = %lu", (unsigned long) sigbuflen, (unsigned long) *pulSignatureLen); retval = CKR_BUFFER_TOO_SMALL; terminate_sign = 0; |
| < > > > > > > > | | | < < < < > > > > > > > > > > > > > > > > > > | | | | | > > > > > | > > > > > > | > |
549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 .... 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 .... 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 .... 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 .... 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 .... 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 .... 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 .... 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 5315 5316 5317 5318 5319 5320 |
CACKEY_TLV_OBJID_CAC_BENEFITS = 0x0202, CACKEY_TLV_OBJID_CAC_OTHERBENEFITS = 0x0203, CACKEY_TLV_OBJID_CAC_PERSONNEL = 0x0201, CACKEY_TLV_OBJID_CAC_PKICERT = 0x02FE } cackey_tlv_objectid; typedef enum { CACKEY_PCSC_S_TOKENPRESENT = 1, CACKEY_PCSC_S_OK = 0, CACKEY_PCSC_E_GENERIC = -1, CACKEY_PCSC_E_BADPIN = -2, CACKEY_PCSC_E_LOCKED = -3, CACKEY_PCSC_E_NEEDLOGIN = -4, CACKEY_PCSC_E_TOKENABSENT = -6, } cackey_ret; struct cackey_tlv_cardurl { unsigned char rid[5]; cackey_tlv_apptype apptype; cackey_tlv_objectid objectid; cackey_tlv_objectid appid; ................................................................................ CACKEY_DEBUG_PRINTF("Sending APDU: <<censored>>"); } else { CACKEY_DEBUG_PRINTBUF("Sending APDU:", xmit_buf, xmit_len); } recv_len = sizeof(recv_buf); scard_xmit_ret = SCardTransmit(slot->pcsc_card, SCARD_PCI_T0, xmit_buf, xmit_len, SCARD_PCI_T1, recv_buf, &recv_len); if (scard_xmit_ret == SCARD_E_NOT_TRANSACTED) { CACKEY_DEBUG_PRINTF("Failed to send APDU to card (SCardTransmit() = SCARD_E_NOT_TRANSACTED), retrying..."); scard_xmit_ret = SCardTransmit(slot->pcsc_card, SCARD_PCI_T0, xmit_buf, xmit_len, SCARD_PCI_T1, recv_buf, &recv_len); } if (scard_xmit_ret != SCARD_S_SUCCESS) { CACKEY_DEBUG_PRINTF("Failed to send APDU to card (SCardTransmit() = %s/%lx)", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_xmit_ret), (unsigned long) scard_xmit_ret); CACKEY_DEBUG_PRINTF("Marking slot as having been reset"); slot->transaction_depth = 0; slot->slot_reset = 1; ................................................................................ SCardDisconnect(slot->pcsc_card, SCARD_RESET_CARD); slot->pcsc_card_connected = 0; /* End Smartcard Transaction */ slot->transaction_depth = 1; cackey_end_transaction(slot); return(CACKEY_PCSC_E_TOKENABSENT); } } else { CACKEY_DEBUG_PRINTF("Disconnecting card"); SCardDisconnect(slot->pcsc_card, SCARD_RESET_CARD); slot->pcsc_card_connected = 0; /* End Smartcard Transaction */ slot->transaction_depth = 1; cackey_end_transaction(slot); CACKEY_DEBUG_PRINTF("Returning in failure"); return(CACKEY_PCSC_E_TOKENABSENT); } } else { CACKEY_DEBUG_PRINTF("Disconnecting card"); SCardDisconnect(slot->pcsc_card, SCARD_RESET_CARD); slot->pcsc_card_connected = 0; /* End Smartcard Transaction */ slot->transaction_depth = 1; cackey_end_transaction(slot); CACKEY_DEBUG_PRINTF("Returning in failure"); return(CACKEY_PCSC_E_TOKENABSENT); } } CACKEY_DEBUG_PRINTBUF("Returned Value:", recv_buf, recv_len); if (recv_len < 2) { /* Minimal response length is 2 bytes, returning in failure */ ................................................................................ tmpoutbuflen = outbuflen; send_ret = cackey_send_apdu(slot, GSCIS_CLASS_GLOBAL_PLATFORM, GSCIS_INSTR_SIGNDECRYPT, p1, 0x00, bytes_to_send, tmpbuf, le, &respcode, outbuf, &tmpoutbuflen); if (send_ret != CACKEY_PCSC_S_OK) { CACKEY_DEBUG_PRINTF("ADPU Sending Failed -- returning in error."); if (free_tmpbuf) { if (tmpbuf_s) { free(tmpbuf_s); } } /* End transaction */ cackey_end_transaction(slot); if (respcode == 0x6982) { CACKEY_DEBUG_PRINTF("Security status not satisified. Returning NEEDLOGIN"); slot->slot_reset = 1; slot->token_flags = CKF_LOGIN_REQUIRED; return(CACKEY_PCSC_E_NEEDLOGIN); } if (send_ret == CACKEY_PCSC_E_TOKENABSENT) { CACKEY_DEBUG_PRINTF("Token absent. Returning TOKENABSENT"); slot->slot_reset = 1; slot->token_flags = CKF_LOGIN_REQUIRED; return(CACKEY_PCSC_E_TOKENABSENT); } return(-1); } tmpbuf += bytes_to_send; tmpbuflen -= bytes_to_send; ................................................................................ CACKEY_DEBUG_PRINTF("Called."); pcsc_connect_ret = cackey_connect_card(slot); if (pcsc_connect_ret != CACKEY_PCSC_S_OK) { CACKEY_DEBUG_PRINTF("Unable to connect to card, returning token absent"); return(CACKEY_PCSC_E_TOKENABSENT); } atr_len = sizeof(atr); status_ret = SCardStatus(slot->pcsc_card, NULL, &reader_len, &state, &protocol, atr, &atr_len); if (status_ret != SCARD_S_SUCCESS) { slot->slot_reset = 1; slot->token_flags = CKF_LOGIN_REQUIRED; ................................................................................ } CACKEY_DEBUG_PRINTF("Reset successful, requerying"); status_ret = SCardStatus(slot->pcsc_card, NULL, &reader_len, &state, &protocol, atr, &atr_len); if (status_ret != SCARD_S_SUCCESS) { CACKEY_DEBUG_PRINTF("Still unable to query card status, returning token absent. SCardStatus() = %s", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(status_ret)); return(CACKEY_PCSC_E_TOKENABSENT); } } else { CACKEY_DEBUG_PRINTF("Unable to reconnect to card, returning token absent. SCardReconnect() = %s", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_reconn_ret)); return(CACKEY_PCSC_E_TOKENABSENT); } } else { CACKEY_DEBUG_PRINTF("Unable to query card status, returning token absent. SCardStatus() = %s", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(status_ret)); return(CACKEY_PCSC_E_TOKENABSENT); } } if ((state & SCARD_ABSENT) == SCARD_ABSENT) { CACKEY_DEBUG_PRINTF("Card is absent, returning token absent"); return(CACKEY_PCSC_E_TOKENABSENT); } CACKEY_DEBUG_PRINTF("Returning token present."); return(CACKEY_PCSC_S_TOKENPRESENT); } ................................................................................ switch (cackey_sessions[hSession].decrypt_mechanism) { 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 < 0) { /* Decryption failed. */ if (buflen == CACKEY_PCSC_E_NEEDLOGIN) { retval = CKR_USER_NOT_LOGGED_IN; } else if (buflen == CACKEY_PCSC_E_TOKENABSENT) { retval = CKR_DEVICE_REMOVED; } else { retval = CKR_GENERAL_ERROR; } } else if (((unsigned long) buflen) > *pulPartLen && pPart) { /* Decrypted data too large */ retval = CKR_BUFFER_TOO_SMALL; } else { if (pPart) { memcpy(pPart, buf, buflen); } ................................................................................ case CKM_RSA_PKCS: /* Ask card to sign */ CACKEY_DEBUG_PRINTF("Asking to sign from identity %p in session %lu", 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 < 0) { /* Signing failed. */ if (sigbuflen == CACKEY_PCSC_E_NEEDLOGIN) { retval = CKR_USER_NOT_LOGGED_IN; } else if (sigbuflen == CACKEY_PCSC_E_TOKENABSENT) { retval = CKR_DEVICE_REMOVED; } else { retval = CKR_GENERAL_ERROR; } } else if (((unsigned long) sigbuflen) > *pulSignatureLen && pSignature) { /* Signed data too large */ CACKEY_DEBUG_PRINTF("retval = CKR_BUFFER_TOO_SMALL; sigbuflen = %lu, pulSignatureLen = %lu", (unsigned long) sigbuflen, (unsigned long) *pulSignatureLen); retval = CKR_BUFFER_TOO_SMALL; terminate_sign = 0; |