Diff

Differences From Artifact [be5fbbbf72]:

To Artifact [97ac9efbb9]:


1812
1813
1814
1815
1816
1817
1818












































1819
1820
1821
1822
1823
1824
1825
....
1921
1922
1923
1924
1925
1926
1927

























1928
1929
1930
1931
1932
1933
1934
....
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
....
2649
2650
2651
2652
2653
2654
2655



2656

2657
2658
2659
2660
2661
2662
2663
....
2701
2702
2703
2704
2705
2706
2707

2708
2709















2710
2711
2712
2713
2714
2715
2716
2717
2718
....
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
....
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
....
3562
3563
3564
3565
3566
3567
3568







3569
3570
3571
3572
3573
3574
3575
....
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
	send_ret = cackey_select_applet(slot, ccc_aid, sizeof(ccc_aid));
	if (send_ret != CACKEY_PCSC_S_OK) {
		return(CACKEY_PCSC_S_TOKENABSENT);
	}

	return(CACKEY_PCSC_S_TOKENPRESENT);
}













































/* Returns 0 on success */
static int cackey_mutex_create(void **mutex) {
	pthread_mutex_t *pthread_mutex;
	int pthread_retval;
	CK_RV custom_retval;

................................................................................
		}
	}

	CACKEY_DEBUG_PRINTF("Returning sucessfully (0)");

	return(0);
}


























static CK_ATTRIBUTE_PTR cackey_get_attributes(CK_OBJECT_CLASS objectclass, struct cackey_pcsc_identity *identity, unsigned long identity_num, CK_ULONG_PTR pulCount) {
	static CK_BBOOL ck_true = 1;
	static CK_BBOOL ck_false = 0;
	CK_ULONG numattrs = 0, retval_count;
	CK_ATTRIBUTE_TYPE curr_attr_type;
	CK_ATTRIBUTE curr_attr, *retval;
................................................................................
				CACKEY_DEBUG_PRINTF(" ... returning %lu (%p/%lu)", (unsigned long) *((CK_BBOOL *) pValue), pValue, (unsigned long) ulValueLen);

				break;
			case CKA_LABEL:
				CACKEY_DEBUG_PRINTF("Requesting attribute CKA_LABEL (0x%08lx) ...", (unsigned long) curr_attr_type);

				/* Determine name */
				if (certificate_len >= 0) {
					x509_read_ret = x509_to_subject(certificate, certificate_len, &pValue);
					if (x509_read_ret > 0) {
						x509_read_ret = x509_dn_to_string(pValue, x509_read_ret, (char *) ucTmpBuf, sizeof(ucTmpBuf), "CN");
						if (x509_read_ret <= 0) {
							x509_read_ret = x509_dn_to_string(pValue, x509_read_ret, (char *) ucTmpBuf, sizeof(ucTmpBuf), NULL);

							if (x509_read_ret <= 0) {
								pValue = NULL;
							} else {
								pValue = ucTmpBuf;
								ulValueLen = x509_read_ret;
							}
						} else {
							pValue = ucTmpBuf;
							ulValueLen = x509_read_ret;
						}
					} else {
						pValue = NULL;
					}
				}

				CACKEY_DEBUG_PRINTF(" ... returning (%p/%lu)", pValue, (unsigned long) ulValueLen);

				break;
			case CKA_VALUE:
				CACKEY_DEBUG_PRINTF("Requesting attribute CKA_VALUE (0x%08lx) ...", (unsigned long) curr_attr_type);
................................................................................
	return(CKR_OK);
}

CK_DEFINE_FUNCTION(CK_RV, C_GetTokenInfo)(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) {
	static CK_UTF8CHAR manufacturerID[] = "U.S. Government";
	static CK_UTF8CHAR defaultLabel[] = "Unknown Token";
	static CK_UTF8CHAR model[] = "CAC Token";



	int mutex_retval;


	CACKEY_DEBUG_PRINTF("Called.");

	if (pInfo == NULL) {
		CACKEY_DEBUG_PRINTF("Error. pInfo is NULL.");

		return(CKR_ARGUMENTS_BAD);
................................................................................
	mutex_retval = cackey_mutex_unlock(cackey_biglock);
	if (mutex_retval != 0) {
		CACKEY_DEBUG_PRINTF("Error.  Unlocking failed.");

		return(CKR_GENERAL_ERROR);
	}


	memset(pInfo->label, ' ', sizeof(pInfo->label));
	if (1) {















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

	memset(pInfo->manufacturerID, ' ', sizeof(pInfo->manufacturerID));
	memcpy(pInfo->manufacturerID, manufacturerID, sizeof(manufacturerID) - 1);

	memset(pInfo->model, ' ', sizeof(pInfo->model));
	memcpy(pInfo->model, model, sizeof(model) - 1);
................................................................................

	CACKEY_DEBUG_PRINTF("Returning CKR_OK (%i)", CKR_OK);

	return(CKR_OK);
}

CK_DEFINE_FUNCTION(CK_RV, C_CloseSession)(CK_SESSION_HANDLE hSession) {
	CK_ATTRIBUTE *curr_attr;
	unsigned long id_idx, attr_idx;
	int mutex_retval;

	CACKEY_DEBUG_PRINTF("Called.");

	if (!cackey_initialized) {
		CACKEY_DEBUG_PRINTF("Error.  Not initialized.");

................................................................................

		CACKEY_DEBUG_PRINTF("Error.  Session not active.");
		
		return(CKR_SESSION_HANDLE_INVALID);
	}

	cackey_sessions[hSession].active = 0;
	if (cackey_sessions[hSession].identities) {
		for (id_idx = 0; id_idx < cackey_sessions[hSession].identities_count; id_idx++) {
			if (cackey_sessions[hSession].identities[id_idx].attributes) {
				for (attr_idx = 0; attr_idx < cackey_sessions[hSession].identities[id_idx].attributes_count; attr_idx++) {
					curr_attr = &cackey_sessions[hSession].identities[id_idx].attributes[attr_idx];

					if (curr_attr->pValue) {
						free(curr_attr->pValue);
					}
				}

				free(cackey_sessions[hSession].identities[id_idx].attributes);
			}
		}

		free(cackey_sessions[hSession].identities);
	}

	mutex_retval = cackey_mutex_unlock(cackey_biglock);
	if (mutex_retval != 0) {
		CACKEY_DEBUG_PRINTF("Error.  Unlocking failed.");

		return(CKR_GENERAL_ERROR);
	}
................................................................................
	if (cackey_sessions[hSession].search_active) {
		cackey_mutex_unlock(cackey_biglock);

		CACKEY_DEBUG_PRINTF("Error.  Search already active.");
		
		return(CKR_OPERATION_ACTIVE);
	}








	if (cackey_sessions[hSession].identities == NULL) {
		pcsc_identities = cackey_read_certs(&cackey_slots[cackey_sessions[hSession].slotID], NULL, &num_certs);
		if (pcsc_identities != NULL) {
			/* Convert number of Certs to number of objects */
			num_ids = (CKO_PRIVATE_KEY - CKO_CERTIFICATE + 1) * num_certs;

................................................................................
		cackey_mutex_unlock(cackey_biglock);

		CACKEY_DEBUG_PRINTF("Error.  Search not active.");
		
		return(CKR_OPERATION_NOT_INITIALIZED);
	}

	curr_id_idx = 0;
	curr_out_id_idx = 0;
	for (curr_id_idx = cackey_sessions[hSession].search_curr_id; curr_id_idx < cackey_sessions[hSession].identities_count && ulMaxObjectCount; curr_id_idx++) {
		curr_id = &cackey_sessions[hSession].identities[curr_id_idx];

		CACKEY_DEBUG_PRINTF("Processing identity:%lu", (unsigned long) curr_id_idx);

		matched_count = 0;







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
<
|
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<







 







>
>
>

>







 







>

<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

<







 







<
<







 







|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







>
>
>
>
>
>
>







 







<







1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
....
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
....
2084
2085
2086
2087
2088
2089
2090
2091

2092







2093
2094








2095
2096
2097
2098
2099
2100
2101
....
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
....
2758
2759
2760
2761
2762
2763
2764
2765
2766

2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782

2783
2784
2785
2786
2787
2788
2789
....
3077
3078
3079
3080
3081
3082
3083


3084
3085
3086
3087
3088
3089
3090
....
3109
3110
3111
3112
3113
3114
3115
3116
















3117
3118
3119
3120
3121
3122
3123
....
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
....
3760
3761
3762
3763
3764
3765
3766

3767
3768
3769
3770
3771
3772
3773
	send_ret = cackey_select_applet(slot, ccc_aid, sizeof(ccc_aid));
	if (send_ret != CACKEY_PCSC_S_OK) {
		return(CACKEY_PCSC_S_TOKENABSENT);
	}

	return(CACKEY_PCSC_S_TOKENPRESENT);
}

/*
 * SYNPOSIS
 *     ...
 *
 * ARGUMENTS
 *     ...
 *
 * RETURN VALUE
 *     ...
 *
 * NOTES
 *     ...
 *
 */
static ssize_t cackey_pcsc_identity_to_label(struct cackey_pcsc_identity *identity, unsigned char *label_buf, unsigned long label_buf_len) {
	unsigned long certificate_len;
	char *label_asn1;
	void *certificate;
	int x509_read_ret;

	certificate = identity->certificate;
	certificate_len = identity->certificate_len;

	if (certificate_len < 0) {
		return(-1);
	}

	x509_read_ret = x509_to_subject(certificate, certificate_len, (void **) &label_asn1);
	if (x509_read_ret < 0) {
		return(-1);
	}

	x509_read_ret = x509_dn_to_string(label_asn1, x509_read_ret, (char *) label_buf, label_buf_len, "CN");
	if (x509_read_ret <= 0) {
		x509_read_ret = x509_dn_to_string(label_asn1, x509_read_ret, (char *) label_buf, label_buf_len, NULL);

		if (x509_read_ret <= 0) {
			return(-1);
		}
	}

	return(x509_read_ret);
}

/* Returns 0 on success */
static int cackey_mutex_create(void **mutex) {
	pthread_mutex_t *pthread_mutex;
	int pthread_retval;
	CK_RV custom_retval;

................................................................................
		}
	}

	CACKEY_DEBUG_PRINTF("Returning sucessfully (0)");

	return(0);
}

static void cackey_free_identities(struct cackey_identity *identities, unsigned long identities_count) {
	CK_ATTRIBUTE *curr_attr;
	unsigned long id_idx, attr_idx;

	if (identities || identities_count == 0) {
		return;
	}

	for (id_idx = 0; id_idx < identities_count; id_idx++) {
		if (identities[id_idx].attributes) {
			for (attr_idx = 0; attr_idx < identities[id_idx].attributes_count; attr_idx++) {
				curr_attr = &identities[id_idx].attributes[attr_idx];

				if (curr_attr->pValue) {
					free(curr_attr->pValue);
				}
			}

			free(identities[id_idx].attributes);
		}
	}

	free(identities);
}

static CK_ATTRIBUTE_PTR cackey_get_attributes(CK_OBJECT_CLASS objectclass, struct cackey_pcsc_identity *identity, unsigned long identity_num, CK_ULONG_PTR pulCount) {
	static CK_BBOOL ck_true = 1;
	static CK_BBOOL ck_false = 0;
	CK_ULONG numattrs = 0, retval_count;
	CK_ATTRIBUTE_TYPE curr_attr_type;
	CK_ATTRIBUTE curr_attr, *retval;
................................................................................
				CACKEY_DEBUG_PRINTF(" ... returning %lu (%p/%lu)", (unsigned long) *((CK_BBOOL *) pValue), pValue, (unsigned long) ulValueLen);

				break;
			case CKA_LABEL:
				CACKEY_DEBUG_PRINTF("Requesting attribute CKA_LABEL (0x%08lx) ...", (unsigned long) curr_attr_type);

				/* Determine name */
				x509_read_ret = cackey_pcsc_identity_to_label(identity, ucTmpBuf, sizeof(ucTmpBuf));

				if (x509_read_ret > 0) {







					pValue = ucTmpBuf;
					ulValueLen = x509_read_ret;








				}

				CACKEY_DEBUG_PRINTF(" ... returning (%p/%lu)", pValue, (unsigned long) ulValueLen);

				break;
			case CKA_VALUE:
				CACKEY_DEBUG_PRINTF("Requesting attribute CKA_VALUE (0x%08lx) ...", (unsigned long) curr_attr_type);
................................................................................
	return(CKR_OK);
}

CK_DEFINE_FUNCTION(CK_RV, C_GetTokenInfo)(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) {
	static CK_UTF8CHAR manufacturerID[] = "U.S. Government";
	static CK_UTF8CHAR defaultLabel[] = "Unknown Token";
	static CK_UTF8CHAR model[] = "CAC Token";
	struct cackey_pcsc_identity *pcsc_identities;
	unsigned long num_certs;
	ssize_t label_ret;
	int mutex_retval;
	int use_default_label;

	CACKEY_DEBUG_PRINTF("Called.");

	if (pInfo == NULL) {
		CACKEY_DEBUG_PRINTF("Error. pInfo is NULL.");

		return(CKR_ARGUMENTS_BAD);
................................................................................
	mutex_retval = cackey_mutex_unlock(cackey_biglock);
	if (mutex_retval != 0) {
		CACKEY_DEBUG_PRINTF("Error.  Unlocking failed.");

		return(CKR_GENERAL_ERROR);
	}

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

	use_default_label = 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_free_certs(pcsc_identities, num_certs, 1);
	}

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

	}

	memset(pInfo->manufacturerID, ' ', sizeof(pInfo->manufacturerID));
	memcpy(pInfo->manufacturerID, manufacturerID, sizeof(manufacturerID) - 1);

	memset(pInfo->model, ' ', sizeof(pInfo->model));
	memcpy(pInfo->model, model, sizeof(model) - 1);
................................................................................

	CACKEY_DEBUG_PRINTF("Returning CKR_OK (%i)", CKR_OK);

	return(CKR_OK);
}

CK_DEFINE_FUNCTION(CK_RV, C_CloseSession)(CK_SESSION_HANDLE hSession) {


	int mutex_retval;

	CACKEY_DEBUG_PRINTF("Called.");

	if (!cackey_initialized) {
		CACKEY_DEBUG_PRINTF("Error.  Not initialized.");

................................................................................

		CACKEY_DEBUG_PRINTF("Error.  Session not active.");
		
		return(CKR_SESSION_HANDLE_INVALID);
	}

	cackey_sessions[hSession].active = 0;
	cackey_free_identities(cackey_sessions[hSession].identities, cackey_sessions[hSession].identities_count);

















	mutex_retval = cackey_mutex_unlock(cackey_biglock);
	if (mutex_retval != 0) {
		CACKEY_DEBUG_PRINTF("Error.  Unlocking failed.");

		return(CKR_GENERAL_ERROR);
	}
................................................................................
	if (cackey_sessions[hSession].search_active) {
		cackey_mutex_unlock(cackey_biglock);

		CACKEY_DEBUG_PRINTF("Error.  Search already active.");
		
		return(CKR_OPERATION_ACTIVE);
	}

	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_sessions[hSession].identities == NULL) {
		pcsc_identities = cackey_read_certs(&cackey_slots[cackey_sessions[hSession].slotID], NULL, &num_certs);
		if (pcsc_identities != NULL) {
			/* Convert number of Certs to number of objects */
			num_ids = (CKO_PRIVATE_KEY - CKO_CERTIFICATE + 1) * num_certs;

................................................................................
		cackey_mutex_unlock(cackey_biglock);

		CACKEY_DEBUG_PRINTF("Error.  Search not active.");
		
		return(CKR_OPERATION_NOT_INITIALIZED);
	}


	curr_out_id_idx = 0;
	for (curr_id_idx = cackey_sessions[hSession].search_curr_id; curr_id_idx < cackey_sessions[hSession].identities_count && ulMaxObjectCount; curr_id_idx++) {
		curr_id = &cackey_sessions[hSession].identities[curr_id_idx];

		CACKEY_DEBUG_PRINTF("Processing identity:%lu", (unsigned long) curr_id_idx);

		matched_count = 0;