Diff

Differences From Artifact [ecdd31141d]:

To Artifact [5676179bd7]:


538
539
540
541
542
543
544


545
546
547
548
549
550
551
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553







+
+







	int transaction_depth;

	int slot_reset;

	CK_FLAGS token_flags;

	unsigned char *label;

	DWORD protocol;
};

typedef enum {
	CACKEY_TLV_APP_GENERIC = 0x01,
	CACKEY_TLV_APP_SKI     = 0x02,
	CACKEY_TLV_APP_PKI     = 0x04
} cackey_tlv_apptype;
841
842
843
844
845
846
847


848
849

850
851
852
853


854
855
856
857
858
859
860
861
862
863

864
865
866
867
868
869
870
843
844
845
846
847
848
849
850
851
852

853
854
855


856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875







+
+

-
+


-
-
+
+










+







		CACKEY_DEBUG_PRINTF("Connection to PC/SC failed, returning in failure");

		return(CACKEY_PCSC_E_GENERIC);
	}

	/* Connect to reader, if needed */
	if (!slot->pcsc_card_connected) {
		slot->protocol = 0;

		CACKEY_DEBUG_PRINTF("SCardConnect(%s) called", slot->pcsc_reader);
		scard_conn_ret = SCardConnect(*cackey_pcsc_handle, slot->pcsc_reader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &slot->pcsc_card, &protocol);
		scard_conn_ret = SCardConnect(*cackey_pcsc_handle, slot->pcsc_reader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &slot->pcsc_card, &protocol);

		if (scard_conn_ret == SCARD_W_UNPOWERED_CARD) {
			scard_conn_ret = SCardConnect(*cackey_pcsc_handle, slot->pcsc_reader, SCARD_SHARE_DIRECT, SCARD_PROTOCOL_T0, &slot->pcsc_card, &protocol);
			scard_conn_ret = SCardReconnect(slot->pcsc_card, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, SCARD_RESET_CARD, &protocol);
			scard_conn_ret = SCardConnect(*cackey_pcsc_handle, slot->pcsc_reader, SCARD_SHARE_DIRECT, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &slot->pcsc_card, &protocol);
			scard_conn_ret = SCardReconnect(slot->pcsc_card, SCARD_SHARE_SHARED, protocol, SCARD_RESET_CARD, &protocol);
		}

		if (scard_conn_ret != SCARD_S_SUCCESS) {
			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);

			return(CACKEY_PCSC_E_GENERIC);
		}

		slot->pcsc_card_connected = 1;
		slot->transaction_depth = 0;
		slot->protocol = protocol;
	}

	return(CACKEY_PCSC_S_OK);
}

/*
 * SYNPOSIS
1036
1037
1038
1039
1040
1041
1042

1043
1044
1045
1046
1047
1048
1049
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055







+







 *     specified.  It will reconnect to the card if the connection
 *     goes away.
 *
 */
static cackey_ret cackey_send_apdu(struct cackey_slot *slot, unsigned char class, unsigned char instruction, unsigned char p1, unsigned char p2, unsigned char lc, unsigned char *data, unsigned char le, uint16_t *respcode, unsigned char *respdata, size_t *respdata_len) {
	uint8_t major_rc, minor_rc;
	size_t bytes_to_copy, tmp_respdata_len;
	LPCSCARD_IO_REQUEST pioSendPci;
	DWORD protocol;
	DWORD xmit_len, recv_len;
	LONG scard_xmit_ret, scard_reconn_ret;
	BYTE xmit_buf[1024], recv_buf[1024];
	int pcsc_connect_ret, pcsc_getresp_ret;
	int idx;

1057
1058
1059
1060
1061
1062
1063
















1064
1065
1066
1067
1068
1069
1070
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+








	pcsc_connect_ret = cackey_connect_card(slot);
	if (pcsc_connect_ret != CACKEY_PCSC_S_OK) {
		CACKEY_DEBUG_PRINTF("Unable to connect to card, returning in failure");

		return(CACKEY_PCSC_E_GENERIC);
	}

	/* Determine which protocol to send using */
	switch (slot->protocol) {
		case SCARD_PROTOCOL_T0:
			pioSendPci = SCARD_PCI_T0;

			break;
		case SCARD_PROTOCOL_T1:
			pioSendPci = SCARD_PCI_T1;

			break;
		default:
			CACKEY_DEBUG_PRINTF("Invalid protocol found, aborting.");

			return(CACKEY_PCSC_E_GENERIC);
	}

	/* Transmit */
	xmit_len = 0;
	xmit_buf[xmit_len++] = class;
	xmit_buf[xmit_len++] = instruction;
	xmit_buf[xmit_len++] = p1;
	xmit_buf[xmit_len++] = p2;
1085
1086
1087
1088
1089
1090
1091
1092

1093
1094
1095
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
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
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152

1153
1154
1155
1156
1157
1158
1159
1160







-
+










-
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+









-
+







	if (class == GSCIS_CLASS_ISO7816 && instruction == GSCIS_INSTR_VERIFY && p1 == 0x00 && p2 == 0x00) {
		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, NULL, recv_buf, &recv_len);
	scard_xmit_ret = SCardTransmit(slot->pcsc_card, pioSendPci, xmit_buf, xmit_len, NULL, 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;

		if (scard_xmit_ret == SCARD_W_RESET_CARD) {
			CACKEY_DEBUG_PRINTF("Reset required, please hold...");

			scard_reconn_ret = SCardReconnect(slot->pcsc_card, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, SCARD_RESET_CARD, &protocol);
			scard_reconn_ret = SCardReconnect(slot->pcsc_card, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, SCARD_RESET_CARD, &protocol);
			if (scard_reconn_ret == SCARD_S_SUCCESS) {
				/* Update protocol */
				slot->protocol = protocol;
				switch (slot->protocol) {
					case SCARD_PROTOCOL_T0:
						pioSendPci = SCARD_PCI_T0;

						break;
					case SCARD_PROTOCOL_T1:
						pioSendPci = SCARD_PCI_T1;

						break;
					default:
						CACKEY_DEBUG_PRINTF("Invalid protocol found, but too late to do anything about it now -- trying anyway.");

						break;
				}

				/* Re-establish transaction, if it was present */
				if (slot->transaction_depth > 0) {
					slot->transaction_depth--;
					cackey_begin_transaction(slot);
				}

				CACKEY_DEBUG_PRINTF("Reset successful, retransmitting");

				recv_len = sizeof(recv_buf);
				scard_xmit_ret = SCardTransmit(slot->pcsc_card, SCARD_PCI_T0, xmit_buf, xmit_len, NULL, recv_buf, &recv_len);
				scard_xmit_ret = SCardTransmit(slot->pcsc_card, pioSendPci, xmit_buf, xmit_len, NULL, recv_buf, &recv_len);

				if (scard_xmit_ret != SCARD_S_SUCCESS) {
					CACKEY_DEBUG_PRINTF("Retransmit failed, returning in failure after disconnecting the card (SCardTransmit = %s/%li)", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_xmit_ret), (long) scard_xmit_ret);

					SCardDisconnect(slot->pcsc_card, SCARD_LEAVE_CARD);
					slot->pcsc_card_connected = 0;

2233
2234
2235
2236
2237
2238
2239
2240

2241



2242
2243
2244
2245
2246
2247
2248
2272
2273
2274
2275
2276
2277
2278

2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290







-
+

+
+
+







	if (status_ret != SCARD_S_SUCCESS) {
		slot->slot_reset = 1;
		slot->token_flags = CKF_LOGIN_REQUIRED;

		if (status_ret == SCARD_W_RESET_CARD) {
			CACKEY_DEBUG_PRINTF("Reset required, please hold...");

			scard_reconn_ret = SCardReconnect(slot->pcsc_card, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, SCARD_RESET_CARD, &protocol);
			scard_reconn_ret = SCardReconnect(slot->pcsc_card, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, SCARD_RESET_CARD, &protocol);
			if (scard_reconn_ret == SCARD_S_SUCCESS) {
				/* Update protocol */
				slot->protocol = protocol;

				/* Re-establish transaction, if it was present */
				if (slot->transaction_depth > 0) {
					slot->transaction_depth--;
					cackey_begin_transaction(slot);
				}

				CACKEY_DEBUG_PRINTF("Reset successful, requerying");
5185
5186
5187
5188
5189
5190
5191
5192

5193
5194
5195
5196
5197
5198
5199
5227
5228
5229
5230
5231
5232
5233

5234
5235
5236
5237
5238
5239
5240
5241







-
+








		CACKEY_DEBUG_PRINTF("Error.  SignFinal() returned failure (rv = %lu).", (unsigned long) sign_ret);

		return(sign_ret);
	}

	if (pSignature == NULL) {
		CACKEY_DEBUG_PRINTF("pSignature specified as NULL, undoing C_SignUpdate()", (unsigned long) sign_ret);
		CACKEY_DEBUG_PRINTF("pSignature specified as NULL, undoing C_SignUpdate()");

		cackey_sessions[hSession].sign_bufused = start_sign_bufused;

		return(sign_ret);
	}

	CACKEY_DEBUG_PRINTF("Returning CKR_OK (%i)", CKR_OK);