Check-in [b6a0e30bff]
Overview
Comment:Added support for supplying a command to provide a PIN via standard output
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | protected-auth-path
Files: files | file ages | folders
SHA1:b6a0e30bff76eec5f60582aa5d99c6ade1944a6f
User & Date: rkeene on 2013-08-14 03:48:01
Other Links: manifest | tags
Context
2013-08-14
03:55
Updated to allow the Protected Authentication Path to be set only if an X server display is available check-in: b6ea2dbe0a user: rkeene tags: protected-auth-path
03:48
Added support for supplying a command to provide a PIN via standard output check-in: b6a0e30bff user: rkeene tags: protected-auth-path
03:01
Made test driver aware of PKCS#11 protected authentication path flag check-in: 06eb7a2600 user: rkeene tags: protected-auth-path
Changes

Modified cackey.c from [8554f45411] to [1675cfdb33].

   865    865   static int cackey_biglock_init = 0;
   866    866   CK_C_INITIALIZE_ARGS cackey_args;
   867    867   
   868    868   /** Extra certificates to include in token **/
   869    869   struct cackey_pcsc_identity extra_certs[] = {
   870    870   #include "cackey_builtin_certs.h"
   871    871   };
          872  +
          873  +/* Protected Authentication Path command */
          874  +#ifdef CACKEY_PIN_COMMAND_DEFAULT
          875  +#  define CACKEY_PIN_COMMAND_DEFAULT_XSTR(str) CACKEY_PIN_COMMAND_DEFAULT_STR(str)
          876  +#  define CACKEY_PIN_COMMAND_DEFAULT_STR(str) #str
          877  +static char *cackey_pin_command = CACKEY_PIN_COMMAND_DEFAULT_XSTR(CACKEY_PIN_COMMAND_DEFAULT);
          878  +#else
          879  +static char *cackey_pin_command = NULL;
          880  +#endif
   872    881   
   873    882   /* PCSC Global Handles */
   874    883   static LPSCARDCONTEXT cackey_pcsc_handle = NULL;
   875    884   
   876    885   static unsigned long cackey_getversion(void) {
   877    886   	static unsigned long retval = 255;
   878    887   	unsigned long major = 0;
................................................................................
  3046   3055   
  3047   3056   	/* Apparently, CAC PINs are *EXACTLY* 8 bytes long -- pad with 0xFF if too short */
  3048   3057   	if (pin_len >= 8) {
  3049   3058   		memcpy(cac_pin, pin, 8);
  3050   3059   	} else {
  3051   3060   		memcpy(cac_pin, pin, pin_len);
  3052   3061   	}
         3062  +
         3063  +	/* Reject PINs which are too short */
         3064  +	if (pin_len < 5) {
         3065  +		CACKEY_DEBUG_PRINTF("Rejecting PIN which is too short (length = %lu, must be atleast 5)", pin_len);
         3066  +
         3067  +		return(CACKEY_PCSC_E_BADPIN);
         3068  +	}
  3053   3069   
  3054   3070   	/* PIV authentication uses a "key_reference" of 0x80 */
  3055   3071   	pcsc_identities = cackey_read_certs(slot, NULL, &num_certs);
  3056   3072   	if (num_certs > 0 && pcsc_identities != NULL) {
  3057   3073   		switch (pcsc_identities[0].id_type) {
  3058   3074   			case CACKEY_ID_TYPE_PIV:
  3059   3075   				CACKEY_DEBUG_PRINTF("We recently had a PIV card, so we will attempt to authenticate using the PIV Application key reference");
................................................................................
  4113   4129   			CACKEY_DEBUG_PRINTF("Error.  Mutex initialization failed.");
  4114   4130   
  4115   4131   			return(CKR_CANT_LOCK);
  4116   4132   		}
  4117   4133   
  4118   4134   		cackey_biglock_init = 1;
  4119   4135   	}
         4136  +
         4137  +	/* Define a command to prompt user for a PIN */
         4138  +	if (getenv("CACKEY_PIN_COMMAND") != NULL) {
         4139  +		cackey_pin_command = getenv("CACKEY_PIN_COMMAND");
         4140  +	}
  4120   4141   
  4121   4142   	CACKEY_DEBUG_PRINTF("Returning CKR_OK (%i)", CKR_OK);
  4122   4143   
  4123   4144   	return(CKR_OK);
  4124   4145   }
  4125   4146   
  4126   4147   CK_DEFINE_FUNCTION(CK_RV, C_Finalize)(CK_VOID_PTR pReserved) {
................................................................................
  4645   4666   	pInfo->hardwareVersion.major = (cackey_getversion() >> 16) & 0xff;
  4646   4667   	pInfo->hardwareVersion.minor = (cackey_getversion() >> 8) & 0xff;
  4647   4668   
  4648   4669   	pInfo->firmwareVersion.major = 0x00;
  4649   4670   	pInfo->firmwareVersion.minor = 0x00;
  4650   4671   
  4651   4672   	pInfo->flags = CKF_WRITE_PROTECTED | CKF_USER_PIN_INITIALIZED | CKF_TOKEN_INITIALIZED | cackey_slots[slotID].token_flags;
         4673  +
         4674  +	if (cackey_pin_command != NULL) {
         4675  +		pInfo->flags |= CKF_PROTECTED_AUTHENTICATION_PATH;
         4676  +	}
  4652   4677   
  4653   4678   	pInfo->ulMaxSessionCount = (sizeof(cackey_sessions) / sizeof(cackey_sessions[0])) - 1;
  4654   4679   	pInfo->ulSessionCount = CK_UNAVAILABLE_INFORMATION;
  4655   4680   	pInfo->ulMaxRwSessionCount = 0;
  4656   4681   	pInfo->ulRwSessionCount = CK_UNAVAILABLE_INFORMATION;
  4657   4682   	pInfo->ulMaxPinLen = 128;
  4658   4683   	pInfo->ulMinPinLen = 0;
................................................................................
  5108   5133   	CACKEY_DEBUG_PRINTF("Returning CKR_FUNCTION_NOT_SUPPORTED (%i)", CKR_FUNCTION_NOT_SUPPORTED);
  5109   5134   
  5110   5135   	return(CKR_FUNCTION_NOT_SUPPORTED);
  5111   5136   }
  5112   5137   
  5113   5138   CK_DEFINE_FUNCTION(CK_RV, C_Login)(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen) {
  5114   5139   	CK_SLOT_ID slotID;
         5140  +	FILE *pinfd;
         5141  +	char *pincmd, pinbuf[64], *fgets_ret;
  5115   5142   	int mutex_retval;
  5116   5143   	int tries_remaining;
  5117   5144   	int login_ret;
         5145  +	int pclose_ret;
  5118   5146   
  5119   5147   	CACKEY_DEBUG_PRINTF("Called.");
  5120   5148   
  5121   5149   	if (!cackey_initialized) {
  5122   5150   		CACKEY_DEBUG_PRINTF("Error.  Not initialized.");
  5123   5151   
  5124   5152   		return(CKR_CRYPTOKI_NOT_INITIALIZED);
................................................................................
  5162   5190   	if (cackey_slots[slotID].active == 0) {
  5163   5191   		CACKEY_DEBUG_PRINTF("Error. Invalid slot requested (%lu), slot not currently active", slotID);
  5164   5192   
  5165   5193   		cackey_mutex_unlock(cackey_biglock);
  5166   5194   
  5167   5195   		return(CKR_GENERAL_ERROR);
  5168   5196   	}
         5197  +
         5198  +	pincmd = cackey_pin_command;
         5199  +	if (pincmd != NULL) {
         5200  +		CACKEY_DEBUG_PRINTF("CACKEY_PIN_COMMAND = %s", pincmd);
         5201  +
         5202  +		if (pPin != NULL) {
         5203  +			CACKEY_DEBUG_PRINTF("Error.  Protected authentication path in effect and PIN provided !?");
         5204  +
         5205  +			cackey_mutex_unlock(cackey_biglock);
         5206  +
         5207  +			return(CKR_GENERAL_ERROR);
         5208  +		}
         5209  +
         5210  +		pinfd = popen(pincmd, "r");
         5211  +		if (pinfd == NULL) {
         5212  +			CACKEY_DEBUG_PRINTF("Error.  %s: Unable to run", pincmd);
         5213  +
         5214  +			cackey_mutex_unlock(cackey_biglock);
         5215  +
         5216  +			return(CKR_PIN_INCORRECT);
         5217  +		}
         5218  +
         5219  +		fgets_ret = fgets(pinbuf, sizeof(pinbuf), pinfd);
         5220  +		if (fgets_ret == NULL) {
         5221  +			pinbuf[0] = '\0';
         5222  +		}
         5223  +
         5224  +		pclose_ret = pclose(pinfd);
         5225  +		if (pclose_ret != 0) {
         5226  +			CACKEY_DEBUG_PRINTF("Error.  %s: exited with non-zero status of %i", pincmd, pclose_ret);
         5227  +
         5228  +			cackey_mutex_unlock(cackey_biglock);
         5229  +
         5230  +			return(CKR_PIN_INCORRECT);
         5231  +		}
         5232  +
         5233  +		if (strlen(pinbuf) < 1) {
         5234  +			CACKEY_DEBUG_PRINTF("Error.  %s: returned no data", pincmd);
         5235  +
         5236  +			cackey_mutex_unlock(cackey_biglock);
         5237  +
         5238  +			return(CKR_PIN_INCORRECT);
         5239  +		}
         5240  +
         5241  +		if (pinbuf[strlen(pinbuf) - 1] == '\n') {
         5242  +			pinbuf[strlen(pinbuf) - 1] = '\0';
         5243  +		}
         5244  +
         5245  +		pPin = (CK_UTF8CHAR_PTR) pinbuf;
         5246  +		ulPinLen = strlen(pinbuf);
         5247  +	}
  5169   5248   
  5170   5249   	login_ret = cackey_login(&cackey_slots[slotID], pPin, ulPinLen, &tries_remaining);
  5171   5250   	if (login_ret != CACKEY_PCSC_S_OK) {
  5172   5251   		cackey_mutex_unlock(cackey_biglock);
  5173   5252   
  5174   5253   		if (login_ret == CACKEY_PCSC_E_LOCKED) {
  5175   5254   			CACKEY_DEBUG_PRINTF("Error.  Token is locked.");

Modified configure.ac from [9a7cfcd810] to [0e5526103b].

   149    149   ], [
   150    150   	dodcertsonhwslots=no
   151    151   ])
   152    152   
   153    153   if ! test "${dodcertsonhwslots}" = 'no'; then
   154    154   	AC_DEFINE(CACKEY_CARD_SLOT_INCLUDE_EXTRA_CERTS, [1], [Specify that DoD certificates should be made available on hardware token slots])
   155    155   fi
          156  +
          157  +dnl Option to hard-code a command to run to request a PIN (enabling protected authentication path)
          158  +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.]), [
          159  +	pincommand="${withval}"
          160  +], [
          161  +	pincommand="no"
          162  +])
          163  +
          164  +if ! test "${pincommand}" = 'no'; then
          165  +	AC_DEFINE_UNQUOTED(CACKEY_PIN_COMMAND_DEFAULT, [$pincommand], [Command to run to prompt user for PIN])
          166  +fi
   156    167   
   157    168   dnl Set version script, to limit the scope of symbols
   158    169   DC_SETVERSIONSCRIPT(libcackey.vers, libcackey.syms)
   159    170   
   160    171   dnl Upate LDFLAGS to include setting the run-time linker path to the same as our compile-time linker
   161    172   DC_SYNC_RPATH
   162    173   
   163    174   dnl If we updated LIBOBJS, update SHLIBOBJS -- must be last.
   164    175   DC_SYNC_SHLIBOBJS
   165    176   
   166    177   dnl Produce Makefile
   167    178   AC_OUTPUT(Makefile libcackey.syms)