Check-in [27d18fd03a]
Overview
Comment:Updated to not dead-lock when prompting for PIN during a signing operation
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | protected-auth-path
Files: files | file ages | folders
SHA1:27d18fd03aac61b9054a3ac0963a2bce5e6f8a24
User & Date: rkeene on 2013-08-14 06:29:03
Other Links: manifest | tags
Context
2013-09-14
04:11
Merged in changes from piv check-in: 5f8f3e59a7 user: rkeene tags: protected-auth-path
2013-08-14
06:29
Updated to not dead-lock when prompting for PIN during a signing operation check-in: 27d18fd03a user: rkeene tags: protected-auth-path
05:53
If using Protected Authentication Path, don't set the LOGIN_REQUIRED flag check-in: 14d49a499f user: rkeene tags: protected-auth-path
Changes

Modified cackey.c from [345685b667] to [37c3fd69d4].

  2870   2870   					free(tmpbuf_s);
  2871   2871   				}
  2872   2872   			}
  2873   2873   
  2874   2874   			/* End transaction */
  2875   2875   			cackey_end_transaction(slot);
  2876   2876   
  2877         -			if (respcode == 0x6982) {
         2877  +			if (respcode == 0x6982 || respcode == 0x6e00) {
  2878   2878   				CACKEY_DEBUG_PRINTF("Security status not satisified.  Returning NEEDLOGIN");
  2879   2879   
  2880   2880   				cackey_mark_slot_reset(slot);
  2881   2881   
  2882   2882   				return(CACKEY_PCSC_E_NEEDLOGIN);
  2883   2883   			}
  2884   2884   
................................................................................
  5170   5170   	}
  5171   5171   
  5172   5172   	CACKEY_DEBUG_PRINTF("Returning CKR_FUNCTION_NOT_SUPPORTED (%i)", CKR_FUNCTION_NOT_SUPPORTED);
  5173   5173   
  5174   5174   	return(CKR_FUNCTION_NOT_SUPPORTED);
  5175   5175   }
  5176   5176   
  5177         -CK_DEFINE_FUNCTION(CK_RV, C_Login)(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen) {
         5177  +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) {
  5178   5178   	CK_SLOT_ID slotID;
  5179   5179   	FILE *pinfd;
  5180   5180   	char *pincmd, pinbuf[64], *fgets_ret;
  5181   5181   	int mutex_retval;
  5182   5182   	int tries_remaining;
  5183   5183   	int login_ret;
  5184   5184   	int pclose_ret;
................................................................................
  5199   5199   
  5200   5200   	if (userType != CKU_USER) {
  5201   5201   		CACKEY_DEBUG_PRINTF("Error.  We only support USER mode, asked for %lu mode.", (unsigned long) userType)
  5202   5202   
  5203   5203   		return(CKR_USER_TYPE_INVALID);
  5204   5204   	}
  5205   5205   
  5206         -	mutex_retval = cackey_mutex_lock(cackey_biglock);
  5207         -	if (mutex_retval != 0) {
  5208         -		CACKEY_DEBUG_PRINTF("Error.  Locking failed.");
         5206  +	if (lock_mutex) {
         5207  +		mutex_retval = cackey_mutex_lock(cackey_biglock);
         5208  +		if (mutex_retval != 0) {
         5209  +			CACKEY_DEBUG_PRINTF("Error.  Locking failed.");
  5209   5210   
  5210         -		return(CKR_GENERAL_ERROR);
         5211  +			return(CKR_GENERAL_ERROR);
         5212  +		}
  5211   5213   	}
  5212   5214   
  5213   5215   	if (!cackey_sessions[hSession].active) {
  5214         -		cackey_mutex_unlock(cackey_biglock);
         5216  +		if (lock_mutex) {
         5217  +			cackey_mutex_unlock(cackey_biglock);
         5218  +		}
  5215   5219   
  5216   5220   		CACKEY_DEBUG_PRINTF("Error.  Session not active.");
  5217   5221   		
  5218   5222   		return(CKR_SESSION_HANDLE_INVALID);
  5219   5223   	}
  5220   5224   
  5221   5225   	slotID = cackey_sessions[hSession].slotID;
  5222   5226   
  5223   5227   	if (slotID < 0 || slotID >= (sizeof(cackey_slots) / sizeof(cackey_slots[0]))) {
  5224   5228   		CACKEY_DEBUG_PRINTF("Error. Invalid slot requested (%lu), outside of valid range", slotID);
         5229  +
         5230  +		if (lock_mutex) {
         5231  +			cackey_mutex_unlock(cackey_biglock);
         5232  +		}
  5225   5233   
  5226   5234   		return(CKR_GENERAL_ERROR);
  5227   5235   	}
  5228   5236   
  5229   5237   	if (cackey_slots[slotID].active == 0) {
  5230   5238   		CACKEY_DEBUG_PRINTF("Error. Invalid slot requested (%lu), slot not currently active", slotID);
  5231   5239   
  5232         -		cackey_mutex_unlock(cackey_biglock);
         5240  +		if (lock_mutex) {
         5241  +			cackey_mutex_unlock(cackey_biglock);
         5242  +		}
  5233   5243   
  5234   5244   		return(CKR_GENERAL_ERROR);
  5235   5245   	}
  5236   5246   
  5237   5247   	pincmd = cackey_pin_command;
  5238   5248   	if (pincmd != NULL) {
  5239   5249   		CACKEY_DEBUG_PRINTF("CACKEY_PIN_COMMAND = %s", pincmd);
................................................................................
  5242   5252   			CACKEY_DEBUG_PRINTF("Protected authentication path in effect and PIN provided !?");
  5243   5253   		}
  5244   5254   
  5245   5255   		pinfd = popen(pincmd, "r");
  5246   5256   		if (pinfd == NULL) {
  5247   5257   			CACKEY_DEBUG_PRINTF("Error.  %s: Unable to run", pincmd);
  5248   5258   
  5249         -			cackey_mutex_unlock(cackey_biglock);
         5259  +			if (lock_mutex) {
         5260  +				cackey_mutex_unlock(cackey_biglock);
         5261  +			}
  5250   5262   
  5251   5263   			CACKEY_DEBUG_PRINTF("Returning CKR_PIN_INCORRECT (%i)", (int) CKR_PIN_INCORRECT);
  5252   5264   
  5253   5265   			return(CKR_PIN_INCORRECT);
  5254   5266   		}
  5255   5267   
  5256   5268   		fgets_ret = fgets(pinbuf, sizeof(pinbuf), pinfd);
................................................................................
  5258   5270   			pinbuf[0] = '\0';
  5259   5271   		}
  5260   5272   
  5261   5273   		pclose_ret = pclose(pinfd);
  5262   5274   		if (pclose_ret != 0) {
  5263   5275   			CACKEY_DEBUG_PRINTF("Error.  %s: exited with non-zero status of %i", pincmd, pclose_ret);
  5264   5276   
  5265         -			cackey_mutex_unlock(cackey_biglock);
         5277  +			if (lock_mutex) {
         5278  +				cackey_mutex_unlock(cackey_biglock);
         5279  +			}
  5266   5280   
  5267   5281   			CACKEY_DEBUG_PRINTF("Returning CKR_PIN_INCORRECT (%i)", (int) CKR_PIN_INCORRECT);
  5268   5282   
  5269   5283   			return(CKR_PIN_INCORRECT);
  5270   5284   		}
  5271   5285   
  5272   5286   		if (strlen(pinbuf) < 1) {
  5273   5287   			CACKEY_DEBUG_PRINTF("Error.  %s: returned no data", pincmd);
  5274   5288   
  5275         -			cackey_mutex_unlock(cackey_biglock);
         5289  +			if (lock_mutex) {
         5290  +				cackey_mutex_unlock(cackey_biglock);
         5291  +			}
  5276   5292   
  5277   5293   			CACKEY_DEBUG_PRINTF("Returning CKR_PIN_INCORRECT (%i)", (int) CKR_PIN_INCORRECT);
  5278   5294   
  5279   5295   			return(CKR_PIN_INCORRECT);
  5280   5296   		}
  5281   5297   
  5282   5298   		if (pinbuf[strlen(pinbuf) - 1] == '\n') {
................................................................................
  5285   5301   
  5286   5302   		pPin = (CK_UTF8CHAR_PTR) pinbuf;
  5287   5303   		ulPinLen = strlen(pinbuf);
  5288   5304   	}
  5289   5305   
  5290   5306   	login_ret = cackey_login(&cackey_slots[slotID], pPin, ulPinLen, &tries_remaining);
  5291   5307   	if (login_ret != CACKEY_PCSC_S_OK) {
  5292         -		cackey_mutex_unlock(cackey_biglock);
         5308  +		if (lock_mutex) {
         5309  +			cackey_mutex_unlock(cackey_biglock);
         5310  +		}
  5293   5311   
  5294   5312   		if (login_ret == CACKEY_PCSC_E_LOCKED) {
  5295   5313   			CACKEY_DEBUG_PRINTF("Error.  Token is locked.");
  5296   5314   
  5297   5315   			cackey_slots[slotID].token_flags |= CKF_USER_PIN_LOCKED;
  5298   5316   
  5299   5317   			CACKEY_DEBUG_PRINTF("Returning CKR_PIN_LOCKED (%i)", (int) CKR_PIN_LOCKED);
................................................................................
  5318   5336   		return(CKR_GENERAL_ERROR);
  5319   5337   	}
  5320   5338   
  5321   5339   	cackey_slots[slotID].token_flags &= ~(CKF_USER_PIN_LOCKED | CKF_USER_PIN_COUNT_LOW | CKF_LOGIN_REQUIRED | CKF_USER_PIN_FINAL_TRY);
  5322   5340   
  5323   5341   	cackey_sessions[hSession].state = CKS_RO_USER_FUNCTIONS;
  5324   5342   
  5325         -	mutex_retval = cackey_mutex_unlock(cackey_biglock);
  5326         -	if (mutex_retval != 0) {
  5327         -		CACKEY_DEBUG_PRINTF("Error.  Unlocking failed.");
         5343  +	if (lock_mutex) {
         5344  +		mutex_retval = cackey_mutex_unlock(cackey_biglock);
         5345  +		if (mutex_retval != 0) {
         5346  +			CACKEY_DEBUG_PRINTF("Error.  Unlocking failed.");
  5328   5347   
  5329         -		return(CKR_GENERAL_ERROR);
         5348  +			return(CKR_GENERAL_ERROR);
         5349  +		}
  5330   5350   	}
  5331   5351   
  5332   5352   	CACKEY_DEBUG_PRINTF("Returning CKR_OK (%i)", CKR_OK);
  5333   5353   
  5334   5354   	return(CKR_OK);
  5335   5355   }
         5356  +
         5357  +CK_DEFINE_FUNCTION(CK_RV, C_Login)(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen) {
         5358  +	return(_C_LoginMutexArg(hSession, userType, pPin, ulPinLen, 1));
         5359  +}
  5336   5360   
  5337   5361   CK_DEFINE_FUNCTION(CK_RV, C_Logout)(CK_SESSION_HANDLE hSession) {
  5338   5362   	CK_SLOT_ID slotID;
  5339   5363   	int mutex_retval;
  5340   5364   
  5341   5365   	CACKEY_DEBUG_PRINTF("Called.");
  5342   5366   
................................................................................
  6311   6335   
  6312   6336   	switch (cackey_sessions[hSession].decrypt_mechanism) {
  6313   6337   		case CKM_RSA_PKCS:
  6314   6338   			/* Ask card to decrypt */
  6315   6339   			buflen = cackey_signdecrypt(&cackey_slots[slotID], cackey_sessions[hSession].decrypt_identity, pEncryptedPart, ulEncryptedPartLen, buf, sizeof(buf), 0, 1);
  6316   6340   
  6317   6341   			if (buflen == CACKEY_PCSC_E_NEEDLOGIN && cackey_pin_command != NULL) {
  6318         -				if (C_Login(hSession, CKU_USER, NULL, 0) == CKR_OK) {
         6342  +				if (_C_LoginMutexArg(hSession, CKU_USER, NULL, 0, 0) == CKR_OK) {
  6319   6343   					buflen = cackey_signdecrypt(&cackey_slots[slotID], cackey_sessions[hSession].decrypt_identity, pEncryptedPart, ulEncryptedPartLen, buf, sizeof(buf), 0, 1);
  6320   6344   				}
  6321   6345   			}
  6322   6346   
  6323   6347   			if (buflen < 0) {
  6324   6348   				/* Decryption failed. */
  6325   6349   				if (buflen == CACKEY_PCSC_E_NEEDLOGIN) {
................................................................................
  6828   6852   	switch (cackey_sessions[hSession].sign_mechanism) {
  6829   6853   		case CKM_RSA_PKCS:
  6830   6854   			/* Ask card to sign */
  6831   6855   			CACKEY_DEBUG_PRINTF("Asking to sign from identity %p in session %lu", (void *) cackey_sessions[hSession].sign_identity, (unsigned long) hSession);
  6832   6856   			sigbuflen = cackey_signdecrypt(&cackey_slots[slotID], cackey_sessions[hSession].sign_identity, cackey_sessions[hSession].sign_buf, cackey_sessions[hSession].sign_bufused, sigbuf, sizeof(sigbuf), 1, 0);
  6833   6857   
  6834   6858   			if (sigbuflen == CACKEY_PCSC_E_NEEDLOGIN && cackey_pin_command != NULL) {
  6835         -				if (C_Login(hSession, CKU_USER, NULL, 0) == CKR_OK) {
         6859  +				if (_C_LoginMutexArg(hSession, CKU_USER, NULL, 0, 0) == CKR_OK) {
  6836   6860   					sigbuflen = cackey_signdecrypt(&cackey_slots[slotID], cackey_sessions[hSession].sign_identity, cackey_sessions[hSession].sign_buf, cackey_sessions[hSession].sign_bufused, sigbuf, sizeof(sigbuf), 1, 0);
  6837   6861   				}
  6838   6862   			}
  6839   6863   
  6840   6864   			if (sigbuflen < 0) {
  6841   6865   				/* Signing failed. */
  6842   6866   				if (sigbuflen == CACKEY_PCSC_E_NEEDLOGIN) {