Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[question] T0/T1 protocol choice during SCardConnect and SCardTransmit #213

Open
lisa-bella97 opened this issue Oct 9, 2024 · 8 comments
Assignees
Labels

Comments

@lisa-bella97
Copy link

I have two questions about your SCardConnect and SCardTransmit implementation.

  1. I call SCardConnect with dwPreferredProtocols = SCARD_PROTOCOL_T0. CCID reader and card both support T0 and T1 protocols, reader has feature "Automatic parameters negotiation made by the CCID". Such readers exist and can be found in https://ccid.apdu.fr/select_readers/?dwFeatures=6&dwProtocols=3. In theory, reader and card can agree on T1 protocol during automatic parameters negotiation, but SCardConnect will return T0 protocol as pdwActiveProtocol because of dwPreferredProtocols. Is it correct behaviour? How to know which protocol is negotiated between reader and card during automatic parameters negotiation? Looking at your sources of SCardConnect and IFDHSetProtocolParameters, I don't see any checks whether the auto-negotiated protocol is equal to the active protocol.

  2. SCardTransmit calls CmdXfrBlock at CCID driver level. I can't figure out why at APDU (short and extended) exchange level APDUs are always transmitted using T0 protocol (even though pdwActiveProtocol can be T1 protocol)? I also noticed that readers from previous question (with Automatic parameters negotiation and T0 and T1 support) have only APDU level of exchange (not TPDU or Character). Is it true that at this level of exchange we don't care which protocol is active - the real communication between reader and card will always be done using the negotiated parameters or T0 only?

Thank you very much for help!

@LudovicRousseau
Copy link
Owner

  1. the application is requesting SCARD_PROTOCOL_T0 only. Maybe SCardConnect() should reject the connection in your case. What do you propose?
  2. PC_to_RDR_XfrBlock does not include a T=0 or T=1 parameter. Maybe the function name CmdXfrBlockTPDU_T0() is not correct.

@lisa-bella97
Copy link
Author

  1. Let me try to describe the possible situation better.

The pcsclite/ccid driver functions call stack looks like this (only the protocol is left as parameters for convenience):
SCardConnect(dwPreferredProtocols = SCARD_PROTOCOL_T0) -> PHSetProtocol(dwPreferred = SCARD_PROTOCOL_T0) -> IFDSetPTS(dwProtocol = SCARD_PROTOCOL_T0) -> IFDHSetProtocolParameters(Protocol = SCARD_PROTOCOL_T0).

As the CCID reader has feature "Automatic parameters negotiation made by the CCID", in the function IFDHSetProtocolParameters we will fall under the following condition:

if (ccid_desc->dwFeatures & CCID_CLASS_AUTO_PPS_PROP)
	goto end;

Under the end label, we will skip setting parameters because reader will do it itself:

if (ccid_desc->dwFeatures & CCID_CLASS_AUTO_PPS_PROP)
	DEBUG_COMM("Skip SetParameters");

At the end of the method we can see:

ccid_desc->cardProtocol = Protocol;

Protocol is equal to SCARD_PROTOCOL_T0 in our case (and this value will be return as pdwActiveProtocol in SCardConnect function). But what if reader and card negotiated T1 protocol during automatic parameters negotiation made by the CCID? Is this situation possible? If yes, how can we check which protocol is negotiated by the reader? Because in this case we should not return success in SCardConnect (T0 protocol can't be established).

As automatic parameters negotiation is proprietary algorithm (this is mentioned in the CCID specification rev. 1.1), I cannot find out how to know which protocol is chosen. Maybe you have thoughts about it.

  1. OK, the function name CmdXfrBlockTPDU_T0() led me to incorrect judgments. Thank you for the answer.

@LudovicRousseau
Copy link
Owner

We could use the CCID command PC_to_RDR_GetParameters to get the negotiated protocol in bProtocolNum field of RDR_to_PC_Parameters.

Is it problematic if the pcsc-lite does not fail SCardConnect() in this case?

The only case I see that would be problematic is if the reader is in TPDU mode. Only 1 reader has such configuration: the SCM SCL010 https://ccid.apdu.fr/select_readers/?dwFeatures=6&dwProtocols=3&dwFeatures=12

@lisa-bella97
Copy link
Author

We could use the CCID command PC_to_RDR_GetParameters to get the negotiated protocol in bProtocolNum field of RDR_to_PC_Parameters.

Yes, but this command may not be supported by the reader (see possible errors of RDR_to_PC_Parameters in CCID specification). So I do not have any ideas what to do in this case.

Is it problematic if the pcsc-lite does not fail SCardConnect() in this case?

The only thing I see is that the pcsclite user will think that the communication between the card and the reader will be carried out via the T0 protocol, but in fact it will not.

@LudovicRousseau
Copy link
Owner

The only thing I see is that the pcsclite user will think that the communication between the card and the reader will be carried out via the T0 protocol, but in fact it will not.

Exact.
Is it preferable to abort the communication?

@lisa-bella97
Copy link
Author

I have not seen any problems with current pcsclite implementation, but I think it would be more honest to abort the communication. What do you think about it? Is such a situation specified in the standards and specifications and is its implementation important? Maybe your expertise says that such a situation is extremely unlikely for modern readers, and support of some abstract situations is not just difficult, but even impossible?

@LudovicRousseau
Copy link
Owner

It would be interesting to know what Windows is doing in such a case.

@lisa-bella97
Copy link
Author

Agreed. Unfortunately, I don't have such a reader to check the behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants