Overview
Comment: | Updated to reset the card if a retry is required |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | protected-auth-path |
Files: | files | file ages | folders |
SHA1: | ad6536ceb0480aa102f0720db9caf3ff59847433 |
User & Date: | rkeene on 2014-03-14 14:25:57 |
Other Links: | manifest | tags |
Context
2015-07-15
| ||
20:08 | Merged in trunk Closed-Leaf check-in: bab332232a user: rkeene tags: protected-auth-path | |
2014-03-14
| ||
14:30 | Merged in changes from PIV check-in: 8ba93699b4 user: rkeene tags: trunk | |
14:25 | Updated to reset the card if a retry is required check-in: ad6536ceb0 user: rkeene tags: protected-auth-path | |
2014-01-17
| ||
13:42 | Merged in trunk check-in: b5af3ab373 user: rkeene tags: protected-auth-path | |
Changes
Modified cackey.c from [8c591e3548] to [318588635a].
1126 1126 CACKEY_DEBUG_PRINTF("Returning."); 1127 1127 1128 1128 return; 1129 1129 } 1130 1130 1131 1131 /* 1132 1132 * SYNPOSIS 1133 - * LONG cackey_reconnect_card(struct cackey_slot *slot, DWORD default_protocol, LPDWORD selected_protocol); 1133 + * LONG cackey_reconnect_card(struct cackey_slot *slot, DWORD default_protocol); 1134 1134 * 1135 1135 * ARGUMENTS 1136 1136 * cackey_slot *slot 1137 1137 * Slot to send commands to 1138 1138 * 1139 1139 * DWORD default_protocol 1140 1140 * Protocol to attempt first 1141 1141 * 1142 - * LPDWORD selected_protocol 1143 - * [OUT] Protocol selected 1144 - * 1145 1142 * RETURN VALUE 1146 1143 * The return value from SCardReconnect() 1147 1144 * 1148 1145 * NOTES 1149 1146 * This function is a wrapper around SCardReconnect() 1150 1147 * 1151 1148 * The SCardReconnect() function call will be called first with the 1152 1149 * dwPreferredProtocols of "default_protocol". If that call returns 1153 1150 * SCARD_E_PROTO_MISMATCH try again with a protocol of T=0, and failing 1154 1151 * that T=1. 1155 1152 * 1156 1153 */ 1157 -static LONG cackey_reconnect_card(struct cackey_slot *slot, DWORD default_protocol, LPDWORD selected_protocol) { 1154 +static LONG cackey_reconnect_card(struct cackey_slot *slot, DWORD default_protocol) { 1155 + DWORD selected_protocol; 1158 1156 LONG scard_conn_ret; 1159 1157 1160 - scard_conn_ret = SCardReconnect(slot->pcsc_card, SCARD_SHARE_SHARED, default_protocol, SCARD_RESET_CARD, selected_protocol); 1158 + selected_protocol = 0; 1159 + 1160 + scard_conn_ret = SCardReconnect(slot->pcsc_card, SCARD_SHARE_SHARED, default_protocol, SCARD_RESET_CARD, &selected_protocol); 1161 1161 1162 1162 if (scard_conn_ret == SCARD_E_PROTO_MISMATCH) { 1163 1163 CACKEY_DEBUG_PRINTF("SCardReconnect() returned SCARD_E_PROTO_MISMATCH, trying with just T=0") 1164 - scard_conn_ret = SCardReconnect(slot->pcsc_card, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, SCARD_RESET_CARD, selected_protocol); 1164 + scard_conn_ret = SCardReconnect(slot->pcsc_card, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, SCARD_RESET_CARD, &selected_protocol); 1165 1165 1166 1166 if (scard_conn_ret == SCARD_E_PROTO_MISMATCH) { 1167 1167 CACKEY_DEBUG_PRINTF("SCardReconnect() returned SCARD_E_PROTO_MISMATCH, trying with just T=1") 1168 - scard_conn_ret = SCardReconnect(slot->pcsc_card, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T1, SCARD_RESET_CARD, selected_protocol); 1168 + scard_conn_ret = SCardReconnect(slot->pcsc_card, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T1, SCARD_RESET_CARD, &selected_protocol); 1169 1169 } 1170 1170 } 1171 + 1172 + if (scard_conn_ret == SCARD_S_SUCCESS) { 1173 + slot->protocol = selected_protocol; 1174 + } 1171 1175 1172 1176 return(scard_conn_ret); 1173 1177 } 1174 1178 1175 1179 /* 1176 1180 * SYNPOSIS 1177 1181 * cackey_ret cackey_connect_card(struct cackey_slot *slot); ................................................................................ 1234 1238 1235 1239 if (scard_conn_ret == SCARD_E_PROTO_MISMATCH) { 1236 1240 CACKEY_DEBUG_PRINTF("SCardConnect() returned SCARD_E_PROTO_MISMATCH, trying with just T=1") 1237 1241 scard_conn_ret = SCardConnect(*cackey_pcsc_handle, slot->pcsc_reader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T1, &slot->pcsc_card, &protocol); 1238 1242 } 1239 1243 } 1240 1244 1241 - scard_conn_ret = cackey_reconnect_card(slot, protocol, &protocol); 1245 + scard_conn_ret = cackey_reconnect_card(slot, protocol); 1242 1246 } 1243 1247 1244 1248 if (scard_conn_ret != SCARD_S_SUCCESS) { 1245 1249 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); 1246 1250 1247 1251 return(CACKEY_PCSC_E_GENERIC); 1248 1252 } ................................................................................ 1441 1445 * goes away. 1442 1446 * 1443 1447 */ 1444 1448 static cackey_ret cackey_send_apdu(struct cackey_slot *slot, unsigned char class, unsigned char instruction, unsigned char p1, unsigned char p2, unsigned int lc, unsigned char *data, unsigned int le, uint16_t *respcode, unsigned char *respdata, size_t *respdata_len) { 1445 1449 uint8_t major_rc, minor_rc; 1446 1450 size_t bytes_to_copy, tmp_respdata_len; 1447 1451 LPCSCARD_IO_REQUEST pioSendPci; 1448 - DWORD protocol; 1449 1452 DWORD xmit_len, recv_len; 1450 1453 LONG scard_xmit_ret, scard_reconn_ret; 1451 1454 BYTE xmit_buf[1024], recv_buf[1024]; 1452 1455 int pcsc_connect_ret, pcsc_getresp_ret; 1453 1456 int idx; 1454 1457 1455 1458 CACKEY_DEBUG_PRINTF("Called."); ................................................................................ 1536 1539 1537 1540 if (scard_xmit_ret == SCARD_E_NOT_TRANSACTED) { 1538 1541 CACKEY_DEBUG_PRINTF("Failed to send APDU to card (SCardTransmit() = %s/%lx), will ask calling function to retry (not resetting card)...", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_xmit_ret), (unsigned long) scard_xmit_ret); 1539 1542 1540 1543 /* Begin Smartcard Transaction */ 1541 1544 cackey_end_transaction(slot); 1542 1545 1546 + cackey_reconnect_card(slot, slot->protocol); 1547 + 1543 1548 return(CACKEY_PCSC_E_RETRY); 1544 1549 } 1545 1550 1546 1551 if (scard_xmit_ret != SCARD_S_SUCCESS) { 1547 1552 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); 1548 1553 1549 1554 CACKEY_DEBUG_PRINTF("Marking slot as having been reset"); 1550 1555 cackey_mark_slot_reset(slot); 1551 1556 1552 1557 if (scard_xmit_ret == SCARD_W_RESET_CARD) { 1553 1558 CACKEY_DEBUG_PRINTF("Reset required, please hold..."); 1554 1559 1555 - scard_reconn_ret = cackey_reconnect_card(slot, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &protocol); 1560 + scard_reconn_ret = cackey_reconnect_card(slot, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1); 1556 1561 1557 1562 if (scard_reconn_ret == SCARD_S_SUCCESS) { 1558 - /* Update protocol */ 1559 - slot->protocol = protocol; 1560 1563 switch (slot->protocol) { 1561 1564 case SCARD_PROTOCOL_T0: 1562 1565 pioSendPci = SCARD_PCI_T0; 1563 1566 1564 1567 break; 1565 1568 case SCARD_PROTOCOL_T1: 1566 1569 pioSendPci = SCARD_PCI_T1; ................................................................................ 2857 2860 send_ret = cackey_send_apdu(slot, class, NISTSP800_73_3_INSTR_GENAUTH, NISTSP800_78_3_ALGO_RSA2048, identity->pcsc_identity->card.piv.key_id, bytes_to_send, tmpbuf, le, &respcode, outbuf, &tmpoutbuflen); 2858 2861 break; 2859 2862 case CACKEY_ID_TYPE_CERT_ONLY: 2860 2863 break; 2861 2864 } 2862 2865 2863 2866 if (send_ret != CACKEY_PCSC_S_OK) { 2864 - CACKEY_DEBUG_PRINTF("ADPU Sending Failed -- returning in error."); 2865 - 2866 2867 if (free_tmpbuf) { 2867 2868 if (tmpbuf_s) { 2868 2869 free(tmpbuf_s); 2869 2870 } 2870 2871 } 2871 2872 2872 2873 /* End transaction */ 2873 2874 cackey_end_transaction(slot); 2874 2875 2876 + if (send_ret == CACKEY_PCSC_E_RETRY) { 2877 + CACKEY_DEBUG_PRINTF("ADPU Sending Failed -- retrying."); 2878 + 2879 + return(cackey_signdecrypt(slot, identity, buf, buflen, outbuf, outbuflen, padInput, unpadOutput)); 2880 + } 2881 + 2882 + CACKEY_DEBUG_PRINTF("ADPU Sending Failed -- returning in error."); 2883 + 2875 2884 if (respcode == 0x6982 || respcode == 0x6e00) { 2876 2885 if (respcode == 0x6E00) { 2877 2886 CACKEY_DEBUG_PRINTF("Got \"WRONG CLASS\", this means we are talking to the wrong object (likely because the card went away) -- resetting"); 2878 2887 } else { 2879 2888 CACKEY_DEBUG_PRINTF("Security status not satisified (respcode = 0x%04x). Returning NEEDLOGIN", (int) respcode); 2880 2889 } 2881 2890 ................................................................................ 3180 3189 3181 3190 if (status_ret != SCARD_S_SUCCESS) { 3182 3191 cackey_mark_slot_reset(slot); 3183 3192 3184 3193 if (status_ret == SCARD_W_RESET_CARD) { 3185 3194 CACKEY_DEBUG_PRINTF("Reset required, please hold..."); 3186 3195 3187 - scard_reconn_ret = cackey_reconnect_card(slot, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &protocol); 3196 + scard_reconn_ret = cackey_reconnect_card(slot, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1); 3188 3197 if (scard_reconn_ret == SCARD_S_SUCCESS) { 3189 - /* Update protocol */ 3190 - slot->protocol = protocol; 3191 - 3192 3198 /* Re-establish transaction, if it was present */ 3193 3199 if (slot->transaction_depth > 0) { 3194 3200 slot->transaction_depth--; 3195 3201 slot->transaction_need_hw_lock = 1; 3196 3202 cackey_begin_transaction(slot); 3197 3203 } 3198 3204 ................................................................................ 6369 6375 if (buflen < 0) { 6370 6376 /* Decryption failed. */ 6371 6377 if (buflen == CACKEY_PCSC_E_NEEDLOGIN) { 6372 6378 retval = CKR_USER_NOT_LOGGED_IN; 6373 6379 } else if (buflen == CACKEY_PCSC_E_TOKENABSENT) { 6374 6380 retval = CKR_DEVICE_REMOVED; 6375 6381 } else { 6382 + CACKEY_DEBUG_PRINTF("Failed to send APDU, error = %li", (long int) buflen); 6383 + 6376 6384 retval = CKR_GENERAL_ERROR; 6377 6385 } 6378 6386 } else if (((unsigned long) buflen) > *pulPartLen && pPart) { 6379 6387 /* Decrypted data too large */ 6380 6388 retval = CKR_BUFFER_TOO_SMALL; 6381 6389 } else { 6382 6390 if (pPart) {