Diff

Differences From Artifact [8c591e3548]:

To Artifact [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) {