Overview
Comment: | Fixed bug with selecting between T=0 and T=1 protocol and card going to sleep
Fixed bug with soft-transactions Updated soft-transactions to re-lock hardware card if possible |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: | 9b04a062cc6e52e6f321ae86c7bba543ed946079 |
User & Date: | rkeene on 2010-07-23 09:08:44 |
Other Links: | manifest | tags |
Context
2010-07-23
| ||
17:24 |
Fixed retry on NOT_TRANSACTED to retry at a higher level
Consolidated all SCardReconnect calls into a wrapper that takes care of T=0 or T=1 selection check-in: 93bc06dab6 user: rkeene tags: trunk | |
09:08 |
Fixed bug with selecting between T=0 and T=1 protocol and card going to sleep
Fixed bug with soft-transactions Updated soft-transactions to re-lock hardware card if possible check-in: 9b04a062cc user: rkeene tags: trunk | |
07:08 | Added forgotten Mac OS X PackageMaker contents files check-in: 5dc7094235 user: kvanals tags: trunk | |
Changes
Modified cackey.c from [5676179bd7] to [4c31fc86bf].
532 532 533 533 char *pcsc_reader; 534 534 535 535 int pcsc_card_connected; 536 536 SCARDHANDLE pcsc_card; 537 537 538 538 int transaction_depth; 539 + int transaction_need_hw_lock; 539 540 540 541 int slot_reset; 541 542 542 543 CK_FLAGS token_flags; 543 544 544 545 unsigned char *label; 545 546 ................................................................................ 676 677 free(cackey_slots[idx].label); 677 678 678 679 cackey_slots[idx].label = NULL; 679 680 } 680 681 681 682 cackey_slots[idx].pcsc_card_connected = 0; 682 683 cackey_slots[idx].transaction_depth = 0; 684 + cackey_slots[idx].transaction_need_hw_lock = 0; 683 685 684 686 if (cackey_slots[idx].active) { 685 687 CACKEY_DEBUG_PRINTF("Marking active slot %lu as being reset", (unsigned long) idx); 686 688 } 687 689 688 690 cackey_slots[idx].slot_reset = 1; 689 691 } ................................................................................ 847 849 848 850 /* Connect to reader, if needed */ 849 851 if (!slot->pcsc_card_connected) { 850 852 slot->protocol = 0; 851 853 852 854 CACKEY_DEBUG_PRINTF("SCardConnect(%s) called", slot->pcsc_reader); 853 855 scard_conn_ret = SCardConnect(*cackey_pcsc_handle, slot->pcsc_reader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &slot->pcsc_card, &protocol); 856 + 857 + if (scard_conn_ret == SCARD_E_PROTO_MISMATCH) { 858 + CACKEY_DEBUG_PRINTF("SCardConnect() returned SCARD_E_PROTO_MISMATCH, trying with just T=0") 859 + scard_conn_ret = SCardConnect(*cackey_pcsc_handle, slot->pcsc_reader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &slot->pcsc_card, &protocol); 860 + 861 + if (scard_conn_ret == SCARD_E_PROTO_MISMATCH) { 862 + CACKEY_DEBUG_PRINTF("SCardConnect() returned SCARD_E_PROTO_MISMATCH, trying with just T=1") 863 + scard_conn_ret = SCardConnect(*cackey_pcsc_handle, slot->pcsc_reader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T1, &slot->pcsc_card, &protocol); 864 + } 865 + } 854 866 855 867 if (scard_conn_ret == SCARD_W_UNPOWERED_CARD) { 868 + CACKEY_DEBUG_PRINTF("SCardConnect() returned SCARD_W_UNPOWERED_CARD, trying to re-connect..."); 869 + 856 870 scard_conn_ret = SCardConnect(*cackey_pcsc_handle, slot->pcsc_reader, SCARD_SHARE_DIRECT, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &slot->pcsc_card, &protocol); 871 + 872 + if (scard_conn_ret == SCARD_E_PROTO_MISMATCH) { 873 + CACKEY_DEBUG_PRINTF("SCardConnect() returned SCARD_E_PROTO_MISMATCH, trying with just T=0") 874 + scard_conn_ret = SCardConnect(*cackey_pcsc_handle, slot->pcsc_reader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &slot->pcsc_card, &protocol); 875 + 876 + if (scard_conn_ret == SCARD_E_PROTO_MISMATCH) { 877 + CACKEY_DEBUG_PRINTF("SCardConnect() returned SCARD_E_PROTO_MISMATCH, trying with just T=1") 878 + scard_conn_ret = SCardConnect(*cackey_pcsc_handle, slot->pcsc_reader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T1, &slot->pcsc_card, &protocol); 879 + } 880 + } 881 + 857 882 scard_conn_ret = SCardReconnect(slot->pcsc_card, SCARD_SHARE_SHARED, protocol, SCARD_RESET_CARD, &protocol); 883 + 884 + if (scard_conn_ret == SCARD_E_PROTO_MISMATCH) { 885 + CACKEY_DEBUG_PRINTF("SCardReconnect() returned SCARD_E_PROTO_MISMATCH, trying with just T=0") 886 + scard_conn_ret = SCardReconnect(slot->pcsc_card, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, SCARD_RESET_CARD, &protocol); 887 + 888 + if (scard_conn_ret == SCARD_E_PROTO_MISMATCH) { 889 + CACKEY_DEBUG_PRINTF("SCardReconnect() returned SCARD_E_PROTO_MISMATCH, trying with just T=1") 890 + scard_conn_ret = SCardReconnect(slot->pcsc_card, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T1, SCARD_RESET_CARD, &protocol); 891 + } 892 + } 893 + 858 894 } 859 895 860 896 if (scard_conn_ret != SCARD_S_SUCCESS) { 861 897 CACKEY_DEBUG_PRINTF("Connection to card failed, returning in failure (SCardConnect() = %s/%li)", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_conn_ret), (long) scard_conn_ret); 862 898 863 899 return(CACKEY_PCSC_E_GENERIC); 864 900 } 865 901 866 902 slot->pcsc_card_connected = 1; 867 903 slot->transaction_depth = 0; 904 + slot->transaction_need_hw_lock = 0; 868 905 slot->protocol = protocol; 869 906 } 870 907 871 908 return(CACKEY_PCSC_S_OK); 872 909 } 873 910 874 911 /* ................................................................................ 898 935 CACKEY_DEBUG_PRINTF("Unable to connect to card, returning in error"); 899 936 900 937 return(CACKEY_PCSC_E_GENERIC); 901 938 } 902 939 903 940 slot->transaction_depth++; 904 941 905 - if (slot->transaction_depth > 1) { 942 + if (slot->transaction_depth > 1 && !slot->transaction_need_hw_lock) { 906 943 CACKEY_DEBUG_PRINTF("Already in a transaction, performing no action (new depth = %i)", slot->transaction_depth); 907 944 908 945 return(CACKEY_PCSC_S_OK); 909 946 } 947 + 948 + slot->transaction_need_hw_lock = 0; 910 949 911 950 scard_trans_ret = SCardBeginTransaction(slot->pcsc_card); 912 951 if (scard_trans_ret != SCARD_S_SUCCESS) { 913 952 CACKEY_DEBUG_PRINTF("Unable to begin transaction, returning in error"); 914 953 915 954 return(CACKEY_PCSC_E_GENERIC); 916 955 } ................................................................................ 938 977 */ 939 978 static cackey_ret cackey_end_transaction(struct cackey_slot *slot) { 940 979 LONG scard_trans_ret; 941 980 942 981 CACKEY_DEBUG_PRINTF("Called."); 943 982 944 983 if (!slot->pcsc_card_connected) { 945 - CACKEY_DEBUG_PRINTF("Card is not connected, unable to end transaction"); 984 + CACKEY_DEBUG_PRINTF("Card is not connected, unable to end transaction on card"); 985 + 986 + if (slot->transaction_depth > 0) { 987 + CACKEY_DEBUG_PRINTF("Decreasing transaction depth and asking for a hardware lock on the next begin transaction (current depth = %i)", slot->transaction_depth); 988 + 989 + slot->transaction_depth--; 990 + 991 + if (slot->transaction_depth > 0) { 992 + slot->transaction_need_hw_lock = 1; 993 + } 994 + } 946 995 947 996 return(CACKEY_PCSC_E_GENERIC); 948 997 } 949 998 950 999 if (slot->transaction_depth == 0) { 951 1000 CACKEY_DEBUG_PRINTF("Terminating a transaction that has not begun!"); 952 1001 ................................................................................ 954 1003 } 955 1004 956 1005 slot->transaction_depth--; 957 1006 958 1007 if (slot->transaction_depth > 0) { 959 1008 CACKEY_DEBUG_PRINTF("Transactions still in progress, not terminating on-card Transaction (current depth = %i)", slot->transaction_depth); 960 1009 961 - return(CACKEY_PCSC_E_GENERIC); 1010 + return(CACKEY_PCSC_S_OK); 962 1011 } 963 1012 964 1013 scard_trans_ret = SCardEndTransaction(slot->pcsc_card, SCARD_LEAVE_CARD); 965 1014 if (scard_trans_ret != SCARD_S_SUCCESS) { 966 1015 CACKEY_DEBUG_PRINTF("Unable to end transaction, returning in error"); 967 1016 968 1017 return(CACKEY_PCSC_E_GENERIC); ................................................................................ 1047 1096 size_t bytes_to_copy, tmp_respdata_len; 1048 1097 LPCSCARD_IO_REQUEST pioSendPci; 1049 1098 DWORD protocol; 1050 1099 DWORD xmit_len, recv_len; 1051 1100 LONG scard_xmit_ret, scard_reconn_ret; 1052 1101 BYTE xmit_buf[1024], recv_buf[1024]; 1053 1102 int pcsc_connect_ret, pcsc_getresp_ret; 1054 - int idx; 1103 + int idx, retry; 1055 1104 1056 1105 CACKEY_DEBUG_PRINTF("Called."); 1057 1106 1058 1107 if (!slot) { 1059 1108 CACKEY_DEBUG_PRINTF("Invalid slot specified."); 1060 1109 1061 1110 return(CACKEY_PCSC_E_GENERIC); ................................................................................ 1107 1156 if (class == GSCIS_CLASS_ISO7816 && instruction == GSCIS_INSTR_VERIFY && p1 == 0x00 && p2 == 0x00) { 1108 1157 CACKEY_DEBUG_PRINTF("Sending APDU: <<censored>>"); 1109 1158 } else { 1110 1159 CACKEY_DEBUG_PRINTBUF("Sending APDU:", xmit_buf, xmit_len); 1111 1160 } 1112 1161 1113 1162 recv_len = sizeof(recv_buf); 1114 - scard_xmit_ret = SCardTransmit(slot->pcsc_card, pioSendPci, xmit_buf, xmit_len, NULL, recv_buf, &recv_len); 1163 + for (retry = 0; retry < 10; retry++) { 1164 + CACKEY_DEBUG_PRINTF("Calling SCardTransmit()"); 1165 + scard_xmit_ret = SCardTransmit(slot->pcsc_card, pioSendPci, xmit_buf, xmit_len, NULL, recv_buf, &recv_len); 1166 + 1167 + if (scard_xmit_ret == SCARD_E_NOT_TRANSACTED) { 1168 + CACKEY_DEBUG_PRINTF("Failed to send APDU to card (SCardTransmit() = %s/%lx), will retry...", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_xmit_ret), (unsigned long) scard_xmit_ret); 1169 + } else { 1170 + break; 1171 + } 1172 + } 1173 + 1115 1174 if (scard_xmit_ret != SCARD_S_SUCCESS) { 1116 1175 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); 1176 + 1117 1177 CACKEY_DEBUG_PRINTF("Marking slot as having been reset"); 1118 - 1119 - slot->transaction_depth = 0; 1120 1178 slot->slot_reset = 1; 1121 1179 1122 1180 if (scard_xmit_ret == SCARD_W_RESET_CARD) { 1123 1181 CACKEY_DEBUG_PRINTF("Reset required, please hold..."); 1124 1182 1125 1183 scard_reconn_ret = SCardReconnect(slot->pcsc_card, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, SCARD_RESET_CARD, &protocol); 1126 1184 if (scard_reconn_ret == SCARD_S_SUCCESS) { ................................................................................ 1140 1198 1141 1199 break; 1142 1200 } 1143 1201 1144 1202 /* Re-establish transaction, if it was present */ 1145 1203 if (slot->transaction_depth > 0) { 1146 1204 slot->transaction_depth--; 1205 + slot->transaction_need_hw_lock = 1; 1147 1206 cackey_begin_transaction(slot); 1148 1207 } 1149 1208 1150 1209 CACKEY_DEBUG_PRINTF("Reset successful, retransmitting"); 1151 1210 1152 1211 recv_len = sizeof(recv_buf); 1153 1212 scard_xmit_ret = SCardTransmit(slot->pcsc_card, pioSendPci, xmit_buf, xmit_len, NULL, recv_buf, &recv_len); ................................................................................ 2280 2339 if (scard_reconn_ret == SCARD_S_SUCCESS) { 2281 2340 /* Update protocol */ 2282 2341 slot->protocol = protocol; 2283 2342 2284 2343 /* Re-establish transaction, if it was present */ 2285 2344 if (slot->transaction_depth > 0) { 2286 2345 slot->transaction_depth--; 2346 + slot->transaction_need_hw_lock = 1; 2287 2347 cackey_begin_transaction(slot); 2288 2348 } 2289 2349 2290 2350 CACKEY_DEBUG_PRINTF("Reset successful, requerying"); 2291 2351 status_ret = SCardStatus(slot->pcsc_card, NULL, &reader_len, &state, &protocol, atr, &atr_len); 2292 2352 if (status_ret != SCARD_S_SUCCESS) { 2293 2353 CACKEY_DEBUG_PRINTF("Still unable to query card status, returning token absent. SCardStatus() = %s", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(status_ret)); ................................................................................ 3023 3083 cackey_sessions[idx].active = 0; 3024 3084 } 3025 3085 3026 3086 for (idx = 0; idx < (sizeof(cackey_slots) / sizeof(cackey_slots[0])); idx++) { 3027 3087 cackey_slots[idx].active = 0; 3028 3088 cackey_slots[idx].pcsc_reader = NULL; 3029 3089 cackey_slots[idx].transaction_depth = 0; 3090 + cackey_slots[idx].transaction_need_hw_lock = 0; 3030 3091 cackey_slots[idx].slot_reset = 0; 3031 3092 cackey_slots[idx].token_flags = 0; 3032 3093 cackey_slots[idx].label = NULL; 3033 3094 } 3034 3095 3035 3096 cackey_initialized = 1; 3036 3097 ................................................................................ 3238 3299 3239 3300 /* Only update the list of slots if we are actually being asked supply the slot information */ 3240 3301 if (pSlotList) { 3241 3302 cackey_slots[currslot].active = 1; 3242 3303 cackey_slots[currslot].pcsc_reader = strdup(pcsc_readers); 3243 3304 cackey_slots[currslot].pcsc_card_connected = 0; 3244 3305 cackey_slots[currslot].transaction_depth = 0; 3306 + cackey_slots[currslot].transaction_need_hw_lock = 0; 3245 3307 cackey_slots[currslot].slot_reset = 1; 3246 3308 cackey_slots[currslot].token_flags = CKF_LOGIN_REQUIRED; 3247 3309 cackey_slots[currslot].label = NULL; 3248 3310 } 3249 3311 currslot++; 3250 3312 3251 3313 pcsc_readers += curr_reader_len + 1;