Diff

Differences From Artifact [97ac9efbb9]:

To Artifact [ab26d90d17]:


   492    492   
   493    493   	char *pcsc_reader;
   494    494   
   495    495   	int pcsc_card_connected;
   496    496   	SCARDHANDLE pcsc_card;
   497    497   
   498    498   	int transaction_depth;
          499  +
          500  +	int slot_reset;
   499    501   };
   500    502   
   501    503   typedef enum {
   502    504   	CACKEY_TLV_APP_GENERIC = 0x01,
   503    505   	CACKEY_TLV_APP_SKI     = 0x02,
   504    506   	CACKEY_TLV_APP_PKI     = 0x04
   505    507   } cackey_tlv_apptype;
................................................................................
   621    623   			CACKEY_DEBUG_PRINTF("SCardDisconnect(%lu) called", (unsigned long) idx);
   622    624   
   623    625   			SCardDisconnect(cackey_slots[idx].pcsc_card, SCARD_LEAVE_CARD);
   624    626   		}
   625    627   
   626    628   		cackey_slots[idx].pcsc_card_connected = 0;
   627    629   		cackey_slots[idx].transaction_depth = 0;
          630  +
          631  +		if (cackey_slots[idx].active) {
          632  +			CACKEY_DEBUG_PRINTF("Marking active slot %lu as being reset", (unsigned long) idx);
          633  +		}
          634  +
          635  +		cackey_slots[idx].slot_reset = 1;
   628    636   	}
   629    637   
   630    638   	CACKEY_DEBUG_PRINTF("Returning");
   631    639   
   632    640   	return;
   633    641   }
   634    642   
................................................................................
   698    706   		}
   699    707   
   700    708   		CACKEY_DEBUG_PRINTF("Handle has been re-established");
   701    709   	}
   702    710   #endif
   703    711   
   704    712   	CACKEY_DEBUG_PRINTF("Sucessfully connected to PC/SC, returning in success");
          713  +
          714  +	return(CACKEY_PCSC_S_OK);
          715  +}
          716  +
          717  +/*
          718  + * SYNPOSIS
          719  + *     cackey_ret cackey_pcsc_disconnect(void);
          720  + *
          721  + * ARGUMENTS
          722  + *     None
          723  + *
          724  + * RETURN VALUE
          725  + *     CACKEY_PCSC_S_OK         On success
          726  + *     CACKEY_PCSC_E_GENERIC    On error
          727  + *
          728  + * NOTES
          729  + *     This function disconnects from the PC/SC Connection manager and updates
          730  + *     the global handle.
          731  + *
          732  + */
          733  +static cackey_ret cackey_pcsc_disconnect(void) {
          734  +	LONG scard_rel_context_ret;
          735  +
          736  +	CACKEY_DEBUG_PRINTF("Called.");
          737  +
          738  +	if (cackey_pcsc_handle == NULL) {
          739  +		return(CACKEY_PCSC_S_OK);
          740  +	}
          741  +
          742  +	scard_rel_context_ret = SCardReleaseContext(*cackey_pcsc_handle);
          743  +
          744  +	free(cackey_pcsc_handle);
          745  +	cackey_pcsc_handle = NULL;
          746  +
          747  +	if (scard_rel_context_ret != SCARD_S_SUCCESS) {
          748  +		return(CACKEY_PCSC_E_GENERIC);
          749  +	}
   705    750   
   706    751   	return(CACKEY_PCSC_S_OK);
   707    752   }
   708    753   
   709    754   /*
   710    755    * SYNPOSIS
   711    756    *     cackey_ret cackey_connect_card(struct cackey_slot *slot);
................................................................................
   976   1021   
   977   1022   	CACKEY_DEBUG_PRINTBUF("Sending APDU:", xmit_buf, xmit_len);
   978   1023   
   979   1024   	recv_len = sizeof(recv_buf);
   980   1025   	scard_xmit_ret = SCardTransmit(slot->pcsc_card, SCARD_PCI_T0, xmit_buf, xmit_len, SCARD_PCI_T1, recv_buf, &recv_len);
   981   1026   	if (scard_xmit_ret != SCARD_S_SUCCESS) {
   982   1027   		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);
         1028  +		CACKEY_DEBUG_PRINTF("Marking slot as having been reset");
   983   1029   
   984   1030   		slot->transaction_depth = 0;
         1031  +		slot->slot_reset = 1;
   985   1032   
   986   1033   		if (scard_xmit_ret == SCARD_W_RESET_CARD) {
   987   1034   			CACKEY_DEBUG_PRINTF("Reset required, please hold...");
   988   1035   
   989   1036   			scard_reconn_ret = SCardReconnect(slot->pcsc_card, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, SCARD_RESET_CARD, &protocol);
   990   1037   			if (scard_reconn_ret == SCARD_S_SUCCESS) {
   991   1038   				/* Re-establish transaction, if it was present */
................................................................................
  1593   1640   
  1594   1641   	if (count == NULL) {
  1595   1642   		CACKEY_DEBUG_PRINTF("count is NULL, returning in failure");
  1596   1643   
  1597   1644   		return(NULL);
  1598   1645   	}
  1599   1646   
  1600         -	if (*count == 0) {
  1601         -		if (certs != NULL) {
         1647  +	if (certs != NULL) {
         1648  +		if (*count == 0) {
  1602   1649   			CACKEY_DEBUG_PRINTF("Requested we return 0 objects, short-circuit");
  1603   1650   
  1604   1651   			return(certs);
  1605   1652   		}
  1606   1653   	}
  1607   1654   
  1608   1655   	/* Begin a SmartCard transaction */
................................................................................
  1970   2017   	return(0);
  1971   2018   }
  1972   2019   
  1973   2020   static void cackey_free_identities(struct cackey_identity *identities, unsigned long identities_count) {
  1974   2021   	CK_ATTRIBUTE *curr_attr;
  1975   2022   	unsigned long id_idx, attr_idx;
  1976   2023   
  1977         -	if (identities || identities_count == 0) {
         2024  +	if (identities == NULL || identities_count == 0) {
  1978   2025   		return;
  1979   2026   	}
  1980   2027   
  1981   2028   	for (id_idx = 0; id_idx < identities_count; id_idx++) {
  1982   2029   		if (identities[id_idx].attributes) {
  1983   2030   			for (attr_idx = 0; attr_idx < identities[id_idx].attributes_count; attr_idx++) {
  1984   2031   				curr_attr = &identities[id_idx].attributes[attr_idx];
................................................................................
  2380   2427   		cackey_sessions[idx].active = 0;
  2381   2428   	}
  2382   2429   
  2383   2430   	for (idx = 0; idx < (sizeof(cackey_slots) / sizeof(cackey_slots[0])); idx++) {
  2384   2431   		cackey_slots[idx].active = 0;
  2385   2432   		cackey_slots[idx].pcsc_reader = NULL;
  2386   2433   		cackey_slots[idx].transaction_depth = 0;
         2434  +		cackey_slots[idx].slot_reset = 0;
  2387   2435   	}
  2388   2436   
  2389   2437   	cackey_initialized = 1;
  2390   2438   
  2391   2439   	if (!cackey_biglock_init) {
  2392   2440   		mutex_init_ret = cackey_mutex_create(&cackey_biglock);
  2393   2441   
................................................................................
  2431   2479   	cackey_slots_disconnect_all();
  2432   2480   
  2433   2481   	for (idx = 0; idx < (sizeof(cackey_slots) / sizeof(cackey_slots[0])); idx++) {
  2434   2482   		if (cackey_slots[idx].pcsc_reader) {
  2435   2483   			free(cackey_slots[idx].pcsc_reader);
  2436   2484   		}
  2437   2485   	}
         2486  +
         2487  +	cackey_pcsc_disconnect();
  2438   2488   
  2439   2489   	cackey_initialized = 0;
  2440   2490   
  2441   2491   	CACKEY_DEBUG_PRINTF("Returning CKR_OK (%i)", CKR_OK);
  2442   2492   
  2443   2493   	return(CKR_OK);
  2444   2494   }
................................................................................
  2569   2619   
  2570   2620   					/* Only update the list of slots if we are actually being supply the slot information */
  2571   2621   					if (pSlotList) {
  2572   2622   						cackey_slots[currslot].active = 1;
  2573   2623   						cackey_slots[currslot].pcsc_reader = strdup(pcsc_readers);
  2574   2624   						cackey_slots[currslot].pcsc_card_connected = 0;
  2575   2625   						cackey_slots[currslot].transaction_depth = 0;
         2626  +						cackey_slots[currslot].slot_reset = 1;
  2576   2627   					}
  2577   2628   					currslot++;
  2578   2629   
  2579   2630   					pcsc_readers += curr_reader_len + 1;
  2580   2631   				}
  2581   2632   
  2582   2633   				if (currslot > 0) {
................................................................................
  2616   2667   
  2617   2668   	for (currslot = 0; currslot < slot_count; currslot++) {
  2618   2669   		pSlotList[currslot] = currslot;
  2619   2670   	}
  2620   2671   
  2621   2672   	*pulCount = slot_count;
  2622   2673   
  2623         -	CACKEY_DEBUG_PRINTF("Returning CKR_OK (%i)", CKR_OK);
         2674  +	CACKEY_DEBUG_PRINTF("Returning CKR_OK (%i).  Found %lu readers.", CKR_OK, (unsigned long) slot_count);
  2624   2675   
  2625   2676   	return(CKR_OK);
  2626   2677   
  2627   2678   	tokenPresent = tokenPresent; /* Supress unused variable warning */
  2628   2679   }
  2629   2680   
  2630   2681   CK_DEFINE_FUNCTION(CK_RV, C_GetSlotInfo)(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
................................................................................
  3616   3667   		cackey_mutex_unlock(cackey_biglock);
  3617   3668   
  3618   3669   		CACKEY_DEBUG_PRINTF("Error.  Search already active.");
  3619   3670   		
  3620   3671   		return(CKR_OPERATION_ACTIVE);
  3621   3672   	}
  3622   3673   
  3623         -	if (cackey_sessions[hSession].identities != NULL) {
  3624         -		cackey_free_identities(cackey_sessions[hSession].identities, cackey_sessions[hSession].identities_count);
         3674  +	if (cackey_slots[cackey_sessions[hSession].slotID].slot_reset) {
         3675  +		CACKEY_DEBUG_PRINTF("The slot has been reset since we last looked for identities -- rescanning");
  3625   3676   
  3626         -		cackey_sessions[hSession].identities = NULL;
  3627         -		cackey_sessions[hSession].identities_count = 0;
         3677  +		if (cackey_sessions[hSession].identities != NULL) {
         3678  +			cackey_free_identities(cackey_sessions[hSession].identities, cackey_sessions[hSession].identities_count);
         3679  +
         3680  +			cackey_sessions[hSession].identities = NULL;
         3681  +			cackey_sessions[hSession].identities_count = 0;
         3682  +		}
         3683  +
         3684  +		cackey_slots[cackey_sessions[hSession].slotID].slot_reset = 0;
  3628   3685   	}
  3629   3686   
  3630   3687   	if (cackey_sessions[hSession].identities == NULL) {
  3631   3688   		pcsc_identities = cackey_read_certs(&cackey_slots[cackey_sessions[hSession].slotID], NULL, &num_certs);
  3632   3689   		if (pcsc_identities != NULL) {
  3633   3690   			/* Convert number of Certs to number of objects */
  3634   3691   			num_ids = (CKO_PRIVATE_KEY - CKO_CERTIFICATE + 1) * num_certs;