Misc PC/SC proposals

In a previous post PC/SC workgroup, November 2011 meeting and on the MUSCLE mailing list I asked for suggestion to submit at the PC/SC workgoup planned for November 2011. I got some feedback. Here is the proposal I sent to the PC/SC workgroup.

Misc PC/SC proposals


Author: Ludovic Rousseau
Date: October 2011

Introduction

In October 2011 I asked on the MUSCLE mailing list (http://musclecard.com/list.html) what changes where expected by the PC/SC workgroup.

Here is a list of the items.

Changes in PC/SC workgroup documents

The PC/SC workgroup specifications contain a "Revision History" section with a brief description of the changes. It would be even better to have all the changes directly visible within the document.

This can be done using different processes:

PDF with revision marks

When a new document is provided by the PC/SC workgroup a second document with the changes (compared to the previous version of the document) can be provided. This second document is easy to generate using the "compare" feature of MS Word.

Provide the document in ODF format

If providing the second document with the changes is too much work for the process another solution is to provide the document in ODF (Open Document Format) format (in addition to the PDF format). With this format it is easy to use, for example, Libre Office and compare two versions of the same specification document.

Provide the document in .DOC format

If providing the documents in ODF format is too much work for the process another solution is to provide the document in MS .DOC format. I guess the original format of the specification is already .DOC so the only added step is to store the .DOC documents on the PC/SC workgroup web site.

Firewalled pinpad

Some pinpad readers implement a firewall. If a PIN Verify command (INS byte 0x20) is sent using SCardTransmit() the reader will reject it. With a firewalled pinpad the only way to verify a PIN is by using the secure verify PIN feature. The problem is that 2 different readers will return 2 different status word in case of firewall rejection. In the field we already have noted two different Status Word in this case: 0x6985 and 0x6D00.

According to ISO 7816-4 we have:
0x6D00:
Instruction code not supported or invalid
0x69xx:
Command not allowed (further qualification in SW2)
0x6985:
Conditions of use not satisfied

These values are not really correct. Another problem is that it is hard (or impossible) to know if the error is really a invalid INS code or a rejection by the firewall. Another option it to use an not already used value like 0x6404
0x64xx:
State of non-volatile memory is unchanged (further qualification in SW2)
Some special Status Word values are already used (in the field) with a pinpad:
SW Description
0x6400 Timeout
0x6401 Canceled by user
0x6402 PIN mismatch
0x6403 Too short or too long PIN

The PC/SC workgroup should define the status word (SW1 and SW2) to be reported by the reader in such a case. We propose to use 0x6404.

FEATURE_WRITE_DISPLAY

PC/SC v2 part 10 defines FEATURE_WRITE_DISPLAY. But I could not find how to implement it in the driver at the CCID level. I guess some reader manufacturers have implemented it using CCID proprietary extensions.
Proposal:
Document how FEATURE_WRITE_DISPLAY should or could be implemented at the CCID level

FEATURE_GET_KEY

PC/SC v2 part 10 defines FEATURE_GET_KEY. But I could not find how to implement it in the driver at the CCID level. I guess some reader manufacturers have implemented using CCID proprietary extensions.
Proposal:
Document how FEATURE_GET_KEY should or could be implemented at the CCID level

FEATURE_VERIFY_PIN_START

PC/SC v2 part 10 defines FEATURE_VERIFY_PIN_START, FEATURE_GET_KEY_PRESSED and FEATURE_VERIFY_PIN_FINISH. But I could not find how to implement it in the driver at the CCID level. I guess some reader manufacturers have implemented using CCID proprietary extensions.
Proposal:
Document how FEATURE_VERIFY_PIN_START, FEATURE_GET_KEY_PRESSED and FEATURE_VERIFY_PIN_FINISH should or could be implemented at the CCID level
The same issue also exists for FEATURE_MODIFY_PIN_START and FEATURE_MODIFY_PIN_FINISH.

Unblock PIN feature

Add the possibility to unblock a PIN code using a pinpad. The unblock INS code is 0x2C and defined by TS 51.011 EN (http://www.3gpp.org/ftp/Specs/html-info/51011.htm). Some pinpad reader do not accept INS=0x2C for a VERIFY PIN command.

I propose to accept at least:
INS byte Description
0x20 VERIFY command (ISO 7816-4)
0x2C UNBLOCK (3GPP TS 51.011 EN)
Proposal:
Document the minimum set of INS bytes that a pinpad reader shall accept for a secure verify PIN command.

PIN merge feature

Add a 'pin merge' feature in which: part of the PIN is provided by the application and the other part is entered on the pinpad reader. Some readers already allow this: you just put part of the PIN in the APDU -- but some readers seem to overwrite the APDU's PIN buffer with padding bytes.

For eID cards, it happens that a PUK is split between the citizen and the governement. The examples below come from an eID card with ASCII encoded PINs:

E.g. of a 'PIN unblock without PIN change', in this case you can do an SCardControl(ctrl-for-FEATURE_VERIFY_PIN_DIRECT , data) with:

data = 1E 1E 02 00 00 00 00 08 04 00 02 01 16 08 00 00 00 00 00 00 0D 00 00 00
          00 2C 01 81 08 FF FF FF FF 31 32 33 34  (37 bytes)

So the application provides the last part of the PUK (= "1234" in this case) and the pinpad reader should ask the first part of the PUK to the user and fill it in at the location of the FF FF FF FF.

So for ASCII and BCD encoded PINs, this trick works on readers that don't write padding bytes to the PIN buffer (i.e. they should not change the 31 32 33 34 into FF FF FF FF in the above example).

Another example, of a 'PIN unblock with PIN change', in this case you can do an SCardControl(ctrl-for-FEATURE_CHANGE_PIN_DIRECT , data) with

data = 1E 1E 02 00 00 00 08 08 04 03 02 03 16 08 00 00 00 00 00 00 15 00 00 00
          00 2C 00 81 10 FF FF FF FF 31 32 33 34 FF FF FF FF FF FF FF FF  (45 bytes)

Here again, the first FF FF FF FF are for the user's part of the PUK, and the last 8 FF bytes are for the new PIN. Same remarks as above apply.

Conclusion

PC/SC defines some services at the PC/SC layer. This is fine. But the CCID specification does not provide any documentation or specification for these services.

A documentation is needed so that these services can be implemented in a "class" CCID driver.

Updating the CCID specification may be a difficult task. So I propose to host the documentation in the PC/SC workgroup. I do not ask to add the documentation in an existing document, just to host the documentation in a central place.

One easy solution is to host the CCID level programing manual of readers implementing the solutions we described above.

http://musclecard.com/ is gone (for now)

The domain name musclecard.com has expired. The web site is now a domain parking web site.

Effects

  • The mailing list muscle@lists.musclecard.com is no more working
  • The web site http://musclecard.com/ is unavailable. But the same web site http://linuxnet.com/ is still working

I tried to contact David Corcoran, original author of pcsc-lite and maintainer of the web site. But as expected some of his emails are no more valid. David was not very active on the list since some time now.

New list

I created a new list on the pcsclite project on alioth: pcsclite-muscle

Conclusion


If the domain musclecard.com does not come back we will have to migrate to the new list.
I will keep you informed.

[update]

Oct 16th, 2011

The domain is now back online. It looks like the auto-renew failed due to an old credit card. David Corcoran renewed it for 3 more years. Thanks David!

New version of libccid: 1.4.5

I just released a new version of libccid.

Changelog

1.4.5 - 11 October 2011, Ludovic Rousseau

  • Add support of Alcor Micro AU9540, Ubisys 13.56MHz RFID (CCID),
    BIFIT USB-Token iBank2key, BIFIT iBank2Key, Gemalto Ezio Shield
    PinPad reader, Gemalto SA .NET Dual, Precise Sense MC reader (with
    fingerprint), SDS DOMINO-Key TWIN Pro
  • Add support of bPPDUSupport and FEATURE_CCID_ESC_COMMAND
  • SCARD_ATTR_VENDOR_NAME and SCARD_ATTR_VENDOR_IFD_VERSION are not
    the vendor name and version of the driver but of the IFD:
    InterFace Device i.e. the smart card reader. We then return the
    USB iManufacturer string as SCARD_ATTR_VENDOR_NAME and USB
    bcdDevice as SCARD_ATTR_VENDOR_IFD_VERSION
  • reduce binary size bu removing unused features from simclist
  • Fix some warnings reported bu Coverity

PC/SC workgroup, November 2011 meeting

2 times a year the PC/SC workgroup is having a meeting.

When and Where?

The next meeting is planned on November 15th 2011 during the "Cartes & Identification" international event in Paris, France.

Who?

The members of the PC/SC workgoup are mainly smart card and reader manufacturers.

Core Members:

  • Gemalto
  • Oracle

Associate Members:

  • Advanced Card Systems
  • Athena Smartcard Solutions
  • C3PO S.A.
  • Cherry /ZF Electronics GmbH
  • HID Global
  • Infineon
  • Kobil Systems GmbH
  • NXP Semiconductors
  • O2Micro, Inc.
  • Realtek Semiconductor Corp.
  • Sagem Monetel GmbH
  • SCM Microsystems
  • Siemens
  • Todos
  • Toshiba
  • Xiring

One particularly missing member is Microsoft. Microsoft was a core member for a long time but has now disappeared from the PCSC workgoup list.

Me

Since 1 year I am an invited member of the PC/SC workgroup as a Free Software member and author of pcsc-lite and libccid. In practice I am (just) on one of the PC/SC workgroup mailing list. This list is very quiet since nearly everything is discussed and resolved during the 2 meetings each year.

You

If you are not a member of the PC/SC workgroup you can't change the standard. But you may have good ideas for a new and missing feature.
For example the FEATURE_GET_TLV_PROPERTIES service is something that was added in March 2010 after a proposal I made with the help of Gemalto. So an evolution of the standard is possible.

If, as an PC/SC application author, you think something is missing in the PC/SC standard just tell me. I will try to propose it for inclusion.

Conclusion

Please share your good ideas about the evolution of PC/SC.

FEATURE_CCID_ESC_COMMAND

Since revision 5991 my CCID driver does support FEATURE_CCID_ESC_COMMAND and bPPDUSupport.

These two services have been introduced in PC/SC v2 part 10 version 2.02.07 March 2010 and 2.02.08 April 2010.

FEATURE_CCID_ESC_COMMAND

This feature can be used to retrieve the control code to send a CCID escape command (PC_to_RDR_Escape) to the reader using SCardControl().

The value is returned by the CM_IOCTL_GET_FEATURE_REQUEST command. This will return a TLV data stream. The dwControlCode to use is the value corresponding to the tag FEATURE_CCID_ESC_COMMAND (0x13).

Before this mechanism it was possible to use the value IOCTL_SMARTCARD_VENDOR_IFD_EXCHANGE but this value is not specified/documented in any official document (AFAIK).

Using FEATURE_CCID_ESC_COMMAND is now portable (everywhere the PC/SC drivers implement it).

bPPDUSupport

The SCardControl() function is quiet limited with the Microsoft CCID driver on Windows. So some smart card reader manufacturers use SCardTransmit() to send commands to the reader (instead of the card).

This mechanism is fragile since the reader must interpret the command and determine if the command if for itself or for the card.

The PC/SC workgroup documented a way to know how the driver is expecting to receive commands for itself.

bPPDUSupport is a tag in the TLV data stream returned by FEATURE_GET_TLV_PROPERTIES. The value is coded as:
  • Bit 0: If set to 1, PPDU is supported over SCardControl() using FEATURE_CCID_ESC_COMMAND
  • Bit 1: If set to 1, PPDU is supported over SCardTransmit()

Implementation in my CCID driver

By default, for security reasons, sending an arbitrary PC_to_RDR_Escape command is forbidden. This can be configured using the ifdDriverOptions setting in the driver Info.plist file.


[...]
    <key>ifdDriverOptions</key>
    <string>0x0000</string>

    <!-- Possible values for ifdDriverOptions
    1: DRIVER_OPTION_CCID_EXCHANGE_AUTHORIZED
        the CCID Exchange command is allowed. You can use it through
        SCardControl(hCard, IOCTL_SMARTCARD_VENDOR_IFD_EXCHANGE, ...)

[...]
If the bit 0 of ifdDriverOptions is set then the driver will allow the use of IOCTL_SMARTCARD_VENDOR_IFD_EXCHANGE and now also the value associated to FEATURE_CCID_ESC_COMMAND

The driver will always report bPPDUSupport. By default the value is 0x00. But if If the bit 0 of ifdDriverOptions is set then the value of bPPDUSupport will be 0x01 indicating the support of FEATURE_CCID_ESC_COMMAND using dwControlCode and SCardControl().

Sample code

The use of these features may be hard to understand. So a small example can help.

In Python

#! /usr/bin/env python

"""
#   FEATURE_CCID_ESC_COMMAND.py: Unitary test for FEATURE_CCID_ESC_COMMAND
#   Copyright (C) 2011  Ludovic Rousseau
"""

#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 3 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License along
#   with this program; if not, see <http://www.gnu.org/licenses/>.

from smartcard.System import readers
from smartcard.pcsc.PCSCPart10 import (SCARD_SHARE_DIRECT,
    SCARD_LEAVE_CARD, FEATURE_CCID_ESC_COMMAND, getFeatureRequest, hasFeature)


def main():
    """ main """
    card_connection = readers()[0].createConnection()
    card_connection.connect(mode=SCARD_SHARE_DIRECT,
        disposition=SCARD_LEAVE_CARD)

    feature_list = getFeatureRequest(card_connection)

    ccid_esc_command = hasFeature(feature_list, FEATURE_CCID_ESC_COMMAND)
    if ccid_esc_command is None:
        raise Exception("The reader does not support FEATURE_CCID_ESC_COMMAND")

    # proprietary commands for Xiring readers
    version = [ord(c) for c in "VERSION"]
    res = card_connection.control(ccid_esc_command, version)
    print res
    print ''.join([chr(x) for x in res])

    serial = [ord(c) for c in "GET_SN"]
    res = card_connection.control(ccid_esc_command, serial)
    print res
    print ''.join([chr(x) for x in res])

if __name__ == "__main__":
    main()

In C

The C language is much more verbose than Python. I added support of FEATURE_CCID_ESC_COMMAND and bPPDUSupport in scardcontrol.c example code provided with the CCID driver.

The idea is the same as in Python:
  1. get the control code to use using FEATURE_CCID_ESC_COMMAND
  2. use SCardControl() to send a command
The C source code is 817 lines long. It is available online.

Comments

PC/SC now documents a way to send arbitrary proprietary commands to a reader. We now have two questions:

What command should you send?

You should know what you are doing and use the smart card reader user manual. So the command you want to use is documented, but maybe the documentation is not public. In general proprietary commands are not publicly documented.

How to know what reader exactly you are using?

I do not have an answer to this question. Using the PC/SC reader name is fragile. See a previous blog article What is in a PC/SC reader name? The reader name can change over time like with "Gemplus" becoming "Gemalto".

Maybe PC/SC must provide a new mechanism to report the USB VendorID and ProductID so that an application can be sure a specific reader is used.

Conclusion

Having to use proprietary commands is a sign of failure from the PC/SC workgroup. A service is needed but missing from the PC/SC standard. It has then been implemented using a proprietary mechanism (not documented, not portable, not interoperable).

It is a failure because the application is now linked to a particular smart card reader model.

pcsclite subversion revision 6000

Celebration

I just committed revision 6000 in the pcsclite project :-)

History

Previous notable revisions were:
5000 in 16 June 2010
4000 in 5 October 2007
3000 in 14 June 2008
2000 in 14 April 2006
1000 in 30 June 2004

Maybe you have noted that revision 4000 is dated before revision 3000. I think this is because of the conversion from CVS to SVN. The change occurred between revision 3502 (10 May 2009) and 3503 (2 Jul 2001).

The commit message for 3503 is: "Standard project directories initialized by cvs2svn."

My name in Mac OS X Lion?

I asked myself the question: how many times is my name present in a standard Mac OS X Lion installation?

Command line: pcscd

$ pcscd -v
PCSC Framework version 1.4.0.
Copyright (C) 1999-2002 by David Corcoran <corcoran@linuxnet.com>.
Copyright (C) 2001-2005 by Ludovic Rousseau <ludovic.rousseau@free.fr>.
Copyright (C) 2003-2004 by Damien Sauveron <sauveron@labri.fr>.
Portions Copyright (C) 2000-2007 by Apple Inc.
Report bugs to <sclinux@linuxnet.com>.

Manpage: pcscd

$ man pcscd
[...]
AUTHORS
       David Corcoran <corcoran@identityalliance.com> and Ludovic Rousseau
       <ludovic.rousseau@free.fr>

Configuration file: CCID driver Info.plist

$ grep -A 1 ifdManufacturerString /usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist
	<key>ifdManufacturerString</key>
	<string>Ludovic Rousseau (ludovic.rousseau@free.fr)</string>

Header files: PCSC framework

A standard Lion installation does not contain the header files used to develop PC/SC applications. You need to install the Xcode package for that.

After installing Xcode (available for free from the App Store) you get:
$ cd /System/Library/Frameworks/PCSC.framework/Headers
$ grep rousseau *
pcsclite.h: *  Ludovic Rousseau <ludovic.rousseau@free.fr>
pcsclite.h: * $Id: pcsclite.h 123 2010-03-27 10:50:42Z ludovic.rousseau@gmail.com $
winscard.h: *  Ludovic Rousseau <ludovic.rousseau@free.fr>
winscard.h: * $Id: winscard.h 123 2010-03-27 10:50:42Z ludovic.rousseau@gmail.com $
wintypes.h: * $Id: wintypes.h 123 2010-03-27 10:50:42Z ludovic.rousseau@gmail.com $

My name is in 3 files: pcsclite.h, winscard.h and wintypes.h. The lines with $Id: ... $ are automatically changed by subversion when a new commit is made. If someone make a new commit to these files my name will be replace. But as I wrote in Mac OS X Lion and smart cards status I am nearly the only one to work on pcsc-lite on Mac OS X.

Ask nicely: CCID driver

My name is also present in the binary of the CCID driver.
$ cd /usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/MacOS
$ strings libccid.dylib | grep Rousseau
Ludovic Rousseau

This is because the CCID driver implements the SCARD_ATTR_VENDOR_NAME attribute for SCardGetAttrib(). You can extract the information using a simple getAttrib.py Python program:
#! /usr/bin/env python

from smartcard.System import readers
from smartcard.scard import SCARD_ATTR_VENDOR_NAME

card_connection = readers()[0].createConnection()
card_connection.connect()

name = card_connection.getAttrib(SCARD_ATTR_VENDOR_NAME)
print ''.join([chr(char) for char in name])

The execution gives:
$ ./getAttrib.py 
Ludovic Rousseau

You need to use at least revision 541 of the pyscard project. This version is not yet available in a stable pyscard release.

Other sources

My name is famous in France. Wikipedia lists 50 different Rousseau and I am not (yet) in the list.

Mac OS X provides a dictionary. Using the French Academy Dictionary we have:

From the Oxford Dictionary of English we have:

Conclusion

My full name is present 4 times in a default Mac OS X Lion installation. The number goes up to 9 on a developer system. What about your name?

Yes, this article is useless. Maybe it is a sign I am mad? Ha ha ha!

My blog within wordle

I like the pictures generated by wordle so I used it with my blog as input (click on the image to get a bigger version).


Since I recently blogged about Lion the word Apple is nearly the biggest one.

This is a blog article about my blog. It is a kind of meta-blog.

Mac OS X Lion and tokend

This article is not very technical. This is part of my view of the tokend situation.

It follows the two previous articles about Lion: Mac OS X Lion and smart cards status and Mac OS X Lion and OpenSSL.

Tokend

A tokend is a piece of software used to bridge a cryptographic device (like a smart card) and the CDSA (Common Data Security Architecture) architecture. CDSA and tokend are now deprecated by Apple: [Fed-Talk] [Announcement] OS X Lion - Smart Card Services (emphasis is mine):
" The foundational components for Smart Card Services in OS X have been based on an architecture (CDSA) that has been deprecated in the released version of OS X Lion.

This indicates CDSA's use and support has stopped and will be removed completely in a future release of OS X.

Any solution for OS X still leveraging the deprecated CDSA can continue to function for now, but the CDSA infrastructure would no longer receive enhancements or bug fixes.

CDSA will no longer ship in future releases of OS X. "
This email is written by Shawn Geddis, Security Consulting Engineer. Shawn works at Apple.

Tokend from Apple

So in Mac OS X 10.7 Lion no tokend are provided any more. The directory /System/Library/Security/tokend/ is now empty in a Lion fresh installation.

Tokend from other sources

In the same email Shawn gives some options to replace the tokend no more provided by Apple:

  • Open Source Options (from "Apple")

    The source code of the tokend provided by Apple (in Tiger, Leopard and Snow Leopard) were already available as Free Software from the Smart Card Services project. It is now the official source to get them.
  • Open Source Options (from the rest of the world)

    The OpenSC project provides a tokend to be used with OpenSC. The tokend in included in the installer for Mac OS X.
  • Commercial Options

    Commercial tokend from third parties should still be available and usable on Lion.

Since installing a tokend from source code is not a trivial task "Apple" provides an installer. It is not really Apple that provides the installer but the Smart Card services project. So bugs should be reported to the project bug tracker.

Note that these tokend are (still) signed by Apple:
$ codesign --display --verbose=4 /System/Library/Security/tokend/CACNG.tokend
Executable=/System/Library/Security/tokend/CACNG.tokend/Contents/MacOS/CACNG
Identifier=com.apple.tokend.cacng
Format=bundle with Mach-O universal (i386 ppc7400 x86_64)
CodeDirectory v=20100 size=1351 flags=0x0(none) hashes=61+3 location=embedded
Hash type=sha1 size=20
CDHash=b41a98c192eb5196353926288ff208b5d2415a3e
Signature size=4064
Authority=Software Signing
Authority=Apple Code Signing Certification Authority
Authority=Apple Root CA
Info.plist entries=9
Sealed Resources rules=10 files=6
Internal requirements count=1 size=148

Smart Card Services project

This project has been started by Shawn Geddis in January 2009. The members of the project are listed in this page.

I was invited to join the team to work on the pcsc-lite and CCID parts. These parts are still provided by Apple in Lion.

I am not an Apple employee so know no Apple secret plans. For example I do not know why Lion provides the CCID driver version 1.3.11 and not a more recent version (the latest is 1.4.4). See Mac OS X Lion and smart cards status for more information.

You can see from the project bug tracker that a lot of bugs are open and some are quiet old now (like this one requesting help about a tokend for Mac OS X 10.4 Tiger on a G4 processor). It is hard to get people working for free on a project. So if Apple does not invest some manpower into fixing bugs and answering bug reports the bugs will not be fixed.

After tokend

I guess Apple is working on something to replace tokend when CDSA will be removed. But I have no idea what it will be.

Conclusion

My interpretation is that Apple is doing with tokend what they also do with Java and Flash: they let other people/companies provide and maintain the software.

[update] Add a "Open Source Options (from the rest of the world)"