Important!

Blog moved to https://blog.apdu.fr/

I moved my blog from https://ludovicrousseau.blogspot.com/ to https://blog.apdu.fr/ . Why? I wanted to move away from Blogger (owne...

Friday, October 28, 2011

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.

Thursday, October 13, 2011

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!

Tuesday, October 11, 2011

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

Sunday, October 9, 2011

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.

Wednesday, October 5, 2011

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."