Check-in [9b04a062cc]
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
533
534
535
536
537
538

539
540
541
542
543
544
545

	char *pcsc_reader;

	int pcsc_card_connected;
	SCARDHANDLE pcsc_card;

	int transaction_depth;


	int slot_reset;

	CK_FLAGS token_flags;

	unsigned char *label;








>







532
533
534
535
536
537
538
539
540
541
542
543
544
545
546

	char *pcsc_reader;

	int pcsc_card_connected;
	SCARDHANDLE pcsc_card;

	int transaction_depth;
	int transaction_need_hw_lock;

	int slot_reset;

	CK_FLAGS token_flags;

	unsigned char *label;

676
677
678
679
680
681
682

683
684
685
686
687
688
689
			free(cackey_slots[idx].label);

			cackey_slots[idx].label = NULL;
		}

		cackey_slots[idx].pcsc_card_connected = 0;
		cackey_slots[idx].transaction_depth = 0;


		if (cackey_slots[idx].active) {
			CACKEY_DEBUG_PRINTF("Marking active slot %lu as being reset", (unsigned long) idx);
		}

		cackey_slots[idx].slot_reset = 1;
	}







>







677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
			free(cackey_slots[idx].label);

			cackey_slots[idx].label = NULL;
		}

		cackey_slots[idx].pcsc_card_connected = 0;
		cackey_slots[idx].transaction_depth = 0;
		cackey_slots[idx].transaction_need_hw_lock = 0;

		if (cackey_slots[idx].active) {
			CACKEY_DEBUG_PRINTF("Marking active slot %lu as being reset", (unsigned long) idx);
		}

		cackey_slots[idx].slot_reset = 1;
	}
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

	/* 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 | 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 | 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);
}

/*








>
>
>
>
>
>
>
>
>
>

>
>

>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>










>







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
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911

	/* 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 | SCARD_PROTOCOL_T1, &slot->pcsc_card, &protocol);

		if (scard_conn_ret == SCARD_E_PROTO_MISMATCH) {
			CACKEY_DEBUG_PRINTF("SCardConnect() returned SCARD_E_PROTO_MISMATCH, trying with just T=0")
			scard_conn_ret = SCardConnect(*cackey_pcsc_handle, slot->pcsc_reader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &slot->pcsc_card, &protocol);

			if (scard_conn_ret == SCARD_E_PROTO_MISMATCH) {
				CACKEY_DEBUG_PRINTF("SCardConnect() returned SCARD_E_PROTO_MISMATCH, trying with just T=1")
				scard_conn_ret = SCardConnect(*cackey_pcsc_handle, slot->pcsc_reader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T1, &slot->pcsc_card, &protocol);
			}
		}

		if (scard_conn_ret == SCARD_W_UNPOWERED_CARD) {
			CACKEY_DEBUG_PRINTF("SCardConnect() returned SCARD_W_UNPOWERED_CARD, trying to re-connect...");

			scard_conn_ret = SCardConnect(*cackey_pcsc_handle, slot->pcsc_reader, SCARD_SHARE_DIRECT, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &slot->pcsc_card, &protocol);

			if (scard_conn_ret == SCARD_E_PROTO_MISMATCH) {
				CACKEY_DEBUG_PRINTF("SCardConnect() returned SCARD_E_PROTO_MISMATCH, trying with just T=0")
				scard_conn_ret = SCardConnect(*cackey_pcsc_handle, slot->pcsc_reader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &slot->pcsc_card, &protocol);

				if (scard_conn_ret == SCARD_E_PROTO_MISMATCH) {
					CACKEY_DEBUG_PRINTF("SCardConnect() returned SCARD_E_PROTO_MISMATCH, trying with just T=1")
					scard_conn_ret = SCardConnect(*cackey_pcsc_handle, slot->pcsc_reader, SCARD_SHARE_SHARED, 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_E_PROTO_MISMATCH) {
				CACKEY_DEBUG_PRINTF("SCardReconnect() returned SCARD_E_PROTO_MISMATCH, trying with just T=0")
				scard_conn_ret = SCardReconnect(slot->pcsc_card, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, SCARD_RESET_CARD, &protocol);

				if (scard_conn_ret == SCARD_E_PROTO_MISMATCH) {
					CACKEY_DEBUG_PRINTF("SCardReconnect() returned SCARD_E_PROTO_MISMATCH, trying with just T=1")
					scard_conn_ret = SCardReconnect(slot->pcsc_card, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T1, 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->transaction_need_hw_lock = 0;
		slot->protocol = protocol;
	}

	return(CACKEY_PCSC_S_OK);
}

/*
898
899
900
901
902
903
904
905
906
907
908
909


910
911
912
913
914
915
916
		CACKEY_DEBUG_PRINTF("Unable to connect to card, returning in error");

		return(CACKEY_PCSC_E_GENERIC);
	}

	slot->transaction_depth++;

	if (slot->transaction_depth > 1) {
		CACKEY_DEBUG_PRINTF("Already in a transaction, performing no action (new depth = %i)", slot->transaction_depth);

		return(CACKEY_PCSC_S_OK);
	}



	scard_trans_ret = SCardBeginTransaction(slot->pcsc_card);
	if (scard_trans_ret != SCARD_S_SUCCESS) {
		CACKEY_DEBUG_PRINTF("Unable to begin transaction, returning in error");

		return(CACKEY_PCSC_E_GENERIC);
	}







|




>
>







935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
		CACKEY_DEBUG_PRINTF("Unable to connect to card, returning in error");

		return(CACKEY_PCSC_E_GENERIC);
	}

	slot->transaction_depth++;

	if (slot->transaction_depth > 1 && !slot->transaction_need_hw_lock) {
		CACKEY_DEBUG_PRINTF("Already in a transaction, performing no action (new depth = %i)", slot->transaction_depth);

		return(CACKEY_PCSC_S_OK);
	}

	slot->transaction_need_hw_lock = 0;

	scard_trans_ret = SCardBeginTransaction(slot->pcsc_card);
	if (scard_trans_ret != SCARD_S_SUCCESS) {
		CACKEY_DEBUG_PRINTF("Unable to begin transaction, returning in error");

		return(CACKEY_PCSC_E_GENERIC);
	}
938
939
940
941
942
943
944
945










946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
 */
static cackey_ret cackey_end_transaction(struct cackey_slot *slot) {
	LONG scard_trans_ret;

	CACKEY_DEBUG_PRINTF("Called.");

	if (!slot->pcsc_card_connected) {
		CACKEY_DEBUG_PRINTF("Card is not connected, unable to end transaction");











		return(CACKEY_PCSC_E_GENERIC);
	}

	if (slot->transaction_depth == 0) {
		CACKEY_DEBUG_PRINTF("Terminating a transaction that has not begun!");

		return(CACKEY_PCSC_E_GENERIC);
	}

	slot->transaction_depth--;

	if (slot->transaction_depth > 0) {
		CACKEY_DEBUG_PRINTF("Transactions still in progress, not terminating on-card Transaction (current depth = %i)", slot->transaction_depth);

		return(CACKEY_PCSC_E_GENERIC);
	}

	scard_trans_ret = SCardEndTransaction(slot->pcsc_card, SCARD_LEAVE_CARD);
	if (scard_trans_ret != SCARD_S_SUCCESS) {
		CACKEY_DEBUG_PRINTF("Unable to end transaction, returning in error");

		return(CACKEY_PCSC_E_GENERIC);







|
>
>
>
>
>
>
>
>
>
>















|







977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
 */
static cackey_ret cackey_end_transaction(struct cackey_slot *slot) {
	LONG scard_trans_ret;

	CACKEY_DEBUG_PRINTF("Called.");

	if (!slot->pcsc_card_connected) {
		CACKEY_DEBUG_PRINTF("Card is not connected, unable to end transaction on card");

		if (slot->transaction_depth > 0) {
			CACKEY_DEBUG_PRINTF("Decreasing transaction depth and asking for a hardware lock on the next begin transaction (current depth = %i)", slot->transaction_depth);

			slot->transaction_depth--;

			if (slot->transaction_depth > 0) {
				slot->transaction_need_hw_lock = 1;
			}
		}

		return(CACKEY_PCSC_E_GENERIC);
	}

	if (slot->transaction_depth == 0) {
		CACKEY_DEBUG_PRINTF("Terminating a transaction that has not begun!");

		return(CACKEY_PCSC_E_GENERIC);
	}

	slot->transaction_depth--;

	if (slot->transaction_depth > 0) {
		CACKEY_DEBUG_PRINTF("Transactions still in progress, not terminating on-card Transaction (current depth = %i)", slot->transaction_depth);

		return(CACKEY_PCSC_S_OK);
	}

	scard_trans_ret = SCardEndTransaction(slot->pcsc_card, SCARD_LEAVE_CARD);
	if (scard_trans_ret != SCARD_S_SUCCESS) {
		CACKEY_DEBUG_PRINTF("Unable to end transaction, returning in error");

		return(CACKEY_PCSC_E_GENERIC);
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
	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;

	CACKEY_DEBUG_PRINTF("Called.");

	if (!slot) {
		CACKEY_DEBUG_PRINTF("Invalid slot specified.");

		return(CACKEY_PCSC_E_GENERIC);







|







1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
	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, retry;

	CACKEY_DEBUG_PRINTF("Called.");

	if (!slot) {
		CACKEY_DEBUG_PRINTF("Invalid slot specified.");

		return(CACKEY_PCSC_E_GENERIC);
1107
1108
1109
1110
1111
1112
1113


1114








1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
	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, 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_PROTOCOL_T1, SCARD_RESET_CARD, &protocol);
			if (scard_reconn_ret == SCARD_S_SUCCESS) {







>
>
|
>
>
>
>
>
>
>
>


<

|







1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175

1176
1177
1178
1179
1180
1181
1182
1183
1184
	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);
	for (retry = 0; retry < 10; retry++) {
		CACKEY_DEBUG_PRINTF("Calling SCardTransmit()");
		scard_xmit_ret = SCardTransmit(slot->pcsc_card, pioSendPci, xmit_buf, xmit_len, NULL, recv_buf, &recv_len);

		if (scard_xmit_ret == SCARD_E_NOT_TRANSACTED) {
			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);
		} else {
			break;
		}
	}

	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->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_PROTOCOL_T1, SCARD_RESET_CARD, &protocol);
			if (scard_reconn_ret == SCARD_S_SUCCESS) {
1140
1141
1142
1143
1144
1145
1146

1147
1148
1149
1150
1151
1152
1153

						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, pioSendPci, xmit_buf, xmit_len, NULL, recv_buf, &recv_len);







>







1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212

						break;
				}

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

				CACKEY_DEBUG_PRINTF("Reset successful, retransmitting");

				recv_len = sizeof(recv_buf);
				scard_xmit_ret = SCardTransmit(slot->pcsc_card, pioSendPci, xmit_buf, xmit_len, NULL, recv_buf, &recv_len);
2280
2281
2282
2283
2284
2285
2286

2287
2288
2289
2290
2291
2292
2293
			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");
				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));







>







2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
			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--;
					slot->transaction_need_hw_lock = 1;
					cackey_begin_transaction(slot);
				}

				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));
3023
3024
3025
3026
3027
3028
3029

3030
3031
3032
3033
3034
3035
3036
		cackey_sessions[idx].active = 0;
	}

	for (idx = 0; idx < (sizeof(cackey_slots) / sizeof(cackey_slots[0])); idx++) {
		cackey_slots[idx].active = 0;
		cackey_slots[idx].pcsc_reader = NULL;
		cackey_slots[idx].transaction_depth = 0;

		cackey_slots[idx].slot_reset = 0;
		cackey_slots[idx].token_flags = 0;
		cackey_slots[idx].label = NULL;
	}

	cackey_initialized = 1;








>







3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
		cackey_sessions[idx].active = 0;
	}

	for (idx = 0; idx < (sizeof(cackey_slots) / sizeof(cackey_slots[0])); idx++) {
		cackey_slots[idx].active = 0;
		cackey_slots[idx].pcsc_reader = NULL;
		cackey_slots[idx].transaction_depth = 0;
		cackey_slots[idx].transaction_need_hw_lock = 0;
		cackey_slots[idx].slot_reset = 0;
		cackey_slots[idx].token_flags = 0;
		cackey_slots[idx].label = NULL;
	}

	cackey_initialized = 1;

3238
3239
3240
3241
3242
3243
3244

3245
3246
3247
3248
3249
3250
3251

					/* Only update the list of slots if we are actually being asked supply the slot information */
					if (pSlotList) {
						cackey_slots[currslot].active = 1;
						cackey_slots[currslot].pcsc_reader = strdup(pcsc_readers);
						cackey_slots[currslot].pcsc_card_connected = 0;
						cackey_slots[currslot].transaction_depth = 0;

						cackey_slots[currslot].slot_reset = 1;
						cackey_slots[currslot].token_flags = CKF_LOGIN_REQUIRED;
						cackey_slots[currslot].label = NULL;
					}
					currslot++;

					pcsc_readers += curr_reader_len + 1;







>







3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313

					/* Only update the list of slots if we are actually being asked supply the slot information */
					if (pSlotList) {
						cackey_slots[currslot].active = 1;
						cackey_slots[currslot].pcsc_reader = strdup(pcsc_readers);
						cackey_slots[currslot].pcsc_card_connected = 0;
						cackey_slots[currslot].transaction_depth = 0;
						cackey_slots[currslot].transaction_need_hw_lock = 0;
						cackey_slots[currslot].slot_reset = 1;
						cackey_slots[currslot].token_flags = CKF_LOGIN_REQUIRED;
						cackey_slots[currslot].label = NULL;
					}
					currslot++;

					pcsc_readers += curr_reader_len + 1;