MUSCLE list migration

Hello all,

After one month of discussing with David Corcoran (maintainer of the MUSCLE list) and the technical support of the list service provider David and I decided to move the MUSCLE list to a working system.

I already created the pcsclite-muscle at lists.alioth.debian.org list in 2011 because of a previous "technical" problem with the MUSCLE list.
I now guess the move is definitive.

You may need to:

  • update your email filter to adapt to the new list email: pcsclite-muscle@lists.alioth.debian.org
  • update your address book to use the new list email
  • change your list registration configuration if the default configuration do not suite your preferences

Welcome all to the new MUSCLE list.

USB issues with a Raspberry Pi

Some people report problems with my CCID driver and a Raspberry Pi. The problem is not with the CCID driver but with the Raspberry Pi itself.



I don't know if the problem is hardware, software or a combination of the two. I found a description of the problem on the excellent website yoctopuce.com. For example from the article "Cook and Hold with Raspberry Pi (video)" you can read:

There is one caveat on the Raspberry Pi : the USB support is still somewhat buggy perfectible, and we will need to configure it to make it work reliably. The problem is, the RasPi will occasionally drop USB packets for "full-speed" peripherals (such as keyboard, mouse, modems, as well as some audio devices) when working in standard "high-speed" mode. The problem is less acute with the most recent firmware, but it is not completely solved. The only reliable workaround for now is to force all peripherals to run in "full-speed" mode. This will have the negative side effect of limiting all peripherals (including the on-board network adapter) to 1.5 MBytes/s, but anyway, the Raspberry Pi is not designed to be a race horse...

To force USB to run in "full-speed" mode, simply add dwc_otg.speed=1 to the /boot/cmdline.txt file, as follows:

dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200
dwc_otg.speed=1 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4
elevator=deadline rootwait

CCID descriptor statistics: dwMechanical

Article from the serie "CCID descriptor statistics"

The dwMechanical field is a number value from the CCID USB descriptor:

The value is a bitwise OR operation performed on the following values:
• 00000000h No special characteristics
• 00000001h Card accept mechanism
• 00000002h Card ejection mechanism
• 00000004h Card capture mechanism
• 00000008h Card lock/unlock mechanism
A footnote in the specification also indicates:
These mechanisms of the dwMechanical parameter have been included for completeness; however, these functions of motorized CCIDs are not covered by this release of the specification. A future release may attempt to standardize the interface to these mechanical functions.

dwMechanical # %
0x00000000 246 96.85 %
0x00000001 7 2.76 %
0x03000000 1 0.39 %


The normal value should be 0x00000000: "No special characteristics" since this field is not covered by the CCID specification.

1 reader is using 0x03000000 (that should be 0x00000003)
  • MYSMART MySMART PAD V2.0

7 readers are using 0x00000001 "Card accept mechanism"
  • FujitsuTechnologySolutions GmbH SmartCase KB SCR eSIG
  • Hewlett-Packard Company HP USB CCID Smartcard Keyboard
  • Identive Identive CLOUD 4500 F Dual Interface Reader
  • Identive Identive CLOUD 4510 F Contactless + SAM Reader
  • Identive Identive CLOUD 4700 F Dual Interface Reader
  • Identive Identive CLOUD 4710 F Contactless + SAM Reader
  • Lenovo Lenovo USB Smartcard Keyboard
  • SCM Microsystems Inc. SCL010 Contactless Reader
  • SCM Microsystems Inc. SCL01x Contactless Reader

CCID descriptor statistics: dwProtocols

Article from the serie "CCID descriptor statistics"

The dwProtocols field is a number value from the CCID USB descriptor:

RRRR –Upper Word- is RFU = 0000h
PPPP –Lower Word- Encodes the supported protocol types. A ‘1’ in a given bit position indicates support for the associated ISO protocol.
0001h = Protocol T=0
0002h = Protocol T=1
All other bits are reserved and must be set to zero. The field is intended to correspond to the PCSC specification definitions. See PCSC Part3. Table 3-1 Tag 0x0120.
Example: 00000003h indicates support for T = 0 and T = 1.

dwProtocols # %
0x0000 0x0003 207 81.50 %
0x0000 0x0002 27 10.63 %
0x0000 0x0001 19 7.48 %
0x0000 0x0300 1 0.39 %


The value 0x0300 is bogus and is used by the reader:
  • MYSMART MySMART PAD V2.0

Some readers (7.48%) only supports the T=0 protocol. They are:
  • ATMEL AT91SC192192CT-USB ICCD reader
  • ATMEL AT98SC032CT-USB
  • ATMEL VaultIC420 Smart Object
  • ATMEL VaultIC440
  • ATMEL VaultIC460
  • BIFIT iBank2Key
  • Gemalto Hybrid Smartcard Reader
  • Gemalto SA .NET Dual
  • Gemalto Smart Enterprise Guardian Secure USB Device
  • Gemalto Smart Enterprise Guardian Secure USB Device
  • IID AT90S064 CCID READER
  • INSIDE Secure VaultIC 405 Smart Object
  • INSIDE Secure VaultIC 441 Smart Object
  • Inside Secure VaultIC 420 Smart Object
  • Inside Secure VaultIC 440 Smart Object
  • Inside Secure VaultIC 460 Smart Object
  • KEBTechnology KONA USB SmartCard
  • Kingtrust Multi-Reader
  • RSA RSA SecurID (R) Authenticator
  • SchlumbergerSema SchlumbergerSema Cyberflex Access
  • SecuTech SecuTech Token
  • Softforum Co., Ltd XecureHSM
  • TianYu CCID Key TianYu CCID SmartKey

Some readers (10.63%) only supports T=1 protocol. They are:
  • ACS ACR122U PICC Interface
  • ASK-RFID CPL108
  • Aktiv Co., ProgramPark Rutoken Magistra
  • Aktiv PINPad Ex
  • Aktiv PINPad In
  • Aktiv Rutoken ECP
  • Aktiv Rutoken lite
  • BIFIT USB-Token iBank2key
  • CCB eSafeLD
  • Crypto Stick Crypto Stick v1.4
  • Feitian ePass2003
  • Free Software Initiative of Japan Gnuk
  • Gemalto PDT
  • German Privacy Foundation Crypto Stick v1.2
  • Giesecke & Devrient GmbH Star Sign Card Token 350 (ICCD)
  • Giesecke & Devrient GmbH Star Sign Card Token 550 (ICCD)
  • GoldKey Security PIV Token
  • IIT E.Key Almaz-1C
  • Macally NFC CCID eNetPad
  • OCS ID-One Cosmo Card USB Smart Chip Device
  • Philips Semiconductors JCOP41V221
  • Philips Semiconductors SmartMX Sample
  • REINER SCT cyberJack RFID basis
  • Watchdata W5181
  • Yubico Yubikey NEO CCID
  • Yubico Yubikey NEO OTP+CCID
  • id3 Semiconductors CL1356A_HID
  • id3 Semiconductors CL1356T5
  • id3 Semiconductors CL1356T
  • ubisys 13.56MHz RFID (CCID)
Many of the readers with support of only 1 protocol are tokens with an integrated smart card. Since you can't change the card only the protocol used by the card is declared. So it is not really a limitation of the reader.

CCID descriptor statistics: dwSynchProtocols

Article from the serie "CCID descriptor statistics"

The dwSynchProtocols field is a number value from the CCID USB descriptor:

• RRRR-UpperWord- is RFU=0000h
• PPPP-Lower Word- encodes thes upported protocol types. A ‘1’ in a given bit position indicates support for the associated protocol.
0001h indicates support for the 2-wire protocol
0002h indicates support for the 3-wire protocol
0004h indicates support for the I2C protocol
All other values are outside of this specification, and must be handled by vendor-supplied drivers.

A footnote in the specification also indicates:
This release of the specification does not support devices with the 2-wire, 3-wire, and I2C protocol so PPPP = 0000h. This field is intended to be forward compatible with the PCSC specification.
I imagine this value is for synchronous cards only.

dwSynchProtocols # %
0x00000000 218 85.83 %
0x00000007 35 13.78 %
0x00000001 1 0.39 %


The normal value should be PPPP = 0000h. Most of the readers provide this value.

The reader with value 0x00000001 is:
  • C3PO TLTC2USB

The readers with value 0x00000007 are:
  • Akasa AK-CR-03
  • Alcor Micro AU9520
  • Alcor Micro AU9522
  • Alcor Micro AU9540
  • Alcor Micro SCR001
  • C3PO KBR36
  • C3PO LTC31 v2
  • C3PO LTC32
  • C3PO LTC36
  • Cherry GmbH SmartBoard XX44
  • Cherry GmbH SmartTerminal ST-1275
  • Cherry GmbH SmartTerminal XX44
  • Feitian bR301
  • Fujitsu Siemens Computers SmartCard Keyboard USB 2A
  • Fujitsu Siemens Computers SmartCard USB 2A
  • GIS Ltd SmartMouse USB
  • Giesecke & Devrient GmbH StarSign Crypto USB Token
  • KOBIL KAAN Advanced
  • KOBIL KAAN Base
  • OMNIKEY 6321 CLi USB
  • OMNIKEY AG CardMan 3021
  • OMNIKEY AG CardMan 3121
  • OMNIKEY AG CardMan 3621
  • OMNIKEY AG CardMan 3821
  • OMNIKEY AG CardMan 5121
  • OMNIKEY AG CardMan 5125
  • OMNIKEY AG CardMan 6121
  • OMNIKEY AG Smart Card Reader
  • OMNIKEY CardMan 1021
  • OMNIKEY CardMan 4321
  • OMNIKEY CardMan 5321
  • Precise Biometrics Sense MC
  • Sitecom Sitecom USB simcard reader MD-010
  • THRC Smart Card Reader
  • VASCO DIGIPASS KEY 101
  • VASCO DP905v1.1
  • Watchdata W5181
  • XIRING Teo

Level 1 smart card support on GNU/Linux

As I did for Mac OS X in "Level 1 smart card support on Mac OS X" I propose to present some 1st step actions to check your smart card stack is working correctly on a GNU/Linux system.

Operating System choice

Unix is available in a lot of different versions. I will only consider a GNU/Linux system here and also only a Debian GNU/Linux distribution.

If you use Ubuntu (or another Debian derivative distribution) then the same tools are available.
If you use another GNU/Linux distribution maybe the same software are already packaged and available.

Command line tools

All the commands I will describe are command line tools. You need to start a "terminal" application also called terminal emulator to enter the commands.

I will not describe here how to start a "terminal" application. It depends too much on the graphical environment (or desktop) you are using.

pcsc_scan

pcsc_scan is a command line tool. You need to install the pcsc-tools Debian package (or recompile pcsc_scan yourself from the upstream pcsc-tools).

Normal execution

In green the commands entered by the user.

$ pcsc_scan
PC/SC device scanner
V 1.4.22 (c) 2001-2011, Ludovic Rousseau <ludovic.rousseau@free.fr>
Compiled with PC/SC lite version: 1.8.8
Using reader plug'n play mechanism
Scanning present readers...
0: Gemalto PC Twin Reader (70D7E2EE) 00 00

Mon Mar 24 15:31:17 2014
Reader 0: Gemalto PC Twin Reader (70D7E2EE) 00 00
  Card state: Card inserted, 
  ATR: 3B 7E 13 00 00 00 6A 11 63 54 05 48 05 02 C6 01 22 90 00
ATR: 3B 7E 13 00 00 00 6A 11 63 54 05 48 05 02 C6 01 22 90 00
+ TS = 3B --> Direct Convention
+ T0 = 7E, Y(1): 0111, K: 14 (historical bytes)
  TA(1) = 13 --> Fi=372, Di=4, 93 cycles/ETU
    43010 bits/s at 4 MHz, fMax for Fi = 5 MHz => 53763 bits/s
  TB(1) = 00 --> VPP is not electrically connected
  TC(1) = 00 --> Extra guard time: 0
+ Historical bytes: 00 6A 11 63 54 05 48 05 02 C6 01 22 90 00
  Category indicator byte: 00 (compact TLV data object)
    Tag: 6, len: A (pre-issuing data)
      Data: 11 63 54 05 48 05 02 C6 01
    Mandatory status indicator (3 last bytes)
      LCS (life card cycle): 22 (Proprietary)
      SW: 9000 (Normal processing.)

Possibly identified card (using /home/lroussea/.cache/smartcard_list.txt):
3B 7E 13 00 00 00 6A 11 63 54 05 48 05 02 C6 01 22 90 00
3B 7E 13 00 00 00 6A 11 63 54 05 48 .. .. .. 01 22 90 00
 Sagem Windows for smart cards

Important information your should note:
  • the reader name: "Gemalto PC Twin Reader (70D7E2EE) 00 00"
  • the card ATR: 3B 7E 13 00 00 00 6A 11 63 54 05 48 05 02 C6 01 22 90 00
  • the card description (if available): Sagem Windows for smart cards
Of course in your case the information will be different. Unless you really have a "Windows for smart card" card .

Compared to Apple pcsctest we have some differences:
  • use of colors for important information
  • no need to select a reader
  • no debug messages
  • smart card identification
  • ATR parsing

No reader connected


$ pcsc_scan
PC/SC device scanner
V 1.4.22 (c) 2001-2011, Ludovic Rousseau <ludovic.rousseau@free.fr>
Compiled with PC/SC lite version: 1.8.8
Using reader plug'n play mechanism
Scanning present readers...
Waiting for the first reader...

You do not get an error (as on Mac OS X) but the program is waiting for you to connect a smart card reader.

No smart card inserted


$ pcsc_scan
PC/SC device scanner
V 1.4.22 (c) 2001-2011, Ludovic Rousseau <ludovic.rousseau@free.fr>
Compiled with PC/SC lite version: 1.8.8
Using reader plug'n play mechanism
Scanning present readers...
0: Gemalto PC Twin Reader (70D7E2EE) 00 00

Mon Mar 24 15:36:01 2014
Reader 0: Gemalto PC Twin Reader (70D7E2EE) 00 00
  Card state: Card removed, 

The program is waiting for you to insert a smart card.

scriptor

Once you have checked your reader and your smart card are available using pcsc_scan, you can try to communicate with the card and send some APDUs.

scriptor is a command line tool also part of pcsc-tools.

$ scriptor 
No reader given: using Gemalto PC Twin Reader (70D7E2EE) 00 00
Using T=0 protocol
Reading commands from STDIN
00 A4 00 02 3F 00
> 00 A4 00 02 3F 00
< 6D 00 : Instruction code not supported or invalid.

Here we are sending the APDU "00 A4 00 02 3F 00" which is a SELECT command for the file "3F 00" i.e. the Master File.
The result of the command is "6D 00" here. This is an error code but that is not really important for our test. We just wanted to test we can communicate with the card.

gscriptor

If you really can't use command line tools you can try gscriptor. It is a graphical application also part of pcsc-tools.


Conclusion

These first steps are easy to execute on Debian GNU/Linux, and should also be easy on another GNU/Linux system.

If you do not have the expected results then you need to contact your level 2 support team.

New version of libccid: 1.4.16

I just released a version 1.4.16 of libccid the free software CCID class smart card reader driver.

Changes:
1.4.16 - 23 March 2014, Ludovic Rousseau

  • Add support of
    • Crypto Stick Crypto Stick v1.4
    • Hewlett Packard USB Smartcard CCID Keyboard
    • IID AT90S064 CCID READER
    • INSIDE Secure VaultIC 405 Smart Object
    • INSIDE Secure VaultIC 441 Smart Object
    • Microchip SEC1110
    • Microchip SEC1210
    • Watchdata W5181
  • Add support of DRIVER_OPTION_DISABLE_PIN_RETRIES
    The Gemalto pinpad reader sends a VERIFY command with no PIN value in order to retreive the remaining retries from the card. Some cards (like the OpenPGP card) do not support this.
    It is now possible to disable this behavior from the Gemalto Pinpad and Covadis Véga Alpha.
  • Add support of WTX received before SW during Secure Pin Entry Verify
    The Swiss health care card sends a WTX request before returning the SW code. If the reader is in TPDU and the card is in T=1 the driver must manage the request itself.

Level 1 smart card support on Mac OS X

It may not be easy to check if a smart card stack works or not. I will explain what you can do as a first step to check your smart card stack on Mac OS X.

pcsctest

Apple provides a command line tool pcsctest. It is an evolution of testpcsc provided by the "official" pcsc-lite.

The Apple pcsctest source code is available at http://opensource.apple.com/source/SmartCardServices/SmartCardServices-55111/src/PCSC/testpcsc.c

The good news is that this command line tool is installed by default. So every Mac OS X install should have it out of the box.

Command line tool

To run a command line tool you need to start the Terminal application from the /Applications/Utilities/ directory.
Terminal icon


You will then get a Terminal window with a prompt
$

Normal execution

In green the commands entered by the user.
In yellow the important information.

If your reader is connected and a smart card is inserted you should get something like:
$ pcsctest 

MUSCLE PC/SC Lite Test Program

Testing SCardEstablishContext    : Command successful.
Testing SCardGetStatusChange 
Please insert a working reader   : Command successful.
Testing SCardListReaders         : Command successful.
Reader 01: Gemplus GemPC Twin 00 00
Enter the reader number          : 1
Waiting for card insertion         
                                 : Command successful.
Testing SCardConnect             : Command successful.
Testing SCardStatus              : Command successful.
Current Reader Name              : Gemplus GemPC Twin 00 00
Current Reader State             : 0x34
Current Reader Protocol          : 0x0
Current Reader ATR Size          : 9 (0x9)
Current Reader ATR Value         : 3B 65 00 00 20 63 CB A6 A0 
Testing SCardDisconnect          : Command successful.
Testing SCardReleaseContext      : Command successful.
Testing SCardEstablishContext    : Command successful.
Testing SCardGetStatusChange 
Please insert a working reader   : Command successful.
Testing SCardListReaders         : Command successful.
Reader 01: Gemplus GemPC Twin 00 00
Enter the reader number          : 1
Waiting for card insertion         
                                 : Command successful.
Testing SCardConnect             : Command successful.
Testing SCardStatus              : Command successful.
Current Reader Name              : Gemplus GemPC Twin 00 00
Current Reader State             : 0x34
Current Reader Protocol          : 0x0
Current Reader ATR Size          : 9 (0x9)
Current Reader ATR Value         : 3B 65 00 00 20 63 CB A6 A0 
Testing SCardDisconnect          : Command successful.
Testing SCardReleaseContext      : Command successful.

PC/SC Test Completed Successfully !

You should note:
  • the reader name Gemplus GemPC Twin 00 00
  • the card ATR 3B 65 00 00 20 63 CB A6 A0
In this case the reader is correctly found and the communication with the card is working.

You can then use the online Smart card ATR parsing tool to check the ATR corresponds to the card you inserted. In the present case it is a French banking card.

No reader connected

$ pcsctest 

MUSCLE PC/SC Lite Test Program

Testing SCardEstablishContext    : Service not available.

On Mac OS X the PC/SC service (in fact the pcscd daemon) is started by the securityd process at boot and when a USB smart card reader is connected.
So if no reader is connected you get the error: "Service not available" because pcscd is not yet running.

No smart card inserted

$ pcsctest 

MUSCLE PC/SC Lite Test Program

Testing SCardEstablishContext    : Command successful.
Testing SCardGetStatusChange 
Please insert a working reader   : Command successful.
Testing SCardListReaders         : Command successful.
Reader 01: Gemplus GemPC Twin 00 00
Enter the reader number          : 1
Waiting for card insertion

The program is then waiting for a card insertion.

If you have a card inserted and you do not get the ATR or an error then you have a problem.

If you insert a card and get the error "Card is unpowered" then you may have inserted the card the wrong way (or your card is dead).

System information

If your reader is connected but you can't see it with pcsctest then maybe the USB device is not seen by Mac OS X.

You can use the System Information application from the /Applications/Utilities/ directory.
System Information icon


In the application you select the USB subsection in the Hardware section and can see all the USB devices known by the system.
If you can't see your USB smart card reader then you have a USB issue, not a PC/SC issue.

Command line

You can also use the equivalent command in the Terminal:

$ system_profiler SPUSBDataType

Conclusion

These first steps are easy to execute on Mac OS X. If the pcsctest test succeeds then you can be confident that the smart card reader and the PC/SC layer are working correctly.

If the pcsctest test fails then you need to go to a level 2 smart card support on Mac OS X.

Differences between Apple pcsc-lite and the "official" pcsc-lite

In "Evolution of Apple pcsc-lite (from Jaguar to Mavericks)" I described the evolution of Apple version of pcsc-lite. During the same time the "official" pcsc-lite also evolved.

Terminology

  • Apple pcsc-lite
    The version of pcsc-lite provided by Apple in Mac OS X since Jaguar in 2002. It is provided as a framework and is available at /System/Library/Frameworks/PCSC.framework/.
  • "official" pcsc-lite
    The version of pcsc-lite available at https://pcsclite.apdu.fr/ for the source code and as a binary package for your preferred GNU/Linux distribution.

Features present only in Apple pcsc-lite

  • Integration with securityd
    pcscd is started by securityd when needed. From securityd(1) man page: securityd -- Security context daemon for Authorization and cryptographic operations
  • hotplug using IOKit
    a file hotplug_macosx.c is present in the "official" pcsc-lite but has not evolved since Apple forked the code in 2002. Apple made major changes to the hotplug system.
  • Suspend/resume of the computer
    in the "official" pcsc-lite no special code is used and suspend/resume works. Apple has an explicit suspend and resume of the smart card readers.
  • Rosetta support
    This may be removed in a future version since PowerPC is no more supported by Mac OS X.

Features present only in "official" pcsc-lite

Features present in both projects

Support of 32 and 64-bits applications at the same time

Both projects support the use of a 32-bits application using a 64-bits pcscd. But since the protocol between the client and server has diverged in the two projects they use different (but similar) solutions.

For Mac OS X Apple added this support for the migration from 32 to 64-bits Intel CPU.
For GNU/Linux I added this support to be able to use the same 64-bits pcscd daemon from a 64-bits client application and also from a 32-bits client application in a chroot. Now that Debian multiarch is deploying it is even easier to mix 32 and 64-bits Intel applications on the same system.

Bugs (still) present in Apple pcsc-lite


I discovered (a lot of?) bugs in the smart card components provided by Apple. Some have been fixed and some are still present:
  • Do not support USB devices with more than 1 CCID interface (bug #10469006)
  • Do not support extended APDU longer than 1958 bytes (bug #9983001 and #7334726)
  • Do not support more than 16 PCSC contexts per application (bug #10038432)
  • reader.h header file is not provided in the PCSC Framework (bug #7101554)
  • pcscd does not support TAG_IFD_THREAD_SAFE (bug #6584566)
  • pcscd crashes when the smart card reader is removed when in communication (bug #6114944)
  • PC/SC never returns the warm ATR of a dual-ATR card (bug #5964019)

Apple has a strange way to manage bugs.
  • If a bug report is a duplicate of an already known bug then the duplicate bug report is closed.
  • Even if a bug is not a duplicate the bug is sometimes closed with:
    Thank you for filing this bug report.

    We are closing this bug since our engineers are aware of the issue and will continue to track it.

So I have many bugs that are closed in the bug report tool https://bugreport.apple.com/ but that in fact still not fixed.

Bugs present in "official" pcsc-lite

None known

How to merge the two projects

The question now is what to do with these two projects that share a lot of history and common code?

Include Apple code inside the "official" pcsc-lite

This is technically possible. The source code is available and Mac OS X specific parts should not have an impact on pcsc-lite for the other systems (GNU/Linux).

It is also legally possible. The Apple license "Apple Public Source License Version 1.2" should be compatible with the BSD-like license used by the "official" pcsc-lite. But the APSL 1.2 license is not a Free Software license for the Free Software Foundation. See "The Problems with older versions of the Apple Public Source License (APSL)".

The most important issue is that Apple would not use this code and would continue to "maintain" its own version of pcsc-lite at the SmartCard Services project. So bugs fixed in this merge would not be included in the next version of Mac OS X.

Patch Apple pcsc-lite

The most effective way is to modify the SmartCard Services project to fix bugs and add features. This code may be included in the next version of Mac OS X. I fixed bugs in this code during the year 2009 and the fixes have been released in Snow Leopard and Lion versions of Mac OS X.

Conclusion

Apple version of pcsc-lite has evolved only to support new features introduced by Mac OS X (Rosetta and then 32 and 64-bits Intel codes).
Some very blocking bugs have been fixed in the early years of Apple pcsc-lite. It looks like Apple is now happy with the state of its pcsc-lite and will not invest engineering time in it.

If you are blocked by a bug or a missing feature in Apple pcsc-lite you will have to fix it yourself or recruit someone to fix it for you. You can contact me at ludovic.rousseau@free.fr.

Evolution of Apple pcsc-lite (from Jaguar to Mavericks)

When Apple first introduced the smart card support in Mac OS X 10.2 Jaguar (August 2002) pcsc-lite was at version 1.0.x and I just started to add my patches to it. At that time the author and maintainer of pcsc-lite was David Corcoran.

In this article we will do some archaeology work. Apple moved the SmartCardServices to the SmartCard Services public project in January 2009 at the time of Leopard 10.5. The first tag on source code available in the subversion repository is for OSX-10.5.6. The detailed history of the source code before that version is not publicly available and must be reverse engineered "by hand".

On the "official" pcsc-lite side, the oldest tagged version is 1.1.2-beta1 from September 2002.

Terminology

The pcsc-lite provided by Apple is called, in this article, Apple pcsc-lite.

The original pcsc-lite and ancestor of Apple pcsc-lite is called "official" pcsc-lite. The "official" pcsc-lite is used mainly on GNU/Linux (and GNU/Linux distributions) and is also used on FreeBSD, NetBSD, OpenBSD, Android, and maybe other Unix-like systems I don't know about.

Oracle (ex-Sun) has its own forked version of pcsc-lite for Solaris. An old version of this source code is available in the Solaris branch.

10.2 Jaguar

August 2002

SmartCardServices-10

The PCSCLITE_VERSION_NUMBER in src/pcsclite.h is "1.1.1". The same 1.1.1 version of the "official" pcsc-lite was released 5 Jun, 2002. I wrote above I do not have the version 1.1.1 in the subversion history. So we will use version 1.1.2-beta1 instead.

A diffstat between the two versions gives us:
 debuglog.c         |   76 +++++++++++++++++++++++++++++++++++++-----
 eventhandler.c     |    1 
 ifdwrapper.c       |    8 ++++
 pcscdaemon.c       |   94 +++++++++++++++++++++++++++++++++++++++++++----------
 powermgt_generic.h |    2 -
 readerfactory.c    |    4 +-
 sys_unix.c         |    2 -
 winscard_clnt.c    |    2 -
 winscard_msg.c     |    2 -
 9 files changed, 157 insertions(+), 34 deletions(-)

New code in "official" pcsc-lite (and then not present in Apple pcsc-lite):
  • Win32 support in log functions
  • APDU log
  • store pcscd pid in a file to detect another running pcscd
No code added in Apple version of pcsc-lite.
    So it looks like that Apple just used version 1.1.1 of pcsc-lite without changes at this first step.

    10.3 Panther

    October 2003

    SmartCardServices-15

    Diffstat against the previous version:
    $ diff -ru SmartCardServices-10/src/ SmartCardServices-15/src/PCSC/ | diffstat
     atrhandler.c       |   18 
     atrhandler.h       |   17 
     configfile.c       |   17 
     configfile.h       |   17 
     debuglog.c         |   93 +++-
     debuglog.h         |   49 +-
     dyn_generic.h      |   17 
     dyn_macosx.c       |   17 
     eventhandler.c     |   23 +
     eventhandler.h     |   17 
     hotplug.h          |   28 +
     hotplug_macosx.c   | 1211 +++++++++++++++++++++++++++--------------------------
     ifdhandler.h       |   17 
     ifdwrapper.c       |   17 
     ifdwrapper.h       |   17 
     mscdefines.h       |   30 -
     musclecard.c       |   28 +
     musclecard.h       |   30 -
     muscletest.c       |   19 
     pcscdaemon.c       |  117 ++++-
     pcsclite.h         |   32 -
     powermgt_generic.h |   19 
     powermgt_macosx.c  |   40 +
     prothandler.c      |   19 
     prothandler.h      |   17 
     readerfactory.c    |   28 +
     readerfactory.h    |   17 
     sys_generic.h      |   19 
     sys_unix.c         |   19 
     testpcsc.c         |   17 
     thread_generic.h   |   17 
     thread_macosx.c    |   17 
     tokenfactory.c     |   37 +
     tokenfactory.h     |   29 +
     tokenparser.c      |   17 
     utils/bundleTool.c |   62 +-
     winscard.c         |   25 +
     winscard.h         |   30 -
     winscard_clnt.c    |   19 
     winscard_msg.c     |   19 
     winscard_msg.h     |   17 
     winscard_svc.c     |   17 
     winscard_svc.h     |   17 
     wintypes.h         |   32 -
     44 files changed, 1617 insertions(+), 764 deletions(-)
    

    Changes:
    • integration of CACPlugin, CFlexPlugin, MCardPlugin and PKCS11 directories. pcsc-lite is now in its own PCSC directory
    • add the Apple license (Apple Public Source License Version 1.2) in each source code file
    • merge with pcsc-lite 1.2.0 rc1 (or a more recent version)
    • move from /usr/local/pcsc to /usr/libexec/SmartCardServices in hotplug_macosx.c plus other changes specific to Mac OS X
    It looks like Apple resynchronised with the "official" pcsc-lite at that time.

    10.4 Tiger

    April 2005
    Diffstat between 10.3 and 10.4.0 version
    $ diff -ru SmartCardServices-15 SmartCardServices-31 | diffstat 
     APPLE_LICENSE                      |  509 ++++++++---------
     Makefile.installPhase              |   45 +
     installPhase/man/pcscd.8           |   16 
     installPhase/man/pcsctool.8        |    2 
     src/CACPlugin/commonAccessCard.c   |   24 
     src/CFlexPlugin/cryptoflex.c       |    3 
     src/CFlexPlugin/cryptoflex.h       |    1 
     src/MCardPlugin/musclecardApplet.c |   35 -
     src/PCSC/eventhandler.c            |    7 
     src/PCSC/hotplug_macosx.c          | 1065 +++++++++++++++++++++----------------
     src/PCSC/mscdefines.h              |   29 -
     src/PCSC/musclecard.c              |   83 +-
     src/PCSC/musclecard.h              |   29 -
     src/PCSC/pcscdaemon.c              |   88 ++-
     src/PCSC/pcsclite.h                |   31 -
     src/PCSC/powermgt_macosx.c         |   25 
     src/PCSC/readerfactory.c           |    4 
     src/PCSC/tokenfactory.c            |   12 
     src/PCSC/tokenfactory.h            |    5 
     src/PCSC/winscard.c                |   38 -
     src/PCSC/winscard.h                |   29 -
     src/PCSC/winscard_clnt.c           |  387 +++++++------
     src/PCSC/winscard_msg.c            |  320 -----------
     src/PCSC/winscard_msg.h            |  203 +++----
     src/PCSC/winscard_svc.c            |  496 ++++++++++++++---
     src/PCSC/winscard_svc.h            |   65 ++
     src/PCSC/wintypes.h                |   29 -
     src/PKCS11/p11_crypt.c             |    3 
     src/PKCS11/p11x_object.c           |    6 
     29 files changed, 2016 insertions(+), 1573 deletions(-)
    

    Changes:
    • hotplug_macosx.c: iterate on all the interfaces of a USB device and other changes
    • client/server communication protocol: redesign the protocol to use a 2 parts header+body in the commands

    Diffstat between 10.4.0 and 10.4.11 PowerPC
    $ diff -ru SmartCardServices-31 SmartCardServices-27738 | diffstat
     SmartCardServices.xcode/project.pbxproj |   35 
     src/PCSC/sys_generic.h                  |    4 
     src/PCSC/sys_macosx.cpp                 |    7 
     src/PCSC/sys_unix.c                     |    7 
     src/PCSC/winscard_clnt.c                | 1127 +++++++++++++++-----------------
     src/PKCS11/p11x_prefs.c                 |   32 
     6 files changed, 590 insertions(+), 622 deletions(-)
    

    Changes:
    • minor changes
    • a new function SYS_MUnmap is added and used in winscard_clnt.c. This function was never used in the "official" pcsc-lite.

    Diffstat between 10.4.11 PowerPC and 10.4.11 x86
    $ diff -ru SmartCardServices-27738 SmartCardServices-30487 | diffstat
     SmartCardServices.xcode/project.pbxproj                     |   55 +-
     installPhase/drivers/SCR24XHndlr.bundle/Contents/Info.plist |    2 
     src/CACPlugin/commonAccessCard.c                            |    2 
     src/CCIDDriver/USB/MacOSX/usbserial_mosx.c                  |   22 
     src/CCIDDriver/USB/MacOSX/usbserial_mosx.h                  |    4 
     src/CCIDDriver/common/CCID.c                                |    8 
     src/CCIDDriver/common/CCIDPropExt.c                         |    2 
     src/PCSC/debuglog.c                                         |   10 
     src/PCSC/debuglog.h                                         |    2 
     src/PCSC/eventhandler.c                                     |   42 -
     src/PCSC/hotplug_macosx.c                                   |  267 ++++++------
     src/PCSC/mscdefines.h                                       |   28 -
     src/PCSC/musclecard.c                                       |    4 
     src/PCSC/musclecard.h                                       |    2 
     src/PCSC/pcscdaemon.c                                       |   15 
     src/PCSC/pcsclite.h                                         |   18 
     src/PCSC/readerfactory.c                                    |   10 
     src/PCSC/testpcsc.c                                         |   10 
     src/PCSC/winscard.h                                         |   74 +--
     src/PCSC/winscard_clnt.c                                    |   92 ++--
     src/PCSC/winscard_msg.h                                     |   10 
     src/PCSC/winscard_svc.c                                     |  122 +++++
     src/PCSC/winscard_svc.h                                     |    5 
     src/PCSC/wintypes.h                                         |   26 -
     src/PKCS11/p11_crypt.c                                      |    8 
     src/PKCS11/p11_key.c                                        |    5 
     src/PKCS11/p11_sign.c                                       |   19 
     27 files changed, 515 insertions(+), 349 deletions(-)
    

    Changes:
    • use of htonl() and ntohl() to convert between little and big endian integers
    • hotplug_macosx.c updated again
    • use of uint8_t, uint16_t, uint32_t types to support 32 and 64 bits client applications with the same pcscd server

    The major change here is the support of PowerPC and Intel CPUs at the same time.

    On an Intel Mac it is possible to run a PowerPC appplication using Rosetta. In that case the application code is for PowerPC but the PC/SC daemon is running x86 code (native code). The daemon needs to convert the byte order in all the messages exchanged between the client (PowerPC code) and server (x86 code).

    10.5 Leopard

    October 2007

    SmartCardServices-32672

    $ diff -ruN SmartCardServices-30487 SmartCardServices-32672 | diffstat
     Makefile.installPhase                       |    9 
     SmartCardServices.xcode/project.pbxproj     | 3277 ------------------------
     SmartCardServices.xcodeproj/project.pbxproj | 3030 ++++++++++++++++++++++
     installPhase/man/sc_auth.8                  |   91 
     installPhase/scripts/sc_auth                |  148 +
     src/CCIDDriver/USB/MacOSX/usbserial_mosx.c  |    4 
     src/CCIDDriver/common/tools.c               |    2 
     src/PCSC/PCSC.exp                           |   71 
     src/PCSC/PCSCDevice.cpp                     |   66 
     src/PCSC/PCSCDevice.h                       |  100 
     src/PCSC/PCSCDriverBundle.cpp               |  261 +
     src/PCSC/PCSCDriverBundle.h                 |  125 
     src/PCSC/PCSCDriverBundles.cpp              |   97 
     src/PCSC/PCSCDriverBundles.h                |   76 
     src/PCSC/atrhandler.c                       |    2 
     src/PCSC/atrhandler.h                       |    2 
     src/PCSC/config.h                           |  215 +
     src/PCSC/configfile.c                       |    4 
     src/PCSC/configfile.l                       |    2 
     src/PCSC/debug.c                            |  160 +
     src/PCSC/debug.h                            |   78 
     src/PCSC/debuglog.c                         |  340 +-
     src/PCSC/debuglog.h                         |  157 -
     src/PCSC/eventhandler.c                     |    9 
     src/PCSC/eventhandler.cpp                   |  533 +++
     src/PCSC/eventhandler.h                     |   72 
     src/PCSC/hotplug.h                          |   86 
     src/PCSC/hotplug_macosx.cpp                 |  151 +
     src/PCSC/ifdhandler.h                       |  123 
     src/PCSC/ifdwrapper.c                       |  813 ++---
     src/PCSC/ifdwrapper.h                       |   73 
     src/PCSC/musclecard.c                       |   52 
     src/PCSC/pcscdaemon.c                       |  664 ++--
     src/PCSC/pcscdmonitor.cpp                   | 1129 ++++++++
     src/PCSC/pcscdmonitor.h                     |  191 +
     src/PCSC/pcscdserver.cpp                    |  137 +
     src/PCSC/pcscdserver.h                      |  101 
     src/PCSC/pcscexport.h                       |   62 
     src/PCSC/pcsclite.h                         |  402 +-
     src/PCSC/powermgt_macosx.c                  |   31 
     src/PCSC/prothandler.c                      |  247 -
     src/PCSC/prothandler.h                      |   70 
     src/PCSC/reader.cpp                         |  165 +
     src/PCSC/reader.h                           |  147 +
     src/PCSC/readerfactory.c                    | 2070 ++++++---------
     src/PCSC/readerfactory.h                    |  200 +
     src/PCSC/readerstate.cpp                    |  108 
     src/PCSC/readerstate.h                      |  116 
     src/PCSC/sys_generic.h                      |  108 
     src/PCSC/sys_macosx.cpp                     |  222 -
     src/PCSC/sys_unix.c                         |  316 +-
     src/PCSC/testpcsc.c                         |    4 
     src/PCSC/thread_generic.h                   |   26 
     src/PCSC/thread_macosx.c                    |   38 
     src/PCSC/tokenfactory.c                     |   16 
     src/PCSC/tokenparser.c                      |    4 
     src/PCSC/winscard.c                         | 1558 ++++++-----
     src/PCSC/winscard.h                         |  103 
     src/PCSC/winscard_clnt.c                    | 3798 ++++++++++++++++++----------
     src/PCSC/winscard_msg.cpp                   | 1002 +++++++
     src/PCSC/winscard_msg.h                     |  458 ++-
     src/PCSC/winscard_msg_srv.c                 |  305 ++
     src/PCSC/winscard_svc.c                     | 1311 +++++----
     src/PCSC/winscard_svc.h                     |  136 -
     src/PCSC/wintypes.h                         |   56 
     src/PCSC/xiodevices.cpp                     |  141 +
     src/PCSC/xiodevices.h                       |   70 
     src/PKCS11/p11x_msc.c                       |   12 
     68 files changed, 16622 insertions(+), 9131 deletions(-)
    

    Changes:
    • install the sc_auth command used to configure a smart card Mac OS X login
    • support colored logs but only on Linux terminals. Apple just reused debuglog.c from pcsc-lite 1.3.3
    • use secdebug() to log debug messages (visible using dtrace)
    • reuse ifdwrapper.c, prothandler.c and pcscdaemon.c from pcsc-lite 1.4.0
    • integrate with securityd
    • create new C++ files:
      • eventhandler.cpp
      • hotplug_macosx.cpp
      • PCSCDevice.cpp
      • pcscdmonitor.cpp
      • PCSCDriverBundle.cpp
      • PCSCDriverBundles.cpp
      • pcscdserver.cpp
      • reader.cpp
      • readerstate.cpp
      • sys_macosx.cpp
      • winscard_msg.cpp
      • xiodevices.cpp
    The detection and management of smart card readers is now a C++ code.

    The new file pcscdmonitor.cpp is the link with securityd.
    From the source code:
    pcscmonitor - use PCSC to monitor smartcard reader/card state for securityd

    PCSCDMonitor is the "glue" between PCSC and the securityd objects representing smartcard-related things. Its job is to manage the daemon and translate real-world events (such as card and device insertions) into the securityd object web.

    PCSCDMonitor uses multiple inheritance to the hilt. It is (among others)
      (*) A notification listener, to listen to pcscd state notifications
      (*) A MachServer::Timer, to handle timed actions
      (*) A NotificationPort::Receiver, to get IOKit notifications of device insertions

    This version of Apple pcsc-lite is a major deviation from the "official" pcsc-lite.
    At the same time Apple merged code from the "official" pcsc-lite.

    10.6 Snow Leopard

    August 2009

    SmartCardServices-36160

    $ diff -ruN SmartCardServices-32672/src/PCSC/ SmartCardServices-36160/src/PCSC/ | diffstat
     eventhandler.cpp   |   12 +-
     hotplug.h          |    4 
     hotplug_macosx.cpp |   17 +++
     ifdwrapper.c       |   15 +--
     pcscdaemon.c       |  116 +++++++++++++++++------
     pcscdmonitor.cpp   |   96 ++++++++++++++-----
     readerfactory.c    |  141 +++++++++++++++++++++++++++-
     testpcsc.c         |   34 ++++--
     thread_macosx.c    |   23 ++--
     winscard.c         |  113 +++++++++++-----------
     winscard.h         |    2 
     winscard_clnt.c    |  131 +++++++++++++++-----------
     winscard_msg.cpp   |  122 ++++++++++++------------
     winscard_msg.h     |  264 ++++++++++++++++++++++++++---------------------------
     winscard_msg_srv.c |   50 ++++++----
     winscard_svc.c     |   43 +++++++-
     16 files changed, 761 insertions(+), 422 deletions(-)
    

    Changes:
    • Apple removed the code of the CCID driver from SmartCardServices
    • Apple now provides my CCID driver instead of another (limited) CCID driver
    • this version of SmartCardServices includes patches I made in pcsc-lite 1.5.0 and I backported to the Apple version (ifdwrapper.c and winscard.c) since I am a member of the SmartCardServices project
    • support 32 and 64-bits smart card reader driver. pcscd will restart in 32-bits if a 32-bits only driver is found
    • use OSSwapHostToBigInt64() to support big/little endian conversion and also 32/64 bits conversion

    10.7 Lion

    July 2011

    See my blog article "Mac OS X Lion and smart cards status" for more details.

    SmartCardServices-55000

    $ diff -ru SmartCardServices-36160 SmartCardServices-55000 | diffstat
     Info-PCSC.plist                             |    2 
     SmartCardServices.xcodeproj/project.pbxproj |  106 -
     src/PCSC/PCSCDevice.h                       |    1 
     src/PCSC/PCSCDriverBundle.h                 |    1 
     src/PCSC/atrhandler.c                       |  157 +
     src/PCSC/atrhandler.h                       |   49 
     src/PCSC/configfile.c                       | 2406 ++++++++++++++--------------
     src/PCSC/configfile.h                       |    2 
     src/PCSC/configfile.l                       |  211 +-
     src/PCSC/debug.c                            |   51 
     src/PCSC/debug.h                            |    2 
     src/PCSC/debuglog.c                         |  165 -
     src/PCSC/debuglog.h                         |    2 
     src/PCSC/dyn_generic.h                      |    2 
     src/PCSC/dyn_macosx.c                       |   26 
     src/PCSC/eventhandler.cpp                   |    6 
     src/PCSC/eventhandler.h                     |    2 
     src/PCSC/hotplug.h                          |    2 
     src/PCSC/hotplug_macosx.cpp                 |    1 
     src/PCSC/ifdhandler.h                       |  798 +++++++--
     src/PCSC/ifdwrapper.c                       |  232 +-
     src/PCSC/ifdwrapper.h                       |    2 
     src/PCSC/musclecard.h                       |    2 
     src/PCSC/pcscdaemon.c                       |    2 
     src/PCSC/pcscdmonitor.cpp                   |    4 
     src/PCSC/pcscdmonitor.h                     |    1 
     src/PCSC/pcscdserver.h                      |    1 
     src/PCSC/pcscexport.h                       |    2 
     src/PCSC/pcsclite.h                         |  127 -
     src/PCSC/powermgt_generic.h                 |    2 
     src/PCSC/prothandler.c                      |    2 
     src/PCSC/prothandler.h                      |    2 
     src/PCSC/reader.h                           |  340 ++-
     src/PCSC/readerfactory.c                    |   12 
     src/PCSC/readerfactory.h                    |    2 
     src/PCSC/readerstate.h                      |    1 
     src/PCSC/sys_generic.h                      |    2 
     src/PCSC/sys_macosx.cpp                     |    3 
     src/PCSC/sys_unix.c                         |    2 
     src/PCSC/thread_macosx.c                    |    2 
     src/PCSC/tokenfactory.c                     |    2 
     src/PCSC/utils/bundleTool.c                 |    2 
     src/PCSC/winscard.c                         |    2 
     src/PCSC/winscard.h                         |    2 
     src/PCSC/winscard_clnt.c                    |    2 
     src/PCSC/winscard_msg.c                     |    2 
     src/PCSC/winscard_msg.cpp                   |    2 
     src/PCSC/winscard_msg.h                     |    2 
     src/PCSC/winscard_msg_srv.c                 |    2 
     src/PCSC/winscard_svc.c                     |   10 
     src/PCSC/winscard_svc.h                     |    2 
     src/PCSC/wintypes.h                         |   16 
     52 files changed, 2727 insertions(+), 2054 deletions(-)
    

    Changes:
    • some bugs fixes I made in the "official" pcsc-lite and I then ported to Apple version of pcsc-lite. See my blog article for details.
    • the CCID driver has been updated from 1.3.8 to 1.3.11
    I integrated the changes in SmartCardServices in July 2009 and they were available two years later in the next major version of Mac OS X.

    10.8 Mountain Lion

    July 2012

    Blog article "Mac OS X Mountain Lion and smart card status"

    SmartCardServices-55105

    No change in the source code.

    10.9 Mavericks

    October 2013

    Blog article "OS X Mavericks and smart cards status"

    SmartCardServices-55111

    Changes:
    • The ability to respawn in 32-bits to run a 32-bits only driver (introduced in Snow Leopard) has been removed
    • The CCID driver is now in 64-bits but the version is still 1.3.11

    Conclusion

    The evolution of Apple pcsc-lite is quite different from the evolution of the "official" pcsc-lite.

    In a next article I will describe the differences between the 2 projects after more than 10 years of evolution.