Diff

Differences From Artifact [13b6e88e7c]:

To Artifact [ce38432e82]:


   872    872   CK_C_INITIALIZE_ARGS cackey_args;
   873    873   
   874    874   /** Extra certificates to include in token **/
   875    875   struct cackey_pcsc_identity extra_certs[] = {
   876    876   #include "cackey_builtin_certs.h"
   877    877   };
   878    878   
          879  +/* Protected Authentication Path command */
          880  +#define CACKEY_PIN_COMMAND_DEFAULT_XSTR(str) CACKEY_PIN_COMMAND_DEFAULT_STR(str)
          881  +#define CACKEY_PIN_COMMAND_DEFAULT_STR(str) #str
          882  +static char *cackey_pin_command = NULL;
          883  +static char *cackey_pin_command_xonly = NULL;
          884  +
   879    885   /* PCSC Global Handles */
   880    886   static LPSCARDCONTEXT cackey_pcsc_handle = NULL;
   881    887   
   882    888   static unsigned long cackey_getversion(void) {
   883    889   	static unsigned long retval = 255;
   884    890   	unsigned long major = 0;
   885    891   	unsigned long minor = 0;
................................................................................
  3052   3058   
  3053   3059   	/* Apparently, CAC PINs are *EXACTLY* 8 bytes long -- pad with 0xFF if too short */
  3054   3060   	if (pin_len >= 8) {
  3055   3061   		memcpy(cac_pin, pin, 8);
  3056   3062   	} else {
  3057   3063   		memcpy(cac_pin, pin, pin_len);
  3058   3064   	}
         3065  +
         3066  +	/* Reject PINs which are too short */
         3067  +	if (pin_len < 5) {
         3068  +		CACKEY_DEBUG_PRINTF("Rejecting PIN which is too short (length = %lu, must be atleast 5)", pin_len);
         3069  +
         3070  +		return(CACKEY_PCSC_E_BADPIN);
         3071  +	}
  3059   3072   
  3060   3073   	/* PIV authentication uses a "key_reference" of 0x80 */
  3061   3074   	pcsc_identities = cackey_read_certs(slot, NULL, &num_certs);
  3062   3075   	if (num_certs > 0 && pcsc_identities != NULL) {
  3063   3076   		switch (pcsc_identities[0].id_type) {
  3064   3077   			case CACKEY_ID_TYPE_PIV:
  3065   3078   				CACKEY_DEBUG_PRINTF("We recently had a PIV card, so we will attempt to authenticate using the PIV Application key reference");
................................................................................
  4133   4146   			CACKEY_DEBUG_PRINTF("Error.  Mutex initialization failed.");
  4134   4147   
  4135   4148   			return(CKR_CANT_LOCK);
  4136   4149   		}
  4137   4150   
  4138   4151   		cackey_biglock_init = 1;
  4139   4152   	}
         4153  +
         4154  +	/* Define a command to prompt user for a PIN */
         4155  +#ifdef CACKEY_PIN_COMMAND_DEFAULT
         4156  +	cackey_pin_command = CACKEY_PIN_COMMAND_DEFAULT_XSTR(CACKEY_PIN_COMMAND_DEFAULT);
         4157  +#endif
         4158  +#ifdef CACKEY_PIN_COMMAND_XONLY_DEFAULT
         4159  +	cackey_pin_command_xonly = CACKEY_PIN_COMMAND_DEFAULT_XSTR(CACKEY_PIN_COMMAND_XONLY_DEFAULT);
         4160  +#endif
         4161  +
         4162  +	if (getenv("DISPLAY") != NULL) {
         4163  +		cackey_pin_command = cackey_pin_command_xonly;
         4164  +	}
         4165  +
         4166  +	if (getenv("CACKEY_PIN_COMMAND_XONLY") != NULL && getenv("DISPLAY") != NULL) {
         4167  +		cackey_pin_command = getenv("CACKEY_PIN_COMMAND_XONLY");
         4168  +	}
         4169  +
         4170  +	if (getenv("CACKEY_PIN_COMMAND") != NULL) {
         4171  +		cackey_pin_command = getenv("CACKEY_PIN_COMMAND");
         4172  +	}
  4140   4173   
  4141   4174   	CACKEY_DEBUG_PRINTF("Returning CKR_OK (%i)", CKR_OK);
  4142   4175   
  4143   4176   	return(CKR_OK);
  4144   4177   }
  4145   4178   
  4146   4179   CK_DEFINE_FUNCTION(CK_RV, C_Finalize)(CK_VOID_PTR pReserved) {
................................................................................
  4665   4698   	pInfo->hardwareVersion.major = (cackey_getversion() >> 16) & 0xff;
  4666   4699   	pInfo->hardwareVersion.minor = (cackey_getversion() >> 8) & 0xff;
  4667   4700   
  4668   4701   	pInfo->firmwareVersion.major = 0x00;
  4669   4702   	pInfo->firmwareVersion.minor = 0x00;
  4670   4703   
  4671   4704   	pInfo->flags = CKF_WRITE_PROTECTED | CKF_USER_PIN_INITIALIZED | CKF_TOKEN_INITIALIZED | cackey_slots[slotID].token_flags;
         4705  +
         4706  +	if (cackey_pin_command != NULL) {
         4707  +		pInfo->flags |= CKF_PROTECTED_AUTHENTICATION_PATH;
         4708  +	}
  4672   4709   
  4673   4710   	pInfo->ulMaxSessionCount = (sizeof(cackey_sessions) / sizeof(cackey_sessions[0])) - 1;
  4674   4711   	pInfo->ulSessionCount = CK_UNAVAILABLE_INFORMATION;
  4675   4712   	pInfo->ulMaxRwSessionCount = 0;
  4676   4713   	pInfo->ulRwSessionCount = CK_UNAVAILABLE_INFORMATION;
  4677   4714   	pInfo->ulMaxPinLen = 128;
  4678   4715   	pInfo->ulMinPinLen = 0;
................................................................................
  5128   5165   	CACKEY_DEBUG_PRINTF("Returning CKR_FUNCTION_NOT_SUPPORTED (%i)", CKR_FUNCTION_NOT_SUPPORTED);
  5129   5166   
  5130   5167   	return(CKR_FUNCTION_NOT_SUPPORTED);
  5131   5168   }
  5132   5169   
  5133   5170   CK_DEFINE_FUNCTION(CK_RV, C_Login)(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen) {
  5134   5171   	CK_SLOT_ID slotID;
         5172  +	FILE *pinfd;
         5173  +	char *pincmd, pinbuf[64], *fgets_ret;
  5135   5174   	int mutex_retval;
  5136   5175   	int tries_remaining;
  5137   5176   	int login_ret;
         5177  +	int pclose_ret;
  5138   5178   
  5139   5179   	CACKEY_DEBUG_PRINTF("Called.");
  5140   5180   
  5141   5181   	if (!cackey_initialized) {
  5142   5182   		CACKEY_DEBUG_PRINTF("Error.  Not initialized.");
  5143   5183   
  5144   5184   		return(CKR_CRYPTOKI_NOT_INITIALIZED);
................................................................................
  5182   5222   	if (cackey_slots[slotID].active == 0) {
  5183   5223   		CACKEY_DEBUG_PRINTF("Error. Invalid slot requested (%lu), slot not currently active", slotID);
  5184   5224   
  5185   5225   		cackey_mutex_unlock(cackey_biglock);
  5186   5226   
  5187   5227   		return(CKR_GENERAL_ERROR);
  5188   5228   	}
         5229  +
         5230  +	pincmd = cackey_pin_command;
         5231  +	if (pincmd != NULL) {
         5232  +		CACKEY_DEBUG_PRINTF("CACKEY_PIN_COMMAND = %s", pincmd);
         5233  +
         5234  +		if (pPin != NULL) {
         5235  +			CACKEY_DEBUG_PRINTF("Protected authentication path in effect and PIN provided !?");
         5236  +		}
         5237  +
         5238  +		pinfd = popen(pincmd, "r");
         5239  +		if (pinfd == NULL) {
         5240  +			CACKEY_DEBUG_PRINTF("Error.  %s: Unable to run", pincmd);
         5241  +
         5242  +			cackey_mutex_unlock(cackey_biglock);
         5243  +
         5244  +			CACKEY_DEBUG_PRINTF("Returning CKR_PIN_INCORRECT (%i)", (int) CKR_PIN_INCORRECT);
         5245  +
         5246  +			return(CKR_PIN_INCORRECT);
         5247  +		}
         5248  +
         5249  +		fgets_ret = fgets(pinbuf, sizeof(pinbuf), pinfd);
         5250  +		if (fgets_ret == NULL) {
         5251  +			pinbuf[0] = '\0';
         5252  +		}
         5253  +
         5254  +		pclose_ret = pclose(pinfd);
         5255  +		if (pclose_ret != 0) {
         5256  +			CACKEY_DEBUG_PRINTF("Error.  %s: exited with non-zero status of %i", pincmd, pclose_ret);
         5257  +
         5258  +			cackey_mutex_unlock(cackey_biglock);
         5259  +
         5260  +			CACKEY_DEBUG_PRINTF("Returning CKR_PIN_INCORRECT (%i)", (int) CKR_PIN_INCORRECT);
         5261  +
         5262  +			return(CKR_PIN_INCORRECT);
         5263  +		}
         5264  +
         5265  +		if (strlen(pinbuf) < 1) {
         5266  +			CACKEY_DEBUG_PRINTF("Error.  %s: returned no data", pincmd);
         5267  +
         5268  +			cackey_mutex_unlock(cackey_biglock);
         5269  +
         5270  +			CACKEY_DEBUG_PRINTF("Returning CKR_PIN_INCORRECT (%i)", (int) CKR_PIN_INCORRECT);
         5271  +
         5272  +			return(CKR_PIN_INCORRECT);
         5273  +		}
         5274  +
         5275  +		if (pinbuf[strlen(pinbuf) - 1] == '\n') {
         5276  +			pinbuf[strlen(pinbuf) - 1] = '\0';
         5277  +		}
         5278  +
         5279  +		pPin = (CK_UTF8CHAR_PTR) pinbuf;
         5280  +		ulPinLen = strlen(pinbuf);
         5281  +	}
  5189   5282   
  5190   5283   	login_ret = cackey_login(&cackey_slots[slotID], pPin, ulPinLen, &tries_remaining);
  5191   5284   	if (login_ret != CACKEY_PCSC_S_OK) {
  5192   5285   		cackey_mutex_unlock(cackey_biglock);
  5193   5286   
  5194   5287   		if (login_ret == CACKEY_PCSC_E_LOCKED) {
  5195   5288   			CACKEY_DEBUG_PRINTF("Error.  Token is locked.");
  5196   5289   
  5197   5290   			cackey_slots[slotID].token_flags |= CKF_USER_PIN_LOCKED;
         5291  +
         5292  +			CACKEY_DEBUG_PRINTF("Returning CKR_PIN_LOCKED (%i)", (int) CKR_PIN_LOCKED);
  5198   5293   
  5199   5294   			return(CKR_PIN_LOCKED);
  5200   5295   		} else if (login_ret == CACKEY_PCSC_E_BADPIN) {
  5201   5296   			CACKEY_DEBUG_PRINTF("Error.  Invalid PIN.");
  5202   5297   
  5203   5298   			cackey_slots[slotID].token_flags |= CKF_USER_PIN_COUNT_LOW;
  5204   5299   
  5205   5300   			if (tries_remaining == 1) {
  5206   5301   				cackey_slots[slotID].token_flags |= CKF_USER_PIN_FINAL_TRY;
  5207   5302   			}
         5303  +
         5304  +			CACKEY_DEBUG_PRINTF("Returning CKR_PIN_INCORRECT (%i)", (int) CKR_PIN_INCORRECT);
  5208   5305   
  5209   5306   			return(CKR_PIN_INCORRECT);
  5210   5307   		}
  5211   5308   
  5212   5309   		CACKEY_DEBUG_PRINTF("Error.  Unknown error returned from cackey_login() (%i)", login_ret);
  5213   5310   
  5214   5311   		return(CKR_GENERAL_ERROR);