Changes On Branch a68e222d00bf4883

Changes In Branch protected-auth-path Through [a68e222d00] Excluding Merge-Ins

This is equivalent to a diff from f42b92cf98 to a68e222d00

2013-08-14
04:22
Merged in updates check-in: 5469f9a4d0 user: rkeene tags: protected-auth-path
04:22
Merged in trunk check-in: 8c73344738 user: rkeene tags: piv
04:16
Added return value printing for C_Login() and removed requirement that PIN not be provided if using protected authentication path (some tools provide it anyway) check-in: a68e222d00 user: rkeene tags: protected-auth-path
04:15
Added start of script to ask for PIN via X11 check-in: 20ddc71853 user: rkeene tags: protected-auth-path
02:26
Create new branch named "protected-auth-path" check-in: 93bebaff52 user: rkeene tags: protected-auth-path
2013-02-07
23:29
Added script to generate certificate bundles in heirarchy order check-in: 6a49836224 user: rkeene tags: piv
2013-01-16
15:46
Updated macbuild contact information to have valid government email addresses to contact us. check-in: f42b92cf98 user: kvanals tags: piv
15:21
Updated to determine what kind of authentication to perform based on token present (PIV/CAC) check-in: def08b9deb user: rkeene tags: piv

Added build/ask-pass/cackey-askpass version [5c6636f8ba].



































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#! /usr/bin/env bash

ZENITY="$(which 'zenity' 2>/dev/null)"
GDIALOG="$(which 'gdialog' 2>/dev/null)"
ASKPASS="$(which 'ssh-askpass' 'x11-ssh-askpass' '/usr/libexec/x11-ssh-askpass' 2>/dev/null | head -n 1)"
DIALOG="$(which 'dialog' 2>/dev/null)"
XTERM="$(which 'xterm' 2>/dev/null)"

if [ -x "${ZENITY}" ]; then
	# XXX: TODO: Zenity
	true
fi

if [ -x "${GDIALOG}" ]; then
	# XXX: TODO: Gdialog
	true
fi

if [ -x "${ASKPASS}" ]; then
	exec "${ASKPASS}" "$@"
	exit 1
fi

if [ -x "${DIALOG}" -a -x "${XTERM}" ]; then
	# XXX: TODO: dialog
	true
fi

if [ -x "${XTERM}" ]; then
	# XXX: TODO: xterm
	true
fi

exit 1

Modified cackey.c from [8554f45411] to [1a206186e3].

866
867
868
869
870
871
872






873
874
875
876
877
878
879
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885







+
+
+
+
+
+







CK_C_INITIALIZE_ARGS cackey_args;

/** Extra certificates to include in token **/
struct cackey_pcsc_identity extra_certs[] = {
#include "cackey_builtin_certs.h"
};

/* Protected Authentication Path command */
#define CACKEY_PIN_COMMAND_DEFAULT_XSTR(str) CACKEY_PIN_COMMAND_DEFAULT_STR(str)
#define CACKEY_PIN_COMMAND_DEFAULT_STR(str) #str
static char *cackey_pin_command = NULL;
static char *cackey_pin_command_xonly = NULL;

/* PCSC Global Handles */
static LPSCARDCONTEXT cackey_pcsc_handle = NULL;

static unsigned long cackey_getversion(void) {
	static unsigned long retval = 255;
	unsigned long major = 0;
	unsigned long minor = 0;
3046
3047
3048
3049
3050
3051
3052







3053
3054
3055
3056
3057
3058
3059
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072







+
+
+
+
+
+
+








	/* Apparently, CAC PINs are *EXACTLY* 8 bytes long -- pad with 0xFF if too short */
	if (pin_len >= 8) {
		memcpy(cac_pin, pin, 8);
	} else {
		memcpy(cac_pin, pin, pin_len);
	}

	/* Reject PINs which are too short */
	if (pin_len < 5) {
		CACKEY_DEBUG_PRINTF("Rejecting PIN which is too short (length = %lu, must be atleast 5)", pin_len);

		return(CACKEY_PCSC_E_BADPIN);
	}

	/* PIV authentication uses a "key_reference" of 0x80 */
	pcsc_identities = cackey_read_certs(slot, NULL, &num_certs);
	if (num_certs > 0 && pcsc_identities != NULL) {
		switch (pcsc_identities[0].id_type) {
			case CACKEY_ID_TYPE_PIV:
				CACKEY_DEBUG_PRINTF("We recently had a PIV card, so we will attempt to authenticate using the PIV Application key reference");
4113
4114
4115
4116
4117
4118
4119




















4120
4121
4122
4123
4124
4125
4126
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







			CACKEY_DEBUG_PRINTF("Error.  Mutex initialization failed.");

			return(CKR_CANT_LOCK);
		}

		cackey_biglock_init = 1;
	}

	/* Define a command to prompt user for a PIN */
#ifdef CACKEY_PIN_COMMAND_DEFAULT
	cackey_pin_command = CACKEY_PIN_COMMAND_DEFAULT_XSTR(CACKEY_PIN_COMMAND_DEFAULT);
#endif
#ifdef CACKEY_PIN_COMMAND_XONLY_DEFAULT
	cackey_pin_command_xonly = CACKEY_PIN_COMMAND_DEFAULT_XSTR(CACKEY_PIN_COMMAND_XONLY_DEFAULT);
#endif

	if (getenv("DISPLAY") != NULL) {
		cackey_pin_command = cackey_pin_command_xonly;
	}

	if (getenv("CACKEY_PIN_COMMAND_XONLY") != NULL && getenv("DISPLAY") != NULL) {
		cackey_pin_command = getenv("CACKEY_PIN_COMMAND_XONLY");
	}

	if (getenv("CACKEY_PIN_COMMAND") != NULL) {
		cackey_pin_command = getenv("CACKEY_PIN_COMMAND");
	}

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

	return(CKR_OK);
}

CK_DEFINE_FUNCTION(CK_RV, C_Finalize)(CK_VOID_PTR pReserved) {
4645
4646
4647
4648
4649
4650
4651




4652
4653
4654
4655
4656
4657
4658
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695







+
+
+
+







	pInfo->hardwareVersion.major = (cackey_getversion() >> 16) & 0xff;
	pInfo->hardwareVersion.minor = (cackey_getversion() >> 8) & 0xff;

	pInfo->firmwareVersion.major = 0x00;
	pInfo->firmwareVersion.minor = 0x00;

	pInfo->flags = CKF_WRITE_PROTECTED | CKF_USER_PIN_INITIALIZED | CKF_TOKEN_INITIALIZED | cackey_slots[slotID].token_flags;

	if (cackey_pin_command != NULL) {
		pInfo->flags |= CKF_PROTECTED_AUTHENTICATION_PATH;
	}

	pInfo->ulMaxSessionCount = (sizeof(cackey_sessions) / sizeof(cackey_sessions[0])) - 1;
	pInfo->ulSessionCount = CK_UNAVAILABLE_INFORMATION;
	pInfo->ulMaxRwSessionCount = 0;
	pInfo->ulRwSessionCount = CK_UNAVAILABLE_INFORMATION;
	pInfo->ulMaxPinLen = 128;
	pInfo->ulMinPinLen = 0;
5108
5109
5110
5111
5112
5113
5114


5115
5116
5117

5118
5119
5120
5121
5122
5123
5124
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164







+
+



+







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

	return(CKR_FUNCTION_NOT_SUPPORTED);
}

CK_DEFINE_FUNCTION(CK_RV, C_Login)(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen) {
	CK_SLOT_ID slotID;
	FILE *pinfd;
	char *pincmd, pinbuf[64], *fgets_ret;
	int mutex_retval;
	int tries_remaining;
	int login_ret;
	int pclose_ret;

	CACKEY_DEBUG_PRINTF("Called.");

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

		return(CKR_CRYPTOKI_NOT_INITIALIZED);
5162
5163
5164
5165
5166
5167
5168





















































5169
5170
5171
5172
5173
5174
5175
5176
5177


5178
5179
5180
5181
5182
5183
5184
5185
5186
5187


5188
5189
5190
5191
5192
5193
5194
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+









+
+










+
+







	if (cackey_slots[slotID].active == 0) {
		CACKEY_DEBUG_PRINTF("Error. Invalid slot requested (%lu), slot not currently active", slotID);

		cackey_mutex_unlock(cackey_biglock);

		return(CKR_GENERAL_ERROR);
	}

	pincmd = cackey_pin_command;
	if (pincmd != NULL) {
		CACKEY_DEBUG_PRINTF("CACKEY_PIN_COMMAND = %s", pincmd);

		if (pPin != NULL) {
			CACKEY_DEBUG_PRINTF("Protected authentication path in effect and PIN provided !?");
		}

		pinfd = popen(pincmd, "r");
		if (pinfd == NULL) {
			CACKEY_DEBUG_PRINTF("Error.  %s: Unable to run", pincmd);

			cackey_mutex_unlock(cackey_biglock);

			CACKEY_DEBUG_PRINTF("Returning CKR_PIN_INCORRECT (%i)", (int) CKR_PIN_INCORRECT);

			return(CKR_PIN_INCORRECT);
		}

		fgets_ret = fgets(pinbuf, sizeof(pinbuf), pinfd);
		if (fgets_ret == NULL) {
			pinbuf[0] = '\0';
		}

		pclose_ret = pclose(pinfd);
		if (pclose_ret != 0) {
			CACKEY_DEBUG_PRINTF("Error.  %s: exited with non-zero status of %i", pincmd, pclose_ret);

			cackey_mutex_unlock(cackey_biglock);

			CACKEY_DEBUG_PRINTF("Returning CKR_PIN_INCORRECT (%i)", (int) CKR_PIN_INCORRECT);

			return(CKR_PIN_INCORRECT);
		}

		if (strlen(pinbuf) < 1) {
			CACKEY_DEBUG_PRINTF("Error.  %s: returned no data", pincmd);

			cackey_mutex_unlock(cackey_biglock);

			CACKEY_DEBUG_PRINTF("Returning CKR_PIN_INCORRECT (%i)", (int) CKR_PIN_INCORRECT);

			return(CKR_PIN_INCORRECT);
		}

		if (pinbuf[strlen(pinbuf) - 1] == '\n') {
			pinbuf[strlen(pinbuf) - 1] = '\0';
		}

		pPin = (CK_UTF8CHAR_PTR) pinbuf;
		ulPinLen = strlen(pinbuf);
	}

	login_ret = cackey_login(&cackey_slots[slotID], pPin, ulPinLen, &tries_remaining);
	if (login_ret != CACKEY_PCSC_S_OK) {
		cackey_mutex_unlock(cackey_biglock);

		if (login_ret == CACKEY_PCSC_E_LOCKED) {
			CACKEY_DEBUG_PRINTF("Error.  Token is locked.");

			cackey_slots[slotID].token_flags |= CKF_USER_PIN_LOCKED;

			CACKEY_DEBUG_PRINTF("Returning CKR_PIN_LOCKED (%i)", (int) CKR_PIN_LOCKED);

			return(CKR_PIN_LOCKED);
		} else if (login_ret == CACKEY_PCSC_E_BADPIN) {
			CACKEY_DEBUG_PRINTF("Error.  Invalid PIN.");

			cackey_slots[slotID].token_flags |= CKF_USER_PIN_COUNT_LOW;

			if (tries_remaining == 1) {
				cackey_slots[slotID].token_flags |= CKF_USER_PIN_FINAL_TRY;
			}

			CACKEY_DEBUG_PRINTF("Returning CKR_PIN_INCORRECT (%i)", (int) CKR_PIN_INCORRECT);

			return(CKR_PIN_INCORRECT);
		}

		CACKEY_DEBUG_PRINTF("Error.  Unknown error returned from cackey_login() (%i)", login_ret);

		return(CKR_GENERAL_ERROR);

Modified configure.ac from [9a7cfcd810] to [34fbe03317].

149
150
151
152
153
154
155





















156
157
158
159
160
161
162
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







], [
	dodcertsonhwslots=no
])

if ! test "${dodcertsonhwslots}" = 'no'; then
	AC_DEFINE(CACKEY_CARD_SLOT_INCLUDE_EXTRA_CERTS, [1], [Specify that DoD certificates should be made available on hardware token slots])
fi

dnl Option to hard-code a command to run to request a PIN (enabling protected authentication path)
AC_ARG_WITH(pin-command, AC_HELP_STRING([--with-pin-command=<command>], [Specify a command to run to request a PIN from the user.  The user may override this with the CACKEY_PIN_COMMAND environment variable.]), [
	pincommand="${withval}"
], [
	pincommand="no"
])

AC_ARG_WITH(pin-command-x, AC_HELP_STRING([--with-pin-command-x=<command>], [Same as --with-pin-command, but only sets Protected Authentication Path if the DISPLAY environment variable is set]), [
	pincommandxonly="${withval}"
], [
	pincommandxonly="no"
])

if ! test "${pincommand}" = 'no'; then
	AC_DEFINE_UNQUOTED(CACKEY_PIN_COMMAND_DEFAULT, [$pincommand], [Command to run to prompt user for PIN])
fi

if ! test "${pincommandxonly}" = 'no'; then
	AC_DEFINE_UNQUOTED(CACKEY_PIN_COMMAND_XONLY_DEFAULT, [$pincommandxonly], [Command to run to prompt user for PIN only if DISPLAY environment variable is set])
fi

dnl Set version script, to limit the scope of symbols
DC_SETVERSIONSCRIPT(libcackey.vers, libcackey.syms)

dnl Upate LDFLAGS to include setting the run-time linker path to the same as our compile-time linker
DC_SYNC_RPATH

Modified test.c from [86bd0fe2e2] to [47338c5b52].

331
332
333
334
335
336
337
338

339
340
341
342
343
344
345
331
332
333
334
335
336
337

338
339
340
341
342
343
344
345







-
+







	chk_rv = C_OpenSession(slots[0], CKF_SERIAL_SESSION, NULL, NULL, &hSession);
	if (chk_rv == CKR_OK) {
		chk_rv = C_GetTokenInfo(slots[0], &tokenInfo);
		if (chk_rv != CKR_OK) {
			return(1);
		}

		if ((tokenInfo.flags & CKF_LOGIN_REQUIRED) == CKF_LOGIN_REQUIRED) {
		if ((tokenInfo.flags & CKF_LOGIN_REQUIRED) == CKF_LOGIN_REQUIRED && (tokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH) == 0) {
			fgets_ret = NULL;

			while (fgets_ret == NULL) {
				printf("** ENTER PIN: ");
				fflush(stdout);

				fgets_ret = fgets((char *) user_pin, sizeof(user_pin), stdin);