Diff

Differences From Artifact [a15198f18c]:

To Artifact [f66c56f731]:


460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
460
461
462
463
464
465
466


467
468
469
470
471
472
473







-
-







#  define CACKEY_DEBUG_FUNC_APPTYPE_TO_STR(x) "DEBUG_DISABLED"
#endif

struct cackey_pcsc_identity {
	unsigned char applet[7];
	uint16_t file;

	unsigned char *label;

	size_t certificate_len;
	unsigned char *certificate;

	ssize_t keysize;
};

struct cackey_identity {
521
522
523
524
525
526
527


528
529
530
531
532
533
534
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534







+
+







	SCARDHANDLE pcsc_card;

	int transaction_depth;

	int slot_reset;

	CK_FLAGS token_flags;

	unsigned char *label;
};

typedef enum {
	CACKEY_TLV_APP_GENERIC = 0x01,
	CACKEY_TLV_APP_SKI     = 0x02,
	CACKEY_TLV_APP_PKI     = 0x04
} cackey_tlv_apptype;
647
648
649
650
651
652
653






654
655
656
657
658
659
660
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666







+
+
+
+
+
+








	for (idx = 0; idx < (sizeof(cackey_slots) / sizeof(cackey_slots[0])); idx++) {
		if (cackey_slots[idx].pcsc_card_connected) {
			CACKEY_DEBUG_PRINTF("SCardDisconnect(%lu) called", (unsigned long) idx);

			SCardDisconnect(cackey_slots[idx].pcsc_card, SCARD_LEAVE_CARD);
		}

		if (cackey_slots[idx].label) {
			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);
		}
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1790
1791
1792
1793
1794
1795
1796

1797
1798
1799
1800
1801
1802
1803







-







			}

			curr_id = &certs[outidx];
			outidx++;

			memcpy(curr_id->applet, curr_aid, sizeof(curr_id->applet));
			curr_id->file = ccc_curr->value_cardurl->objectid;
			curr_id->label = NULL;
			curr_id->keysize = -1;

			CACKEY_DEBUG_PRINTF("Filling curr_id->applet (%p) with %lu bytes:", curr_id->applet, (unsigned long) sizeof(curr_id->applet));
			CACKEY_DEBUG_PRINTBUF("VAL:", curr_id->applet, sizeof(curr_id->applet));

			curr_id->certificate_len = app_curr->length;

2168
2169
2170
2171
2172
2173
2174




2175
2176






2177


2178
2179
2180
2181
2182









































2183
2184
2185
2186
2187
2188
2189
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183


2184
2185
2186
2187
2188
2189
2190
2191
2192





2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240







+
+
+
+
-
-
+
+
+
+
+
+

+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







 *     ...
 *
 * NOTES
 *     ...
 *
 */
static cackey_ret cackey_token_present(struct cackey_slot *slot) {
	cackey_ret pcsc_connect_ret;
	DWORD reader_len, state, protocol, atr_len;
	BYTE atr[MAX_ATR_SIZE];
	LONG status_ret, scard_reconn_ret;
	unsigned char ccc_aid[] = {GSCIS_AID_CCC};
	int send_ret;

	CACKEY_DEBUG_PRINTF("Called.");

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

		return(CACKEY_PCSC_S_TOKENABSENT);
	}
	/* Select the CCC Applet */
	send_ret = cackey_select_applet(slot, ccc_aid, sizeof(ccc_aid));
	if (send_ret != CACKEY_PCSC_S_OK) {
		return(CACKEY_PCSC_S_TOKENABSENT);
	}

	atr_len = sizeof(atr);
	status_ret = SCardStatus(slot->pcsc_card, NULL, &reader_len, &state, &protocol, atr, &atr_len);
	if (status_ret != SCARD_S_SUCCESS) {
		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);
			if (scard_reconn_ret == SCARD_S_SUCCESS) {
				/* 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));

					return(CACKEY_PCSC_S_TOKENABSENT);
				}
			} else {
				CACKEY_DEBUG_PRINTF("Unable to reconnect to card, returning token absent.  SCardReconnect() = %s", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_reconn_ret));

				return(CACKEY_PCSC_S_TOKENABSENT);
			}
		} else {
			CACKEY_DEBUG_PRINTF("Unable to query card status, returning token absent.  SCardStatus() = %s", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(status_ret));

			return(CACKEY_PCSC_S_TOKENABSENT);
		}
	}

	if ((state & SCARD_ABSENT) == SCARD_ABSENT) {
		CACKEY_DEBUG_PRINTF("Card is absent, returning token absent");

		return(CACKEY_PCSC_S_TOKENABSENT);
	}

	CACKEY_DEBUG_PRINTF("Returning token present.");

	return(CACKEY_PCSC_S_TOKENPRESENT);
}

/*
 * SYNPOSIS
 *     ...
2813
2814
2815
2816
2817
2818
2819

2820
2821
2822
2823
2824
2825
2826
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878







+








	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;

	if (!cackey_biglock_init) {
		mutex_init_ret = cackey_mutex_create(&cackey_biglock);

2946
2947
2948
2949
2950
2951
2952


2953
2954
2955
2956
2957
2958
2959
2960
2961






2962
2963
2964
2965
2966
2967
2968
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028







+
+









+
+
+
+
+
+







		CACKEY_DEBUG_PRINTF("Error.  Locking failed.");

		return(CKR_GENERAL_ERROR);
	}

	/* Clear list of slots */
	if (pSlotList) {
		CACKEY_DEBUG_PRINTF("Purging all slot information.");

		/* Only update the list of slots if we are actually being supply the slot information */
		cackey_slots_disconnect_all();

		for (currslot = 0; currslot < (sizeof(cackey_slots) / sizeof(cackey_slots[0])); currslot++) {
			if (cackey_slots[currslot].pcsc_reader) {
				free(cackey_slots[currslot].pcsc_reader);

				cackey_slots[currslot].pcsc_reader = NULL;
			}

			if (cackey_slots[currslot].label) {
				free(cackey_slots[currslot].label);

				cackey_slots[currslot].label = NULL;
			}

			cackey_slots[currslot].active = 0;
		}
	}

	/* Determine list of readers */
	pcsc_connect_ret = cackey_pcsc_connect();
2998
2999
3000
3001
3002
3003
3004
3005

3006
3007
3008
3009
3010
3011
3012

3013
3014
3015
3016
3017
3018
3019
3058
3059
3060
3061
3062
3063
3064

3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080







-
+







+







						CACKEY_DEBUG_PRINTF("Found more readers than slots are available!");

						break;
					}

					CACKEY_DEBUG_PRINTF("Found reader: %s", pcsc_readers);

					/* Only update the list of slots if we are actually being supply the slot information */
					/* 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;
				}

				if (currslot > 0) {
3199
3200
3201
3202
3203
3204
3205

3206
3207
3208
3209
3210
3211
3212
3213
3214
3215



















3216
3217
3218
3219
3220
3221
3222
3260
3261
3262
3263
3264
3265
3266
3267










3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293







+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







		return(CKR_GENERAL_ERROR);
	}

	/* Determine token label from certificates */
	memset(pInfo->label, ' ', sizeof(pInfo->label));
	use_default_label = 1;

	if (cackey_slots[slotID].label == NULL) {
	pcsc_identities = cackey_read_certs(&cackey_slots[slotID], NULL, &num_certs);
	if (pcsc_identities != NULL) {
		if (num_certs > 0) {
			label_ret = cackey_pcsc_identity_to_label(pcsc_identities, pInfo->label, sizeof(pInfo->label));
			if (label_ret > 0) {
				use_default_label = 0;
			}
		}

		cackey_free_certs(pcsc_identities, num_certs, 1);
		pcsc_identities = cackey_read_certs(&cackey_slots[slotID], NULL, &num_certs);
		if (pcsc_identities != NULL) {
			if (num_certs > 0) {
				label_ret = cackey_pcsc_identity_to_label(pcsc_identities, pInfo->label, sizeof(pInfo->label));
				if (label_ret > 0) {
					use_default_label = 0;

					cackey_slots[slotID].label = malloc(sizeof(pInfo->label));

					memcpy(cackey_slots[slotID].label, pInfo->label, sizeof(pInfo->label));
				}
			}

			cackey_free_certs(pcsc_identities, num_certs, 1);
		}
	} else {
		memcpy(pInfo->label, cackey_slots[slotID].label, sizeof(pInfo->label));

		use_default_label = 0;
	}

	if (use_default_label) {
		memcpy(pInfo->label, defaultLabel, sizeof(defaultLabel) - 1);
	}

	memset(pInfo->manufacturerID, ' ', sizeof(pInfo->manufacturerID));
4073
4074
4075
4076
4077
4078
4079





4080
4081
4082
4083
4084
4085
4086
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162







+
+
+
+
+








		if (cackey_sessions[hSession].identities != NULL) {
			cackey_free_identities(cackey_sessions[hSession].identities, cackey_sessions[hSession].identities_count);

			cackey_sessions[hSession].identities = NULL;
			cackey_sessions[hSession].identities_count = 0;
		}

		if (cackey_slots[cackey_sessions[hSession].slotID].label != NULL) {
			free(cackey_slots[cackey_sessions[hSession].slotID].label);
			cackey_slots[cackey_sessions[hSession].slotID].label = NULL;
		}

		cackey_slots[cackey_sessions[hSession].slotID].slot_reset = 0;
		cackey_slots[cackey_sessions[hSession].slotID].token_flags = CKF_LOGIN_REQUIRED;
	}

	if (cackey_sessions[hSession].identities == NULL) {
		cackey_sessions[hSession].identities = cackey_read_identities(&cackey_slots[cackey_sessions[hSession].slotID], &cackey_sessions[hSession].identities_count);