[Pcsclite-muscle] macOS and proprietary reader SCardControl interface

Ludovic Rousseau ludovic.rousseau at gmail.com
Tue Jun 13 13:01:46 PDT 2023


Le mar. 13 juin 2023 à 16:29, Martin Paljak <martin at martinpaljak.net> a écrit :
>
> Hello,

Hello Martin,

> I'm trying to do NFC tag emulation with ACS ACR1252U reader, via proprietary SCardControl commands. Things work on Linux (Debian Bookworm) and Windows10, but not on macOS (13.4), which should also carry the same open source CCID driver.
> I trigger things via Java/jnasmartcardio on a M1 mac. The proprietary ACS commands don't work, except for pinpad properties request, as seen below:
>
> Linux:
> # query pinpad properties, success
> SCardControl("ACS ACR1252 CL Reader [ACR1252 Reader PICC] 01 00", 0x42000D48, null) -> 110442330011120442330012130442000DAC
> SCardControl("ACS ACR1252 CL Reader [ACR1252 Reader PICC] 01 00", 0x42330012, null) -> 010200000301000901030B022F070C023E220A0400000100
> SCardDisconnect("ACS ACR1252 CL Reader [ACR1252 Reader PICC] 01 00", false) tx:0/rx:0 in 1ms
>
> # issue ACS proprietary command for firmware version, success
> SCardConnect("ACS ACR1252 CL Reader [ACR1252 Reader PICC] 01 00", DIRECT) -> DIRECT
> SCardControl("ACS ACR1252 CL Reader [ACR1252 Reader PICC] 01 00", 0x42000DAC, E000001800) -> E10000000F41435231323532555F563230362E30
>
> macOS:
> # query pinpad properties, success
> SCardConnect("ACS ACR1252 Reader", DIRECT) -> DIRECT
> SCardControl("ACS ACR1252 Reader", 0x42000D48, null) -> 120442330012
> SCardControl("ACS ACR1252 Reader", 0x42330012, null) -> 010200000301000901000B022F070C023E220A0400000100
> SCardDisconnect("ACS ACR1252 Reader", false) tx:0/rx:0
>
> # issue ACS proprietary command for firmware version, failure
> SCardConnect("ACS ACR1252 Reader", DIRECT) -> DIRECT
> SCardControl("ACS ACR1252 Reader", 0x42000DAC, E000001800)-> SCARD_E_NOT_TRANSACTED

Where do you get the control code value 0x42000DAC you used above?


The only defined value in PC/SC V2 part 2 is CM_IOCTL_GET_FEATURE_REQUEST
With pcsc-lite this value is SCARD_CTL_CODE(3400) or 0x42000D48 and is
used to get the other magic values.

On GNU/Linux you have (using a Python script):
from smartcard.pcsc.PCSCPart10 import parseFeatureRequest
from smartcard.util import toBytes
data_in = toBytes("110442330011120442330012130442000DAC")        #
value returned by SCardControl(.., CM_IOCTL_GET_FEATURE_REQUEST, ...)
features = parseFeatureRequest(data_in)
for (feature, value) in features:
    print(feature, hex(value))

This gives:
FEATURE_IFD_DISPLAY_PROPERTIES 0x42330011
FEATURE_GET_TLV_PROPERTIES 0x42330012
FEATURE_CCID_ESC_COMMAND 0x42000dac


On macOS you have:
data_in = toBytes("120442330012")
features = parseFeatureRequest(data_in)
for (feature, value) in features:
    print(feature, hex(value))

This gives:
FEATURE_GET_TLV_PROPERTIES 0x42330012

Note that FEATURE_CCID_ESC_COMMAND (0x42000dac) is NOT defined on
macOS so you can't use it.

> As the CCID driver should be the same for mac and linux, is there anything I've missed? Would love to try with an intel mac just to be sure, but looking at the low level debug code I *think* there should be no endian issues in the code path.
>
> Any ideas what could be wrong or what could be done ?

On macOS:
$ grep ifdDriverOptions -A 3
/usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist
54:    <key>ifdDriverOptions</key>
55-    <string>0x0000</string>
56-
57:    <!-- Possible values for ifdDriverOptions
58-    0x01: DRIVER_OPTION_CCID_EXCHANGE_AUTHORIZED
59-        the CCID Exchange command is allowed. You can use it through
60-        SCardControl(hCard, IOCTL_SMARTCARD_VENDOR_IFD_EXCHANGE, ...)

DRIVER_OPTION_CCID_EXCHANGE_AUTHORIZED is NOT enabled in ifdDriverOptions.
So:
- FEATURE_CCID_ESC_COMMAND is not returned by CM_IOCTL_GET_FEATURE_REQUEST
- SCardControl() with the value 0x42000dac will fail.

Because of SIP (System Integrity Protection) it is not easy to modify
the system file
/usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist

My best solution is to install a custom CCID driver with
DRIVER_OPTION_CCID_EXCHANGE_AUTHORIZED enabled.

Bye

-- 
 Dr. Ludovic Rousseau



More information about the pcsclite-muscle mailing list