Check-in [9b8b8e3b4a]
Overview
Comment:Updated to retry APDU in some cases

Updated to recognize when a card is logged out without being switched

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:9b8b8e3b4ad44774d04ca207013ae14af26833dc
User & Date: rkeene on 2010-05-23 02:59:54
Other Links: manifest | tags
Context
2010-05-23
03:42
Updated to retry if got NOT_TRANSACTED

Fixed issue with retry in APDU transmit check-in: 7cc9fb64cc user: rkeene tags: trunk

02:59
Updated to retry APDU in some cases

Updated to recognize when a card is logged out without being switched check-in: 9b8b8e3b4a user: rkeene tags: trunk

2010-05-22
21:31
Updated to set LOGIN_REQUIRED flag when C_Logout is called

Updated to check all references to a session's slot check-in: a08de24384 user: rkeene tags: trunk

Changes

Modified cackey.c from [26bb9837f1] to [6811fa6136].

   549    549   	CACKEY_TLV_OBJID_CAC_BENEFITS      = 0x0202,
   550    550   	CACKEY_TLV_OBJID_CAC_OTHERBENEFITS = 0x0203,
   551    551   	CACKEY_TLV_OBJID_CAC_PERSONNEL     = 0x0201,
   552    552   	CACKEY_TLV_OBJID_CAC_PKICERT       = 0x02FE
   553    553   } cackey_tlv_objectid;
   554    554   
   555    555   typedef enum {
   556         -	CACKEY_PCSC_S_TOKENPRESENT    = 2,
   557         -	CACKEY_PCSC_S_TOKENABSENT     = 1,
          556  +	CACKEY_PCSC_S_TOKENPRESENT    = 1,
   558    557   	CACKEY_PCSC_S_OK              = 0,
   559    558   	CACKEY_PCSC_E_GENERIC         = -1,
   560    559   	CACKEY_PCSC_E_BADPIN          = -2,
   561    560   	CACKEY_PCSC_E_LOCKED          = -3,
          561  +	CACKEY_PCSC_E_NEEDLOGIN       = -4,
          562  +	CACKEY_PCSC_E_TOKENABSENT     = -6,
   562    563   } cackey_ret;
   563    564   
   564    565   struct cackey_tlv_cardurl {
   565    566   	unsigned char        rid[5];
   566    567   	cackey_tlv_apptype   apptype;
   567    568   	cackey_tlv_objectid  objectid;
   568    569   	cackey_tlv_objectid  appid;
................................................................................
  1065   1066   		CACKEY_DEBUG_PRINTF("Sending APDU: <<censored>>");
  1066   1067   	} else {
  1067   1068   		CACKEY_DEBUG_PRINTBUF("Sending APDU:", xmit_buf, xmit_len);
  1068   1069   	}
  1069   1070   
  1070   1071   	recv_len = sizeof(recv_buf);
  1071   1072   	scard_xmit_ret = SCardTransmit(slot->pcsc_card, SCARD_PCI_T0, xmit_buf, xmit_len, SCARD_PCI_T1, recv_buf, &recv_len);
         1073  +	if (scard_xmit_ret == SCARD_E_NOT_TRANSACTED) {
         1074  +		CACKEY_DEBUG_PRINTF("Failed to send APDU to card (SCardTransmit() = SCARD_E_NOT_TRANSACTED), retrying...");
         1075  +
         1076  +		scard_xmit_ret = SCardTransmit(slot->pcsc_card, SCARD_PCI_T0, xmit_buf, xmit_len, SCARD_PCI_T1, recv_buf, &recv_len);
         1077  +	}
  1072   1078   	if (scard_xmit_ret != SCARD_S_SUCCESS) {
  1073   1079   		CACKEY_DEBUG_PRINTF("Failed to send APDU to card (SCardTransmit() = %s/%lx)", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_xmit_ret), (unsigned long) scard_xmit_ret);
  1074   1080   		CACKEY_DEBUG_PRINTF("Marking slot as having been reset");
  1075   1081   
  1076   1082   		slot->transaction_depth = 0;
  1077   1083   		slot->slot_reset = 1;
  1078   1084   
................................................................................
  1096   1102   					SCardDisconnect(slot->pcsc_card, SCARD_RESET_CARD);
  1097   1103   					slot->pcsc_card_connected = 0;
  1098   1104   
  1099   1105   					/* End Smartcard Transaction */
  1100   1106   					slot->transaction_depth = 1;
  1101   1107   					cackey_end_transaction(slot);
  1102   1108   
  1103         -					return(CACKEY_PCSC_E_GENERIC);
         1109  +					return(CACKEY_PCSC_E_TOKENABSENT);
  1104   1110   				}
  1105   1111   			} else {
  1106   1112   				CACKEY_DEBUG_PRINTF("Disconnecting card");
  1107   1113   
  1108   1114   				SCardDisconnect(slot->pcsc_card, SCARD_RESET_CARD);
  1109   1115   				slot->pcsc_card_connected = 0;
  1110   1116   
  1111   1117   				/* End Smartcard Transaction */
  1112   1118   				slot->transaction_depth = 1;
  1113   1119   				cackey_end_transaction(slot);
  1114   1120   
  1115   1121   				CACKEY_DEBUG_PRINTF("Returning in failure");
  1116         -				return(CACKEY_PCSC_E_GENERIC);
         1122  +				return(CACKEY_PCSC_E_TOKENABSENT);
  1117   1123   			}
  1118   1124   		} else {
  1119   1125   			CACKEY_DEBUG_PRINTF("Disconnecting card");
  1120   1126   
  1121   1127   			SCardDisconnect(slot->pcsc_card, SCARD_RESET_CARD);
  1122   1128   			slot->pcsc_card_connected = 0;
  1123   1129   
  1124   1130   			/* End Smartcard Transaction */
  1125   1131   			slot->transaction_depth = 1;
  1126   1132   			cackey_end_transaction(slot);
  1127   1133   
  1128   1134   			CACKEY_DEBUG_PRINTF("Returning in failure");
  1129         -			return(CACKEY_PCSC_E_GENERIC);
         1135  +			return(CACKEY_PCSC_E_TOKENABSENT);
  1130   1136   		}
  1131   1137   	}
  1132   1138   
  1133   1139   	CACKEY_DEBUG_PRINTBUF("Returned Value:", recv_buf, recv_len);
  1134   1140   
  1135   1141   	if (recv_len < 2) {
  1136   1142   		/* Minimal response length is 2 bytes, returning in failure */
................................................................................
  1972   1978   
  1973   1979   		tmpoutbuflen = outbuflen;
  1974   1980   
  1975   1981   		send_ret = cackey_send_apdu(slot, GSCIS_CLASS_GLOBAL_PLATFORM, GSCIS_INSTR_SIGNDECRYPT, p1, 0x00, bytes_to_send, tmpbuf, le, &respcode, outbuf, &tmpoutbuflen);
  1976   1982   		if (send_ret != CACKEY_PCSC_S_OK) {
  1977   1983   			CACKEY_DEBUG_PRINTF("ADPU Sending Failed -- returning in error.");
  1978   1984   
  1979         -			if (respcode == 0x6982) {
  1980         -				CACKEY_DEBUG_PRINTF("Security status not satisified.");
  1981         -			}
  1982         -
  1983   1985   			if (free_tmpbuf) {
  1984   1986   				if (tmpbuf_s) {
  1985   1987   					free(tmpbuf_s);
  1986   1988   				}
  1987   1989   			}
  1988   1990   
  1989   1991   			/* End transaction */
  1990   1992   			cackey_end_transaction(slot);
         1993  +
         1994  +			if (respcode == 0x6982) {
         1995  +				CACKEY_DEBUG_PRINTF("Security status not satisified.  Returning NEEDLOGIN");
         1996  +
         1997  +				slot->slot_reset = 1;
         1998  +				slot->token_flags = CKF_LOGIN_REQUIRED;
         1999  +
         2000  +				return(CACKEY_PCSC_E_NEEDLOGIN);
         2001  +			}
         2002  +
         2003  +			if (send_ret == CACKEY_PCSC_E_TOKENABSENT) {
         2004  +				CACKEY_DEBUG_PRINTF("Token absent.  Returning TOKENABSENT");
         2005  +
         2006  +				slot->slot_reset = 1;
         2007  +				slot->token_flags = CKF_LOGIN_REQUIRED;
         2008  +
         2009  +				return(CACKEY_PCSC_E_TOKENABSENT);
         2010  +			}
  1991   2011   
  1992   2012   			return(-1);
  1993   2013   		}
  1994   2014   
  1995   2015   		tmpbuf += bytes_to_send;
  1996   2016   		tmpbuflen -= bytes_to_send;
  1997   2017   
................................................................................
  2184   2204   
  2185   2205   	CACKEY_DEBUG_PRINTF("Called.");
  2186   2206   
  2187   2207   	pcsc_connect_ret = cackey_connect_card(slot);
  2188   2208   	if (pcsc_connect_ret != CACKEY_PCSC_S_OK) {
  2189   2209   		CACKEY_DEBUG_PRINTF("Unable to connect to card, returning token absent");
  2190   2210   
  2191         -		return(CACKEY_PCSC_S_TOKENABSENT);
         2211  +		return(CACKEY_PCSC_E_TOKENABSENT);
  2192   2212   	}
  2193   2213   
  2194   2214   	atr_len = sizeof(atr);
  2195   2215   	status_ret = SCardStatus(slot->pcsc_card, NULL, &reader_len, &state, &protocol, atr, &atr_len);
  2196   2216   	if (status_ret != SCARD_S_SUCCESS) {
  2197   2217   		slot->slot_reset = 1;
  2198   2218   		slot->token_flags = CKF_LOGIN_REQUIRED;
................................................................................
  2209   2229   				}
  2210   2230   
  2211   2231   				CACKEY_DEBUG_PRINTF("Reset successful, requerying");
  2212   2232   				status_ret = SCardStatus(slot->pcsc_card, NULL, &reader_len, &state, &protocol, atr, &atr_len);
  2213   2233   				if (status_ret != SCARD_S_SUCCESS) {
  2214   2234   					CACKEY_DEBUG_PRINTF("Still unable to query card status, returning token absent.  SCardStatus() = %s", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(status_ret));
  2215   2235   
  2216         -					return(CACKEY_PCSC_S_TOKENABSENT);
         2236  +					return(CACKEY_PCSC_E_TOKENABSENT);
  2217   2237   				}
  2218   2238   			} else {
  2219   2239   				CACKEY_DEBUG_PRINTF("Unable to reconnect to card, returning token absent.  SCardReconnect() = %s", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_reconn_ret));
  2220   2240   
  2221         -				return(CACKEY_PCSC_S_TOKENABSENT);
         2241  +				return(CACKEY_PCSC_E_TOKENABSENT);
  2222   2242   			}
  2223   2243   		} else {
  2224   2244   			CACKEY_DEBUG_PRINTF("Unable to query card status, returning token absent.  SCardStatus() = %s", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(status_ret));
  2225   2245   
  2226         -			return(CACKEY_PCSC_S_TOKENABSENT);
         2246  +			return(CACKEY_PCSC_E_TOKENABSENT);
  2227   2247   		}
  2228   2248   	}
  2229   2249   
  2230   2250   	if ((state & SCARD_ABSENT) == SCARD_ABSENT) {
  2231   2251   		CACKEY_DEBUG_PRINTF("Card is absent, returning token absent");
  2232   2252   
  2233         -		return(CACKEY_PCSC_S_TOKENABSENT);
         2253  +		return(CACKEY_PCSC_E_TOKENABSENT);
  2234   2254   	}
  2235   2255   
  2236   2256   	CACKEY_DEBUG_PRINTF("Returning token present.");
  2237   2257   
  2238   2258   	return(CACKEY_PCSC_S_TOKENPRESENT);
  2239   2259   }
  2240   2260   
................................................................................
  4804   4824   	switch (cackey_sessions[hSession].decrypt_mechanism) {
  4805   4825   		case CKM_RSA_PKCS:
  4806   4826   			/* Ask card to decrypt */
  4807   4827   			buflen = cackey_signdecrypt(&cackey_slots[slotID], cackey_sessions[hSession].decrypt_identity, pEncryptedPart, ulEncryptedPartLen, buf, sizeof(buf), 0, 1);
  4808   4828   
  4809   4829   			if (buflen < 0) {
  4810   4830   				/* Decryption failed. */
  4811         -				retval = CKR_GENERAL_ERROR;
         4831  +				if (buflen == CACKEY_PCSC_E_NEEDLOGIN) {
         4832  +					retval = CKR_USER_NOT_LOGGED_IN;
         4833  +				} else if (buflen == CACKEY_PCSC_E_TOKENABSENT) {
         4834  +					retval = CKR_DEVICE_REMOVED;
         4835  +				} else {
         4836  +					retval = CKR_GENERAL_ERROR;
         4837  +				}
  4812   4838   			} else if (((unsigned long) buflen) > *pulPartLen && pPart) {
  4813   4839   				/* Decrypted data too large */
  4814   4840   				retval = CKR_BUFFER_TOO_SMALL;
  4815   4841   			} else {
  4816   4842   				if (pPart) {
  4817   4843   					memcpy(pPart, buf, buflen);
  4818   4844   				}
................................................................................
  5274   5300   		case CKM_RSA_PKCS:
  5275   5301   			/* Ask card to sign */
  5276   5302   			CACKEY_DEBUG_PRINTF("Asking to sign from identity %p in session %lu", cackey_sessions[hSession].sign_identity, (unsigned long) hSession);
  5277   5303   			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);
  5278   5304   
  5279   5305   			if (sigbuflen < 0) {
  5280   5306   				/* Signing failed. */
  5281         -				retval = CKR_GENERAL_ERROR;
         5307  +				if (sigbuflen == CACKEY_PCSC_E_NEEDLOGIN) {
         5308  +					retval = CKR_USER_NOT_LOGGED_IN;
         5309  +				} else if (sigbuflen == CACKEY_PCSC_E_TOKENABSENT) {
         5310  +					retval = CKR_DEVICE_REMOVED;
         5311  +				} else {
         5312  +					retval = CKR_GENERAL_ERROR;
         5313  +				}
  5282   5314   			} else if (((unsigned long) sigbuflen) > *pulSignatureLen && pSignature) {
  5283   5315   				/* Signed data too large */
  5284   5316   				CACKEY_DEBUG_PRINTF("retval = CKR_BUFFER_TOO_SMALL;  sigbuflen = %lu, pulSignatureLen = %lu", (unsigned long) sigbuflen, (unsigned long) *pulSignatureLen);
  5285   5317   
  5286   5318   				retval = CKR_BUFFER_TOO_SMALL;
  5287   5319   
  5288   5320   				terminate_sign = 0;