Check-in [cca6a7fec4]
Overview
Comment:Merged in "dodcerts-on-seperate-slot" branch
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:cca6a7fec4ae194f2ccf66057ae9097e93405f96
User & Date: rkeene on 2012-07-25 02:31:15
Other Links: manifest | tags
Context
2012-07-25
02:33
CACKey 0.6.7 check-in: 11563df531 user: rkeene tags: trunk, 0.6.7
02:31
Merged in "dodcerts-on-seperate-slot" branch check-in: cca6a7fec4 user: rkeene tags: trunk
02:30
Merged from trunk Closed-Leaf check-in: 62f39ca124 user: rkeene tags: dodcerts-on-seperate-slot
2012-07-24
22:24
Updated Mac OS X build script to support building a Snow Leopard to Mountain Lion-compatible package. check-in: 07c7888bc0 user: kvanals tags: trunk
Changes

Modified build/cackey_osx_build/build_osx.sh from [3980f85216] to [04fe9e319d].

   134    134   	CUROSXVER=10.6
   135    135   	for HOST in i386-apple-darwin10 x86_64-apple-darwin10; do
   136    136   		genbuild
   137    137   	done
   138    138   	libbuild
   139    139   	pkgbuild
   140    140   }
          141  +
          142  +# Build function for Snow Leopard/Lion/Mountain Lion
          143  +sltoml() {
          144  +	makedir
          145  +	HEADERS=/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/PCSC.framework/Versions/A/Headers/
          146  +	LIBRARY=/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/PCSC.framework/PCSC
          147  +	LIB=""
          148  +	ARCHLIST=""
          149  +	DLIB=""
          150  +	DARCHLIST=""
          151  +	OSX=Sltoml
          152  +	PKTARGETOS=3
          153  +	NEXTOSXVER=10.9
          154  +	CUROSXVER=10.6
          155  +	for HOST in i386-apple-darwin10 x86_64-apple-darwin10; do
          156  +		genbuild
          157  +	done
          158  +	libbuild
          159  +	pkgbuild
          160  +}
   141    161   
   142    162   # Generic build function
   143    163   genbuild() {
   144    164   	make distclean
   145    165   	ARCH=`echo ${HOST} | cut -d "-" -f 1`
   146    166   	if [ ${ARCH} == "powerpc" ]; then
   147    167   		if [ ${OSX} == "Leopard" ]; then
................................................................................
   148    168   			ARCH="ppc -mcpu=G4"
   149    169   		else
   150    170   			ARCH="ppc -mcpu=G3"
   151    171   		fi
   152    172   	fi
   153    173   	if [ "${LIONBUILD}" = 1 ]; then
   154    174   		if [ "${ARCH}" == "ppc -mcpu=G4" ]; then
   155         -			CC=powerpc-apple-darwin11-gcc-4.2.1 CPP=powerpc-apple-darwin11-cpp-4.2.1 CFLAGS="-m32 -I/Developer/Platforms/iPhoneOS.platform/Developer/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/include -isysroot /Developer/SDKs/MacOSX10.5.sdk" CPPFLAGS="-D_LIBC_LIMITS_H_" ./configure --with-pcsc-headers=${HEADERS} --with-pcsc-libs=${LIBRARY} --host=${HOST}
          175  +			CC=powerpc-apple-darwin11-gcc-4.2.1 CPP=powerpc-apple-darwin11-cpp-4.2.1 CFLAGS="-m32 -I/Developer/Platforms/iPhoneOS.platform/Developer/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/include -isysroot /Developer/SDKs/MacOSX10.5.sdk" CPPFLAGS="-D_LIBC_LIMITS_H_" ./configure --with-pcsc-headers=${HEADERS} --with-pcsc-libs=${LIBRARY} --host=${HOST} --enable-dod-certs-on-hw-slots
   156    176   		else
   157         -			CFLAGS="-arch ${ARCH}" ./configure --with-pcsc-headers=${HEADERS} --with-pcsc-libs=${LIBRARY} --host=${HOST}
          177  +			CFLAGS="-arch ${ARCH}" ./configure --with-pcsc-headers=${HEADERS} --with-pcsc-libs=${LIBRARY} --host=${HOST} --enable-dod-certs-on-hw-slots
   158    178   		fi
   159    179   	else
   160         -		CFLAGS="-arch ${ARCH}" ./configure --with-pcsc-headers=${HEADERS} --with-pcsc-libs=${LIBRARY} --host=${HOST}
          180  +		CFLAGS="-arch ${ARCH}" ./configure --with-pcsc-headers=${HEADERS} --with-pcsc-libs=${LIBRARY} --host=${HOST} --enable-dod-certs-on-hw-slots
   161    181   	fi
   162    182   	make
   163    183   	cp libcackey.dylib macbuild/${OSX}/libcackey.dylib.`echo ${ARCH} | cut -d ' ' -f 1`
   164    184   	cp libcackey_g.dylib macbuild/${OSX}/libcackey_g.dylib.`echo ${ARCH} | cut -d ' ' -f 1` 
   165    185   }
   166    186   
   167    187   # Library build function

Modified cackey.c from [1be2f8a22e] to [0661f619de].

   709    709   	CK_VOID_PTR decrypt_mech_parm;
   710    710   	CK_ULONG decrypt_mech_parmlen;
   711    711   	struct cackey_identity *decrypt_identity;
   712    712   };
   713    713   
   714    714   struct cackey_slot {
   715    715   	int active;
          716  +	int internal;
   716    717   
   717    718   	char *pcsc_reader;
   718    719   
   719    720   	int pcsc_card_connected;
   720    721   	SCARDHANDLE pcsc_card;
   721    722   
   722    723   	int transaction_depth;
................................................................................
   853    854    */
   854    855   static void cackey_slots_disconnect_all(void) {
   855    856   	uint32_t idx;
   856    857   
   857    858   	CACKEY_DEBUG_PRINTF("Called.");
   858    859   
   859    860   	for (idx = 0; idx < (sizeof(cackey_slots) / sizeof(cackey_slots[0])); idx++) {
          861  +		if (cackey_slots[idx].internal) {
          862  +			/* Skip internal slots */
          863  +			continue;
          864  +		}
          865  +
   860    866   		if (cackey_slots[idx].pcsc_card_connected) {
   861    867   			CACKEY_DEBUG_PRINTF("SCardDisconnect(%lu) called", (unsigned long) idx);
   862    868   
   863    869   			SCardDisconnect(cackey_slots[idx].pcsc_card, SCARD_LEAVE_CARD);
   864    870   		}
   865    871   
   866    872   		if (cackey_slots[idx].label) {
................................................................................
  2602   2608   static cackey_ret cackey_token_present(struct cackey_slot *slot) {
  2603   2609   	cackey_ret pcsc_connect_ret;
  2604   2610   	DWORD reader_len, state, protocol, atr_len;
  2605   2611   	BYTE atr[MAX_ATR_SIZE];
  2606   2612   	LONG status_ret, scard_reconn_ret;
  2607   2613   
  2608   2614   	CACKEY_DEBUG_PRINTF("Called.");
         2615  +
         2616  +	if (slot->internal) {
         2617  +		CACKEY_DEBUG_PRINTF("Returning token present (internal token)");
         2618  +
         2619  +		return(CACKEY_PCSC_S_TOKENPRESENT);
         2620  +	}
  2609   2621   
  2610   2622   	pcsc_connect_ret = cackey_connect_card(slot);
  2611   2623   	if (pcsc_connect_ret != CACKEY_PCSC_S_OK) {
  2612   2624   		CACKEY_DEBUG_PRINTF("Unable to connect to card, returning token absent");
  2613   2625   
  2614   2626   		return(CACKEY_PCSC_E_TOKENABSENT);
  2615   2627   	}
................................................................................
  3396   3408   
  3397   3409   			cackey_free_certs(identities[id_idx].pcsc_identity, 1, 1);
  3398   3410   		}
  3399   3411   	}
  3400   3412   
  3401   3413   	free(identities);
  3402   3414   }
         3415  +
         3416  +static unsigned long cackey_read_dod_identities(struct cackey_identity *identities, unsigned long id_idx, unsigned long num_dod_certs) {
         3417  +	unsigned long cert_idx;
         3418  +
         3419  +	for (cert_idx = 0; cert_idx < num_dod_certs; cert_idx++) {
         3420  +		identities[id_idx].pcsc_identity = NULL;
         3421  +		identities[id_idx].attributes = cackey_get_attributes(CKO_CERTIFICATE, &extra_certs[cert_idx], 0xf000 | cert_idx, &identities[id_idx].attributes_count);
         3422  +		id_idx++;
         3423  +
         3424  +		identities[id_idx].pcsc_identity = NULL;
         3425  +		identities[id_idx].attributes = cackey_get_attributes(CKO_PUBLIC_KEY, &extra_certs[cert_idx], 0xf000 | cert_idx, &identities[id_idx].attributes_count);
         3426  +		id_idx++;
         3427  +
         3428  +		identities[id_idx].pcsc_identity = NULL;
         3429  +		identities[id_idx].attributes = cackey_get_attributes(CKO_NETSCAPE_TRUST, &extra_certs[cert_idx], 0xf000 | cert_idx, &identities[id_idx].attributes_count);
         3430  +		id_idx++;
         3431  +	}
         3432  +
         3433  +	return(id_idx);
         3434  +}
  3403   3435   
  3404   3436   static struct cackey_identity *cackey_read_identities(struct cackey_slot *slot, unsigned long *ids_found) {
  3405   3437   	struct cackey_pcsc_identity *pcsc_identities;
  3406   3438   	struct cackey_identity *identities;
  3407   3439   	unsigned long num_ids, id_idx, curr_id_type;
  3408         -	unsigned long num_certs, num_extra_certs, cert_idx;
  3409         -	int include_extra_certs = 1;
         3440  +	unsigned long num_certs, num_dod_certs, cert_idx;
         3441  +	int include_extra_certs = 0;
  3410   3442   
  3411   3443   	CACKEY_DEBUG_PRINTF("Called.");
  3412   3444   
  3413         -	if (getenv("CACKEY_NO_EXTRA_CERTS") != NULL) {
  3414         -		CACKEY_DEBUG_PRINTF("Asked not to include extra (DoD) certificates");
  3415         -
  3416         -		include_extra_certs = 0;
  3417         -	}
  3418         -
  3419         -	if (include_extra_certs) {
  3420         -		num_extra_certs = sizeof(extra_certs) / sizeof(extra_certs[0]);
  3421         -
  3422         -		CACKEY_DEBUG_PRINTF("Including %li DoD Certificates as objects on this token", num_extra_certs);
  3423         -	} else {
  3424         -		num_extra_certs = 0;
  3425         -	}
  3426         -
  3427   3445   	if (ids_found == NULL) {
  3428   3446   		CACKEY_DEBUG_PRINTF("Error.  ids_found is NULL");
  3429   3447   
  3430   3448   		return(NULL);
  3431   3449   	}
         3450  +
         3451  +#ifdef CACKEY_CARD_SLOT_INCLUDE_EXTRA_CERTS
         3452  +	include_extra_certs = 1;
         3453  +#endif
         3454  +
         3455  +	if (getenv("CACKEY_DOD_CERTS_ON_HW_SLOTS") != NULL) {
         3456  +		include_extra_certs = 1;
         3457  +	}
         3458  +
         3459  +	if (getenv("CACKEY_NO_DOD_CERTS_ON_HW_SLOTS") != NULL) {
         3460  +		include_extra_certs = 0;
         3461  +	}
         3462  +
         3463  +	if (getenv("CACKEY_NO_EXTRA_CERTS") != NULL) {
         3464  +		num_dod_certs = 0;
         3465  +	} else {
         3466  +		num_dod_certs = sizeof(extra_certs) / sizeof(extra_certs[0]);
         3467  +	}
         3468  +
         3469  +	if (slot->internal) {
         3470  +		num_ids = num_dod_certs;
         3471  +
         3472  +		if (num_ids != 0) {
         3473  +			identities = malloc(num_ids * sizeof(*identities));
         3474  +
         3475  +			cackey_read_dod_identities(identities, 0, num_dod_certs);
         3476  +		} else {
         3477  +			identities = NULL;
         3478  +		}
         3479  +
         3480  +		*ids_found = num_ids;
         3481  +
         3482  +		return(identities);
         3483  +	}
  3432   3484   
  3433   3485   	pcsc_identities = cackey_read_certs(slot, NULL, &num_certs);
  3434   3486   	if (pcsc_identities != NULL) {
  3435   3487   		/* Convert number of Certs to number of objects */
  3436   3488   		num_ids = (CKO_PRIVATE_KEY - CKO_CERTIFICATE + 1) * num_certs;
  3437         -		num_ids += num_extra_certs * 3;
         3489  +
         3490  +		if (include_extra_certs) {
         3491  +			num_ids += num_dod_certs;
         3492  +		}
  3438   3493   
  3439   3494   		identities = malloc(num_ids * sizeof(*identities));
  3440   3495   
  3441   3496   		/* Add certificates, public keys, and private keys from the smartcard */
  3442   3497   		id_idx = 0;
  3443   3498   		for (cert_idx = 0; cert_idx < num_certs; cert_idx++) {
  3444   3499   			for (curr_id_type = CKO_CERTIFICATE; curr_id_type <= CKO_PRIVATE_KEY; curr_id_type++) {
................................................................................
  3449   3504   
  3450   3505   				identities[id_idx].pcsc_identity->certificate = malloc(pcsc_identities[cert_idx].certificate_len);
  3451   3506   				memcpy(identities[id_idx].pcsc_identity->certificate, pcsc_identities[cert_idx].certificate, pcsc_identities[cert_idx].certificate_len);
  3452   3507   
  3453   3508   				id_idx++;
  3454   3509   			}
  3455   3510   		}
         3511  +
         3512  +		if (include_extra_certs) {
         3513  +			CACKEY_DEBUG_PRINTF("Including DoD Certificates on hardware slot");
         3514  +
         3515  +			cackey_read_dod_identities(identities, id_idx, num_dod_certs);
         3516  +		}
  3456   3517   
  3457   3518   		cackey_free_certs(pcsc_identities, num_certs, 1);
  3458   3519   
  3459         -		/* Add DoD Certificates and Netscape Trust Objects */
  3460         -		for (cert_idx = 0; cert_idx < num_extra_certs; cert_idx++) {
  3461         -			identities[id_idx].pcsc_identity = NULL;
  3462         -			identities[id_idx].attributes = cackey_get_attributes(CKO_CERTIFICATE, &extra_certs[cert_idx], 0xf000 | cert_idx, &identities[id_idx].attributes_count);
  3463         -			id_idx++;
  3464         -
  3465         -			identities[id_idx].pcsc_identity = NULL;
  3466         -			identities[id_idx].attributes = cackey_get_attributes(CKO_PUBLIC_KEY, &extra_certs[cert_idx], 0xf000 | cert_idx, &identities[id_idx].attributes_count);
  3467         -			id_idx++;
  3468         -
  3469         -			identities[id_idx].pcsc_identity = NULL;
  3470         -			identities[id_idx].attributes = cackey_get_attributes(CKO_NETSCAPE_TRUST, &extra_certs[cert_idx], 0xf000 | cert_idx, &identities[id_idx].attributes_count);
  3471         -			id_idx++;
  3472         -		}
  3473         -
  3474   3520   		*ids_found = num_ids;
         3521  +
  3475   3522   		return(identities);
  3476   3523   	}
         3524  +
  3477   3525   
  3478   3526   	*ids_found = 0;
  3479   3527   	return(NULL);
  3480   3528   }
  3481   3529   
  3482   3530   CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(CK_VOID_PTR pInitArgs) {
  3483   3531   	CK_C_INITIALIZE_ARGS CK_PTR args;
  3484         -	uint32_t idx;
         3532  +	uint32_t idx, highest_slot;
  3485   3533   	int mutex_init_ret;
  3486   3534   
  3487   3535   	CACKEY_DEBUG_PRINTF("Called.");
  3488   3536   
  3489   3537   	if (cackey_initialized) {
  3490   3538   		CACKEY_DEBUG_PRINTF("Error.  Already initialized.");
  3491   3539   
................................................................................
  3519   3567   		cackey_slots[idx].active = 0;
  3520   3568   		cackey_slots[idx].pcsc_reader = NULL;
  3521   3569   		cackey_slots[idx].transaction_depth = 0;
  3522   3570   		cackey_slots[idx].transaction_need_hw_lock = 0;
  3523   3571   		cackey_slots[idx].slot_reset = 0;
  3524   3572   		cackey_slots[idx].token_flags = 0;
  3525   3573   		cackey_slots[idx].label = NULL;
         3574  +		cackey_slots[idx].internal = 0;
         3575  +	}
         3576  +
         3577  +	if (getenv("CACKEY_NO_EXTRA_CERTS") != NULL) {
         3578  +		CACKEY_DEBUG_PRINTF("Asked not to include DoD certificates");
         3579  +	} else {
         3580  +		highest_slot = (sizeof(cackey_slots) / sizeof(cackey_slots[0])) - 1;
         3581  +
         3582  +		CACKEY_DEBUG_PRINTF("Including DoD certs in slot %lu", (unsigned long) highest_slot);
         3583  +
         3584  +		cackey_slots[highest_slot].active = 1;
         3585  +		cackey_slots[highest_slot].internal = 1;
         3586  +		cackey_slots[highest_slot].label = (unsigned char *) "DoD Certificates";
         3587  +		cackey_slots[highest_slot].pcsc_reader = "CACKey";
         3588  +		cackey_slots[highest_slot].token_flags = 0;
  3526   3589   	}
  3527   3590   
  3528   3591   	cackey_initialized = 1;
  3529   3592   
  3530   3593   	if (!cackey_biglock_init) {
  3531   3594   		mutex_init_ret = cackey_mutex_create(&cackey_biglock);
  3532   3595   
................................................................................
  3566   3629   			C_CloseSession(idx);
  3567   3630   		}
  3568   3631   	}
  3569   3632   
  3570   3633   	cackey_slots_disconnect_all();
  3571   3634   
  3572   3635   	for (idx = 0; idx < (sizeof(cackey_slots) / sizeof(cackey_slots[0])); idx++) {
         3636  +		if (cackey_slots[idx].internal) {
         3637  +			continue;
         3638  +		}
         3639  +
  3573   3640   		if (cackey_slots[idx].pcsc_reader) {
  3574   3641   			free(cackey_slots[idx].pcsc_reader);
  3575   3642   		}
  3576   3643   	}
  3577   3644   
  3578   3645   	cackey_pcsc_disconnect();
  3579   3646   
................................................................................
  3623   3690   
  3624   3691   /*
  3625   3692    * Process list of readers, and create mapping between reader name and slot ID
  3626   3693    */
  3627   3694   CK_DEFINE_FUNCTION(CK_RV, C_GetSlotList)(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount) {
  3628   3695   	int mutex_retval;
  3629   3696   	int pcsc_connect_ret;
  3630         -	CK_ULONG count, slot_count = 0, currslot;
         3697  +	CK_ULONG count, slot_count = 0, currslot, slot_idx;
  3631   3698   	char *pcsc_readers, *pcsc_readers_s, *pcsc_readers_e;
  3632   3699   	DWORD pcsc_readers_len;
  3633   3700   	LONG scard_listreaders_ret;
  3634   3701   	size_t curr_reader_len;
  3635   3702   
  3636   3703   	CACKEY_DEBUG_PRINTF("Called.");
  3637   3704   
................................................................................
  3658   3725   	if (pSlotList) {
  3659   3726   		CACKEY_DEBUG_PRINTF("Purging all slot information.");
  3660   3727   
  3661   3728   		/* Only update the list of slots if we are actually being supply the slot information */
  3662   3729   		cackey_slots_disconnect_all();
  3663   3730   
  3664   3731   		for (currslot = 0; currslot < (sizeof(cackey_slots) / sizeof(cackey_slots[0])); currslot++) {
         3732  +			if (cackey_slots[currslot].internal) {
         3733  +				continue;
         3734  +			}
         3735  +
  3665   3736   			if (cackey_slots[currslot].pcsc_reader) {
  3666   3737   				free(cackey_slots[currslot].pcsc_reader);
  3667   3738   
  3668   3739   				cackey_slots[currslot].pcsc_reader = NULL;
  3669   3740   			}
  3670   3741   
  3671   3742   			if (cackey_slots[currslot].label) {
................................................................................
  3706   3777   			scard_listreaders_ret = SCardListReaders(*cackey_pcsc_handle, NULL, pcsc_readers, &pcsc_readers_len);
  3707   3778   			if (scard_listreaders_ret == SCARD_S_SUCCESS) {
  3708   3779   				pcsc_readers_e = pcsc_readers + pcsc_readers_len;
  3709   3780   
  3710   3781   				/* Start with Slot ID 1, to avoid a bug in GDM on RHEL */
  3711   3782   				/* Bug 594911: https://bugzilla.redhat.com/show_bug.cgi?id=594911 */
  3712   3783   				currslot = 1;
         3784  +				slot_count = 0;
  3713   3785   				while (pcsc_readers < pcsc_readers_e) {
         3786  +					/* Find next available slot */
         3787  +					for (; currslot < (sizeof(cackey_slots) / sizeof(cackey_slots[0])); currslot++) {
         3788  +						if (!cackey_slots[currslot].active) {
         3789  +							break;
         3790  +						}
         3791  +					}
         3792  +
  3714   3793   					curr_reader_len = strlen(pcsc_readers);
  3715   3794   
  3716   3795   					if ((pcsc_readers + curr_reader_len) > pcsc_readers_e) {
  3717   3796   						break;
  3718   3797   					}
  3719   3798   
  3720   3799   					if (curr_reader_len == 0) {
................................................................................
  3728   3807   					}
  3729   3808   
  3730   3809   					CACKEY_DEBUG_PRINTF("Found reader: %s", pcsc_readers);
  3731   3810   
  3732   3811   					/* Only update the list of slots if we are actually being asked supply the slot information */
  3733   3812   					if (pSlotList) {
  3734   3813   						cackey_slots[currslot].active = 1;
         3814  +						cackey_slots[currslot].internal = 0;
  3735   3815   						cackey_slots[currslot].pcsc_reader = strdup(pcsc_readers);
  3736   3816   						cackey_slots[currslot].pcsc_card_connected = 0;
  3737   3817   						cackey_slots[currslot].transaction_depth = 0;
  3738   3818   						cackey_slots[currslot].transaction_need_hw_lock = 0;
  3739   3819   						cackey_slots[currslot].slot_reset = 1;
  3740   3820   						cackey_slots[currslot].token_flags = CKF_LOGIN_REQUIRED;
  3741   3821   						cackey_slots[currslot].label = NULL;
  3742   3822   
  3743   3823   						cackey_mark_slot_reset(&cackey_slots[currslot]);
         3824  +					} else {
         3825  +						/* Artificially increase the number of active slots by what will become active */
         3826  +						slot_count++;
  3744   3827   					}
  3745   3828   					currslot++;
  3746   3829   
  3747   3830   					pcsc_readers += curr_reader_len + 1;
  3748   3831   				}
  3749   3832   
  3750         -				/* Start with Slot ID 1, to avoid a bug in GDM on RHEL */
  3751         -				/* Bug 594911: https://bugzilla.redhat.com/show_bug.cgi?id=594911 */
  3752         -				if (currslot > 1) {
  3753         -					/* Start with Slot ID 1, to avoid a bug in GDM on RHEL */
  3754         -					/* Bug 594911: https://bugzilla.redhat.com/show_bug.cgi?id=594911 */
  3755         -					slot_count = currslot - 1;
         3833  +				for (currslot = 0; currslot < (sizeof(cackey_slots) / sizeof(cackey_slots[0])); currslot++) {
         3834  +					if (cackey_slots[currslot].active) {
         3835  +						CACKEY_DEBUG_PRINTF("Found active slot %lu", (unsigned long) currslot);
         3836  +
         3837  +						slot_count++;
         3838  +					}
  3756   3839   				}
  3757   3840   			} else {
  3758   3841   				CACKEY_DEBUG_PRINTF("Second call to SCardListReaders failed, return %s/%li", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_listreaders_ret), (long) scard_listreaders_ret);
  3759   3842   			}
  3760   3843   
  3761   3844   			free(pcsc_readers_s);
  3762   3845   		} else {
................................................................................
  3779   3862   		return(CKR_OK);
  3780   3863   	}
  3781   3864   
  3782   3865   	count = *pulCount;
  3783   3866   	if (count < slot_count) {
  3784   3867   		CACKEY_DEBUG_PRINTF("Error. User allocated %lu entries, but we have %lu entries.", count, slot_count);
  3785   3868   
         3869  +		CACKEY_DEBUG_PRINTF("Returning CKR_BUFFER_TOO_SMALL");
         3870  +
  3786   3871   		return(CKR_BUFFER_TOO_SMALL);	
  3787   3872   	}
  3788   3873   
  3789         -	for (currslot = 0; currslot < slot_count; currslot++) {
  3790         -		/* Start with Slot ID 1, to avoid a bug in GDM on RHEL */
  3791         -		/* Bug 594911: https://bugzilla.redhat.com/show_bug.cgi?id=594911 */
  3792         -		pSlotList[currslot] = currslot + 1;
         3874  +	mutex_retval = cackey_mutex_lock(cackey_biglock);
         3875  +	if (mutex_retval != 0) {
         3876  +		CACKEY_DEBUG_PRINTF("Error.  Locking failed.");
         3877  +
         3878  +		return(CKR_GENERAL_ERROR);
         3879  +	}
         3880  +
         3881  +	slot_idx = 0;
         3882  +	for (currslot = 0; (currslot < (sizeof(cackey_slots) / sizeof(cackey_slots[0]))); currslot++) {
         3883  +		if (!cackey_slots[currslot].active) {
         3884  +			continue;
         3885  +		}
         3886  +
         3887  +		if (slot_idx >= count) {
         3888  +			CACKEY_DEBUG_PRINTF("Error. User allocated %lu entries, but we just tried to write to the %lu index -- ignoring", count, slot_idx);
         3889  +
         3890  +			continue;
         3891  +		}
         3892  +
         3893  +		pSlotList[slot_idx] = currslot;
         3894  +		slot_idx++;
         3895  +	}
         3896  +
         3897  +	mutex_retval = cackey_mutex_unlock(cackey_biglock);
         3898  +	if (mutex_retval != 0) {
         3899  +		CACKEY_DEBUG_PRINTF("Error.  Unlocking failed.");
         3900  +
         3901  +		return(CKR_GENERAL_ERROR);
  3793   3902   	}
  3794   3903   
  3795   3904   	*pulCount = slot_count;
  3796   3905   
  3797   3906   	CACKEY_DEBUG_PRINTF("Returning CKR_OK (%i).  Found %lu readers.", CKR_OK, (unsigned long) slot_count);
  3798   3907   
  3799   3908   	return(CKR_OK);
................................................................................
  3837   3946   		CACKEY_DEBUG_PRINTF("Error. Invalid slot requested (%lu), slot not currently active", slotID);
  3838   3947   
  3839   3948   		cackey_mutex_unlock(cackey_biglock);
  3840   3949   
  3841   3950   		return(CKR_SLOT_ID_INVALID);
  3842   3951   	}
  3843   3952   
  3844         -	pInfo->flags = CKF_REMOVABLE_DEVICE | CKF_HW_SLOT;
         3953  +	pInfo->flags = CKF_HW_SLOT;
         3954  +
         3955  +	if (!cackey_slots[slotID].internal) {
         3956  +		pInfo->flags |= CKF_REMOVABLE_DEVICE;
         3957  +	}
  3845   3958   
  3846   3959   	if (cackey_token_present(&cackey_slots[slotID]) == CACKEY_PCSC_S_TOKENPRESENT) {
  3847   3960   		pInfo->flags |= CKF_TOKEN_PRESENT;
  3848   3961   	}
  3849   3962   
  3850   3963   	bytes_to_copy = strlen(cackey_slots[slotID].pcsc_reader);
  3851   3964   	if (sizeof(pInfo->manufacturerID) < bytes_to_copy) {

Modified configure.ac from [8952b0e3fb] to [34ff5a91b6].

   138    138   		AC_MSG_RESULT(okay)
   139    139   	], [
   140    140   		AC_MSG_RESULT(failed)
   141    141   
   142    142   		AC_MSG_FAILURE([simple PC/SC program failed])
   143    143   	]
   144    144   )
          145  +
          146  +dnl Option to enable DoD certs on hardware slot
          147  +AC_ARG_ENABLE(dod-certs-on-hw-slots, AC_HELP_STRING([--enable-dod-certs-on-hw-slots], [Specify that DoD certificates should be made available on hardware token slots]), [
          148  +	dodcertsonhwslots=$enableval
          149  +], [
          150  +	dodcertsonhwslots=no
          151  +])
          152  +
          153  +if ! test "${dodcertsonhwslots}" = 'no'; then
          154  +	AC_DEFINE(CACKEY_CARD_SLOT_INCLUDE_EXTRA_CERTS, [1], [Specify that DoD certificates should be made available on hardware token slots])
          155  +fi
   145    156   
   146    157   dnl Set version script, to limit the scope of symbols
   147    158   DC_SETVERSIONSCRIPT(libcackey.vers, libcackey.syms)
   148    159   
   149    160   dnl Upate LDFLAGS to include setting the run-time linker path to the same as our compile-time linker
   150    161   DC_SYNC_RPATH
   151    162   
   152    163   dnl If we updated LIBOBJS, update SHLIBOBJS -- must be last.
   153    164   DC_SYNC_SHLIBOBJS
   154    165   
   155    166   dnl Produce Makefile
   156    167   AC_OUTPUT(Makefile libcackey.syms)

Modified test.c from [7438606333] to [86bd0fe2e2].

   234    234   		printf("  Slot %lu:\n", currSlot);
   235    235   
   236    236   		chk_rv = C_GetSlotInfo(slots[currSlot], &slotInfo);
   237    237   		if (chk_rv != CKR_OK) {
   238    238   			return(1);
   239    239   		}
   240    240   
          241  +		printf("    Id     : %lu\n", (unsigned long) slots[currSlot]);
   241    242   		printf("    Desc   : %.*s\n", 32, slotInfo.slotDescription);
   242    243   		printf("    ManufID: %.*s\n", 32, slotInfo.manufacturerID);
   243    244   		printf("    HWVers : %i.%i\n", slotInfo.hardwareVersion.major, slotInfo.hardwareVersion.minor);
   244    245   		printf("    FWVers : %i.%i\n", slotInfo.firmwareVersion.major, slotInfo.firmwareVersion.minor);
   245    246   		printf("    Flags  : ");
   246    247   		if ((slotInfo.flags & CKF_TOKEN_PRESENT) == CKF_TOKEN_PRESENT) {
   247    248   			printf("CKF_TOKEN_PRESENT ");
................................................................................
   325    326   			}
   326    327   			printf("\n");
   327    328   		}
   328    329   	}
   329    330   
   330    331   	chk_rv = C_OpenSession(slots[0], CKF_SERIAL_SESSION, NULL, NULL, &hSession);
   331    332   	if (chk_rv == CKR_OK) {
          333  +		chk_rv = C_GetTokenInfo(slots[0], &tokenInfo);
          334  +		if (chk_rv != CKR_OK) {
          335  +			return(1);
          336  +		}
          337  +
   332    338   		if ((tokenInfo.flags & CKF_LOGIN_REQUIRED) == CKF_LOGIN_REQUIRED) {
   333    339   			fgets_ret = NULL;
   334    340   
   335    341   			while (fgets_ret == NULL) {
   336    342   				printf("** ENTER PIN: ");
   337    343   				fflush(stdout);
   338    344