Diff

Differences From Artifact [60fa6fcd12]:

To Artifact [a802283a94]:


    81     81   #define GSCIS_INSTR_READ_BINARY       0xB0
    82     82   #define GSCIS_INSTR_UPDATE_BINARY     0xD6
    83     83   #define GSCIS_INSTR_SELECT            0xA4
    84     84   #define GSCIS_INSTR_EXTERNAL_AUTH     0x82
    85     85   #define GSCIS_INSTR_GET_CHALLENGE     0x84
    86     86   #define GSCIS_INSTR_INTERNAL_AUTH     0x88
    87     87   #define GSCIS_INSTR_VERIFY            0x20
           88  +#define GSCIS_INSTR_CHANGE_REFERENCE  0x24
    88     89   #define GSCIS_INSTR_SIGN              0x2A
    89     90   #define GSCIS_INSTR_GET_PROP          0x56
    90     91   #define GSCIS_INSTR_GET_ACR           0x4C
    91     92   #define GSCIS_INSTR_READ_BUFFER       0x52
    92     93   #define GSCIS_INSTR_SIGNDECRYPT       0x42
    93     94   
    94     95   #define GSCIS_PARAM_SELECT_APPLET     0x04
................................................................................
  1547   1548   			xmit_buf[xmit_len++] = le;
  1548   1549   		}
  1549   1550   	}
  1550   1551   
  1551   1552   	/* Begin Smartcard Transaction */
  1552   1553   	cackey_begin_transaction(slot);
  1553   1554   
  1554         -	if (class == GSCIS_CLASS_ISO7816 && instruction == GSCIS_INSTR_VERIFY && p1 == 0x00) {
         1555  +	if (class == GSCIS_CLASS_ISO7816 && (instruction == GSCIS_INSTR_VERIFY || instruction == GSCIS_INSTR_CHANGE_REFERENCE) && p1 == 0x00) {
  1555   1556   		CACKEY_DEBUG_PRINTF("Sending APDU: <<censored>>");
  1556   1557   	} else {
  1557   1558   		CACKEY_DEBUG_PRINTBUF("Sending APDU:", xmit_buf, xmit_len);
  1558   1559   	}
  1559   1560   
  1560   1561   	recv_len = sizeof(recv_buf);
  1561   1562   	scard_xmit_ret = SCardTransmit(slot->pcsc_card, pioSendPci, xmit_buf, xmit_len, NULL, recv_buf, &recv_len);
................................................................................
  3153   3154    *
  3154   3155    * RETURN VALUE
  3155   3156    *     ...
  3156   3157    *
  3157   3158    * NOTES
  3158   3159    *     ...
  3159   3160    *
         3161  + */
         3162  +static cackey_ret cackey_set_pin(struct cackey_slot *slot, unsigned char *old_pin, unsigned long old_pin_len, unsigned char *pin, unsigned long pin_len) {
         3163  +	struct cackey_pcsc_identity *pcsc_identities;
         3164  +	unsigned char cac_pin[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
         3165  +	unsigned char old_cac_pin[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
         3166  +	unsigned char pin_update[sizeof(cac_pin) + sizeof(old_cac_pin)];
         3167  +	unsigned long num_certs;
         3168  +	uint16_t response_code;
         3169  +	int tries_remaining;
         3170  +	int send_ret;
         3171  +	int key_reference = 0x00;
         3172  +
         3173  +	/* Apparently, CAC PINs are *EXACTLY* 8 bytes long -- pad with 0xFF if too short */
         3174  +	if (pin_len >= 8) {
         3175  +		memcpy(cac_pin, pin, 8);
         3176  +	} else {
         3177  +		memcpy(cac_pin, pin, pin_len);
         3178  +	}
         3179  +
         3180  +	if (old_pin_len >= 8) {
         3181  +		memcpy(old_cac_pin, old_pin, 8);
         3182  +	} else {
         3183  +		memcpy(old_cac_pin, old_pin, old_pin_len);
         3184  +	}
         3185  +
         3186  +	/* Concatenate both PINs together to send as a single instruction */
         3187  +	memcpy(pin_update, old_cac_pin, sizeof(old_cac_pin));
         3188  +	memcpy(pin_update + sizeof(old_cac_pin), cac_pin, sizeof(cac_pin));
         3189  +
         3190  +	/* Reject PINs which are too short */
         3191  +	if (pin_len < 5) {
         3192  +		CACKEY_DEBUG_PRINTF("Rejecting New PIN which is too short (length = %lu, must be atleast 5)", pin_len);
         3193  +
         3194  +		return(CACKEY_PCSC_E_BADPIN);
         3195  +	}
         3196  +
         3197  +	if (old_pin_len < 5) {
         3198  +		CACKEY_DEBUG_PRINTF("Rejecting Old PIN which is too short (length = %lu, must be atleast 5)", old_pin_len);
         3199  +
         3200  +		return(CACKEY_PCSC_E_BADPIN);
         3201  +	}
         3202  +
         3203  +	/* PIV authentication uses a "key_reference" of 0x80 */
         3204  +	pcsc_identities = cackey_read_certs(slot, NULL, &num_certs);
         3205  +	if (num_certs > 0 && pcsc_identities != NULL) {
         3206  +		switch (pcsc_identities[0].id_type) {
         3207  +			case CACKEY_ID_TYPE_PIV:
         3208  +				CACKEY_DEBUG_PRINTF("We have PIV card, so we will attempt to authenticate using the PIV Application key reference");
         3209  +
         3210  +				key_reference = 0x80;
         3211  +				break;
         3212  +			default:
         3213  +				break;
         3214  +		}
         3215  +
         3216  +		cackey_free_certs(pcsc_identities, num_certs, 1);
         3217  +	}
         3218  +
         3219  +	/* Issue a Set PIN (CHANGE REFERENCE) */
         3220  +	send_ret = cackey_send_apdu(slot, GSCIS_CLASS_ISO7816, GSCIS_INSTR_CHANGE_REFERENCE, 0x00, key_reference, sizeof(pin_update), pin_update, 0x00, &response_code, NULL, NULL);
         3221  +
         3222  +	if (send_ret != CACKEY_PCSC_S_OK) {
         3223  +		if ((response_code & 0x63C0) == 0x63C0) {
         3224  +			tries_remaining = (response_code & 0xF);
         3225  +
         3226  +			CACKEY_DEBUG_PRINTF("PIN Verification failed, %i tries remaining", tries_remaining);
         3227  +
         3228  +			return(CACKEY_PCSC_E_BADPIN);
         3229  +		}
         3230  +
         3231  +		if (response_code == 0x6983) {
         3232  +			CACKEY_DEBUG_PRINTF("Unable to set PIN, device is locked or changing the PIN is disabled");
         3233  +
         3234  +			return(CACKEY_PCSC_E_LOCKED);
         3235  +		}
         3236  +
         3237  +		return(CACKEY_PCSC_E_GENERIC);
         3238  +	}
         3239  +
         3240  +	CACKEY_DEBUG_PRINTF("PIN Change succeeded");
         3241  +
         3242  +	return(CACKEY_PCSC_S_OK);
         3243  +}
         3244  +
         3245  +/*
         3246  + * SYNPOSIS
         3247  + *     ...
         3248  + *
         3249  + * ARGUMENTS
         3250  + *     ...
         3251  + *
         3252  + * RETURN VALUE
         3253  + *     ...
         3254  + *
         3255  + * NOTES
         3256  + *     ...
         3257  + *
  3160   3258    */
  3161   3259   static cackey_ret cackey_login(struct cackey_slot *slot, unsigned char *pin, unsigned long pin_len, int *tries_remaining_p) {
  3162   3260   	struct cackey_pcsc_identity *pcsc_identities;
  3163   3261   	unsigned char cac_pin[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
  3164   3262   	unsigned long num_certs;
  3165   3263   	uint16_t response_code;
  3166   3264   	int tries_remaining;
................................................................................
  4186   4284   		return(identities);
  4187   4285   	}
  4188   4286   
  4189   4287   
  4190   4288   	*ids_found = 0;
  4191   4289   	return(NULL);
  4192   4290   }
         4291  +
         4292  +static cackey_ret cackey_get_pin(char *pinbuf) {
         4293  +	FILE *pinfd;
         4294  +	char *fgets_ret;
         4295  +	int pclose_ret;
         4296  +
         4297  +	if (cackey_pin_command == NULL) {
         4298  +		return(CACKEY_PCSC_E_GENERIC);
         4299  +	}
         4300  +
         4301  +	if (pinbuf == NULL) {
         4302  +		return(CACKEY_PCSC_E_GENERIC);
         4303  +	}
         4304  +
         4305  +	CACKEY_DEBUG_PRINTF("CACKEY_PIN_COMMAND = %s", cackey_pin_command);
         4306  +
         4307  +	pinfd = popen(cackey_pin_command, "r");
         4308  +	if (pinfd == NULL) {
         4309  +		CACKEY_DEBUG_PRINTF("Error.  %s: Unable to run", cackey_pin_command);
         4310  +
         4311  +		return(CACKEY_PCSC_E_BADPIN);
         4312  +	}
         4313  +
         4314  +	fgets_ret = fgets(pinbuf, 32, pinfd);
         4315  +	if (fgets_ret == NULL) {
         4316  +		pinbuf[0] = '\0';
         4317  +	}
         4318  +
         4319  +	pclose_ret = pclose(pinfd);
         4320  +	if (pclose_ret == -1 && errno == ECHILD) {
         4321  +		CACKEY_DEBUG_PRINTF("Notice.  pclose() indicated it could not get the status of the child, assuming it succeeeded !");
         4322  +
         4323  +		pclose_ret = 0;
         4324  +	}
         4325  +
         4326  +	if (pclose_ret != 0) {
         4327  +		CACKEY_DEBUG_PRINTF("Error.  %s: exited with non-zero status of %i", cackey_pin_command, pclose_ret);
         4328  +
         4329  +		return(CACKEY_PCSC_E_BADPIN);
         4330  +	}
         4331  +
         4332  +	if (strlen(pinbuf) < 1) {
         4333  +		CACKEY_DEBUG_PRINTF("Error.  %s: returned no data", cackey_pin_command);
         4334  +
         4335  +		return(CACKEY_PCSC_E_BADPIN);
         4336  +	}
         4337  +
         4338  +	if (pinbuf[strlen(pinbuf) - 1] == '\n') {
         4339  +		pinbuf[strlen(pinbuf) - 1] = '\0';
         4340  +	}
         4341  +
         4342  +	return(CACKEY_PCSC_S_OK);
         4343  +}
  4193   4344   
  4194   4345   CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(CK_VOID_PTR pInitArgs) {
  4195   4346   	CK_C_INITIALIZE_ARGS CK_PTR args;
  4196   4347   	uint32_t idx, highest_slot;
  4197   4348   	int mutex_init_ret;
  4198   4349   	int include_dod_certs;
  4199   4350   
................................................................................
  4999   5150   	}
  5000   5151   
  5001   5152   	CACKEY_DEBUG_PRINTF("Returning CKR_TOKEN_WRITE_PROTECTED (%i)", CKR_TOKEN_WRITE_PROTECTED);
  5002   5153   
  5003   5154   	return(CKR_TOKEN_WRITE_PROTECTED);
  5004   5155   }
  5005   5156   
  5006         -/* We don't support this method. */
  5007   5157   CK_DEFINE_FUNCTION(CK_RV, C_SetPIN)(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pOldPin, CK_ULONG ulOldPinLen, CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewPinLen) {
  5008         -	CACKEY_DEBUG_PRINTF("Called.");
  5009         -
  5010         -	if (!cackey_initialized) {
  5011         -		CACKEY_DEBUG_PRINTF("Error.  Not initialized.");
  5012         -
  5013         -		return(CKR_CRYPTOKI_NOT_INITIALIZED);
  5014         -	}
  5015         -
  5016         -	CACKEY_DEBUG_PRINTF("Returning CKR_FUNCTION_NOT_SUPPORTED (%i)", CKR_FUNCTION_NOT_SUPPORTED);
  5017         -
  5018         -	return(CKR_FUNCTION_NOT_SUPPORTED);
         5158  +	char oldpinbuf[64], newpinbuf[64];
         5159  +	cackey_ret set_pin_ret, get_pin_ret;
         5160  +	CK_SLOT_ID slotID;
         5161  +	int mutex_retval;
         5162  +
         5163  +	CACKEY_DEBUG_PRINTF("Called.");
         5164  +
         5165  +	if (!cackey_initialized) {
         5166  +		CACKEY_DEBUG_PRINTF("Error.  Not initialized.");
         5167  +
         5168  +		return(CKR_CRYPTOKI_NOT_INITIALIZED);
         5169  +	}
         5170  +
         5171  +	mutex_retval = cackey_mutex_lock(cackey_biglock);
         5172  +	if (mutex_retval != 0) {
         5173  +		CACKEY_DEBUG_PRINTF("Error.  Locking failed.");
         5174  +
         5175  +		return(CKR_GENERAL_ERROR);
         5176  +	}
         5177  +
         5178  +	if (!cackey_sessions[hSession].active) {
         5179  +		cackey_mutex_unlock(cackey_biglock);
         5180  +
         5181  +		CACKEY_DEBUG_PRINTF("Error.  Session not active.");
         5182  +		
         5183  +		return(CKR_SESSION_HANDLE_INVALID);
         5184  +	}
         5185  +
         5186  +	slotID = cackey_sessions[hSession].slotID;
         5187  +
         5188  +	if (slotID < 0 || slotID >= (sizeof(cackey_slots) / sizeof(cackey_slots[0]))) {
         5189  +		CACKEY_DEBUG_PRINTF("Error. Invalid slot requested (%lu), outside of valid range", slotID);
         5190  +
         5191  +		cackey_mutex_unlock(cackey_biglock);
         5192  +
         5193  +		return(CKR_GENERAL_ERROR);
         5194  +	}
         5195  +
         5196  +	if (cackey_slots[slotID].active == 0) {
         5197  +		CACKEY_DEBUG_PRINTF("Error. Invalid slot requested (%lu), slot not currently active", slotID);
         5198  +
         5199  +		cackey_mutex_unlock(cackey_biglock);
         5200  +
         5201  +		return(CKR_GENERAL_ERROR);
         5202  +	}
         5203  +
         5204  +	if (cackey_pin_command != NULL) {
         5205  +		/* Get old PIN */
         5206  +		get_pin_ret = cackey_get_pin(oldpinbuf);
         5207  +
         5208  +		if (get_pin_ret != CACKEY_PCSC_S_OK) {
         5209  +			CACKEY_DEBUG_PRINTF("Error while getting Old PIN, returning CKR_PIN_INCORRECT.");
         5210  +
         5211  +			cackey_mutex_unlock(cackey_biglock);
         5212  +			
         5213  +			return(CKR_PIN_INCORRECT);
         5214  +		}
         5215  +
         5216  +		pOldPin = (CK_UTF8CHAR_PTR) oldpinbuf;
         5217  +		ulOldPinLen = strlen(oldpinbuf);
         5218  +
         5219  +		/* Get new PIN */
         5220  +		get_pin_ret = cackey_get_pin(newpinbuf);
         5221  +
         5222  +		if (get_pin_ret != CACKEY_PCSC_S_OK) {
         5223  +			CACKEY_DEBUG_PRINTF("Error while getting New PIN, returning CKR_PIN_INVALID.");
         5224  +
         5225  +			cackey_mutex_unlock(cackey_biglock);
         5226  +			
         5227  +			return(CKR_PIN_INVALID);
         5228  +		}
         5229  +
         5230  +		pNewPin = (CK_UTF8CHAR_PTR) newpinbuf;
         5231  +		ulNewPinLen = strlen(newpinbuf);
         5232  +	}
         5233  +
         5234  +	if (pOldPin == NULL) {
         5235  +		CACKEY_DEBUG_PRINTF("Old PIN value is wrong (null).");
         5236  +
         5237  +		cackey_mutex_unlock(cackey_biglock);
         5238  +
         5239  +		return(CKR_PIN_INCORRECT);
         5240  +	}
         5241  +
         5242  +	if (ulOldPinLen == 0 || ulOldPinLen > 8) {
         5243  +		CACKEY_DEBUG_PRINTF("Old PIN length is wrong: %lu.", (unsigned long) ulOldPinLen);
         5244  +
         5245  +		cackey_mutex_unlock(cackey_biglock);
         5246  +
         5247  +		return(CKR_PIN_INCORRECT);
         5248  +	}
         5249  +
         5250  +	if (pNewPin == NULL) {
         5251  +		CACKEY_DEBUG_PRINTF("New PIN value is wrong (either NULL, or too long/short).");
         5252  +
         5253  +		cackey_mutex_unlock(cackey_biglock);
         5254  +
         5255  +		return(CKR_PIN_INVALID);
         5256  +	}
         5257  +
         5258  +	if (ulNewPinLen < 5 || ulNewPinLen > 8) {
         5259  +		CACKEY_DEBUG_PRINTF("New PIN length is wrong: %lu, must be atleast 5 and no more than 8.", (unsigned long) ulNewPinLen);
         5260  +
         5261  +		cackey_mutex_unlock(cackey_biglock);
         5262  +
         5263  +		return(CKR_PIN_LEN_RANGE);
         5264  +	}
         5265  +
         5266  +	set_pin_ret = cackey_set_pin(&cackey_slots[slotID], pOldPin, ulOldPinLen, pNewPin, ulNewPinLen);
         5267  +
         5268  +	if (set_pin_ret != CACKEY_PCSC_S_OK) {
         5269  +		if (cackey_pin_command == NULL) {
         5270  +			cackey_slots[slotID].token_flags |= CKF_LOGIN_REQUIRED;
         5271  +		}
         5272  +
         5273  +		if (set_pin_ret == CACKEY_PCSC_E_LOCKED) {
         5274  +			cackey_slots[slotID].token_flags |= CKF_USER_PIN_LOCKED;
         5275  +		}
         5276  +	}
         5277  +
         5278  +	mutex_retval = cackey_mutex_unlock(cackey_biglock);
         5279  +	if (mutex_retval != 0) {
         5280  +		CACKEY_DEBUG_PRINTF("Error.  Unlocking failed.");
         5281  +
         5282  +		return(CKR_GENERAL_ERROR);
         5283  +	}
         5284  +
         5285  +	switch (set_pin_ret) {
         5286  +		case CACKEY_PCSC_S_OK:
         5287  +			CACKEY_DEBUG_PRINTF("Successfully set PIN.");
         5288  +
         5289  +			return(CKR_OK);
         5290  +		case CACKEY_PCSC_E_BADPIN:
         5291  +			CACKEY_DEBUG_PRINTF("PIN was invalid.");
         5292  +
         5293  +			return(CKR_PIN_INVALID);
         5294  +		case CACKEY_PCSC_E_LOCKED:
         5295  +			CACKEY_DEBUG_PRINTF("Token is locked or this change is not permitted.");
         5296  +
         5297  +			return(CKR_PIN_LOCKED);
         5298  +		default:
         5299  +			CACKEY_DEBUG_PRINTF("Something else went wrong changing the PIN: %i", set_pin_ret);
         5300  +
         5301  +			return(CKR_GENERAL_ERROR);
         5302  +	}
         5303  +
         5304  +	return(CKR_GENERAL_ERROR);
  5019   5305   }
  5020   5306   
  5021   5307   CK_DEFINE_FUNCTION(CK_RV, C_OpenSession)(CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication, CK_NOTIFY notify, CK_SESSION_HANDLE_PTR phSession) {
  5022   5308   	unsigned long idx;
  5023   5309   	int mutex_retval;
  5024   5310   	int found_session = 0;
  5025   5311   
................................................................................
  5299   5585   	CACKEY_DEBUG_PRINTF("Returning CKR_FUNCTION_NOT_SUPPORTED (%i)", CKR_FUNCTION_NOT_SUPPORTED);
  5300   5586   
  5301   5587   	return(CKR_FUNCTION_NOT_SUPPORTED);
  5302   5588   }
  5303   5589   
  5304   5590   CK_DEFINE_FUNCTION(CK_RV, _C_LoginMutexArg)(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen, int lock_mutex) {
  5305   5591   	CK_SLOT_ID slotID;
  5306         -	FILE *pinfd;
  5307         -	char *pincmd, pinbuf[64], *fgets_ret;
         5592  +	cackey_ret get_pin_ret;
         5593  +	char pinbuf[64];
  5308   5594   	int mutex_retval;
  5309   5595   	int tries_remaining;
  5310   5596   	int login_ret;
  5311         -	int pclose_ret;
  5312   5597   
  5313   5598   	CACKEY_DEBUG_PRINTF("Called.");
  5314   5599   
  5315   5600   	if (!cackey_initialized) {
  5316   5601   		CACKEY_DEBUG_PRINTF("Error.  Not initialized.");
  5317   5602   
  5318   5603   		return(CKR_CRYPTOKI_NOT_INITIALIZED);
................................................................................
  5367   5652   		if (lock_mutex) {
  5368   5653   			cackey_mutex_unlock(cackey_biglock);
  5369   5654   		}
  5370   5655   
  5371   5656   		return(CKR_GENERAL_ERROR);
  5372   5657   	}
  5373   5658   
  5374         -	pincmd = cackey_pin_command;
  5375         -	if (pincmd != NULL) {
  5376         -		CACKEY_DEBUG_PRINTF("CACKEY_PIN_COMMAND = %s", pincmd);
  5377         -
         5659  +	if (cackey_pin_command != NULL) {
  5378   5660   		if (pPin != NULL) {
  5379   5661   			CACKEY_DEBUG_PRINTF("Protected authentication path in effect and PIN provided !?");
  5380   5662   		}
  5381   5663   
  5382         -		pinfd = popen(pincmd, "r");
  5383         -		if (pinfd == NULL) {
  5384         -			CACKEY_DEBUG_PRINTF("Error.  %s: Unable to run", pincmd);
         5664  +		get_pin_ret = cackey_get_pin(pinbuf);
         5665  +
         5666  +		if (get_pin_ret != CACKEY_PCSC_S_OK) {
         5667  +			CACKEY_DEBUG_PRINTF("cackey_get_pin() returned in failure, assuming the PIN was incorrect.");
  5385   5668   
  5386   5669   			if (lock_mutex) {
  5387   5670   				cackey_mutex_unlock(cackey_biglock);
  5388   5671   			}
  5389   5672   
  5390         -			CACKEY_DEBUG_PRINTF("Returning CKR_PIN_INCORRECT (%i)", (int) CKR_PIN_INCORRECT);
  5391         -
  5392   5673   			return(CKR_PIN_INCORRECT);
  5393   5674   		}
  5394   5675   
  5395         -		fgets_ret = fgets(pinbuf, sizeof(pinbuf), pinfd);
  5396         -		if (fgets_ret == NULL) {
  5397         -			pinbuf[0] = '\0';
  5398         -		}
  5399         -
  5400         -		pclose_ret = pclose(pinfd);
  5401         -		if (pclose_ret == -1 && errno == ECHILD) {
  5402         -			CACKEY_DEBUG_PRINTF("Notice.  pclose() indicated it could not get the status of the child, assuming it succeeeded !");
  5403         -
  5404         -			pclose_ret = 0;
  5405         -		}
  5406         -
  5407         -		if (pclose_ret != 0) {
  5408         -			CACKEY_DEBUG_PRINTF("Error.  %s: exited with non-zero status of %i", pincmd, pclose_ret);
  5409         -
  5410         -			if (lock_mutex) {
  5411         -				cackey_mutex_unlock(cackey_biglock);
  5412         -			}
  5413         -
  5414         -			CACKEY_DEBUG_PRINTF("Returning CKR_PIN_INCORRECT (%i)", (int) CKR_PIN_INCORRECT);
  5415         -
  5416         -			return(CKR_PIN_INCORRECT);
  5417         -		}
  5418         -
  5419         -		if (strlen(pinbuf) < 1) {
  5420         -			CACKEY_DEBUG_PRINTF("Error.  %s: returned no data", pincmd);
  5421         -
  5422         -			if (lock_mutex) {
  5423         -				cackey_mutex_unlock(cackey_biglock);
  5424         -			}
  5425         -
  5426         -			CACKEY_DEBUG_PRINTF("Returning CKR_PIN_INCORRECT (%i)", (int) CKR_PIN_INCORRECT);
  5427         -
  5428         -			return(CKR_PIN_INCORRECT);
  5429         -		}
  5430         -
  5431         -		if (pinbuf[strlen(pinbuf) - 1] == '\n') {
  5432         -			pinbuf[strlen(pinbuf) - 1] = '\0';
  5433         -		}
  5434         -
  5435   5676   		pPin = (CK_UTF8CHAR_PTR) pinbuf;
  5436   5677   		ulPinLen = strlen(pinbuf);
  5437   5678   	}
  5438   5679   
  5439   5680   	login_ret = cackey_login(&cackey_slots[slotID], pPin, ulPinLen, &tries_remaining);
  5440   5681   	if (login_ret != CACKEY_PCSC_S_OK) {
  5441   5682   		if (lock_mutex) {