Monday, February 23, 2015

Debug a smart card application on Yosemite

In the previous article "Debug a smart card reader driver on Yosemite" I wrote about how to get some log from a new version of my CCID driver.

APDU logging from Apple

After I wrote the previous article Dustin N. told me that Apple now provides a logging facility for APDUs.

SmartCardServices.7

The SmartCardServices manpage says (online HTML version at SmartCardServices):

SMARTCARDSERVICES(7) BSD Miscellaneous Information Manual SMARTCARDSERVICES(7)

NAME

SmartCardServices — overview of smart card support

DESCRIPTION

The SmartCardServices is a set of components which add native support for smart cards
to operating system. Supported smart cards appear as separate keychains.

USB SMART CARD READER DRIVERS

OS X has built-in support for USB CCID class-compliant smart card readers. For other
readers, install the reader driver in /usr/libexec/SmartCardServices/drivers. Each driver
is a bundle. The bundle contains an XML file Info.plist which contains the device’s USB vendor ID and product ID. For detailed description of plist format and how to write driver, see <http://pcsclite.alioth.debian.org/api/group__IFDHandler.html>

SMART CARD APDU LOGGING

It is possible to turn on logging for smart cards. Logging is turned on by setting global preference:
sudo defaults write /Library/Preferences/com.apple.security.smartcard Logging -bool yes
After a smart card reader is connected (or after reboot) all operations including contents of sent and received APDU messages are then logged into system log. Logging uses facility com.apple.security.smartcard.log so it is possible to set up filtering of these logs into custom targets (see asl.conf(5)) Note that logging setting is one-shot; it must be turned on by the command above to start logging again with a new reader. This is to avoid security risk that logging is turned on indefinitely.

SEE ALSO

sc_auth(8), defaults(1), asl.conf(5)

Mac OS X August 5, 2014 Mac OS X

Configuration


As documented the activation of APDU logging is easy. Just do (on 1 line):
$ sudo defaults write /Library/Preferences/com.apple.security.smartcard Logging -bool yes

A new file /Library/Preferences/com.apple.security.smartcard.plist will be created.

You can display the .plist file using Xcode for example. But you can't edit it directly with Xcode since the file can only be updated by root.
$ ls -l /Library/Preferences/com.apple.security.smartcard.plist
-rw-r--r--  1 root  wheel  55 23 fév 10:09 /Library/Preferences/com.apple.security.smartcard.plist

You can get the logging status using:
$ defaults read /Library/Preferences/com.apple.security.smartcard Logging
1
You do not need to be root to read the logging status.

First time only

As indicated in the manpage documentation, you can note that the logging activation is only one shoot. Once the logging state has been read and activated by com.apple.ifdreader then the value is reset to no logging.

To see that just do:
  1. Activate logging
    $ sudo defaults write /Library/Preferences/com.apple.security.smartcard Logging -bool yes
  2. Read logging state
    $ defaults read /Library/Preferences/com.apple.security.smartcard Logging
    1
  3. Plug in a USB reader
  4. Read logging state again
    $ defaults read /Library/Preferences/com.apple.security.smartcard Logging
    0

This is very smart idea. It will prevent you from forgeting to disable logging after use. You can be sure that the logging will be disabled after a reboot or at the next USB reader connection and no secret PIN code will be stored in your log file without you explicitly requesting it.

Sample output

As in "Debug a smart card reader driver on Yosemite" I used a combination of lwatch and ansi2html. If the file foo contains the log lines I use the combination:
$ lwatch -i - < foo | ansi2html -i

$ syslog -w -k Sender com.apple.ifdreader
Feb 23 19:54:49 iMac-de-Ludovic.local com.apple.ifdreader[586] <Notice>: logging slot 'Gemalto PC Twin Reader'
Feb 23 19:54:53 iMac-de-Ludovic.local com.apple.ifdreader[586] <Notice>: card in
Feb 23 19:54:53 iMac-de-Ludovic.local com.apple.ifdreader[586] <Notice>: ATR:3b fa 94 00 00 81 31 20 43 80 65 a2 01 01 01 3d 72 d6 43 21
Feb 23 19:54:58 iMac-de-Ludovic.local com.apple.ifdreader[586] <Notice>: unpower
Feb 23 19:54:59 iMac-de-Ludovic.local com.apple.ifdreader[586] <Notice>: ATR:3b fa 94 00 00 81 31 20 43 80 65 a2 01 01 01 3d 72 d6 43 21
Feb 23 19:54:59 iMac-de-Ludovic.local com.apple.ifdreader[586] <Notice>: T=1
Feb 23 19:54:59 iMac-de-Ludovic.local com.apple.ifdreader[586] <Notice>: APDU ->:00 a4 04 00 0a a0 00 00 00 62 03 01 0c 06 01
Feb 23 19:54:59 iMac-de-Ludovic.local com.apple.ifdreader[586] <Notice>: APDU <-:90 00
Feb 23 19:54:59 iMac-de-Ludovic.local com.apple.ifdreader[586] <Notice>: APDU ->:00 00 00 00
Feb 23 19:54:59 iMac-de-Ludovic.local com.apple.ifdreader[586] <Notice>: APDU <-:48 65 6c 6c 6f 20 77 6f 72 6c 64 21 90 00
Feb 23 19:55:04 iMac-de-Ludovic.local com.apple.ifdreader[586] <Notice>: unpower
Feb 23 19:55:07 iMac-de-Ludovic.local com.apple.ifdreader[586] <Notice>: card out

You can see that the card in inserted at 19:54:53, the log is "card in" And 5 seconds later the card is power off, the log line is "unpower". This is what I already explained in "OS X Yosemite bug: SCardTransmit returns SCARD_W_UNPOWERED_CARD".

Security

Since you need to have the administration privilege (be root) to edit the file /Library/Preferences/com.apple.security.smartcard.plist the situation is not less secure than what I presented in "Debug a smart card reader driver on Yosemite" since you also needed to have the same administration privilege (be root) to edit the driver configuration file /usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist.

Conclusion

Apple provides a nice way to get the card ATR, APDU sent to the card and response from a smart card reader.

Maybe I should add a similar feature in pcsc-lite for GNU/Linux. What do you think?