Bug in reconnecting to a card.

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Bug in reconnecting to a card.

Abraham Macias Paredes

Hi PCSC lite Project people,

  I’m developing a software that nowadays is not stable (my software is buggy), but I detected that a bug in my software causes a bug in pcsc-lite.

 

The “SCardReconnect” doesn’t check if the connection has a transaction opened. So if you open a transtaction and reconnects the transaction is still opened. And also you can open a new transaction.

 

Check this sample code:

 

#ifdef WIN32

#undef UNICODE

#endif

 

#include <stdio.h>

#include <stdlib.h>

 

#ifdef __APPLE__

#include <PCSC/winscard.h>

#include <PCSC/wintypes.h>

#else

#include <winscard.h>

#endif

 

#ifdef WIN32

static char *pcsc_stringify_error(LONG rv)

{

static char out[20];

sprintf_s(out, sizeof(out), "0x%08X", rv);

 

return out;

}

#endif

 

#define CHECK(f, rv) \

if (SCARD_S_SUCCESS != rv) \

{ \

  printf(f ": %s\n", pcsc_stringify_error(rv)); \

  return -1; \

}

 

int main(void)

{

LONG rv;

 

SCARDCONTEXT hContext;

LPTSTR mszReaders;

SCARDHANDLE hCard;

DWORD dwReaders, dwActiveProtocol, dwRecvLength;

 

SCARD_IO_REQUEST pioSendPci;

BYTE pbRecvBuffer[258];

BYTE cmd1[] = { 0x00, 0xA4, 0x04, 0x00, 0x0A, 0xA0,

  0x00, 0x00, 0x00, 0x62, 0x03, 0x01, 0x0C, 0x06, 0x01 };

BYTE cmd2[] = { 0x00, 0x00, 0x00, 0x00 };

 

unsigned int i;

 

rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);

CHECK("SCardEstablishContext", rv)

 

#ifdef SCARD_AUTOALLOCATE

dwReaders = SCARD_AUTOALLOCATE;

 

rv = SCardListReaders(hContext, NULL, (LPTSTR)&mszReaders, &dwReaders);

CHECK("SCardListReaders", rv)

#else

rv = SCardListReaders(hContext, NULL, NULL, &dwReaders);

CHECK("SCardListReaders", rv)

 

mszReaders = calloc(dwReaders, sizeof(char));

rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders);

CHECK("SCardListReaders", rv)

#endif

printf("reader name: %s\n", mszReaders);

 

printf("SCardConnect\n");

rv = SCardConnect(hContext, mszReaders, SCARD_SHARE_SHARED,

  SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol);

CHECK("SCardConnect", rv)

printf("hCard = %08x\n",hCard);

 

printf("First SCardBeginTransaction\n");

rv =  SCardBeginTransaction(hCard);

CHECK("SCardBeginTransaction", rv)

 

printf("First SCardReconnect\n");

rv = SCardReconnect(hCard, SCARD_SHARE_SHARED,

  SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, SCARD_LEAVE_CARD, &dwActiveProtocol);

CHECK("SCardReconnect", rv)

 

printf("hCard = %08x\n",hCard);

 

printf("Second SCardBeginTransaction\n");

rv =  SCardBeginTransaction(hCard);

CHECK("SCardBeginTransaction", rv)

 

printf("SCardEndTransaction\n");

rv =  SCardEndTransaction(hCard, SCARD_LEAVE_CARD);

CHECK("SCardEndTransaction", rv)

 

printf("SCardEstablishContext --- \n");

rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);

CHECK("SCardEstablishContext", rv)

 

printf("SCardConnect to the new context\n");

rv = SCardConnect(hContext, mszReaders, SCARD_SHARE_SHARED,

  SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol);

CHECK("SCardConnect", rv)

 

printf("Connected OK!\n");

 

 

rv = SCardDisconnect(hCard, SCARD_LEAVE_CARD);

CHECK("SCardDisconnect", rv)

 

#ifdef SCARD_AUTOALLOCATE

rv = SCardFreeMemory(hContext, mszReaders);

CHECK("SCardFreeMemory", rv)

 

#else

free(mszReaders);

#endif

 

rv = SCardReleaseContext(hContext);

 

CHECK("SCardReleaseContext", rv)

 

return 0;

}

 

 

The output of this code is:

 

reader name: C3PO LTC31 v2 (17070129) 00 00

SCardConnect

hCard = 761d7d91

First SCardBeginTransaction

First SCardReconnect

hCard = 761d7d91

Second SCardBeginTransaction

SCardEndTransaction

SCardEstablishContext ---

SCardConnect to the new context

 

 

I think that the problem could be in “readerfactory.c” in the “RFCheckSharing” function:

 

LONG RFCheckSharing(SCARDHANDLE hCard, READER_CONTEXT * rContext)

{

     if (rContext->hLockId == 0 || rContext->hLockId == hCard)

          return SCARD_S_SUCCESS;

     else

          return SCARD_E_SHARING_VIOLATION;

}

 

This code only checks the card handle, that is the same for the “reconnection”. So you can begin several transactions in the same card.

 

I added a debug line to see the LockCount:

 

00000004 pcscdaemon.c:134:SVCServiceRunLoop() A new context thread creation is requested: 12

00005871 winscard_svc.c:331:ContextThread() Authorized PC/SC client

00000017 winscard_svc.c:335:ContextThread() Thread is started: dwClientID=12, threadContext @0x2408d00

00000010 winscard_svc.c:353:ContextThread() Received command: CMD_VERSION from client 12

00000005 winscard_svc.c:365:ContextThread() Client is protocol version 4:3

00000003 winscard_svc.c:385:ContextThread() CMD_VERSION rv=0x0 for client 12

00000035 winscard_svc.c:353:ContextThread() Received command: ESTABLISH_CONTEXT from client 12

00000012 winscard.c:215:SCardEstablishContext() Establishing Context: 0x76FF5983

00000004 winscard_svc.c:446:ContextThread() ESTABLISH_CONTEXT rv=0x0 for client 12

00000016 winscard_svc.c:353:ContextThread() Received command: CMD_GET_READERS_STATE from client 12

00000093 winscard_svc.c:353:ContextThread() Received command: CONNECT from client 12

00002777 winscard_svc.c:484:ContextThread() Authorized client for 'C3PO LTC31 v2 (17070129) 00 00'

00000011 winscard.c:257:SCardConnect() Attempting Connect to C3PO LTC31 v2 (17070129) 00 00 using protocol: 3

00000004 readerfactory.c:768:RFReaderInfo() RefReader() count was: 1

00000003 winscard.c:352:SCardConnect() powerState: POWER_STATE_INUSE

00000003 prothandler.c:110:PHSetProtocol() Attempting PTS to T=0

00000005 ifdhandler.c:682:IFDHSetProtocolParameters() protocol T=0, usb:0783/0006:libudev:0:/dev/bus/usb/001/003 (lun: 0)

00000003 ifdhandler.c:2047:extra_egt() Extra EGT patch applied

00023748 winscard.c:431:SCardConnect() Active Protocol: T=0

00000033 winscard.c:451:SCardConnect() hCard Identity: 761d7d91

00000006 winscard.c:512:SCardConnect() UnrefReader() count was: 2

00000005 winscard_svc.c:498:ContextThread() CONNECT rv=0x0 for client 12

00000068 winscard_svc.c:353:ContextThread() Received command: BEGIN_TRANSACTION from client 12

00000007 readerfactory.c:795:RFReaderInfoById() RefReader() count was: 1

00000003 readerfactory.c:955:RFLockSharing() BEGIN

00000003 readerfactory.c:962:RFLockSharing() Card: 761d7d91 LockCount: 1

00000003 readerfactory.c:966:RFLockSharing() END

00000003 winscard.c:1104:SCardBeginTransaction() Status: 0x00000000

00000002 winscard.c:1107:SCardBeginTransaction() UnrefReader() count was: 2

00000003 winscard_svc.c:550:ContextThread() BEGIN_TRANSACTION rv=0x0 for client 12

00000017 winscard_svc.c:353:ContextThread() Received command: RECONNECT from client 12

00000005 winscard.c:526:SCardReconnect() Attempting reconnect to token.

00000002 readerfactory.c:795:RFReaderInfoById() RefReader() count was: 1

00000003 winscard.c:725:SCardReconnect() Active Protocol: T=0

00000013 winscard.c:815:SCardReconnect() UnrefReader() count was: 2

00000003 winscard_svc.c:517:ContextThread() RECONNECT rv=0x0 for client 12

00000019 winscard_svc.c:353:ContextThread() Received command: BEGIN_TRANSACTION from client 12

00000004 readerfactory.c:795:RFReaderInfoById() RefReader() count was: 1

00000003 readerfactory.c:955:RFLockSharing() BEGIN

00000002 readerfactory.c:962:RFLockSharing() Card: 761d7d91 LockCount: 2

00000002 readerfactory.c:966:RFLockSharing() END

00000003 winscard.c:1104:SCardBeginTransaction() Status: 0x00000000

00000002 winscard.c:1107:SCardBeginTransaction() UnrefReader() count was: 2

00000003 winscard_svc.c:550:ContextThread() BEGIN_TRANSACTION rv=0x0 for client 12

00000014 winscard_svc.c:353:ContextThread() Received command: END_TRANSACTION from client 12

00000005 readerfactory.c:795:RFReaderInfoById() RefReader() count was: 1

00000002 readerfactory.c:974:RFUnlockSharing() BEGIN

00000003 readerfactory.c:982:RFUnlockSharing() Card: 761d7d91 LockCount: 1

00000002 readerfactory.c:994:RFUnlockSharing() END

00000003 winscard.c:1247:SCardEndTransaction() Status: 0x00000000

00000002 winscard.c:1250:SCardEndTransaction() UnrefReader() count was: 2

00000003 winscard_svc.c:566:ContextThread() END_TRANSACTION rv=0x0 for client 12

00009089 winscard_msg_srv.c:253:ProcessEventsServer() Common channel packet arrival

00000016 winscard_msg_srv.c:265:ProcessEventsServer() ProcessCommonChannelRequest detects: 14

00000004 pcscdaemon.c:134:SVCServiceRunLoop() A new context thread creation is requested: 14

00003876 winscard_svc.c:331:ContextThread() Authorized PC/SC client

00000011 winscard_svc.c:335:ContextThread() Thread is started: dwClientID=14, threadContext @0x2412cf0

00000007 winscard_svc.c:353:ContextThread() Received command: CMD_VERSION from client 14

00000004 winscard_svc.c:365:ContextThread() Client is protocol version 4:3

00000003 winscard_svc.c:385:ContextThread() CMD_VERSION rv=0x0 for client 14

00000015 winscard_svc.c:353:ContextThread() Received command: ESTABLISH_CONTEXT from client 14

00000005 winscard.c:215:SCardEstablishContext() Establishing Context: 0x2F00BA9

00000002 winscard_svc.c:446:ContextThread() ESTABLISH_CONTEXT rv=0x0 for client 14

00000019 winscard_svc.c:353:ContextThread() Received command: CONNECT from client 14

00004487 winscard_svc.c:484:ContextThread() Authorized client for 'C3PO LTC31 v2 (17070129) 00 00'

00000013 winscard.c:257:SCardConnect() Attempting Connect to C3PO LTC31 v2 (17070129) 00 00 using protocol: 3

00000004 readerfactory.c:768:RFReaderInfo() RefReader() count was: 1

00000003 winscard.c:294:SCardConnect() Waiting for release of lock

 

 

Thanks and best regards!

 

Abraham Macías Paredes

Analista / Programador

Departamento de Desarrollo y Soluciones

[hidden email]

 

cid:image001.gif@01D2158A.8B9147F0

Ir a la Web de
                  Solutia

cid:image003.gif@01D2158A.8B9147F0

Solutia Innovaworld Technologies S.L.
Parque empresarial Los Llanos
C/ Extremadura, 108 - 41909 - Salteras (Sevilla)
T: +34 955 11 11 55
F: +34 954 37 11 42
www.solutia-it.es

Ver
                  Certificaciones de Calidad de Solutia

Sus datos personales contenidos en esta comunicación han sido recogidos de los contactos mantenidos por Vd. o por personas de su entorno, con personal de SOLUTIA INNOVAWORLD TECHNOLOGIES, S.L. y han sido incorporados al fichero de GESTIÓN COMERCIAL con la finalidad de realizar la gestión, seguimiento y mantenimiento de nuestra relación comercial, o a otro fichero correspondiente al tipo de relación que mantiene con nosotros, de lo que Vd. fue convenientemente informado al recibir bien el documento contractual entregado al inicio de los contactos bien en una comunicación inmediatamente posterior en que se daba cumplimiento al derecho de información y se le solicitaba consentimiento para tratar sus datos personales, tratamiento que se efectuará de acuerdo a las finalidades allí expresadas.

En el caso en que ésta sea la primera comunicación que recibe por nuestra parte, le solicitamos su consentimiento para proceder al tratamiento de sus datos de acuerdo a las condiciones detalladas al inicio. Entenderemos que nos presta su consentimiento si en el plazo de un mes a contar desde la recepción de esta comunicación no nos expresa su voluntad en contra. Le informamos que puede revocar en cualquier momento su consentimiento respondiendo a este mail indicando que no desea recibir más información acerca de nuestra empresa, supuesto en el que será automáticamente dado de baja de nuestra lista de correo.

Podrá ejercer sus derechos de acceso, rectificación, cancelación y oposición ante el Responsable del fichero, SOLUTIA INNOVAWORLD TECHNOLOGIES, S.L. en la dirección C/ Extremadura, 108 Parque empresarial Los Llanos; 41909 Salteras, SEVILLA, indicando en la comunicación la referencia "LOPD"

 

 

 

 


_______________________________________________
Pcsclite-muscle mailing list
[hidden email]
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pcsclite-muscle
Reply | Threaded
Open this post in threaded view
|

Re: Bug in reconnecting to a card.

Ludovic Rousseau
2016-09-23 12:45 GMT+02:00 Abraham Macias Paredes <[hidden email]>:

Hi PCSC lite Project people,


Hello,
 

  I’m developing a software that nowadays is not stable (my software is buggy), but I detected that a bug in my software causes a bug in pcsc-lite.

 

The “SCardReconnect” doesn’t check if the connection has a transaction opened. So if you open a transtaction and reconnects the transaction is still opened. And also you can open a new transaction.


Interesting.

Do you get the same behavior on Windows?

What should be the correct behavior of pcsc-lite?

Bye

--
 Dr. Ludovic Rousseau

_______________________________________________
Pcsclite-muscle mailing list
[hidden email]
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pcsclite-muscle
Reply | Threaded
Open this post in threaded view
|

Re: Bug in reconnecting to a card.

Abraham Macias Paredes

Hi,

·         Do you get the same behavior on Windows?
No, in Windows seems that “disconnect” and “reconnect” ends all started transactions.

·         What should be the correct behavior of pcsc-lite?
I think that is logical to think that when you “reconnect” or “disconnect” a card, all estarted transactions are ended.

Thank you and best regards!

 

 

De: Pcsclite-muscle [mailto:pcsclite-muscle-bounces+amacias=[hidden email]] En nombre de Ludovic Rousseau
Enviado el: viernes, 23 de septiembre de 2016 12:54
Para: Talks about MUSCLE <[hidden email]>
Asunto: Re: [Pcsclite-muscle] Bug in reconnecting to a card.

 

2016-09-23 12:45 GMT+02:00 Abraham Macias Paredes <[hidden email]>:

Hi PCSC lite Project people,

 

Hello,
 

  I’m developing a software that nowadays is not stable (my software is buggy), but I detected that a bug in my software causes a bug in pcsc-lite.

 

The “SCardReconnect” doesn’t check if the connection has a transaction opened. So if you open a transtaction and reconnects the transaction is still opened. And also you can open a new transaction.

 

Interesting.

Do you get the same behavior on Windows?

What should be the correct behavior of pcsc-lite?

Bye

 

--

 Dr. Ludovic Rousseau


_______________________________________________
Pcsclite-muscle mailing list
[hidden email]
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pcsclite-muscle
Reply | Threaded
Open this post in threaded view
|

Re: Bug in reconnecting to a card.

Abraham Macias Paredes

Hi again,

 After some tests I think that a second “Connect” invalidates the transactions (Python test attached).

 

Or maybe there are a couple of seconds of timeout before invalidating the transactions and allowing the connection (because when you run the test you can notice a couple of seconds of delay before the second “connect”).

 

The output of the test in my Windows 10 is:

 

c:\Python27>python.exe test.py

Context established!

PCSC Readers: ['Dell Smart Card Reader Keyboard 0']

Using reader: Dell Smart Card Reader Keyboard 0

Connected with active protocol 1

Start transaction

Connect again

Connected with active protocol 1

Start transaction (card 2)

End transaction (card 2)

End transaction in the first connection

Exception: failed to end a transaction: Se ha reiniciado la tarjeta inteligente, por lo que no es vßlida ninguna informaci¾n de estado compartido.

Released context.

press Enter to continue

 

Best regards!

 

 

De: Pcsclite-muscle [mailto:pcsclite-muscle-bounces+amacias=[hidden email]] En nombre de Abraham Macias Paredes
Enviado el: viernes, 23 de septiembre de 2016 13:31
Para: 'Talks about MUSCLE' <[hidden email]>
Asunto: Re: [Pcsclite-muscle] Bug in reconnecting to a card.

 

Hi,

·         Do you get the same behavior on Windows?
No, in Windows seems that “disconnect” and “reconnect” ends all started transactions.

·         What should be the correct behavior of pcsc-lite?
I think that is logical to think that when you “reconnect” or “disconnect” a card, all estarted transactions are ended.

Thank you and best regards!

 

 

De: Pcsclite-muscle [[hidden email]] En nombre de Ludovic Rousseau
Enviado el: viernes, 23 de septiembre de 2016 12:54
Para: Talks about MUSCLE <[hidden email]>
Asunto: Re: [Pcsclite-muscle] Bug in reconnecting to a card.

 

2016-09-23 12:45 GMT+02:00 Abraham Macias Paredes <[hidden email]>:

Hi PCSC lite Project people,

 

Hello,
 

  I’m developing a software that nowadays is not stable (my software is buggy), but I detected that a bug in my software causes a bug in pcsc-lite.

 

The “SCardReconnect” doesn’t check if the connection has a transaction opened. So if you open a transtaction and reconnects the transaction is still opened. And also you can open a new transaction.

 

Interesting.

Do you get the same behavior on Windows?

What should be the correct behavior of pcsc-lite?

Bye

 

--

 Dr. Ludovic Rousseau


_______________________________________________
Pcsclite-muscle mailing list
[hidden email]
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pcsclite-muscle

test.py (3K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Bug in reconnecting to a card.

Ludovic Rousseau


2016-09-23 14:49 GMT+02:00 Abraham Macias Paredes <[hidden email]>:

Hi again,

 After some tests I think that a second “Connect” invalidates the transactions (Python test attached).

 

Or maybe there are a couple of seconds of timeout before invalidating the transactions and allowing the connection (because when you run the test you can notice a couple of seconds of delay before the second “connect”).

 

The output of the test in my Windows 10 is:

 

c:\Python27>python.exe test.py

Context established!

PCSC Readers: ['Dell Smart Card Reader Keyboard 0']

Using reader: Dell Smart Card Reader Keyboard 0

Connected with active protocol 1

Start transaction

Connect again

Connected with active protocol 1

Start transaction (card 2)

End transaction (card 2)

End transaction in the first connection

Exception: failed to end a transaction: Se ha reiniciado la tarjeta inteligente, por lo que no es vßlida ninguna informaci¾n de estado compartido.

Released context.

press Enter to continue

 

Best regards!


On pcsc-lite your sample output is:

$ python test.py
Context established!
PCSC Readers: ['Gemalto PC Twin Reader (70D7E2EE) 00 00']
Using reader: Gemalto PC Twin Reader (70D7E2EE) 00 00
Connected with active protocol 1
Start transaction
Connect again
and the execution is blocked here.

The second SCardConnect() blocks because a transaction is ongoing.


I guess it "works" on Windows because the card is reset and the transaction is aborted after 5 seconds.
The second SCardConnect() will block, link with pcsc-lite, but will continue after a 5 seconds delay.

https://msdn.microsoft.com/de-de/library/windows/desktop/aa379469%28v=vs.85%29.aspx
" If a transaction is held on the card for more than five seconds with no operations happening on that card, then the card is reset. Calling any of the Smart Card and Reader Access Functions or Direct Card Access Functions on the card that is transacted results in the timer being reset to continue allowing the transaction to be used. "

pcsc-lite does not implement this card reset after 5 seconds of no-use. I don't think that is a good idea.

Bye

--
 Dr. Ludovic Rousseau

_______________________________________________
Pcsclite-muscle mailing list
[hidden email]
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pcsclite-muscle