Check-in [1b3d82054b]
Overview
Comment: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

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:1b3d82054ba6dbc4c9cdbe81851420742a339173
User & Date: rkeene on 2010-05-14 22:10:13
Other Links: manifest | tags
Context
2010-05-14
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

20:50
Added support for reading label from CAC as string check-in: 2f0a97a3f1 user: rkeene tags: trunk
Changes

Modified cackey.c from [be5fbbbf72] to [97ac9efbb9].

  1812   1812   	send_ret = cackey_select_applet(slot, ccc_aid, sizeof(ccc_aid));
  1813   1813   	if (send_ret != CACKEY_PCSC_S_OK) {
  1814   1814   		return(CACKEY_PCSC_S_TOKENABSENT);
  1815   1815   	}
  1816   1816   
  1817   1817   	return(CACKEY_PCSC_S_TOKENPRESENT);
  1818   1818   }
         1819  +
         1820  +/*
         1821  + * SYNPOSIS
         1822  + *     ...
         1823  + *
         1824  + * ARGUMENTS
         1825  + *     ...
         1826  + *
         1827  + * RETURN VALUE
         1828  + *     ...
         1829  + *
         1830  + * NOTES
         1831  + *     ...
         1832  + *
         1833  + */
         1834  +static ssize_t cackey_pcsc_identity_to_label(struct cackey_pcsc_identity *identity, unsigned char *label_buf, unsigned long label_buf_len) {
         1835  +	unsigned long certificate_len;
         1836  +	char *label_asn1;
         1837  +	void *certificate;
         1838  +	int x509_read_ret;
         1839  +
         1840  +	certificate = identity->certificate;
         1841  +	certificate_len = identity->certificate_len;
         1842  +
         1843  +	if (certificate_len < 0) {
         1844  +		return(-1);
         1845  +	}
         1846  +
         1847  +	x509_read_ret = x509_to_subject(certificate, certificate_len, (void **) &label_asn1);
         1848  +	if (x509_read_ret < 0) {
         1849  +		return(-1);
         1850  +	}
         1851  +
         1852  +	x509_read_ret = x509_dn_to_string(label_asn1, x509_read_ret, (char *) label_buf, label_buf_len, "CN");
         1853  +	if (x509_read_ret <= 0) {
         1854  +		x509_read_ret = x509_dn_to_string(label_asn1, x509_read_ret, (char *) label_buf, label_buf_len, NULL);
         1855  +
         1856  +		if (x509_read_ret <= 0) {
         1857  +			return(-1);
         1858  +		}
         1859  +	}
         1860  +
         1861  +	return(x509_read_ret);
         1862  +}
  1819   1863   
  1820   1864   /* Returns 0 on success */
  1821   1865   static int cackey_mutex_create(void **mutex) {
  1822   1866   	pthread_mutex_t *pthread_mutex;
  1823   1867   	int pthread_retval;
  1824   1868   	CK_RV custom_retval;
  1825   1869   
................................................................................
  1921   1965   		}
  1922   1966   	}
  1923   1967   
  1924   1968   	CACKEY_DEBUG_PRINTF("Returning sucessfully (0)");
  1925   1969   
  1926   1970   	return(0);
  1927   1971   }
         1972  +
         1973  +static void cackey_free_identities(struct cackey_identity *identities, unsigned long identities_count) {
         1974  +	CK_ATTRIBUTE *curr_attr;
         1975  +	unsigned long id_idx, attr_idx;
         1976  +
         1977  +	if (identities || identities_count == 0) {
         1978  +		return;
         1979  +	}
         1980  +
         1981  +	for (id_idx = 0; id_idx < identities_count; id_idx++) {
         1982  +		if (identities[id_idx].attributes) {
         1983  +			for (attr_idx = 0; attr_idx < identities[id_idx].attributes_count; attr_idx++) {
         1984  +				curr_attr = &identities[id_idx].attributes[attr_idx];
         1985  +
         1986  +				if (curr_attr->pValue) {
         1987  +					free(curr_attr->pValue);
         1988  +				}
         1989  +			}
         1990  +
         1991  +			free(identities[id_idx].attributes);
         1992  +		}
         1993  +	}
         1994  +
         1995  +	free(identities);
         1996  +}
  1928   1997   
  1929   1998   static CK_ATTRIBUTE_PTR cackey_get_attributes(CK_OBJECT_CLASS objectclass, struct cackey_pcsc_identity *identity, unsigned long identity_num, CK_ULONG_PTR pulCount) {
  1930   1999   	static CK_BBOOL ck_true = 1;
  1931   2000   	static CK_BBOOL ck_false = 0;
  1932   2001   	CK_ULONG numattrs = 0, retval_count;
  1933   2002   	CK_ATTRIBUTE_TYPE curr_attr_type;
  1934   2003   	CK_ATTRIBUTE curr_attr, *retval;
................................................................................
  2015   2084   				CACKEY_DEBUG_PRINTF(" ... returning %lu (%p/%lu)", (unsigned long) *((CK_BBOOL *) pValue), pValue, (unsigned long) ulValueLen);
  2016   2085   
  2017   2086   				break;
  2018   2087   			case CKA_LABEL:
  2019   2088   				CACKEY_DEBUG_PRINTF("Requesting attribute CKA_LABEL (0x%08lx) ...", (unsigned long) curr_attr_type);
  2020   2089   
  2021   2090   				/* Determine name */
  2022         -				if (certificate_len >= 0) {
  2023         -					x509_read_ret = x509_to_subject(certificate, certificate_len, &pValue);
         2091  +				x509_read_ret = cackey_pcsc_identity_to_label(identity, ucTmpBuf, sizeof(ucTmpBuf));
  2024   2092   					if (x509_read_ret > 0) {
  2025         -						x509_read_ret = x509_dn_to_string(pValue, x509_read_ret, (char *) ucTmpBuf, sizeof(ucTmpBuf), "CN");
  2026         -						if (x509_read_ret <= 0) {
  2027         -							x509_read_ret = x509_dn_to_string(pValue, x509_read_ret, (char *) ucTmpBuf, sizeof(ucTmpBuf), NULL);
  2028         -
  2029         -							if (x509_read_ret <= 0) {
  2030         -								pValue = NULL;
  2031         -							} else {
  2032   2093   								pValue = ucTmpBuf;
  2033   2094   								ulValueLen = x509_read_ret;
  2034   2095   							}
  2035         -						} else {
  2036         -							pValue = ucTmpBuf;
  2037         -							ulValueLen = x509_read_ret;
  2038         -						}
  2039         -					} else {
  2040         -						pValue = NULL;
  2041         -					}
  2042         -				}
  2043   2096   
  2044   2097   				CACKEY_DEBUG_PRINTF(" ... returning (%p/%lu)", pValue, (unsigned long) ulValueLen);
  2045   2098   
  2046   2099   				break;
  2047   2100   			case CKA_VALUE:
  2048   2101   				CACKEY_DEBUG_PRINTF("Requesting attribute CKA_VALUE (0x%08lx) ...", (unsigned long) curr_attr_type);
  2049   2102   
................................................................................
  2649   2702   	return(CKR_OK);
  2650   2703   }
  2651   2704   
  2652   2705   CK_DEFINE_FUNCTION(CK_RV, C_GetTokenInfo)(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) {
  2653   2706   	static CK_UTF8CHAR manufacturerID[] = "U.S. Government";
  2654   2707   	static CK_UTF8CHAR defaultLabel[] = "Unknown Token";
  2655   2708   	static CK_UTF8CHAR model[] = "CAC Token";
         2709  +	struct cackey_pcsc_identity *pcsc_identities;
         2710  +	unsigned long num_certs;
         2711  +	ssize_t label_ret;
  2656   2712   	int mutex_retval;
         2713  +	int use_default_label;
  2657   2714   
  2658   2715   	CACKEY_DEBUG_PRINTF("Called.");
  2659   2716   
  2660   2717   	if (pInfo == NULL) {
  2661   2718   		CACKEY_DEBUG_PRINTF("Error. pInfo is NULL.");
  2662   2719   
  2663   2720   		return(CKR_ARGUMENTS_BAD);
................................................................................
  2701   2758   	mutex_retval = cackey_mutex_unlock(cackey_biglock);
  2702   2759   	if (mutex_retval != 0) {
  2703   2760   		CACKEY_DEBUG_PRINTF("Error.  Unlocking failed.");
  2704   2761   
  2705   2762   		return(CKR_GENERAL_ERROR);
  2706   2763   	}
  2707   2764   
         2765  +	/* Determine token label from certificates */
  2708   2766   	memset(pInfo->label, ' ', sizeof(pInfo->label));
  2709         -	if (1) {
         2767  +	use_default_label = 1;
         2768  +
         2769  +	pcsc_identities = cackey_read_certs(&cackey_slots[slotID], NULL, &num_certs);
         2770  +	if (pcsc_identities != NULL) {
         2771  +		if (num_certs > 0) {
         2772  +			label_ret = cackey_pcsc_identity_to_label(pcsc_identities, pInfo->label, sizeof(pInfo->label));
         2773  +			if (label_ret > 0) {
         2774  +				use_default_label = 0;
         2775  +			}
         2776  +		}
         2777  +
         2778  +		cackey_free_certs(pcsc_identities, num_certs, 1);
         2779  +	}
         2780  +
         2781  +	if (use_default_label) {
  2710   2782   		memcpy(pInfo->label, defaultLabel, sizeof(defaultLabel) - 1);
  2711         -	} else {
  2712   2783   	}
  2713   2784   
  2714   2785   	memset(pInfo->manufacturerID, ' ', sizeof(pInfo->manufacturerID));
  2715   2786   	memcpy(pInfo->manufacturerID, manufacturerID, sizeof(manufacturerID) - 1);
  2716   2787   
  2717   2788   	memset(pInfo->model, ' ', sizeof(pInfo->model));
  2718   2789   	memcpy(pInfo->model, model, sizeof(model) - 1);
................................................................................
  3006   3077   
  3007   3078   	CACKEY_DEBUG_PRINTF("Returning CKR_OK (%i)", CKR_OK);
  3008   3079   
  3009   3080   	return(CKR_OK);
  3010   3081   }
  3011   3082   
  3012   3083   CK_DEFINE_FUNCTION(CK_RV, C_CloseSession)(CK_SESSION_HANDLE hSession) {
  3013         -	CK_ATTRIBUTE *curr_attr;
  3014         -	unsigned long id_idx, attr_idx;
  3015   3084   	int mutex_retval;
  3016   3085   
  3017   3086   	CACKEY_DEBUG_PRINTF("Called.");
  3018   3087   
  3019   3088   	if (!cackey_initialized) {
  3020   3089   		CACKEY_DEBUG_PRINTF("Error.  Not initialized.");
  3021   3090   
................................................................................
  3040   3109   
  3041   3110   		CACKEY_DEBUG_PRINTF("Error.  Session not active.");
  3042   3111   		
  3043   3112   		return(CKR_SESSION_HANDLE_INVALID);
  3044   3113   	}
  3045   3114   
  3046   3115   	cackey_sessions[hSession].active = 0;
  3047         -	if (cackey_sessions[hSession].identities) {
  3048         -		for (id_idx = 0; id_idx < cackey_sessions[hSession].identities_count; id_idx++) {
  3049         -			if (cackey_sessions[hSession].identities[id_idx].attributes) {
  3050         -				for (attr_idx = 0; attr_idx < cackey_sessions[hSession].identities[id_idx].attributes_count; attr_idx++) {
  3051         -					curr_attr = &cackey_sessions[hSession].identities[id_idx].attributes[attr_idx];
  3052         -
  3053         -					if (curr_attr->pValue) {
  3054         -						free(curr_attr->pValue);
  3055         -					}
  3056         -				}
  3057         -
  3058         -				free(cackey_sessions[hSession].identities[id_idx].attributes);
  3059         -			}
  3060         -		}
  3061         -
  3062         -		free(cackey_sessions[hSession].identities);
  3063         -	}
         3116  +	cackey_free_identities(cackey_sessions[hSession].identities, cackey_sessions[hSession].identities_count);
  3064   3117   
  3065   3118   	mutex_retval = cackey_mutex_unlock(cackey_biglock);
  3066   3119   	if (mutex_retval != 0) {
  3067   3120   		CACKEY_DEBUG_PRINTF("Error.  Unlocking failed.");
  3068   3121   
  3069   3122   		return(CKR_GENERAL_ERROR);
  3070   3123   	}
................................................................................
  3562   3615   	if (cackey_sessions[hSession].search_active) {
  3563   3616   		cackey_mutex_unlock(cackey_biglock);
  3564   3617   
  3565   3618   		CACKEY_DEBUG_PRINTF("Error.  Search already active.");
  3566   3619   		
  3567   3620   		return(CKR_OPERATION_ACTIVE);
  3568   3621   	}
         3622  +
         3623  +	if (cackey_sessions[hSession].identities != NULL) {
         3624  +		cackey_free_identities(cackey_sessions[hSession].identities, cackey_sessions[hSession].identities_count);
         3625  +
         3626  +		cackey_sessions[hSession].identities = NULL;
         3627  +		cackey_sessions[hSession].identities_count = 0;
         3628  +	}
  3569   3629   
  3570   3630   	if (cackey_sessions[hSession].identities == NULL) {
  3571   3631   		pcsc_identities = cackey_read_certs(&cackey_slots[cackey_sessions[hSession].slotID], NULL, &num_certs);
  3572   3632   		if (pcsc_identities != NULL) {
  3573   3633   			/* Convert number of Certs to number of objects */
  3574   3634   			num_ids = (CKO_PRIVATE_KEY - CKO_CERTIFICATE + 1) * num_certs;
  3575   3635   
................................................................................
  3700   3760   		cackey_mutex_unlock(cackey_biglock);
  3701   3761   
  3702   3762   		CACKEY_DEBUG_PRINTF("Error.  Search not active.");
  3703   3763   		
  3704   3764   		return(CKR_OPERATION_NOT_INITIALIZED);
  3705   3765   	}
  3706   3766   
  3707         -	curr_id_idx = 0;
  3708   3767   	curr_out_id_idx = 0;
  3709   3768   	for (curr_id_idx = cackey_sessions[hSession].search_curr_id; curr_id_idx < cackey_sessions[hSession].identities_count && ulMaxObjectCount; curr_id_idx++) {
  3710   3769   		curr_id = &cackey_sessions[hSession].identities[curr_id_idx];
  3711   3770   
  3712   3771   		CACKEY_DEBUG_PRINTF("Processing identity:%lu", (unsigned long) curr_id_idx);
  3713   3772   
  3714   3773   		matched_count = 0;