[Pcsclite-cvs-commit] r2063 - trunk/PCSC/src

Ludovic Rousseau rousseau at costa.debian.org
Thu May 25 21:52:35 UTC 2006


Author: rousseau
Date: 2006-05-25 21:52:34 +0000 (Thu, 25 May 2006)
New Revision: 2063

Modified:
   trunk/PCSC/src/winscard_clnt.c
   trunk/PCSC/src/winscard_msg.c
   trunk/PCSC/src/winscard_svc.c
Log:
add support of extended APDU as a new command so we do not need to
compile pcsc-lite with or without extended APDU


Modified: trunk/PCSC/src/winscard_clnt.c
===================================================================
--- trunk/PCSC/src/winscard_clnt.c	2006-05-25 21:50:34 UTC (rev 2062)
+++ trunk/PCSC/src/winscard_clnt.c	2006-05-25 21:52:34 UTC (rev 2063)
@@ -2556,8 +2556,6 @@
 	LPDWORD pcbRecvLength)
 {
 	LONG rv;
-	transmit_struct scTransmitStruct;
-	sharedSegmentMsg msgStruct;
 	int i;
 	DWORD dwContextIndex, dwChannelIndex;
 
@@ -2598,76 +2596,168 @@
 		return SCARD_E_READER_UNAVAILABLE;
 	}
 
-	if (cbSendLength > MAX_BUFFER_SIZE)
+	if ((cbSendLength > MAX_BUFFER_SIZE_EXTENDED)
+		|| (*pcbRecvLength > MAX_BUFFER_SIZE_EXTENDED))
 	{
 		SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);	
 		return SCARD_E_INSUFFICIENT_BUFFER;
 	}
 
-	scTransmitStruct.hCard = hCard;
-	scTransmitStruct.cbSendLength = cbSendLength;
-	scTransmitStruct.pcbRecvLength = *pcbRecvLength;
-	memcpy(&scTransmitStruct.pioSendPci, pioSendPci,
-		sizeof(SCARD_IO_REQUEST));
-	memcpy(scTransmitStruct.pbSendBuffer, pbSendBuffer, cbSendLength);
+	if ((cbSendLength > MAX_BUFFER_SIZE) || (*pcbRecvLength > MAX_BUFFER_SIZE))
+	{
+		/* extended APDU */
+		unsigned char buffer[sizeof(sharedSegmentMsg) + MAX_BUFFER_SIZE_EXTENDED];
+		transmit_struct_extended *scTransmitStructExtended = (transmit_struct_extended *)buffer;
+		sharedSegmentMsg *pmsgStruct = (psharedSegmentMsg)buffer;
 
-	if (pioRecvPci)
-	{
-		memcpy(&scTransmitStruct.pioRecvPci, pioRecvPci,
+		scTransmitStructExtended->hCard = hCard;
+		scTransmitStructExtended->cbSendLength = cbSendLength;
+		scTransmitStructExtended->pcbRecvLength = *pcbRecvLength;
+		scTransmitStructExtended->size = sizeof(*scTransmitStructExtended) + cbSendLength;
+		memcpy(&scTransmitStructExtended->pioSendPci, pioSendPci,
 			sizeof(SCARD_IO_REQUEST));
-	}
-	else
-		scTransmitStruct.pioRecvPci.dwProtocol = SCARD_PROTOCOL_ANY;
+		memcpy(scTransmitStructExtended->data, pbSendBuffer, cbSendLength);
 
-	rv = WrapSHMWrite(SCARD_TRANSMIT, psContextMap[dwContextIndex].dwClientID,
-		sizeof(scTransmitStruct),
-		PCSCLITE_CLIENT_ATTEMPTS, (void *) &scTransmitStruct);
+		if (pioRecvPci)
+		{
+			memcpy(&scTransmitStructExtended->pioRecvPci, pioRecvPci,
+				sizeof(SCARD_IO_REQUEST));
+		}
+		else
+			scTransmitStructExtended->pioRecvPci.dwProtocol = SCARD_PROTOCOL_ANY;
 
-	if (rv == -1)
-	{
-		SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);	
-		return SCARD_E_NO_SERVICE;
-	}
+		rv = WrapSHMWrite(SCARD_TRANSMIT_EXTENDED,
+			psContextMap[dwContextIndex].dwClientID,
+			scTransmitStructExtended->size,
+			PCSCLITE_CLIENT_ATTEMPTS, buffer);
 
-	/*
-	 * Read a message from the server
-	 */
-	rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
+		if (rv == -1)
+		{
+			SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);	
+			return SCARD_E_NO_SERVICE;
+		}
 
-	memcpy(&scTransmitStruct, &msgStruct.data, sizeof(scTransmitStruct));
+		/*
+		 * Read a message from the server
+		 */
+		/* read the first block */
+		rv = SHMMessageReceive(buffer, sizeof(sharedSegmentMsg), psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
+		if (rv == -1)
+		{
+			SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);	
+			return SCARD_F_COMM_ERROR;
+		}
 
-	if (rv == -1)
-	{
+		/* we receive a sharedSegmentMsg and not a transmit_struct_extended */
+		scTransmitStructExtended = (transmit_struct_extended *)&(pmsgStruct -> data);
+
+		/* a second block is present */
+		if (scTransmitStructExtended->size > PCSCLITE_MAX_MESSAGE_SIZE)
+		{
+			rv = SHMMessageReceive(buffer + sizeof(sharedSegmentMsg),
+				scTransmitStructExtended->size-PCSCLITE_MAX_MESSAGE_SIZE,
+				psContextMap[dwContextIndex].dwClientID,
+				PCSCLITE_CLIENT_ATTEMPTS);
+			if (rv == -1)
+			{
+				SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);	
+				return SCARD_F_COMM_ERROR;
+			}
+		}
+
+		if (scTransmitStructExtended -> rv == SCARD_S_SUCCESS)
+		{
+			/*
+			 * Copy and zero it so any secret information is not leaked
+			 */
+			memcpy(pbRecvBuffer, scTransmitStructExtended -> data,
+				scTransmitStructExtended -> pcbRecvLength);
+			memset(scTransmitStructExtended -> data, 0x00,
+				scTransmitStructExtended -> pcbRecvLength);
+
+			if (pioRecvPci)
+				memcpy(pioRecvPci, &scTransmitStructExtended -> pioRecvPci,
+					sizeof(SCARD_IO_REQUEST));
+		}
+
+		*pcbRecvLength = scTransmitStructExtended -> pcbRecvLength;
 		SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);	
-		return SCARD_F_COMM_ERROR;
+
+		rv = scTransmitStructExtended -> rv;
 	}
+	else
+	{
+		/* short APDU */
+		transmit_struct scTransmitStruct;
+		sharedSegmentMsg msgStruct;
 
-	/*
-	 * Zero it and free it so any secret information cannot be leaked
-	 */
-	memset(scTransmitStruct.pbSendBuffer, 0x00, cbSendLength);
+		scTransmitStruct.hCard = hCard;
+		scTransmitStruct.cbSendLength = cbSendLength;
+		scTransmitStruct.pcbRecvLength = *pcbRecvLength;
+		memcpy(&scTransmitStruct.pioSendPci, pioSendPci,
+			sizeof(SCARD_IO_REQUEST));
+		memcpy(scTransmitStruct.pbSendBuffer, pbSendBuffer, cbSendLength);
 
-	if (scTransmitStruct.rv == SCARD_S_SUCCESS)
-	{
+		if (pioRecvPci)
+		{
+			memcpy(&scTransmitStruct.pioRecvPci, pioRecvPci,
+				sizeof(SCARD_IO_REQUEST));
+		}
+		else
+			scTransmitStruct.pioRecvPci.dwProtocol = SCARD_PROTOCOL_ANY;
+
+		rv = WrapSHMWrite(SCARD_TRANSMIT,
+			psContextMap[dwContextIndex].dwClientID, sizeof(scTransmitStruct),
+			PCSCLITE_CLIENT_ATTEMPTS, (void *) &scTransmitStruct);
+
+		if (rv == -1)
+		{
+			SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);	
+			return SCARD_E_NO_SERVICE;
+		}
+
 		/*
-		 * Copy and zero it so any secret information is not leaked
+		 * Read a message from the server
 		 */
-		memcpy(pbRecvBuffer, scTransmitStruct.pbRecvBuffer,
-			scTransmitStruct.pcbRecvLength);
-		memset(scTransmitStruct.pbRecvBuffer, 0x00,
-			scTransmitStruct.pcbRecvLength);
+		rv = SHMClientRead(&msgStruct, psContextMap[dwContextIndex].dwClientID, PCSCLITE_CLIENT_ATTEMPTS);
 
-		if (pioRecvPci)
-			memcpy(pioRecvPci, &scTransmitStruct.pioRecvPci,
-				sizeof(SCARD_IO_REQUEST));
+		memcpy(&scTransmitStruct, &msgStruct.data, sizeof(scTransmitStruct));
+
+		if (rv == -1)
+		{
+			SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);	
+			return SCARD_F_COMM_ERROR;
+		}
+
+		/*
+		 * Zero it and free it so any secret information cannot be leaked
+		 */
+		memset(scTransmitStruct.pbSendBuffer, 0x00, cbSendLength);
+
+		if (scTransmitStruct.rv == SCARD_S_SUCCESS)
+		{
+			/*
+			 * Copy and zero it so any secret information is not leaked
+			 */
+			memcpy(pbRecvBuffer, scTransmitStruct.pbRecvBuffer,
+				scTransmitStruct.pcbRecvLength);
+			memset(scTransmitStruct.pbRecvBuffer, 0x00,
+				scTransmitStruct.pcbRecvLength);
+
+			if (pioRecvPci)
+				memcpy(pioRecvPci, &scTransmitStruct.pioRecvPci,
+					sizeof(SCARD_IO_REQUEST));
+		}
+
+		*pcbRecvLength = scTransmitStruct.pcbRecvLength;
+		SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);	
+
+		rv = scTransmitStruct.rv;
 	}
 
-	*pcbRecvLength = scTransmitStruct.pcbRecvLength;
-	SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);	
-
 	PROFILE_END
 
-	return scTransmitStruct.rv;
+	return rv;
 }
 
 /**

Modified: trunk/PCSC/src/winscard_msg.c
===================================================================
--- trunk/PCSC/src/winscard_msg.c	2006-05-25 21:50:34 UTC (rev 2062)
+++ trunk/PCSC/src/winscard_msg.c	2006-05-25 21:52:34 UTC (rev 2063)
@@ -384,6 +384,7 @@
 	unsigned int size, unsigned int blockAmount, void *data)
 {
 	sharedSegmentMsg msgStruct;
+	int ret;
 
 	/*
 	 * Set the appropriate packet parameters 
@@ -395,10 +396,33 @@
 	msgStruct.group_id = SYS_GetGID();
 	msgStruct.command = command;
 	msgStruct.date = time(NULL);
-	memcpy(msgStruct.data, data, size);
+	if (SCARD_TRANSMIT_EXTENDED == command)
+	{
+		/* first block */
+		memcpy(msgStruct.data, data, PCSCLITE_MAX_MESSAGE_SIZE);
+		ret = SHMMessageSend(&msgStruct, sizeof(msgStruct), dwClientID,
+			blockAmount);
+		if (ret)
+			return ret;
 
-	return SHMMessageSend(&msgStruct, sizeof(msgStruct), dwClientID,
-		blockAmount);
+		/* do not send an empty second block */
+		if (size > PCSCLITE_MAX_MESSAGE_SIZE)
+		{
+			/* second block */
+			ret = SHMMessageSend(data+PCSCLITE_MAX_MESSAGE_SIZE,
+				size-PCSCLITE_MAX_MESSAGE_SIZE, dwClientID, blockAmount);
+			if (ret)
+				return ret;
+		}
+	}
+	else
+	{
+		memcpy(msgStruct.data, data, size);
+
+		ret = SHMMessageSend(&msgStruct, sizeof(msgStruct), dwClientID,
+			blockAmount);
+	}
+	return ret;
 }
 
 /**

Modified: trunk/PCSC/src/winscard_svc.c
===================================================================
--- trunk/PCSC/src/winscard_svc.c	2006-05-25 21:50:34 UTC (rev 2062)
+++ trunk/PCSC/src/winscard_svc.c	2006-05-25 21:52:34 UTC (rev 2063)
@@ -152,9 +152,13 @@
 				 * Command must be found
 				 */
 				MSGFunctionDemarshall(&msgStruct, dwContextIndex);
-				rv = SHMMessageSend(&msgStruct, sizeof(msgStruct),
-					psContext[dwContextIndex].dwClientID,
-					PCSCLITE_SERVER_ATTEMPTS);
+
+				/* the SCARD_TRANSMIT_EXTENDED anwser is already sent by
+				 * MSGFunctionDemarshall */
+				if (msgStruct.command != SCARD_TRANSMIT_EXTENDED)
+					rv = SHMMessageSend(&msgStruct, sizeof(msgStruct),
+						psContext[dwContextIndex].dwClientID,
+						PCSCLITE_SERVER_ATTEMPTS);
 			}
 			else
 				/* pcsc-lite client/server protocol version */
@@ -364,6 +368,77 @@
 			gsStr->pbAttr, gsStr->cbAttrLen);
 		break;
 
+	case SCARD_TRANSMIT_EXTENDED:
+		{
+			transmit_struct_extended *treStr;
+			unsigned char pbSendBuffer[MAX_BUFFER_SIZE_EXTENDED];
+			unsigned char pbRecvBuffer[MAX_BUFFER_SIZE_EXTENDED];
+
+			treStr = ((transmit_struct_extended *) msgStruct->data);
+			rv = MSGCheckHandleAssociation(treStr->hCard, dwContextIndex);
+			if (rv != 0) return rv;
+
+			/* on more block to read? */
+			if (treStr->size > PCSCLITE_MAX_MESSAGE_SIZE)
+			{
+				/* copy the first APDU part */
+				memcpy(pbSendBuffer, treStr->data,
+					PCSCLITE_MAX_MESSAGE_SIZE-sizeof(*treStr));
+
+				/* receive the second block */
+				rv = SHMMessageReceive(
+					pbSendBuffer+PCSCLITE_MAX_MESSAGE_SIZE-sizeof(*treStr),
+					treStr->size - PCSCLITE_MAX_MESSAGE_SIZE,
+					psContext[dwContextIndex].dwClientID,
+					PCSCLITE_SERVER_ATTEMPTS);
+				if (rv)
+					Log1(PCSC_LOG_CRITICAL, "reception failed");
+			}
+			else
+				memcpy(pbSendBuffer, treStr->data, treStr->cbSendLength);
+
+			Log2(PCSC_LOG_INFO, "%ld", treStr->pcbRecvLength);
+			treStr->rv = SCardTransmit(treStr->hCard, &treStr->pioSendPci,
+				pbSendBuffer, treStr->cbSendLength,
+				&treStr->pioRecvPci, pbRecvBuffer,
+				&treStr->pcbRecvLength);
+
+			Log2(PCSC_LOG_INFO, "%lX", treStr->rv);
+			treStr->size = sizeof(*treStr) + treStr->pcbRecvLength;
+			if (treStr->size > PCSCLITE_MAX_MESSAGE_SIZE)
+			{
+				/* two blocks */
+				memcpy(treStr->data, pbRecvBuffer, PCSCLITE_MAX_MESSAGE_SIZE
+					- sizeof(*treStr));
+
+				rv = SHMMessageSend(msgStruct, sizeof(*msgStruct),
+					psContext[dwContextIndex].dwClientID,
+					PCSCLITE_SERVER_ATTEMPTS);
+				if (rv)
+					Log1(PCSC_LOG_CRITICAL, "transmission failed");
+
+				rv = SHMMessageSend(pbRecvBuffer + PCSCLITE_MAX_MESSAGE_SIZE
+					- sizeof(*treStr),
+					treStr->size - PCSCLITE_MAX_MESSAGE_SIZE, 
+					psContext[dwContextIndex].dwClientID,
+					PCSCLITE_SERVER_ATTEMPTS);
+				if (rv)
+					Log1(PCSC_LOG_CRITICAL, "transmission failed");
+			}
+			else
+			{
+				/* one block only */
+				memcpy(treStr->data, pbRecvBuffer, treStr->pcbRecvLength);
+
+				rv = SHMMessageSend(msgStruct, sizeof(*msgStruct),
+					psContext[dwContextIndex].dwClientID,
+					PCSCLITE_SERVER_ATTEMPTS);
+				if (rv)
+					Log1(PCSC_LOG_CRITICAL, "transmission failed");
+			}
+		}
+		break;
+
 	default:
 		Log2(PCSC_LOG_CRITICAL, "Unknown command: %d", msgStruct->command);
 		return -1;




More information about the Pcsclite-cvs-commit mailing list