Diff

Differences From Artifact [e8f3ee7748]:

To Artifact [4cc11579bd]:


1757
1758
1759
1760
1761
1762
1763



1764
1765
1766
1767
1768
1769
1770
....
1809
1810
1811
1812
1813
1814
1815

1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827

1828
1829
1830
1831
1832
1833
1834
1835
....
1846
1847
1848
1849
1850
1851
1852

1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
....
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
....
2477
2478
2479
2480
2481
2482
2483





































































2484
2485
2486
2487
2488
2489
2490
....
3171
3172
3173
3174
3175
3176
3177

3178
3179
3180
3181
3182
3183
3184
....
3201
3202
3203
3204
3205
3206
3207



3208
3209
3210
3211
3212
3213
3214
....
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
....
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
....
4538
4539
4540
4541
4542
4543
4544


4545
4546
4547
4548
4549
4550
4551
....
4730
4731
4732
4733
4734
4735
4736

4737
4738
4739
4740
4741
4742
4743
			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->certificate_len = app_curr->length;

			curr_id->certificate = malloc(curr_id->certificate_len);
			memcpy(curr_id->certificate, app_curr->value, curr_id->certificate_len);

			if (outidx >= *count) {
				if (certs_resizable) {
................................................................................
 *
 * NOTES
 *     ...
 *
 */
static ssize_t cackey_signdecrypt(struct cackey_slot *slot, struct cackey_identity *identity, unsigned char *buf, size_t buflen, unsigned char *outbuf, size_t outbuflen) {
	cackey_ret send_ret;


	CACKEY_DEBUG_PRINTF("Called.");

	if (buflen > 255) {
		CACKEY_DEBUG_PRINTF("Error.  buflen is greater than 255 (buflen = %lu)", (unsigned long) buflen);

		return(-1);
	}

	if (outbuflen > 255) {
		CACKEY_DEBUG_PRINTF("Error.  outbuflen is grater than 255 (outbuflen = %lu)", (unsigned long) outbuflen);


		return(-1);
	}

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

		return(-1);
	}
................................................................................
		return(-1);
	}

	/* Begin transaction */
	cackey_begin_transaction(slot);

	/* Select correct applet */

	cackey_select_applet(slot, identity->identity->applet, sizeof(identity->identity->applet));

	/* Select correct file */
	cackey_select_file(slot, identity->identity->file);

	send_ret = cackey_send_apdu(slot, GSCIS_CLASS_GLOBAL_PLATFORM, GSCIS_INSTR_SIGNDECRYPT, 0x00, 0x00, buflen, buf, outbuflen, NULL, outbuf, &outbuflen);
	if (send_ret != CACKEY_PCSC_S_OK) {
		CACKEY_DEBUG_PRINTF("ADPU Sending Failed -- returning in error.");

		/* End transaction */
		cackey_end_transaction(slot);

		return(-1);
................................................................................
	}

	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 == NULL || 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;
	CK_VOID_PTR pValue;
................................................................................

	*pulCount = numattrs;

	CACKEY_DEBUG_PRINTF("Returning %lu objects (%p).", numattrs, retval);

	return(retval);
}






































































CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(CK_VOID_PTR pInitArgs) {
	CK_C_INITIALIZE_ARGS CK_PTR args;
	uint32_t idx;
	int mutex_init_ret;

	CACKEY_DEBUG_PRINTF("Called.");
................................................................................

		cackey_mutex_unlock(cackey_biglock);

		return(CKR_SLOT_ID_INVALID);
	}

	/* Verify that the card is actually in the slot. */

	if (cackey_token_present(&cackey_slots[slotID]) != CACKEY_PCSC_S_TOKENPRESENT) {
		CACKEY_DEBUG_PRINTF("Error.  Card not present.  Returning CKR_DEVICE_REMOVED");

		cackey_mutex_unlock(cackey_biglock);

		return(CKR_DEVICE_REMOVED);
	}
................................................................................
			cackey_sessions[idx].identities_count = 0;

			cackey_sessions[idx].search_active = 0;

			cackey_sessions[idx].sign_active = 0;

			cackey_sessions[idx].decrypt_active = 0;




			break;
		}
	}

	mutex_retval = cackey_mutex_unlock(cackey_biglock);
	if (mutex_retval != 0) {
................................................................................

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

	return(CKR_FUNCTION_NOT_SUPPORTED);
}

CK_DEFINE_FUNCTION(CK_RV, C_FindObjectsInit)(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) {
	struct cackey_pcsc_identity *pcsc_identities;
	struct cackey_identity *identities;
	unsigned long num_ids, id_idx, curr_id_type;
	unsigned long num_certs, cert_idx;
	int mutex_retval;

	CACKEY_DEBUG_PRINTF("Called.");

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

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

		cackey_slots[cackey_sessions[hSession].slotID].slot_reset = 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;

			identities = malloc(num_ids * sizeof(*identities));

			id_idx = 0;
			for (cert_idx = 0; cert_idx < num_certs; cert_idx++) {
				for (curr_id_type = CKO_CERTIFICATE; curr_id_type <= CKO_PRIVATE_KEY; curr_id_type++) {
					identities[id_idx].attributes = cackey_get_attributes(curr_id_type, &pcsc_identities[cert_idx], cert_idx, &identities[id_idx].attributes_count);

					if (identities[id_idx].attributes == NULL) {
						identities[id_idx].attributes_count = 0;
					}

					id_idx++;
				}
			}

			cackey_sessions[hSession].identities = identities;
			cackey_sessions[hSession].identities_count = num_ids;

			cackey_free_certs(pcsc_identities, num_certs, 1);
		}
	}

	if (pTemplate != NULL) {
		if (ulCount != 0) {
			cackey_sessions[hSession].search_query_count = ulCount;
			cackey_sessions[hSession].search_query = malloc(ulCount * sizeof(*pTemplate));

................................................................................
	cackey_sessions[hSession].sign_active = 1;

	cackey_sessions[hSession].sign_mechanism = pMechanism->mechanism;

	cackey_sessions[hSession].sign_buflen = 128;
	cackey_sessions[hSession].sign_bufused = 0;
	cackey_sessions[hSession].sign_buf = malloc(sizeof(*cackey_sessions[hSession].sign_buf) * cackey_sessions[hSession].sign_buflen);


	cackey_sessions[hSession].sign_identity = &cackey_sessions[hSession].identities[hKey];

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

		return(CKR_GENERAL_ERROR);
................................................................................
		
		return(CKR_OPERATION_NOT_INITIALIZED);
	}

	switch (cackey_sessions[hSession].sign_mechanism) {
		case CKM_RSA_PKCS:
			/* Ask card to sign */

			sigbuflen = cackey_signdecrypt(&cackey_slots[cackey_sessions[hSession].slotID], cackey_sessions[hSession].sign_identity, cackey_sessions[hSession].sign_buf, cackey_sessions[hSession].sign_buflen, sigbuf, sizeof(sigbuf));

			if (sigbuflen < 0) {
				/* Signing failed. */
				retval = CKR_GENERAL_ERROR;
			} else if (((unsigned long) sigbuflen) > *pulSignatureLen && pSignature) {
				/* Signed data too large */







>
>
>







 







>









|
|
<
>
|







 







>





|







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







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







 







>







 







>
>
>







 







<
<
<
<







 







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







 







>
>







 







>







1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
....
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
....
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
....
2115
2116
2117
2118
2119
2120
2121

























2122
2123
2124
2125
2126
2127
2128
....
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
....
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
....
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
....
3774
3775
3776
3777
3778
3779
3780




3781
3782
3783
3784
3785
3786
3787
....
3827
3828
3829
3830
3831
3832
3833
3834
























3835
3836
3837
3838
3839
3840
3841
....
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
....
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
			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;

			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;

			curr_id->certificate = malloc(curr_id->certificate_len);
			memcpy(curr_id->certificate, app_curr->value, curr_id->certificate_len);

			if (outidx >= *count) {
				if (certs_resizable) {
................................................................................
 *
 * NOTES
 *     ...
 *
 */
static ssize_t cackey_signdecrypt(struct cackey_slot *slot, struct cackey_identity *identity, unsigned char *buf, size_t buflen, unsigned char *outbuf, size_t outbuflen) {
	cackey_ret send_ret;
	int le;

	CACKEY_DEBUG_PRINTF("Called.");

	if (buflen > 255) {
		CACKEY_DEBUG_PRINTF("Error.  buflen is greater than 255 (buflen = %lu)", (unsigned long) buflen);

		return(-1);
	}

	if (outbuflen > 253) {
		le = 253;

	} else {
		le = outbuflen;
	}

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

		return(-1);
	}
................................................................................
		return(-1);
	}

	/* Begin transaction */
	cackey_begin_transaction(slot);

	/* Select correct applet */
	CACKEY_DEBUG_PRINTF("Selecting applet found at %p ...", identity->identity->applet);
	cackey_select_applet(slot, identity->identity->applet, sizeof(identity->identity->applet));

	/* Select correct file */
	cackey_select_file(slot, identity->identity->file);

	send_ret = cackey_send_apdu(slot, GSCIS_CLASS_GLOBAL_PLATFORM, GSCIS_INSTR_SIGNDECRYPT, 0x00, 0x00, buflen, buf, le, NULL, outbuf, &outbuflen);
	if (send_ret != CACKEY_PCSC_S_OK) {
		CACKEY_DEBUG_PRINTF("ADPU Sending Failed -- returning in error.");

		/* End transaction */
		cackey_end_transaction(slot);

		return(-1);
................................................................................
	}

	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;
	CK_VOID_PTR pValue;
................................................................................

	*pulCount = numattrs;

	CACKEY_DEBUG_PRINTF("Returning %lu objects (%p).", numattrs, retval);

	return(retval);
}

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 == NULL || 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 struct cackey_identity *cackey_read_identities(struct cackey_slot *slot, unsigned long *ids_found) {
	struct cackey_pcsc_identity *pcsc_identities;
	struct cackey_identity *identities;
	unsigned long num_ids, id_idx, curr_id_type;
	unsigned long num_certs, cert_idx;

	CACKEY_DEBUG_PRINTF("Called.");

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

		return(NULL);
	}

	pcsc_identities = cackey_read_certs(slot, 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;

		identities = malloc(num_ids * sizeof(*identities));

		id_idx = 0;
		for (cert_idx = 0; cert_idx < num_certs; cert_idx++) {
			for (curr_id_type = CKO_CERTIFICATE; curr_id_type <= CKO_PRIVATE_KEY; curr_id_type++) {
				identities[id_idx].attributes = cackey_get_attributes(curr_id_type, &pcsc_identities[cert_idx], cert_idx, &identities[id_idx].attributes_count);

				if (identities[id_idx].attributes == NULL) {
					identities[id_idx].attributes_count = 0;
				}

				id_idx++;
			}
		}

		cackey_free_certs(pcsc_identities, num_certs, 1);

		*ids_found = num_ids;
		return(identities);
	}

	*ids_found = 0;
	return(NULL);
}

CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(CK_VOID_PTR pInitArgs) {
	CK_C_INITIALIZE_ARGS CK_PTR args;
	uint32_t idx;
	int mutex_init_ret;

	CACKEY_DEBUG_PRINTF("Called.");
................................................................................

		cackey_mutex_unlock(cackey_biglock);

		return(CKR_SLOT_ID_INVALID);
	}

	/* Verify that the card is actually in the slot. */
	/* XXX: Check to make sure this is in the PKCS#11 specification */
	if (cackey_token_present(&cackey_slots[slotID]) != CACKEY_PCSC_S_TOKENPRESENT) {
		CACKEY_DEBUG_PRINTF("Error.  Card not present.  Returning CKR_DEVICE_REMOVED");

		cackey_mutex_unlock(cackey_biglock);

		return(CKR_DEVICE_REMOVED);
	}
................................................................................
			cackey_sessions[idx].identities_count = 0;

			cackey_sessions[idx].search_active = 0;

			cackey_sessions[idx].sign_active = 0;

			cackey_sessions[idx].decrypt_active = 0;

			cackey_sessions[idx].identities = cackey_read_identities(&cackey_slots[slotID], &cackey_sessions[idx].identities_count);


			break;
		}
	}

	mutex_retval = cackey_mutex_unlock(cackey_biglock);
	if (mutex_retval != 0) {
................................................................................

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

	return(CKR_FUNCTION_NOT_SUPPORTED);
}

CK_DEFINE_FUNCTION(CK_RV, C_FindObjectsInit)(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) {




	int mutex_retval;

	CACKEY_DEBUG_PRINTF("Called.");

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

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

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

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
























	}

	if (pTemplate != NULL) {
		if (ulCount != 0) {
			cackey_sessions[hSession].search_query_count = ulCount;
			cackey_sessions[hSession].search_query = malloc(ulCount * sizeof(*pTemplate));

................................................................................
	cackey_sessions[hSession].sign_active = 1;

	cackey_sessions[hSession].sign_mechanism = pMechanism->mechanism;

	cackey_sessions[hSession].sign_buflen = 128;
	cackey_sessions[hSession].sign_bufused = 0;
	cackey_sessions[hSession].sign_buf = malloc(sizeof(*cackey_sessions[hSession].sign_buf) * cackey_sessions[hSession].sign_buflen);

	CACKEY_DEBUG_PRINTF("Session %lu sign_identity is %p (identitie #%lu)", (unsigned long) hSession, &cackey_sessions[hSession].identities[hKey], (unsigned long) hKey);
	cackey_sessions[hSession].sign_identity = &cackey_sessions[hSession].identities[hKey];

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

		return(CKR_GENERAL_ERROR);
................................................................................
		
		return(CKR_OPERATION_NOT_INITIALIZED);
	}

	switch (cackey_sessions[hSession].sign_mechanism) {
		case CKM_RSA_PKCS:
			/* Ask card to sign */
			CACKEY_DEBUG_PRINTF("Asking to decrypt from identity %p in session %lu", cackey_sessions[hSession].sign_identity, (unsigned long) hSession);
			sigbuflen = cackey_signdecrypt(&cackey_slots[cackey_sessions[hSession].slotID], cackey_sessions[hSession].sign_identity, cackey_sessions[hSession].sign_buf, cackey_sessions[hSession].sign_buflen, sigbuf, sizeof(sigbuf));

			if (sigbuflen < 0) {
				/* Signing failed. */
				retval = CKR_GENERAL_ERROR;
			} else if (((unsigned long) sigbuflen) > *pulSignatureLen && pSignature) {
				/* Signed data too large */