Diff

Differences From Artifact [fd9c15d1e5]:

To Artifact [7a1e8d322f]:


63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84

#include "pkcs11.h"
#include "pkcs11n.h"
#include "asn1-x509.h"
#include "sha1.h"
#include "md5.h"

/*
 * Include these source files in this translation unit so that we can bind to
 * functions and not include any symbols in the output shared object.
 */
#include "asn1-x509.c"
#include "sha1.c"
#include "md5.c"

#ifndef CACKEY_CRYPTOKI_VERSION_CODE
#  define CACKEY_CRYPTOKI_VERSION_CODE 0x021e00
#endif

/* GSC-IS v2.1 Definitions */
/** Classes **/
#define GSCIS_CLASS_ISO7816           0x00







<
<
<
<
<
<
<
<







63
64
65
66
67
68
69








70
71
72
73
74
75
76

#include "pkcs11.h"
#include "pkcs11n.h"
#include "asn1-x509.h"
#include "sha1.h"
#include "md5.h"









#ifndef CACKEY_CRYPTOKI_VERSION_CODE
#  define CACKEY_CRYPTOKI_VERSION_CODE 0x021e00
#endif

/* GSC-IS v2.1 Definitions */
/** Classes **/
#define GSCIS_CLASS_ISO7816           0x00
226
227
228
229
230
231
232

233
234
235
236
237
238
239
#  define CACKEY_DEBUG_PRINTBUF(f, x, y) { \
	static char buf_user[4096] = {0}, *buf_user_p; \
	unsigned long buf_user_size; \
	unsigned char *TMPBUF; \
	unsigned long idx; \
	int snprintf_ret; \
	TMPBUF = (unsigned char *) (x); \

	buf_user_p = buf_user; \
	buf_user_size = sizeof(buf_user); \
	for (idx = 1; idx < (y); idx++) { \
		if (buf_user_size <= 0) { \
			break; \
		}; \
		snprintf_ret = snprintf(buf_user_p, buf_user_size, ", %02x", TMPBUF[idx]); \







>







218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
#  define CACKEY_DEBUG_PRINTBUF(f, x, y) { \
	static char buf_user[4096] = {0}, *buf_user_p; \
	unsigned long buf_user_size; \
	unsigned char *TMPBUF; \
	unsigned long idx; \
	int snprintf_ret; \
	TMPBUF = (unsigned char *) (x); \
	buf_user[0] = 0; \
	buf_user_p = buf_user; \
	buf_user_size = sizeof(buf_user); \
	for (idx = 1; idx < (y); idx++) { \
		if (buf_user_size <= 0) { \
			break; \
		}; \
		snprintf_ret = snprintf(buf_user_p, buf_user_size, ", %02x", TMPBUF[idx]); \
718
719
720
721
722
723
724








725
726
727
728
729
730
731
#  define CACKEY_DEBUG_FUNC_TAG_TO_STR(x) "DEBUG_DISABLED"
#  define CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(x) "DEBUG_DISABLED"
#  define CACKEY_DEBUG_FUNC_OBJID_TO_STR(x) "DEBUG_DISABLED"
#  define CACKEY_DEBUG_FUNC_APPTYPE_TO_STR(x) "DEBUG_DISABLED"
#  define CACKEY_DEBUG_FUNC_ATTRIBUTE_TO_STR(x) "DEBUG_DISABLED"
#endif









typedef enum {
	CACKEY_ID_TYPE_CAC,
	CACKEY_ID_TYPE_PIV,
	CACKEY_ID_TYPE_CERT_ONLY
} cackey_pcsc_id_type;

struct cackey_pcsc_identity {







>
>
>
>
>
>
>
>







711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
#  define CACKEY_DEBUG_FUNC_TAG_TO_STR(x) "DEBUG_DISABLED"
#  define CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(x) "DEBUG_DISABLED"
#  define CACKEY_DEBUG_FUNC_OBJID_TO_STR(x) "DEBUG_DISABLED"
#  define CACKEY_DEBUG_FUNC_APPTYPE_TO_STR(x) "DEBUG_DISABLED"
#  define CACKEY_DEBUG_FUNC_ATTRIBUTE_TO_STR(x) "DEBUG_DISABLED"
#endif

/*
 * Include these source files in this translation unit so that we can bind to
 * functions and not include any symbols in the output shared object.
 */
#include "asn1-x509.c"
#include "sha1.c"
#include "md5.c"

typedef enum {
	CACKEY_ID_TYPE_CAC,
	CACKEY_ID_TYPE_PIV,
	CACKEY_ID_TYPE_CERT_ONLY
} cackey_pcsc_id_type;

struct cackey_pcsc_identity {
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
		CACKEY_DEBUG_PRINTF("Connection to PC/SC failed, returning in failure");

		return(CACKEY_PCSC_E_GENERIC);
	}

	/* Connect to reader, if needed */
	if (!slot->pcsc_card_connected) {
		CACKEY_DEBUG_PRINTF("SCardConnect(%s) called", slot->pcsc_reader);
		scard_conn_ret = SCardConnect(*cackey_pcsc_handle, slot->pcsc_reader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &slot->pcsc_card, &protocol);

		if (scard_conn_ret == SCARD_E_PROTO_MISMATCH) {
			CACKEY_DEBUG_PRINTF("SCardConnect() returned SCARD_E_PROTO_MISMATCH, trying with just T=0")
			scard_conn_ret = SCardConnect(*cackey_pcsc_handle, slot->pcsc_reader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &slot->pcsc_card, &protocol);

			if (scard_conn_ret == SCARD_E_PROTO_MISMATCH) {







|







1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
		CACKEY_DEBUG_PRINTF("Connection to PC/SC failed, returning in failure");

		return(CACKEY_PCSC_E_GENERIC);
	}

	/* Connect to reader, if needed */
	if (!slot->pcsc_card_connected) {
		CACKEY_DEBUG_PRINTF("SCardConnect(%s) called for slot %p", slot->pcsc_reader, slot);
		scard_conn_ret = SCardConnect(*cackey_pcsc_handle, slot->pcsc_reader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &slot->pcsc_card, &protocol);

		if (scard_conn_ret == SCARD_E_PROTO_MISMATCH) {
			CACKEY_DEBUG_PRINTF("SCardConnect() returned SCARD_E_PROTO_MISMATCH, trying with just T=0")
			scard_conn_ret = SCardConnect(*cackey_pcsc_handle, slot->pcsc_reader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &slot->pcsc_card, &protocol);

			if (scard_conn_ret == SCARD_E_PROTO_MISMATCH) {
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443




2444
2445
2446
2447
2448
2449
2450
 */
static struct cackey_pcsc_identity *cackey_read_certs(struct cackey_slot *slot, struct cackey_pcsc_identity *certs, unsigned long *count) {
	struct cackey_pcsc_identity *curr_id;
	struct cackey_tlv_entity *ccc_tlv, *ccc_curr, *app_tlv, *app_curr;
	unsigned char ccc_aid[] = {GSCIS_AID_CCC}, piv_aid[] = {NISTSP800_73_3_PIV_AID};
	unsigned char *piv_oid, piv_oid_pivauth[] = {NISTSP800_73_3_OID_PIVAUTH}, piv_oid_signature[] = {NISTSP800_73_3_OID_SIGNATURE}, piv_oid_keymgt[] = {NISTSP800_73_3_OID_KEYMGT};
	unsigned char curr_aid[7];
	unsigned char buffer[8192], *buffer_p;
	unsigned long outidx = 0;
	char *piv_label;
	cackey_ret transaction_ret;
	ssize_t read_ret;
	size_t buffer_len;
	int certs_resizable;
	int send_ret, select_ret;
	int piv_key, piv = 0;
	int idx;





	CACKEY_DEBUG_PRINTF("Called.");

	if (count == NULL) {
		CACKEY_DEBUG_PRINTF("count is NULL, returning in failure");

		return(NULL);







|




|




>
>
>
>







2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
 */
static struct cackey_pcsc_identity *cackey_read_certs(struct cackey_slot *slot, struct cackey_pcsc_identity *certs, unsigned long *count) {
	struct cackey_pcsc_identity *curr_id;
	struct cackey_tlv_entity *ccc_tlv, *ccc_curr, *app_tlv, *app_curr;
	unsigned char ccc_aid[] = {GSCIS_AID_CCC}, piv_aid[] = {NISTSP800_73_3_PIV_AID};
	unsigned char *piv_oid, piv_oid_pivauth[] = {NISTSP800_73_3_OID_PIVAUTH}, piv_oid_signature[] = {NISTSP800_73_3_OID_SIGNATURE}, piv_oid_keymgt[] = {NISTSP800_73_3_OID_KEYMGT};
	unsigned char curr_aid[7];
	unsigned char buffer[8192], *buffer_p, *tmpbuf;
	unsigned long outidx = 0;
	char *piv_label;
	cackey_ret transaction_ret;
	ssize_t read_ret;
	size_t buffer_len, tmpbuflen;
	int certs_resizable;
	int send_ret, select_ret;
	int piv_key, piv = 0;
	int idx;
#ifdef HAVE_LIBZ
	int uncompress_ret;
	z_stream gzip_stream;
#endif

	CACKEY_DEBUG_PRINTF("Called.");

	if (count == NULL) {
		CACKEY_DEBUG_PRINTF("count is NULL, returning in failure");

		return(NULL);
2554
2555
2556
2557
2558
2559
2560

2561
2562


2563
2564
2565
2566













































2567
2568
2569
2570
2571
2572
2573
			curr_id->certificate = malloc(curr_id->certificate_len);

			buffer_len = sizeof(buffer);
			buffer_p = cackey_read_bertlv_tag(buffer, &buffer_len, 0x70, curr_id->certificate, &curr_id->certificate_len);

			if (buffer_p == NULL) {
				CACKEY_DEBUG_PRINTF("Reading certificate from BER-TLV response failed, skipping key %i", idx);

				free(curr_id->certificate);



				outidx--;

				continue;
			}













































		}
	} else {
		/* Read all the applets from the CCC's TLV */
		ccc_tlv = cackey_read_tlv(slot);

		/* Look for CARDURLs that coorespond to PKI applets */
		for (ccc_curr = ccc_tlv; ccc_curr; ccc_curr = ccc_curr->_next) {







>


>
>




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







2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
			curr_id->certificate = malloc(curr_id->certificate_len);

			buffer_len = sizeof(buffer);
			buffer_p = cackey_read_bertlv_tag(buffer, &buffer_len, 0x70, curr_id->certificate, &curr_id->certificate_len);

			if (buffer_p == NULL) {
				CACKEY_DEBUG_PRINTF("Reading certificate from BER-TLV response failed, skipping key %i", idx);

				free(curr_id->certificate);

				curr_id->certificate = NULL;

				outidx--;

				continue;
			}

#ifdef HAVE_LIBZ
			if (curr_id->certificate_len > 4) {
				if (memcmp(curr_id->certificate, "\x1f\x8b\x08\x00", 4) == 0) {
					tmpbuflen = curr_id->certificate_len * 2;
					tmpbuf = malloc(tmpbuflen);

					CACKEY_DEBUG_PRINTBUF("Attempting to decompress:", curr_id->certificate, curr_id->certificate_len);

					gzip_stream.zalloc = NULL;
					gzip_stream.zfree = NULL;
					gzip_stream.opaque = NULL;

					gzip_stream.next_in  = curr_id->certificate;
					gzip_stream.avail_in = curr_id->certificate_len;
					gzip_stream.next_out = tmpbuf;
					gzip_stream.avail_out = tmpbuflen;

					uncompress_ret = inflateInit(&gzip_stream);
					if (uncompress_ret == Z_OK) {
						uncompress_ret = inflateReset2(&gzip_stream, 31);
					}
					if (uncompress_ret == Z_OK) {
						uncompress_ret = inflate(&gzip_stream, 0);
					}
					if (uncompress_ret == Z_STREAM_END) {
						uncompress_ret = inflateEnd(&gzip_stream);
					} else {
						uncompress_ret = Z_DATA_ERROR;
					}
					if (uncompress_ret == Z_OK) {
						CACKEY_DEBUG_PRINTBUF("Decompressed to:", tmpbuf, tmpbuflen);

						free(curr_id->certificate);

						curr_id->certificate = tmpbuf;
						curr_id->certificate_len = tmpbuflen;
					} else {
						CACKEY_DEBUG_PRINTF("Decompressing failed! uncompress() returned %i", uncompress_ret);

						free(tmpbuf);
					}
				}
			}
#endif
		}
	} else {
		/* Read all the applets from the CCC's TLV */
		ccc_tlv = cackey_read_tlv(slot);

		/* Look for CARDURLs that coorespond to PKI applets */
		for (ccc_curr = ccc_tlv; ccc_curr; ccc_curr = ccc_curr->_next) {
2635
2636
2637
2638
2639
2640
2641

2642



2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661

2662



2663
2664
2665
2666
2667
2668
2669

				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) {
						*count *= 2;

						certs = realloc(certs, sizeof(*certs) * (*count));



					} else {
						break;
					}
				}
			}

			cackey_free_tlv(app_tlv);

			if (outidx >= *count) {
				break;
			}
		}

		cackey_free_tlv(ccc_tlv);
	}

	*count = outidx;

	if (certs_resizable) {

		certs = realloc(certs, sizeof(*certs) * (*count));



	}

	slot->cached_certs = cackey_copy_certs(NULL, certs, *count);
	slot->cached_certs_count = *count;

	/* Terminate SmartCard Transaction */
	cackey_end_transaction(slot);







>
|
>
>
>



















>
|
>
>
>







2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730

				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) {
						*count *= 2;
						if (*count != 0) {
							certs = realloc(certs, sizeof(*certs) * (*count));
						} else {
							certs = NULL;
						}
					} else {
						break;
					}
				}
			}

			cackey_free_tlv(app_tlv);

			if (outidx >= *count) {
				break;
			}
		}

		cackey_free_tlv(ccc_tlv);
	}

	*count = outidx;

	if (certs_resizable) {
		if (*count != 0) {
			certs = realloc(certs, sizeof(*certs) * (*count));
		} else {
			certs = NULL;
		}
	}

	slot->cached_certs = cackey_copy_certs(NULL, certs, *count);
	slot->cached_certs_count = *count;

	/* Terminate SmartCard Transaction */
	cackey_end_transaction(slot);