Check-in [f006b206b1]
Overview
Comment:Fixed memory leaks

Updated to only rescan for identities if a slot reset has been detected

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:f006b206b1065aedfb1de964c59c435123539363
User & Date: rkeene on 2010-05-14 23:11:47
Other Links: manifest | tags
Context
2010-05-14
23:33
Added untested support for Sign/Decrypt check-in: fc063dd0df user: rkeene tags: trunk
23:11
Fixed memory leaks

Updated to only rescan for identities if a slot reset has been detected check-in: f006b206b1 user: rkeene tags: trunk

22:10
Wrote function for freeing identities

Wrote function for determining label from identity

Consolidated freeing of identities to use new function

Consolidated label lookups to use new function

Fixed bug with releasing identities, but not reducing the number of identities check-in: 1b3d82054b user: rkeene tags: trunk

Changes

Modified cackey.c from [97ac9efbb9] to [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   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   
         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");
         3676  +
  3623   3677   	if (cackey_sessions[hSession].identities != NULL) {
  3624   3678   		cackey_free_identities(cackey_sessions[hSession].identities, cackey_sessions[hSession].identities_count);
  3625   3679   
  3626   3680   		cackey_sessions[hSession].identities = NULL;
  3627   3681   		cackey_sessions[hSession].identities_count = 0;
  3628   3682   	}
         3683  +
         3684  +		cackey_slots[cackey_sessions[hSession].slotID].slot_reset = 0;
         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;
  3635   3692