pcsclite¶
- Author
Russell Stuart
Abstract
The pcsclite
package communicates with smart cards.
Introduction¶
This package enables Python programs to communicate with smart cards (this includes GSM SIM’s and 3G USIM’s) via a suitable reader. It is a wrapper for the C libpcsclite library, making the functions and definitions defined by libpcsclite available to Python programmers. It is a full and direct an implementation, meaning if there is a function or constant defined in libpcsclite then the same constant will appear in this module with a similar name. Anybody who knows libpcsclite should find themselves in familiar territory, and libpcsclite’s documentation applies to this module as well. See Musclecard.com, the home page for libpcsclite, for a copy of the libpcsclite library and its documentation.
To use this module you must have the C libpcsclite library installed and the pcsc-lite daemon must be running. Libpcsclite talks to the daemon, it is the daemon that communicates with the card.
Note
This module comes in Python 2 and Python 3 verions. They are identical
with one major exception: where Python 3 uses bytes
, Python 2 uses
str
. This documentation is written from the Python 3 perspective,
so where it says bytes
for Python 2 you should substitude
str
. The Python modules supplied work with both Python 2 and
Python 3.
Module Contents¶
The two major classes in the module are Context
and Card
.
These are the ones you need to focus on. There are also several classes which
serve purely as name spaces for various constants defined pcsclite
C
library. Their names are spelt using all capitals. All classes and all their
members have __doc__
strings; even the integer and string members
have them which is somewhat unusual.
Constants defined at directly in the module are:
-
INFINITE
¶ Passing this value to
Context.get_status_change()
for the timeout causes it to wait indefinitely.
-
MAX_ATR_SIZE
¶ The maximum length of an attribute string handled by the functions
Card.get_attrib()
andCard.set_attrib()
.
-
MAX_BUFFER_SIZE_EXTENDED
¶ The maximum size of bytes that can be sent and received by
Card.transmit()
.
-
MAX_READERNAME
¶ The maximum length of a card reader name returned by
Context.list_readers()
.
Context object¶
Context objects encapsulate a connection to the pcsc daemon. You need only one
of these. Create it by calling the constructor. Deleting it using
del
will close the connection.
-
class
Context
([scope])¶ The constructor creates a new connection to the pcsc daemon. The optional scope parameter is a number, typically one of the constants defined in the
SCOPE
object. It defaults toSCOPE.SYSTEM
. ThrowsPcscliteException
if the connection to the daemon can not be created.
-
Context.
hContext
¶ The C libpcsclite context handle, which is an integer. Read only.
-
Context.
scope
¶ The scope used to create the connection to the daemon. This is a member of the
SCOPE
object, and as such has a__doc__
string describing the scope.
-
Context.
cancel
()¶ Cancels all pending blocking requests on the
Context.get_status_change()
function. RaisesPcscliteException
on failure.
-
Context.
connect
(readername[, sharemode, protocol])¶ Establish a connection to the card reader. The first connection will power up and perform a reset on the card. The parameter readername is a
string
containing the name of the card reader to connect to. Typically you will obtain it by callinglist_readers()
. The parameter sharemode says whether others can use this reader. It is anint
, typically one of the constants defined in theSHARE
object. If omittedSHARE.SHARED
is used. The parameter protocol specifies the protocol used to talk to the reader. It is anint
, typically one of the constants defined in thePROTOCOL
object. If omittedPROTOCOL.ANY
is used. A newCard
object is returned. The protocol field in the returned object is set to the protocol established for the session. RaisesPcscliteException
on failure.
-
Context.
get_status_change
(readers[, timeout])¶ Wait for a card reader to change status, or until the timeout (given in seconds) expires. If the timeout is
INFINITY
or is omitted the method waits indefinitely. The parameter readers is a sequence of objects that each must contain the fields readername and currentstate. The field readername is astring
containing the name of a reader you want to wait for a state change on, and the field currentstate is the current state (a bitwise or of members of theSTATE
object) of that reader. The classCardStatus
is a convenient way of creating a suitable object. The function returns when one of the readers states is different to that passed in currentstate. The return value is a new list ofCardStatus
objects, one for each readername passed. In addition to the original readername and currentstate fields these objects have eventstate and answertoreset fields. The eventstate contains the new state of the reader, and answertoreset field contains its answer to reset string sent by the card. If readers isNone
the function returns as soon as a card reader becomes available. RaisesPcscliteException
on failure.
-
Context.
is_valid_context
()¶ Returns
True
if the smart card context handle is still valid. RaisesPcscliteException
otherwise.
-
Context.
list_readers
([groups])¶ Returns a list of currently the names available readers the daemon is connected to. If the list groups is passed then only readers in those reader group names it contains are returned. Raises
PcscliteException
on failure.
-
Context.
list_reader_groups
()¶ Returns a list of currently available reader group names on the system. A reader group name is a
string
. RaisesPcscliteException
on failure.
Card object¶
Card objects encapsulate a connection to a particular card. They are created
by calling Context.connect()
. Deleting a Card object using
del
will close the connection to the card.
-
Card.
hCard
¶ The C libpcsclite card handle, which is an integer. Read only.
-
Card.
protocol
¶ The protocol established for the session. This is a member of the
PROTOCOL
object, and as such as a__doc__
string describing the protocol. Read only.
-
Card.
readername
¶ The readername passed to
Context.connect()
, which is astring
. Read only.
The share mode used to create the connection. This is a member of the
SHARE
object, and as such as a__doc__
string describing the share mode. Read only.
-
Card.
begin_transaction
()¶ Establish a temporary exclusive access mode to the card for doing a series of commands or a transaction. Raises
PcscliteException
on failure.
-
Card.
control
(code, data)¶ Sends a command directly to the reader. This is useful for creating client side reader drivers for functions like PIN pads, biometrics, or other extensions to the normal smart card reader that are not normally handled by
pcsclite
. Both code and data arebytes
containing the raw data to be sent to the card. Returns the reply from the card as a bytes. RaisesPcscliteException
on failure.
-
Card.
disconnect
([disposition])¶ Disconnect from the card. The parameter disposition describes what state the card is to be left in on disconnection. It is an
int
, and is typically one of the constants defined by theDISPOSITION
object. If not passedDISPOSITION.LEAVE_CARD
is used. RaisesPcscliteException
on failure.
-
Card.
end_transaction
([disposition])¶ End a transaction previously begun with
Card.begin_transaction()
. The parameter disposition describes what state the card is to be left in on disconnection. It is anint
, and is typically one of the constants defined by theDISPOSITION
object. If not passedDISPOSITION.LEAVE_CARD
is used. RaisesPcscliteException
on failure.
-
Card.
get_attrib
(attrib)¶ Get an attribute. The current value of the attribute is returned. It is a
string
. The parameter attrib is anint
naming the attribute to get. It is typically one of constants defined by theATTR
object. RaisesPcscliteException
on failure.
-
Card.
reconnect
([sharemode, protocol, disposition])¶ Reconnect to a card, typically done when call to transmit() raises a
PcscliteException
withERROR.RESET_CARD
. This is caused by another application resetting the card while you are using it. This is function effectively does aCard.disconnect(disposition)()
followed byContext.connect(oldreadername, sharemode, protocol)()
. The sharemode and protocol default to what was last passed toContext.connect()
. The parameter disposition defaults toDISPOSITION.RESET_CARD
if not supplied. RaisesPcscliteException
on failure.
-
Card.
set_attrib
(attrib, value)¶ Set an attribute to the
string
value. The parameter attrib is anint
naming the attribute to set. It is typically one constants defined by theATTR
object. RaisesPcscliteException
on failure.
-
Card.
status
()¶ Get the current status of the reader. Returns a
CardStatus
object that has these members:Field name
Usage
readername
The name of the reader, a
string
.status
One of the constants defined by the
STATUS
object.protocol
One of the constants defined by the
PROTOCOL
object.answertoreset
The card’s reply when it was reset, a
string
.Raises
PcscliteException
on failure.
-
Card.
transmit
(data[, protocol])¶ Sends the APDU (Application Protocol Data Unit) contained in the
bytes
data to the smart card. The protocol parameter specifies the protocol used to send the data. It is anint
, typically one of the the constants defined by thePROTOCOL
object. If not specified the protocol established byContext.connect()
is used. The return value is the response from card, which is a a subclass ofbytes
. The bytes are the response, but the object has one additional member called protocol which is the protocol used to send the response. It is one of the constants defined by thePROTOCOL
object. RaisesPcscliteException
on failure.
CardStatus object¶
Instances of this class describe the status of a smart card. There is nothing special about instances of this class, any other object with the same fields will work as well. Not all fields are required and they aren’t always present, it depends on how the object is being used.
-
class
CardStatus
([readername, currentstate])¶ If present, the parameters readername and currentstate are used to initialise the fields of the same name.
-
CardStatus.
answertoreset
¶ The smart card’s answer when it was reset. A
bytes
. This field is set byContext.get_status_change()
.
-
CardStatus.
currentstate
¶ The current state of the smart card reader. This is a bitwise or or the constants defined in the
STATE
object.
-
CardStatus.
eventstate
¶ The new state of the smart card reader. This is a bitwise or or the constants defined in the
STATE
object. This field is set byContext.get_status_change()
.
-
CardStatus.
protocol
¶ The protocol used by the smart card when it was reset. This will be one of the constants defined by the
PROTOCOL
object. This field is set byContext.get_status_change()
.
-
CardStatus.
readername
¶ The name of a smart card reader. A
string
.
-
CardStatus.
status
¶ The current status of the smart card. This will be one of the constants defined by the
STATUS
object. This field is set byContext.get_status_change()
.
PcscliteException object¶
The exception is a subclass of StandardError
. It is raised by all
methods defined in pcsclite
when an error occurs. When raised by
pcsclite
it has one additional field:
Objects defining constants¶
The C libpcsclite library defines many constants which are exposed via the
objects described here. All fields of all objects here are read only. They
also all have a __doc__
string describing what the are used for.
-
ATTR
¶ This object holds constants that describe card attributes libpcsclite supports. They are passed to
Card.set_attrib()
andCard.get_attrib()
. Members are:Constant Name
Description
ASYNC_PROTOCOL_TYPES
ATR_STRING
CHANNEL_ID
CHARACTERISTICS
CURRENT_BWT
CURRENT_CLK
CURRENT_CWT
CURRENT_D
CURRENT_EBC_ENCODING
CURRENT_F
CURRENT_IFSC
CURRENT_IFSD
CURRENT_IO_STATE
CURRENT_N
CURRENT_PROTOCOL_TYPE
CURRENT_W
DEFAULT_CLK
DEFAULT_DATA_RATE
DEVICE_FRIENDLY_NAME_A
DEVICE_FRIENDLY_NAME
DEVICE_FRIENDLY_NAME_W
DEVICE_IN_USE
DEVICE_SYSTEM_NAME_A
DEVICE_SYSTEM_NAME
DEVICE_SYSTEM_NAME_W
DEVICE_UNIT
ESC_AUTHREQUEST
ESC_CANCEL
ESC_RESET
EXTENDED_BWT
ICC_INTERFACE_STATUS
ICC_PRESENCE
ICC_TYPE_PER_ATR
MAX_CLK
MAX_DATA_RATE
MAX_IFSD
MAXINPUT
POWER_MGMT_SUPPORT
SUPRESS_T1_IFS_REQUEST
SYNC_PROTOCOL_TYPES
USER_AUTH_INPUT_DEVICE
USER_TO_CARD_AUTH_DEVICE
VENDOR_IFD_SERIAL_NO
VENDOR_IFD_TYPE
VENDOR_IFD_VERSION
VENDOR_NAME
-
ATTRCLASS
¶ The object holds constants that describe the classttribute defined in
ATTR
. Members are:Constant Name
Description
COMMUNICATIONS
Communication definitions
ICC_STATE
ICC State specific definitions
IFD_PROTOCOL
Interface Device Protocol options
MECHANICAL
Mechanical characteristic definitions
POWER_MGMT
Power Management definitions
Protocol definitions
SECURITY
Security Assurance definitions
SYSTEM
System-specific definitions
VENDOR_DEFINED
Vendor specific definitions
VENDOR_INFO
Vendor information definitions
-
DISPOSITION
¶ This object holds constants that describe what to do with a card when the connection to it is closed. They are passed to
Card.disconnect()
,Card.end_transaction()
andCard.reconnect()
. Members are:Constant Name
Description
EJECT_CARD
Eject Card
LEAVE_CARD
Do nothing
RESET_CARD
Reset Card
UNPOWER_CARD
Power down
-
ERROR
¶ This object holds the error codes returned by the C libpcsclite library. The scard_error field of
PcscliteException
will contain one of these. Members are:Constant Name
Description
SUCCESS
No error was encountered
BAD_SEEK
There was an error trying to set the smart card file object pointer
CANCELLED_BY_USER
The user pressed “Cancel” on a Smart Card Selection Dialog
CANCELLED
The action was cancelled by an SCardCancel request
CANT_DISPOSE
The system could not dispose of the media in the requested manner
CARD_NOT_AUTHENTICATED
No PIN was presented to the smart card
CARD_UNSUPPORTED
The smart card does not meet minimal requirements for support
CERTIFICATE_UNAVAILABLE
The requested certificate could not be obtained
CHV_BLOCKED
The card cannot be accessed because the maximum number of PIN entry attempts has been reached
COMM_DATA_LOST
A communications error with the smart card has been detected. Retry the operation
COMM_ERROR
An internal communications error has been detected
DIR_NOT_FOUND
The identified directory does not exist in the smart card
DUPLICATE_READER
The reader driver did not produce a unique reader name
EOF
The end of the smart card file has been reached
FILE_NOT_FOUND
The identified file does not exist in the smart card
ICC_CREATEORDER
The requested order of object creation is not supported
ICC_INSTALLATION
No primary provider can be found for the smart card
INSERTED_CARD
Not Documented in PC/SC Lite
INSUFFICIENT_BUFFER
The data buffer to receive returned data is too small for the returned data
INTERNAL_ERROR
An internal consistency check failed
INVALID_ATR
An ATR obtained from the registry is not a valid ATR string
INVALID_CHV
The supplied PIN is incorrect
INVALID_HANDLE
The supplied handle was invalid
INVALID_PARAMETER
One or more of the supplied parameters could not be properly interpreted
INVALID_TARGET
Registry startup information is missing or invalid
INVALID_VALUE
One or more of the supplied parameters values could not be properly interpreted
NO_ACCESS
Access is denied to this file
NO_DIR
The supplied path does not represent a smart card directory
NO_FILE
The supplied path does not represent a smart card file
NO_KEY_CONTAINER
The requested key container does not exist on the smart card
NO_MEMORY
Not enough memory available to complete this command
NO_READERS_AVAILABLE
Cannot find a smart card reader
NO_SERVICE
The Smart card resource manager is not running
NO_SMARTCARD
The operation requires a Smart Card, but no Smart Card is currently in the device
NO_SUCH_CERTIFICATE
The requested certificate does not exist
NOT_READY
The reader or smart card is not ready to accept commands
NOT_TRANSACTED
An attempt was made to end a non-existent transaction
PCI_TOO_SMALL
The PCI Receive buffer was too small
PROTO_MISMATCH
The requested protocols are incompatible with the protocol currently in use with the smart card
READER_UNAVAILABLE
The specified reader is not currently available for use
READER_UNSUPPORTED
The reader driver does not meet minimal requirements for support
REMOVED_CARD
The smart card has been removed, so further communication is not possible
RESET_CARD
The smart card has been reset, so any shared state information is invalid
SECURITY_VIOLATION
Access was denied because of a security violation
SERVER_TOO_BUSY
The Smart Card Resource Manager is too busy to complete this operation
SERVICE_STOPPED
The Smart card resource manager has shut down
SHARING_VIOLATION
The smart card cannot be accessed because of other connections outstanding
SHUTDOWN
The operation has been aborted to allow the server application to exit
SYSTEM_CANCELLED
The action was cancelled by the system, presumably to log off or shut down
TIMEOUT
The user-specified timeout value has expired
UNEXPECTED
An unexpected card error has occurred
UNKNOWN_CARD
The specified smart card name is not recognized
UNKNOWN_ERROR
An internal error has been detected, but the source is unknown
UNKNOWN_READER
The specified reader name is not recognized
UNKNOWN_RES_MNG
An unrecognized error code was returned from a layered component
UNPOWERED_CARD
Power has been removed from the smart card, so that further communication is not possible
UNRESPONSIVE_CARD
The smart card is not responding to a reset
UNSUPPORTED_CARD
The reader cannot communicate with the card, due to ATR string configuration conflicts
UNSUPPORTED_FEATURE
Feature not supported
WAITED_TOO_LONG
An internal consistency timer has expired
WRITE_TOO_MANY
The smart card does not have enough memory to store the information
WRONG_CHV
The card cannot be accessed because the wrong PIN was presented
-
FEATURES
¶ This object defines TeleTrust Class 2 reader tags. Members are:
Constant Name
Description
ABORT
SCM Proposal
CCID_ESC_COMMAND
CCID control command
EXECUTE_PACE
Supports PACE protocol
GET_KEY
OMNIKEY Proposal
GET_KEY_PRESSED
OMNIKEY Proposal
GET_TLV_PROPERTIES
TLV version of properties
IFD_DISPLAY_PROPERTIES
Gemplus Proposal
IFD_PIN_PROPERTIES
Gemplus Proposal
MCT_READER_DIRECT
KOBIL Proposal
MCT_UNIVERSAL
KOBIL Proposal
MODIFY_PIN_DIRECT
USB CCID PIN Modify
MODIFY_PIN_DIRECT_APP_ID
USB CCID PIN Modify
MODIFY_PIN_FINISH
OMNIKEY Proposal
MODIFY_PIN_START
OMNIKEY Proposal
SET_SPE_MESSAGE
Message displayed during SPE
VERIFY_PIN_DIRECT
USB CCID PIN Verify
VERIFY_PIN_DIRECT_APP_ID
USB CCID PIN Verify
VERIFY_PIN_FINISH
OMNIKEY Proposal
VERIFY_PIN_START
OMNIKEY Proposal
WRITE_DISPLAY
Write UTF8 message to display
-
FEATURE_PROPS
¶ Information returned by
FEATURE
.GET_TLV_PROPERTIESConstant Name
Description
EntryValidationCondition
When PIN entry is considered complete
FirmwareID
UTF8 Reader Firmware String
LcdLayout
Display characteristics
LcdMaxCharacters
Max chars on a single line.
LcdMaxLines
Lines on the display
MaxPINSize
Maximum PIN size accepted by the reader
MinPINSize
Minimum PIN size accepted by the reader
PPDUSupport
How PPDU is implemented
TimeOut2
Timeout in secs after 1st key stroke
-
PROTOCOL
¶ This object holds constants that describe the protocols that can be used to communicate with a smart card. These int’s form a bit map. Members are:
Constant Name
Description
ANY
Protocol T=0 or T=1
RAW
Protocol RAW
T0
Protocol T=0
T15
Protocol T=15
T1
Protocol T=1
UNSET
Protocol not set
-
SCOPE
¶ This object holds constants that define what scope a connection to the libpcsclite daemon. They are passed to the constructor of
Context
. Members are:Constant Name
Description
SYSTEM
scope in system
TERMINAL
scope in terminal
USER
scope in user space
-
SHARE
¶ This object holds constants that describe who else may use a card reader while this context is attached to it. They are passed to
Context.connect()
andCard.reconnect()
. Members are:Constant Name
Description
DIRECT
Direct control of reader, no card required
EXCLUSIVE
No others may share reader
SHARED
Reader may be shared with others
-
STATE
¶ This object holds constants that describe what the current state of a card reader and the card in it. The constants form a bit map, so actual values may be a logical or’ing of the ones shown here. The constants are passed to and returned by
Context.get_status_change()
. Members are:Constant Name
Description
ATRMATCH
ATR matches card
CHANGED
State has changed
EMPTY
Card removed
EXCLUSIVE
Exclusive Mode
IGNORE
Ignore this reader
INUSE
Shared Mode
MUTE
Unresponsive card
PRESENT
Card inserted
UNAVAILABLE
State unavailable
UNAWARE
App wants status
UNKNOWN
Reader unknown
UNPOWERED
Unpowered card
-
STATUS
¶ This object holds constants that describe what a card’s current status is. The are returned by
Card.status()
. Members are:Constant Name
Description
ABSENT
Card is absent
NEGOTIABLE
Card is ready for PTS
POWERED
Card is powered
PRESENT
Card is present
SPECIFIC
Card has been sent PTS
SWALLOWED
Card not powered
UNKNOWN
Card is in an unknown state
Example¶
This example selects the MF, illustrating how to use the library:
>>> import pcsclite, binascii
>>> context = pcsclite.Context()
>>> readers = context.list_readers()
>>> readers
('OmniKey CardMan 6121 00 00',)
>>> card = context.connect(readers[0])
>>> card.reconnect()
>>> response = card.transmit(b'\x00\xa4\x00\x04\x02\x3f\x00')
>>> binascii.b2a_hex(response)
b'615a'
>>> data = card.transmit(b'\x00\xc0\x00\x00' + response[-1])
>>> binascii.b2a_hex(data[-10:])
b'018181040001dbcc9000'
>>> data.protocol
0L
>>> data.protocol.__doc__
'Protocol is not set'
>>> del card; del context
Point of interest are:
context = pcsclite.Context()
This object is the connection to the pcsc daemon. You need one of these. If this or any other call to libpcsclite fails a
PcscliteException
is raised. You use this object to do things to cards: connect to them, list them, wait for one to be available and so on.readers = context.list_readers()
This is a list of smart card readers the daemon knows about.
card = context.connect(readers[0])
The call
Context.connect()
creates a connection to a particular card. It is encapsulated in the returnedCard
object.card.reconnect()
The call
Card.reconnect()
resets the card to a known state. Not always required, but good practice.response = card.transmit(b'x00xa4x00x04x02x3fx00')
The
Card.transmit()
method sends an APDU (which is smart card speak for a “command”) to the card and returns the response. There is a standard set of APDU’s defined by the ISO 7816 standard, however most smarts card implement only part of the standard and add extensions. Both the APDU and the response are ASCII strings. The APDU transmitted here works with ISO 7816 cards; it asks the card to send what it knows about the file 3f00. In smart card parlance this is known as “MF”, the root directory of the file system. The GSM version of the same command isb'\xa0\xa4\x00\x00\x02\x3f\x00'
. A smart card always sends back a response to each command and that response is returned byCard.transmit()
. The last two bytes of the response are called the “status words”. Any additional data returned by the command prefixes those status words. The meaning of the status words is defined in ISO 7816-4. The response seen here, 615a, means the call worked and there is 0x5a bytes of data is waiting to be fetched. Since there is only 2 bytes returned there is no additional data.data = card.transmit(b'x00xc0x00x00' + response[-1])
The second call to
Card.transmit()
asks the card to send the waiting data. As before, the last two bytes of the response are the status words. In this case they are 9000 which ISO 7816-4 defines to mean the command was successful. The remaining bytes are the data generated by the previous command. In this case they contain information about the MF. The format of that information is defined in ISO 7816-4.data.protocol
Although the result returned by
Card.transmit()
looks like astring
and indeed is a subclass ofstring
, it contains an extra field called protocol which is the protocol used to send the response. This field is filled in by the smart card reader driver. The protocol constants are defined in the objectPROTOCOL
.data.protocol.__doc__
To find out what protocol
0L
is you could look up thePROTOCOL
object. But if is it a known protocol it will have a__doc__
string. In this case it looks like the pcsc-lite driver hasn’t set the field. Every numerical constant defined by this module has a__doc__
string.del
When the card object is deleted its connection to the card is released. Similarly when a context is deleted (assuming there are no cards holding references to it) the connection to the daemon is closed.
Installation and Configuration¶
To compile you need pcsclite
you need the GNU C tool chain, the Python
development system and libpcsclite. Then its just a case of running make.
To install put the resulting pcsclite.so somewhere in Python’s sys.path
.
There is no configuration required for pcsclite
, but the pcsc-lite
library and daemon may need some tweaking. Refer to its documentation.
When it comes to hardware, http://www.muscelcard.com has a list of smart
card readers that work with pcsc-lite. That said, the world is moving to USB.
The USB protocol used to talk to a smart card readers has been standardised.
It is called CCID. Pcsc-lite supports CCID USB smart card readers out of the
box. No configuration is required. The reader just appears in the
Context.list_readers()
when it plugged into the USB port.
Other sources of Information¶
The main reference for smart card standards are the International Standards Organisation ISO 7816 series, and in particular ISO 7816-4 and ISO 7816-9. Unfortunately these documents are not free. However, there are cut down versions available on the web which are good enough for most purposes. I found this link by googling “7816 standards”: http://www.cardwerk.com/smartcards/smartcard_standard_ISO7816.aspx.
The major application for smart cards is GSM and its successors. The documentation for these cards is published by 3gpp. They are free and available on the web. The original GSM standard is called GSM 11.11. Googling for that string will find it. GSM SIM’s pre-date ISO 7816-4, so with the release of 3G the 3gpp decided to update the GSM SIM to something that followed 7618-4 a little more closely. The end result is called a USIM. 7618-4 cards can contain several directory trees (think C:, D:, etc under Windows), although in 7618 parlance these are trees are called applications. The default tree contains the original GSM application, so GSM 11.11 still applies to USIM’s. USIM’s however contain another application, the 3G one. This is defined in the 3gpp standards TS 31.101 and TS 31.102. Again googling for those strings will find them. The European Telecommunications Standards Institute publishes a lot of the 3gpp standards under their own banner, again for free. The most relevant ETSI standard is TS 102 221.
The canonical book for smart cards is the Smart Card Handbook, by Wolfgang Ranki and Wolfgang Effing. It is probably required reading for someone designing a smart card application, but for the typical user of this library I don’t think covers any useful material that isn’t available in the links above.
One thing that is hard to find on the web is the contents of ISO 7816-9, which covers the smart card security system. The closest you will get to it is documentation from smart card manufacturers describing whatever bit they deem interesting. Collect enough bits and you will have the entire thing.
Finally, shipped with this module are two Python examples. The file
iso7816.py
contains definitions relating to ISO 7816-4, some ISO 7816-9,
GSM and USIM cards. For example, it decodes the response an a SELECT APDU,
documents the GSM and USIM directory trees, and can pretty print most of the
files found in those trees. The program usimtool.py
uses iso7816.py and
this module to manipulate GSM, ISO 7816 and USIM cards. It can search the
entire directory tree, pretty printing files iso7618 knows about, enter and
change pins and so on. Run usimtool.py without any arguments to get a list of
commands it supports. These two files aren’t supported in any way but do serve
as useful examples.
The usimtool.py program¶
This is a brief guide to usimtool.py
. usimtool.py
manipulates
GSM, USIM and ISO 7816 smart cards. usimtool.py
requires
pcsclite.so
and iso7816.py
to be in Python’s sys.path
.
It is a command line tool. Commands are given on the command line separated by
spaces. When usimtool.py
starts it searches for the first available
card reader, prints its name, connects to it and then executes the commands
given. By default commands are executed using GSM class APDU’s, but this this
can be changed using usim command.
Many commands take or print smart card path names. The syntax used is: /application/fid/fid… A fid is a smart card file name. Smart card file names are 16 bit numbers, and are represented 4 hex digits. The application is an Application Identifier (AID) as defined in ISO 7816-4. This is typically a 32 digit hex number. It is used to select the starting Application Directory File (ADF). If left blank the MF is used. An AID consists of 3 parts: a vendor ID (5 bytes), followed by an application class (2 bytes) followed by a vendor assigned name (11 bytes). I doubt too many people know the entire AID off the top of their head, but they typically do know the application class (eg 1002 is USIM) and possibly the vendor ID. So as a shortcut when specifying an AID on the command line if you specify an AID less that 32 digits a prefix search is used. Giving up to 4 digits will match the first AID on the card whose application class starts with the digits supplied. Giving from 5 to 14 digits will match the first AID on the card whose application class matches the last 4 digits supplied and the vendor ID starts with the rest. Giving more than 14 digits matches the AID on the card that starts with the digits supplied.
Some examples of paths:
/ - matches the MF.
//2f06 - matches the file 2f06 under the MF (typicalled called EFatr in smart card documentation).
//7f10/6f3b - matches the file 6f3b in the MF directory 7f10.
/a0000000871002ff47f00189000001ff - Matches the ADF supplied.
/a0000000871002ff47 - Matches the same ADF as previous, assuming it is the first one listed in EFdir.
/a0000000871002 - Ditto.
/a01002 - Ditto.
/1002 - Ditto.
/10 - Ditto.
/1002/6f3c - Matches the file 6f3c in ADF a0000000871002ff47f00189000001ff.
/1002/7f10/6f3c - Matches the file 6f3c in the directory 7f10 under the same ADF.
Note
When GSM class APDU’s are being issued, and this is the default, an ADF can not be selected. Thus in GSM mode the application component of the path must always be blank. If not you will get an error.
Some commands print out a directory listing. These have the following format:
s:/1002/6f3c = 6f3c:01 EF 8800 lin P1,P1,??,P1,A4,A4 len=176:50
The format will vary a bit depending on the type of file and the class of APDU being used, but this example illustrates the main elements. Breaking the line printed into its constituent bits we have:
s:/1002/6f3c
is the command that generated the listing.6f3c:01
6f3c is the name of the file being listed. The short name is 01.EF
means this is a normal data file.DF
indicates a directory file.8800
The size of the file in bytes.lin
The file structure is linear. Other possibilities arecyc=cyclic
,ctv=cyclic-tlv
,ltv=linear-tlv
,trn=transparent
,vin=linear-variable
,vtv=linear-variable-tlv
.P1,P1,??,P1,A4,A4
The security level for these actions: read, update, increase, rfu, deactivate, activate. Security levelPx
means pin numberx
AW means always allowed,Nx
for anyx
means never allowed,Ax
means administrative pinx
. The security levels are accurate when GSM class commands are being issued but are educated guesses for USIM class commands are being issued.len=176:50
The record length is 176 bytes, and there are 50 records in the file.
Commands available:
- ?, h, -h, help, –help
Prints a short summary of the commands available.
- hex-apdu
The argument is a raw APDU in hex. Issues the APDU and prints the results. The APDU can have ‘.’s inserted for readability.
usimtool.py a0a4.0000.02.3f00 a0a4.0000.02.3f00 = 000009f83f00010000000000169305070400838a838a0003000009f8000009f8000000
- activate:path
Do a USIM ACTIVATE (aka GSM REHABILITATE) on path.
usimtool.py activate://7f10/6f3a
- changeP:old,new
Change pin P from old to new. P can be 1 or 2. This works with GSM and USIM cards.
usimtool.py change1:0000,1234
- deactivate:path
Do a USIM DEACTIVATE (aka GSM INVALIDATE) on path.
usimtool.py deactivate://7f10/6f3a
- dir:path[,*fid*]
List the files in directory path. If the two hex digits fid is given then only files starting with that byte are printed.
usimtool.py dir://7f10,6f dir://7f10,6f = 6f06 EF 2250 lin AW,A4,AW,AW,A4,A4 len=150:? 16:19=6f0601 dir://7f10,6f = 6f3a EF 9500 lin P1,P1,AW,AW,P2,P2 len=38:? life=x02 16:19=6f0605 ...
- disableP:old
Disable pin P. Pin P must have the value old. P can be 1 or 2. This works with GSM and USIM cards.
usimtool.py disable1:1234
- enableP:new
Enable pin P, setting it to new. P can be 1 or 2. This works with GSM and USIM cards.
usimtool.py enable1:1234
- dump:path
Dump the contents of file path in hex.
usimtool.py dump:2fe2 dump://2fe2 = 981620136045138543f2
- dumptree:path
Recursively dump the contents of all files under path in hex.
usimtool.py dumptree dumptree:/ = 3f00 DF pins=1+2 8:12=0fffff01 18=83 23:27=8a8a8a8a dumptree://0002 = 00000000000000000121e6ffff000000 ...
- gsm
Use GSM class APDU’s (ie, class 0xa0) for the following commands, and reset the card. This is the default.
usimtool.py gsm
- pinP:old
Unlock commands requiring pin P using the pin old. P can be 1 or 2. This works with GSM and USIM cards.
usimtool.py pin1:1234
- print:path
Pretty print the file path if its format is known to
iso7816.py
, otherwise dump it.usimtool.py print://7f10/6f3b print://7f10/6f3b[1] = {id:'Emergency', len:3., ton:80, num:+112, cap:ff, recid:ff} print://7f10/6f3b[2] = {id:'Emergency Aust.', len:3., ton:81, num:+000, cap:ff, recid:ff} print://7f10/6f3b[3] = {id:'Emergency TTY', len:3., ton:81, num:+106, cap:ff, recid:ff} print://7f10/6f3b[4..50] = {id:'', len:255., ton:ff, num:+, cap:ff, recid:ff}
- printtree[:*path*,…]
Recursively print all files under path. If path is not supplied all files under the MF are printed if GSM class APDU’s are being issued. If USIM class APDU’s are being issued print all files under all ADF’s as well.
usimtool.py printtree printtree://0002 = 06000915864700015affffffffff10 printtree://2f00[1] = {template:61, template_len:32., tag:4f, aid_len:16., aid:a0000000871002ff47f00189000001ff, appl:[{tag:50, len:7., label:'SingTel'}]} printtree://2f05 = {lang:[656e, ffff, ffff, ffff, ffff]} printtree://2f06[1] = <SAC=01, always=, SAC=1e, or=<crt=<key=0a, action=08>, crt=<key=0b, action=08>>> printtree://2f06[2] = <> printtree://2f06[3] = <SAC=01, always=, SAC=1e, or=<crt=<key=0a, action=08>, crt=<key=0b, action=08>,crt=<key=0d, action=08>>> ...
- pukP:PUK,new
Unlock blocked pin P using the unlock code PUK, setting the pin to be new. P can be 1 or 2. This works with GSM and USIM cards.
usimtool.py puk1:12345678,1234
- s:path
Issue a SELECT command for path. If path isn’t absolute the current DF is used as a starting point.
usimtool.py usim s:/1002/6f3c s:/1002/6f3c = 6f3c: EF 8800 lin P1,P1,??,P1,A4,A4 len=176:50
- trace:value
When trace is on APDU’s sent to the card and responses received are printed in hex. value can be
on
oroff
. Internal file reads are suppressed. So in example below the s command reads EFdir and EFarr in order do the prefix search for the AID and to interpret the results of the SELECT command, but you don’t see that in the trace../usimtool.py trace:on usim s:/1002/7f10/6f3a 00a4040410a0000000871002ff47f00189000001ff=6144, 00c0000044=6242820278218410a0000000871002ff47f00189000001ffa5118001318103010a3282010a8304000009f88a01058b032f0619c60990014083010183018181040000178f9000 00a40004027f10=612e, 00c000002e=622c8202782183027f10a5098001318304000009f88a01058b032f0618c60990014083010183018181040000ed679000 00a40004026f3a=6283 s:/1002/7f10/6f3a = : 6283 execution error, memory unchanged - selected file invalid
- tree[:*path*,…]
Does a recursive directory listing of all files under path. If path is not supplied all files under the MF are listed if GSM class APDU’s are being issued. If USIM class APDU’s are being issued lists all files under all ADF’s as well.
usimtool.py usim tree tree:/ = 3f00:00 DF pins=1 tree://0002 = 0002: EF 15 trn AW,A4,??,A4,A4,A4 tree://2f00 = 2f00:1e EF 38 lin AW,A4,??,A4,A4,A4 len=38:1 tree://2f05 = 2f05:05 EF 10 trn AW,P1,??,P1,A4,A4 tree://2f06 = 2f06:06 EF 4800 lin AW,A4,??,A4,A4,A4 len=150:32 ... tree:/a0000000871002ff47f00189000001ff = ? DF pins=1 dfname=a0000000871002ff47f00189000001ff tree:/a0000000871002ff47f00189000001ff/2f24 = 2f24: EF 52 lin A4,A4,??,A4,A4,A4 len=13:4 tree:/a0000000871002ff47f00189000001ff/2f27 = 2f27: EF 300 lin A4,A4,??,A4,A4,A4 len=6:50 tree:/a0000000871002ff47f00189000001ff/2f28 = 2f28: EF 11 trn A4,A4,??,A4,A4,A4 tree:/a0000000871002ff47f00189000001ff/6f05 = 6f05:02 EF 10 trn AW,P1,??,P1,A4,A4 ...
- update:path,recno,data
Update (overwrite) the data at record number recno in the file path with data. If recno is 0 or blank the entire file is updated, otherwise the specified record is updated. The data is a hex string possibly ending with
*repeat_count
. If arepeat_count
is given the last byte is repeated that many times.usimtool.py update://7ff0/6f56,,05 usimtool.py update://7f10/6f3a,1,ff*37
- usim
Use USIM class APDU’s (ie, class 0x00) for the following commands, and reset the card.
usimtool.py usim