|
From: <lu...@us...> - 2014-12-11 12:54:08
|
Revision: 650
http://sourceforge.net/p/pyscard/code/650
Author: ludov
Date: 2014-12-11 12:54:06 +0000 (Thu, 11 Dec 2014)
Log Message:
-----------
Remove old documentation
The documentation is now in Sphinx format
Removed Paths:
-------------
trunk/pyscard/src/smartcard/doc/framework-samples.html
trunk/pyscard/src/smartcard/doc/index.html
trunk/pyscard/src/smartcard/doc/pyscard-usersguide.html
trunk/pyscard/src/smartcard/doc/scard-samples.html
Deleted: trunk/pyscard/src/smartcard/doc/framework-samples.html
===================================================================
--- trunk/pyscard/src/smartcard/doc/framework-samples.html 2014-12-11 11:22:22 UTC (rev 649)
+++ trunk/pyscard/src/smartcard/doc/framework-samples.html 2014-12-11 12:54:06 UTC (rev 650)
@@ -1,145 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-
-<html>
-<head>
- <meta name="generator" content=
- "HTML Tidy for Linux (vers 25 March 2009), see www.w3.org">
-
- <title>smartcard python framework samples</title>
-</head>
-
-<body bgcolor="#FFFFFF">
- <h1 align="center">pyscard library samples</h1><a href=
- "http://sourceforge.net/projects/pyscard"><img src=
- "http://sflogo.sourceforge.net/sflogo.php?group_id=196342&type=11"
- width="120" height="30" align="right" alt=
- "Get pyscard at SourceForge.net. Fast, secure and Free Open Source software downloads"></a>
- <hr>
-
- Last update : pyscard 1.6.16 (Decembre 2012)
-
- <p><a href="pyscard-usersguide.html">pyscard</a> is a python
- module adding smart cards support to <a href=
- "http://www.python.org">python</a>.</p>
-
- <p>It consists of <a href=
- "epydoc/smartcard.scard.scard-module.html">smartcard.scard</a>,
- an extension module wrapping Windows smart card base components
- (also known as PCSC), and <a href=
- "epydoc/index.html">smartcard</a>, a python framework library
- hiding PCSC complexity.</p>
-
- <p align="center"><img src="images/pyscard.jpg" width="396"
- height="540" align="middle" alt="pyscard"></p>
-
- <h2>Smartcard python framework samples</h2>
-
- <table summary="samples" border>
- <tr>
- <td width="327">Display the ATR of inserted cards</td>
-
- <td width="76"><a href="Examples/simple/getATR.py">view
- source</a></td>
- </tr>
-
- <tr>
- <td width="327">Selecting the DF_TELECOM of a card</td>
-
- <td width="76"><a href=
- "Examples/simple/selectDF_TELECOM.py">view source</a></td>
- </tr>
-
- <tr>
- <td width="327">A simple apdu tracer and interpreter</td>
-
- <td width="76"><a href=
- "Examples/framework/sample_apduTracerInterpreter.py">view
- source</a></td>
- </tr>
-
- <tr>
- <td width="327">Tracing connection events</td>
-
- <td width="76"><a href=
- "Examples/framework/sample_ConsoleConnectionTracer.py">view
- source</a></td>
- </tr>
-
- <tr>
- <td width="327">Decorating Card Connections to add custom
- behavior</td>
-
- <td width="76"><a href=
- "Examples/framework/sample_CardConnectionDecorator.py">view
- source</a></td>
- </tr>
-
- <tr>
- <td width="327">Detecting response apdu errors</td>
-
- <td width="76"><a href=
- "Examples/framework/sample_ErrorChecking.py">view
- source</a></td>
- </tr>
-
- <tr>
- <td width="327">Implementing a custom ErrorChecker</td>
-
- <td width="76"><a href=
- "Examples/framework/sample_CustomErrorChecker.py">view
- source</a></td>
- </tr>
-
- <tr>
- <td width="327">Implementing a custom card type</td>
-
- <td width="76"><a href=
- "Examples/framework/sample_CustomCardType.py">view
- source</a></td>
- </tr>
-
- <tr>
- <td width="327">Monitoring smartcard readers</td>
-
- <td width="76"><a href=
- "Examples/framework/sample_MonitorReaders.py">view
- source</a></td>
- </tr>
-
- <tr>
- <td width="327">Monitoring smartcard insertion/removal</td>
-
- <td width="76"><a href=
- "Examples/framework/sample_MonitorCards.py">view
- source</a></td>
- </tr>
-
- <tr>
- <td width="327">APDU/ATR byte to string utilities</td>
-
- <td width="76"><a href=
- "Examples/framework/sample_toHexString.py">view
- source</a></td>
- </tr>
- </table>
- <hr>
-
- <p>This file is part of pyscard.</p>
-
- <p>pyscard is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later
- version.</p>
-
- <p>pyscard 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
- Lesser General Public License for more details.</p>
-
- <p>You should have received a copy of the GNU Lesser General
- Public License along with pyscard; if not, write to the Free
- Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- MA 02110-1301 USA</p>
-</body>
-</html>
Deleted: trunk/pyscard/src/smartcard/doc/index.html
===================================================================
--- trunk/pyscard/src/smartcard/doc/index.html 2014-12-11 11:22:22 UTC (rev 649)
+++ trunk/pyscard/src/smartcard/doc/index.html 2014-12-11 12:54:06 UTC (rev 650)
@@ -1,88 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-
-<html>
-<head>
- <meta name="generator" content=
- "HTML Tidy for Linux (vers 25 March 2009), see www.w3.org">
-
- <title>pyscard - python for smart cards</title>
-</head>
-
-<body bgcolor="#FFFFFF">
- <h1 align="center">pyscard<a href=
- "http://sourceforge.net/projects/pyscard"></a> <a href=
- "http://sourceforge.net/projects/pyscard"><img src=
- "http://sflogo.sourceforge.net/sflogo.php?group_id=196342&type=11"
- width="120" height="30" align="right" alt=
- "Get pyscard at SourceForge.net. Fast, secure and Free Open Source software downloads">
- </a></h1>
- <hr>
- Last update : pyscard 1.6.16 (Decembre 2012)
-
- <p><a href="pyscard-usersguide.html">pyscard - python smart card
- library</a> is a python module adding smart cards support to
- <a href="http://www.python.org">python.</a></p>
-
- <p><a href=
- "http://sourceforge.net/projects/pyscard/">download</a> pyscard
- from sourceforge.net.</p>
-
- <p>Report bugs, patches and feature requests using the
- sourceforge <a href=
- "https://sourceforge.net/p/pyscard/_list/tickets">pyscard bug
- tracking system</a>.</p>
-
- <p>Pyscard consists of <a href=
- "epydoc/smartcard.scard.scard-module.html">smartcard.scard</a>,
- an extension module wrapping Windows smart card base components
- (also known as PCSC) on Windows and PCSC lite on linux and Mac OS
- X Tiger and later versions, and <a href=
- "epydoc/index.html">smartcard</a>, a higher level python
- framework built on top of the raw PCSC API.</p>
-
- <p align="center"><img src="images/pyscard.jpg" width="396"
- height="540" align="middle" alt="pyscard"></p>
-
- <h2>Documentation Index</h2>
-
- <ul>
- <li>pyscard <a href="pyscard-usersguide.html">user's
- guide</a></li>
-
- <li><a href="epydoc/index.html">smartcard reference (python
- smart card library)</a></li>
-
- <li><a href="epydoc/smartcard.scard.scard-module.html">scard
- reference (python PCSC wrapper)</a>, the python wrapper around
- PCSC</li>
- </ul>
-
- <h2>Samples</h2>
-
- <ul>
- <li><a href="framework-samples.html">pyscard smartcard
- framework samples</a></li>
-
- <li><a href="scard-samples.html">PCSC wrapper samples</a></li>
- </ul>
- <hr>
-
- <p>This file is part of pyscard.</p>
-
- <p>pyscard is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later
- version.</p>
-
- <p>pyscard 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
- Lesser General Public License for more details.</p>
-
- <p>You should have received a copy of the GNU Lesser General
- Public License along with pyscard; if not, write to the Free
- Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- MA 02110-1301 USA</p>
-</body>
-</html>
Deleted: trunk/pyscard/src/smartcard/doc/pyscard-usersguide.html
===================================================================
--- trunk/pyscard/src/smartcard/doc/pyscard-usersguide.html 2014-12-11 11:22:22 UTC (rev 649)
+++ trunk/pyscard/src/smartcard/doc/pyscard-usersguide.html 2014-12-11 12:54:06 UTC (rev 650)
@@ -1,2675 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-
-<html>
-<head>
- <meta name="generator" content=
- "HTML Tidy for Linux (vers 25 March 2009), see www.w3.org">
-
- <title>pyscard smartcard module</title>
-</head>
-
-<body bgcolor="#FFFFFF">
- <h1 align="center">pyscard user's guide</h1><a href=
- "http://sourceforge.net/projects/pyscard"><img src=
- "http://sflogo.sourceforge.net/sflogo.php?group_id=196342&type=11"
- width="120" height="30" align="right" alt=
- "Get pyscard at SourceForge.net. Fast, secure and Free Open Source software downloads"></a>
- <pre>
-
-</pre>
- <hr>
-
- <h1><a name="top" id="top"></a>Contents</h1>
-
- <ul>
- <li><a href="#copyright">Copyright</a></li>
-
- <li><a href="#introduction">Introduction</a></li>
-
- <li><a href="#smartcards">Smart Cards</a></li>
-
- <li>
- <a href="#quickstart">Quick-Start</a>
-
- <ul>
- <li><a href="#readercentric">The reader-centric
- approach</a></li>
-
- <li><a href="#atr">The Answer To Reset (ATR)</a></li>
-
- <li>
- <a href="#cardcentric">The card-centric approach</a>
-
- <ul>
- <li><a href="#atrrequest">Requesting a card with a
- known ATR</a></li>
-
- <li><a href="#anycardrequest">Requesting any
- card</a></li>
-
- <li><a href="#customtyperequest">Designing custom card
- type requests</a></li>
- </ul>
- </li>
-
- <li><a href="#objectcentric">The object-centric
- approach</a></li>
- </ul>
- </li>
-
- <li>
- <a href="#apdutracing">Tracing APDUs</a>
-
- <ul>
- <li><a href="#bruteforcetracing">The brute force</a></li>
-
- <li><a href="#connectionobservers">Using card connection
- observers to trace apdu transmission</a></li>
- </ul>
- </li>
-
- <li>
- <a href="#apduerror">Testing for APDU transmission errors</a>
-
- <ul>
- <li><a href="#bruteforceerror">The brute force</a></li>
-
- <li>
- <a href="#errorcheckingchains">Using error checking
- chains to check for apdu transmission errors</a>
-
- <ul>
- <li><a href="#errorcheckers">Error checkers</a></li>
-
- <li><a href="#errorcheckingchains2">Error checking
- chains</a></li>
-
- <li><a href="#filteringerrors">Filtering
- errors</a></li>
-
- <li><a href="#cardconnectionchecking">Checking errors
- for a card connection</a></li>
-
- <li><a href="#customerrorcheckers">Writing custom error
- checkers</a></li>
- </ul>
- </li>
- </ul>
- </li>
-
- <li>
- <a href="#readers">Smartcard readers</a>
-
- <ul>
- <li><a href="#listingreaders">Listing smartcard
- readers</a></li>
-
- <li><a href="#readergroups">Organizing smartcard readers
- into groups</a></li>
-
- <li><a href="#readermonitoring">Monitoring readers</a></li>
- </ul>
- </li>
-
- <li>
- <a href="#smartcards2">Smart cards</a>
-
- <ul>
- <li><a href="#monitoringsmartcards">Monitoring smart
- cards</a></li>
-
- <li><a href="#sendingapdutocards">Sending APDUs to a smart
- card obtained from card monitoring</a></li>
- </ul>
- </li>
-
- <li>
- <a href="#connections">Connections</a>
-
- <ul>
- <li><a href="#cardrequestconnection">Creating a connection
- from a CardRequest</a></li>
-
- <li><a href="#cardmonitoringconnection">Creating a
- connection from CardMonitoring</a></li>
-
- <li>
- <a href="#cardconnectiondecorators">Card connection
- decorators</a>
-
- <ul>
- <li><a href="#exclusiveconnectiondecorator">Exclusive
- card connection decorator</a></li>
-
- <li><a href="#exclusivetransmitdecorator">Exclusive
- transmit card connection decorator</a></li>
-
- <li><a href="#securechanneldecorator">Secure channel
- decorator</a></li>
- </ul>
- </li>
- </ul>
- </li>
-
- <li><a href="smartcard.html">Smartcard reference</a></li>
-
- <li>
- <a href="#cryptography">A word on cryptography</a>
-
- <ul>
- <li><a href="#binstring">Binary strings and list of
- bytes</a></li>
-
- <li><a href="#hashing">Hashing</a></li>
-
- <li><a href="#secretkey">Secret key cryptography</a></li>
- </ul>
- </li>
-
- <li><a href="#License">License</a></li>
- </ul>
- <hr>
- <a name="copyright" id="copyright"></a>
-
- <h2>Copyright</h2>
- <pre>
-Copyright 2001-2009 <a href=
-"http://www.gemalto.com">gemalto</a><br>Author: Jean-Daniel Aussel, <a href="mailto:jea...@ge...">mailto:jea...@ge...</a>
-</pre>
-
- <p>This file is part of pyscard.</p>
-
- <p>pyscard is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later
- version.</p>
-
- <p>pyscard 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
- Lesser General Public License for more details.</p>
-
- <p>You should have received a copy of the GNU Lesser General
- Public License along with pyscard; if not, write to the Free
- Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- MA 02110-1301 USA<br></p>
- <hr>
- <a name="introduction" id="introduction"></a>
-
- <h2>Introduction</h2>
-
- <p>The pyscard smartcard library is a framework for building
- smart card aware applications in Python. The smartcard module is
- built on top of the <a href="scard.html">PCSC API</a> Python
- wrapper module.</p>
-
- <p>pyscard supports Windows 2000 and XP by using the <a href=
- "http://msdn2.microsoft.com/en-us/library/aa374731.aspx#smart_card_functions">
- Microsoft Smart Card Base</a> components, and linux and Mac OS X
- by using <a href=
- "http://pcsclite.alioth.debian.org/">PCSC-lite</a>.</p>
- <hr>
-
- <h2><a name="smartcards" id="smartcards"></a>Smart Cards</h2>
-
- <p>Smart cards are plastic cards having generally the size of a
- credit card and embedding a microprocessor. Smart cards
- communicate with the outside world thru a serial port interface
- and an half-duplex protocol. Smartcards usually interface with a
- dedicated terminal, such as a point-of-sale terminal or a mobile
- phone. Sometime, smart cards have to be interfaced with personal
- computers. This is the case for some applications such as secure
- login, mail cyphering or digital signature, but also for some PC
- based smart card tools used to personnalize or edit the content
- of smart cards. Smart cards are interfaced with a personnal
- computer using a smart card reader. The smart card reader
- connects on one side to the serial port of the smart card, and on
- the other side to the PC, often nowadays thru a USB port.</p>
-
- <p>The PCSC workgroup has defined a standard API to interface
- smart card and smart card readers to a PC. The resulting
- reference implementation on linux and Mac OS X operating systems
- is <a href="http://pcsclite.alioth.debian.org/">PC/SC-lite</a>.
- All windows operating systems also include out of the box smart
- card support, usually called <a href=
- "http://msdn2.microsoft.com/en-us/library/aa374731.aspx#smart_card_functions">
- PCSC</a>.</p>
-
- <p>The PCSC API is implemented in C language, and several bridges
- are provided to access the PCSC API from different languages such
- as java or visual basic. pyscard is a python framework to develop
- smart card PC applications on linux, Mac OS X and windows.
- pyscard lower layers interface to the PCSC API to access the
- smart cards and smart card readers.</p>
-
- <hr>
-
- <h2><a name="quickstart" id="quickstart"></a>Quick-start</h2>
-
- <p>We will see in this section some variations on how to send
- APDU commands to a smart card.</p>
-
- <h3><a name="readercentric" id="readercentric"></a>The
- reader-centric approach</h3>
-
- <p>A PC application interacts with a card by sending list of
- bytes, known as Application Protocol Data Units (APDU). The
- format of these APDUs is defined in the ISO7816-4 standard. To
- send APDUs to a card, the application needs first to connect to a
- card thru a smart card reader. Smart card aware applications that
- first select a smart card reader, then connect to the card
- inserted in the smart card reader use the reader-centric
- approach.</p>
-
- <p>In the reader-centric approach, we open a connection with a
- card thru a smart card reader, and send APDU commands to the card
- using the connection:</p>
-
- <p><font face="Courier New, Courier, mono" size="2" color=
- "#0033FF">>>> from smartcard.System import readers<br>
- >>> from smartcard.util import toHexString<br>
- >>><br>
- >>> r=readers()<br>
- >>> print r<br>
- ['SchlumbergerSema Reflex USB v.2 0', 'Utimaco CardManUSB 0']<br>
- >>> connection = r[0].createConnection()<br>
- >>> connection.connect()<br>
- >>> SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02]<br>
- >>> DF_TELECOM = [0x7F, 0x10]<br>
- >>> data, sw1, sw2 = connection.transmit( SELECT +
- DF_TELECOM )<br>
- >>> print "%x %x" % (sw1, sw2)<br>
- 9f 1a<br>
- >>></font></p>
-
- <p>The list of available readers is retrieved with the
- <font face="Courier New, Courier, mono" size="2">readers()</font>
- function. We create a connection with the first reader (index 0
- for reader 1, 1 for reader 2, ...) with the <font face=
- "Courier New, Courier, mono" size=
- "2">r[0].createConnection()</font> call and connect to the card
- with the <font face="Courier New, Courier, mono" size=
- "2">connect()</font> method of the connection. We can then send
- APDU commands to the card with the <font face=
- "Courier New, Courier, mono"><font size=
- "2">transmit()</font></font> method.</p>
-
- <p>Scripts written with the reader centric approach however have
- the following drawbacks:</p>
-
- <ul>
- <li>the reader index or reader name is hardcoded in the
- scripts; the scripts must be edited to match each user
- configuration; for example in the previous script, we would
- have to edit the script and change r[0] to r[1] for using the
- second reader</li>
-
- <li>there is no a-priori knowledge that the card is in the
- reader; to detect card insertion, we would have to execute the
- script and eventually catch a CardConnectionException that
- would indicate that there is no card in the reader.</li>
-
- <li>there is no built-in check that the card in the reader is
- of the card type we expect; in the previous example, we might
- try to select the DF_TELECOM of an EMV card.</li>
- </ul>
-
- <p>Most of these issues are solved with the card-centric
- approach, based on card type detection techniques, such as using
- the Answer To Reset (ATR) of the card.</p>
-
- <p><a href="#top">to the top</a></p>
-
- <h3><a name="atr" id="atr"></a>The Answer To Reset (ATR)</h3>
-
- <p>The first answer of a smart card inserted in a smart card
- reader is call the ATR. The purpose of the ATR is to describe the
- supported communication parameters. The smart card reader, smart
- card reader driver, and operating system will use these
- parameters to establish a communication with the card. The ATR is
- described in the ISO7816-3 standard. The first bytes of the ATR
- describe the voltage convention (direct or inverse), followed by
- bytes describing the available communication interfaces and their
- respective parameters. These interface bytes are then followed by
- Historical Bytes which are not standardized, and are useful for
- transmitting proprietary informations such as the card type, the
- version of the embedded software, or the card state. Finally
- these historical bytes are eventually followd by a checksum
- byte.</p>
-
- <p>The class <a href=
- "epydoc/smartcard.ATR.ATR-class.html">smartcard.ATR</a> is a
- pyscard utility class that can interpret the content of an
- ATR:</p>
-
- <p><font face="Courier New, Courier, mono" size="2" color=
- "#0033FF">#! /usr/bin/env python<br>
- from smartcard.ATR import ATR<br>
- from smartcard.util import toHexString<br>
- <br>
- atr = ATR([0x3B, 0x9E, 0x95, 0x80, 0x1F, 0xC3, 0x80, 0x31, 0xA0,
- 0x73,<br>
- 0xBE, 0x21, 0x13, 0x67, 0x29, 0x02, 0x01, 0x01, 0x81,0xCD,0xB9]
- )<br>
- print atr<br>
- print 'historical bytes: ', toHexString( atr.getHistoricalBytes()
- )<br>
- print 'checksum: ', "0x%X" % atr.getChecksum()<br>
- print 'checksum OK: ', atr.checksumOK<br>
- print 'T0 supported: ', atr.isT0Supported()<br>
- print 'T1 supported: ', atr.isT1Supported()<br>
- print 'T15 supported: ', atr.isT15Supported()<br></font></p>
-
- <p>Which results in the following output:</p>
-
- <p><font face="Courier New, Courier, mono" size="2" color=
- "#0033FF">3B 9E 95 80 1F C3 80 31 A0 73 BE 21 13 67 29 02 01 01
- 81 CD B9<br>
- historical bytes: 80 31 A0 73 BE 21 13 67 29 02 01 01 81 CD<br>
- checksum: 0xB9<br>
- checksum OK: True<br>
- T0 supported: True<br>
- T1 supported: False<br>
- T15 supported: True<br></font></p>
-
- <p>In practice, the ATR can be used to detect a particular card,
- either by trying to match a card with a complete ATR, or by
- matching a card with some data in the historical bytes. Smart
- card aware PC applications that detects smart cards based on the
- content of the ATR use the card-centric approach, independently
- on the smart card reader in which the card is inserted..<br></p>
-
- <h3><a name="cardcentric" id="cardcentric"></a>The card-centric
- approach</h3>
-
- <p>In the card-centric approach, we create a request for a
- specific type of card and wait until a card matching the request
- is inserted. Once a matching card is introduced, a connection to
- the card is automatically created and we can send APDU commands
- to the card using this connection.</p>
-
- <h4><a name="atrrequest" id="atrrequest"></a>Requesting a card by
- ATR</h4>
-
- <p>The following scripts requests a card with a known ATR:</p>
-
- <p><font face="Courier New, Courier, mono" size="2" color=
- "#0033FF">>>> from smartcard.CardType import
- ATRCardType<br>
- >>> from smartcard.CardRequest import CardRequest<br>
- >>> from smartcard.util import toHexString, toBytes<br>
- >>><br>
- >>> cardtype = ATRCardType( toBytes( "3B 16 94 20 02 01
- 00 00 0D" ) )<br>
- >>> cardrequest = CardRequest( timeout=1,
- cardType=cardtype )<br>
- >>> cardservice = cardrequest.waitforcard()<br>
- >>><br>
- >>> cardservice.connection.connect()<br>
- >>> print toHexString( cardservice.connection.getATR()
- )<br>
- 3B 16 94 20 02 01 00 00 0D<br>
- >>><br>
- >>> SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02]<br>
- >>> DF_TELECOM = [0x7F, 0x10]<br>
- >>> data, sw1, sw2 = cardservice.connection.transmit(
- SELECT + DF_TELECOM )<br>
- >>> print "%x %x" % (sw1, sw2)<br>
- 9f 1a<br>
- >>></font></p>
-
- <p>To request a card with a know ATR, you must first create an
- <a href=
- "epydoc/smartcard.CardType.ATRCardType-class.html">ATRCardType</a>
- object with the desired ATR:</p>
-
- <p><font face="Courier New, Courier, mono" size="2" color=
- "#0033FF">>>> cardtype = ATRCardType( toBytes( "3B 16 94
- 20 02 01 00 00 0D" ) )<br></font></p>
-
- <p>And then create a <a href=
- "epydoc/smartcard.CardRequest.CardRequest-class.html">CardRequest</a>
- for this card type. In the sample, we request a time-out of 1
- second.</p>
-
- <p><font face="Courier New, Courier, mono" size="2" color=
- "#0033FF">>>> cardrequest = CardRequest( timeout=1,
- cardType=cardtype )<br>
- >>> cardservice =
- cardrequest.waitforcard()<br></font></p>
-
- <p>The waitforcard() will either return with a card service or a
- time-out. The card service connection attribute can be used
- thereafter to transmit APDU commands to the card, as with the
- reader centric approach.</p>
-
- <p><font face="Courier New, Courier, mono" size="2" color=
- "#0033FF">>>> cardservice.connection.connect()<br>
- >>> print toHexString( cardservice.connection.getATR()
- )<br></font></p>
-
- <p>If necessary, the reader used for the connection can be
- accessed thru the <a href=
- "epydoc/smartcard.CardConnection.CardConnection-class.html">CardConnection</a>
- object:</p>
-
- <p><font face="Courier New, Courier, mono" size="2" color=
- "#0033FF">>>> print
- cardservice.connection.getReader()<br>
- SchlumbergerSema Reflex USB v.2 0</font></p>
-
- <p>The <a href=
- "epydoc/smartcard.CardType.ATRCardType-class.html">ATRCardType</a>
- also supports masks:</p>
-
- <p><font face="Courier New, Courier, mono" size="2" color=
- "#0033FF">>>> from smartcard.CardType import
- ATRCardType<br>
- >>> from smartcard.CardRequest import CardRequest<br>
- >>> from smartcard.util import toHexString, toBytes<br>
- >>><br>
- >>> cardtype = ATRCardType( toBytes( "3B 1<b>5</b> 94 20
- 02 01 00 00 0<b>F</b>" ), toBytes( "00 00 FF FF FF FF FF FF 00" )
- )<br>
- >>> cardrequest = CardRequest( timeout=1,
- cardType=cardtype )<br>
- >>> cardservice = cardrequest.waitforcard()<br>
- >>><br>
- >>> cardservice.connection.connect()<br>
- >>> print toHexString( cardservice.connection.getATR()
- )<br>
- 3B 1<b>6</b> 94 20 02 01 00 00 0<b>D</b></font></p>
-
- <p>Other CardTypes are available, and new CardTypes can be
- created, as described below.</p>
-
- <p><a href="#top">to the top</a></p>
-
- <h4><a name="anycardrequest" id="anycardrequest"></a>Requesting
- any card</h4>
-
- <p>The <a href=
- "epydoc/smartcard.CardType.AnyCardType-class.html">AnyCardType</a>
- is useful for requesting any card in any reader:</p>
-
- <p><font face="Courier New, Courier, mono" size="2" color=
- "#0033FF">>>> from smartcard.CardType import
- AnyCardType<br>
- >>> from smartcard.CardRequest import CardRequest<br>
- >>> from smartcard.util import toHexString<br>
- >>><br>
- >>> cardtype = AnyCardType()<br>
- >>> cardrequest = CardRequest( timeout=1,
- cardType=cardtype )<br>
- >>> cardservice = cardrequest.waitforcard()<br>
- >>><br>
- >>> cardservice.connection.connect()<br>
- >>> print toHexString( cardservice.connection.getATR()
- )<br>
- 3B 16 94 20 02 01 00 00 0D<br>
- >>> print cardservice.connection.getReader()<br>
- SchlumbergerSema Reflex USB v.2 0</font></p>
-
- <p><a href="#top">to the top</a></p>
-
- <h4><a name="customtyperequest" id="customtyperequest"></a>Custom
- CardTypes</h4>
-
- <p>Custom CardTypes can be created, e.g. a card type that checks
- the ATR and the historical bytes of the card. To create a custom
- CardType, deriver your CardType class from the the <a href=
- "epydoc/smartcard.CardType.CardType-class.html">CardType</a> base
- class (or any other CardType) and override the <font face=
- "Courier New, Courier, mono" size="2">matches()</font> method.
- For exemple to create a DCCardType that will match cards with the
- direct convention (first byte of ATR to 0x3b):</p>
-
- <p><font face="Courier New, Courier, mono" size="2" color=
- "#0033FF">>>> from smartcard.CardType import
- CardType<br>
- >>> from smartcard.CardRequest import CardRequest<br>
- >>> from smartcard.util import toHexString<br>
- >>><br>
- >>> class DCCardType(CardType):<br>
- ... def matches( self, atr,
- reader=None ):<br>
- ... return
- atr[0]==0x3B<br>
- ...<br>
- >>> cardtype = DCCardType()<br>
- >>> cardrequest = CardRequest( timeout=1,
- cardType=cardtype )<br>
- >>> cardservice = cardrequest.waitforcard()<br>
- >>><br>
- >>> cardservice.connection.connect()<br>
- >>> print toHexString( cardservice.connection.getATR()
- )<br>
- 3B 16 94 20 02 01 00 00 0D<br>
- >>> print cardservice.connection.getReader()<br>
- SchlumbergerSema Reflex USB v.2 0<br>
- >>></font></p>
-
- <p>Scripts written with the card-centric approach fixes the
- problems of the reader-centric approach:</p>
-
- <ul>
- <li>there is no assumption concerning the reader index or
- reader name; the desired card will be located in any
- reader</li>
-
- <li>the request will block or time-out if the desired card type
- is not inserted</li>
-
- <li>since we request the desired card type, the script is not
- played on an unknown or uncompatible card</li>
- </ul>
-
- <p>Scripts written with the card-centric approach have however
- the following drawbacks:</p>
-
- <ul>
- <li>the script is limited to a specific card type; we have to
- modify the script if we want to execute the script on another
- card type. For exemple, we have to modify the ATR of the card
- if we are using the ATRCardType. This can be partially solved
- by having a custom CardType that matches several ATRs,
- though.</li>
- </ul>
-
- <p><a href="#top">to the top</a></p>
-
- <h3><a name="protocol" id="protocol"></a>Selecting the card
- communication protocol</h3>
-
- <p>Communication parameters are mostly important for the protocol
- negociation between the smart card reader and the card. The main
- smartcard protocols are the T=0 protocol and the T=1 protocol,
- for byte or block transmission, respectively. The required
- protocol can be specified at card connection or card
- transmission.</p>
-
- <p>By defaults, the connect() method of the CardConnection
- object.will try to connect using either the T=0 or T=1 protocol.
- To force a connection protocol, you can pass the required
- protocol to the connect() method.</p>
-
- <p><font face="Courier New, Courier, mono" size="2" color=
- "#0033FF">>>> from smartcard.CardType import
- AnyCardType<br>
- >>> from smartcard.CardConnection import
- CardConnection<br>
- >>> from smartcard.CardRequest import CardRequest<br>
- >>> from smartcard.util import toHexString<br>
- >>><br>
- >>> cardtype = AnyCardType()<br>
- >>> cardrequest = CardRequest( timeout=1,
- cardType=cardtype )<br>
- >>> cardservice = cardrequest.waitforcard()<br>
- >>><br>
- >>> cardservice.connection.connect(
- CardConnection.T1_protocol )<br>
- >>> print toHexString( cardservice.connection.getATR()
- )<br>
- 3B 16 94 20 02 01 00 00 0D<br>
- >>> print cardservice.connection.getReader()<br>
- SchlumbergerSema Reflex USB v.2 0</font></p>
-
- <p><a href="#top"></a>Alternatively, you can specify the required
- protocol in the CardConnection transmit() method:</p>
-
- <p><font face="Courier New, Courier, mono" size="2" color=
- "#0033FF">>>> from smartcard.CardType import
- AnyCardType<br>
- >>> from smartcard.CardConnection import
- CardConnection<br>
- >>> from smartcard.CardRequest import CardRequest<br>
- >>> from smartcard.util import toHexString, toBytes<br>
- >>><br>
- >>> cardtype = AnyCardType()<br>
- >>> cardrequest = CardRequest( timeout=1,
- cardType=cardtype )<br>
- >>> cardservice = cardrequest.waitforcard()<br>
- >>><br>
- >>> cardservice.connection.connect()<br>
- >>><br>
- >>> SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02]<br>
- >>> DF_TELECOM = [0x7F, 0x10]<br>
- >>><br>
- >>> apdu = SELECT+DF_TELECOM<br>
- >>> print 'sending ' + toHexString(apdu)<br>
- sending A0 A4 00 00 02 7F 10<br>
- >>> response, sw1, sw2 =
- cardservice.connection.transmit( apdu, CardConnection.T1_protocol
- )<br>
- >>> print 'response: ', response, ' status words: ', "%x
- %x" % (sw1, sw2)<br>
- response: [] status words: 9f 1a<br>
- >>><br>
- >>> if sw1 == 0x9F:<br>
- ... GET_RESPONSE = [0XA0, 0XC0, 00, 00
- ]<br>
- ... apdu = GET_RESPONSE + [sw2]<br>
- ... print 'sending ' +
- toHexString(apdu)<br>
- ... response, sw1, sw2 =
- cardservice.connection.transmit( apdu )<br>
- ... print 'response: ',
- toHexString(response), ' status words: ', "%x %x" % (sw1,
- sw2)<br>
- ...<br>
- sending A0 C0 00 00 1A<br>
- response: 00 00 00 00 7F 10 02 00 00 00 00 00 0D 13 00 0A 04 00
- 83 8A 83 8A 00 01 00 00 status words: 90 0<br>
- >>></font></p>
-
- <h3><a name="objectcentric" id="objectcentric"></a>The
- object-centric approach</h3>
-
- <p>In the object-centric approach, we associate a high-level
- object with a set of smart cards supported by the object. For
- example we associate a javacard loader class with a set of
- javacard smart cards. We create a request for the specific
- object, and wait until a card supported by the object is
- inserted. Once a card supported by the object is inserted, we
- perform the required function by calling the objec methods.</p>
-
- <p><i>To be written...</i></p>
- <hr>
-
- <h2><a name="apdutracing" id="apdutracing"></a>Tracing APDUs</h2>
-
- <h3><a name="bruteforcetracing" id="bruteforcetracing"></a>The
- brute force</h3>
-
- <p>A straightforward way of tracing command and response APDUs is
- to insert print statements around the transmit() method
- calls:</p>
-
- <p><font face="Courier New, Courier, mono" size="2" color=
- "#0033FF">>>> from smartcard.CardType import
- ATRCardType<br>
- >>> from smartcard.CardRequest import CardRequest<br>
- >>> from smartcard.util import toHexString, toBytes<br>
- >>><br>
- >>> cardtype = ATRCardType( toBytes( "3B 16 94 20 02 01
- 00 00 0D" ) )<br>
- >>> cardrequest = CardRequest( timeout=1,
- cardType=cardtype )<br>
- >>> cardservice = cardrequest.waitforcard()<br>
- >>><br>
- >>> cardservice.connection.connect()<br>
- >>><br>
- >>> SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02]<br>
- >>> DF_TELECOM = [0x7F, 0x10]<br>
- >>><br>
- >>> apdu = SELECT+DF_TELECOM<br>
- >>> print 'sending ' + toHexString(apdu)<br>
- sending A0 A4 00 00 02 7F 10<br>
- >>> response, sw1, sw2 =
- cardservice.connection.transmit( apdu )<br>
- >>> print 'response: ', response, ' status words: ', "%x
- %x" % (sw1, sw2)<br>
- response: [] status words: 9f 1a<br>
- >>><br>
- >>> if sw1 == 0x9F:<br>
- ... GET_RESPONSE = [0XA0, 0XC0, 00, 00
- ]<br>
- ... apdu = GET_RESPONSE + [sw2]<br>
- ... print 'sending ' +
- toHexString(apdu)<br>
- ... response, sw1, sw2 =
- cardservice.connection.transmit( apdu )<br>
- ... print 'response: ',
- toHexString(response), ' status words: ', "%x %x" % (sw1,
- sw2)<br>
- ...<br>
- sending A0 C0 00 00 1A<br>
- response: 00 00 00 00 7F 10 02 00 00 00 00 00 0D 13 00 0A 04 00
- 83 8A 83 8A 00 01 00 00 status words: 90 0<br>
- >>></font></p>
-
- <p>Scripts written this way are quite difficult to read, because
- there are more tracing statements than actual apdu
- transmits..</p>
-
- <p>A small improvement in visibility would be to replace the
- print instructions by functions, e.g.:</p>
-
- <p><font face="Courier New, Courier, mono" size="2" color=
- "#0033FF">>>> from smartcard.CardType import
- ATRCardType<br>
- >>> from smartcard.CardRequest import CardRequest<br>
- >>> from smartcard.util import toHexString, toBytes<br>
- >>><br>
- >>> cardtype = ATRCardType( toBytes( "3B 16 94 20 02 01
- 00 00 0D" ) )<br>
- >>> cardrequest = CardRequest( timeout=1,
- cardType=cardtype )<br>
- >>> cardservice = cardrequest.waitforcard()<br>
- >>><br>
- >>> cardservice.connection.connect()<br>
- >>><br>
- >>> SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02]<br>
- >>> DF_TELECOM = [0x7F, 0x10]<br>
- >>><br>
- >>> def trace_command(apdu):<br>
- ... print 'sending ' +
- toHexString(apdu)<br>
- ...<br>
- >>> def trace_response( response, sw1, sw2 ):<br>
- ... if None==response: response=[]<br>
- ... print 'response: ',
- toHexString(response), ' status words: ', "%x %x" % (sw1,
- sw2)<br>
- ...<br>
- >>> apdu = SELECT+DF_TELECOM<br>
- >>> trace_command(apdu)<br>
- sending A0 A4 00 00 02 7F 10<br>
- >>> response, sw1, sw2 =
- cardservice.connection.transmit( apdu )<br>
- >>> trace_response( response, sw1, sw2 )<br>
- response: status words: 9f 1a<br>
- >>><br>
- >>> if sw1 == 0x9F:<br>
- ... GET_RESPONSE = [0XA0, 0XC0, 00, 00 ]<br>
- ... apdu = GET_RESPONSE + [sw2]<br>
- ... trace_command(apdu)<br>
- ... response, sw1, sw2 =
- cardservice.connection.transmit( apdu )<br>
- ... trace_response( response, sw1, sw2 )<br>
- ...<br>
- sending A0 C0 00 00 1A<br>
- response: 00 00 00 00 7F 10 02 00 00 00 00 00 0D 13 00 0A 04 00
- 83 8A 83 8A 00 01 00 00 status words: 90 0<br>
- >>></font></p>
-
- <p><a href="#top">to the top</a></p>
-
- <h3><a name="connectionobservers" id=
- "connectionobservers"></a>Using card connection observers to
- trace apdu transmission</h3>
-
- <p>The prefered solution is to implement a card connection
- observer, and register the observer with the card connection. The
- card connection will then notify the observer when card
- connection events occur (e.g. connection, disconnection, apdu
- command or apdu response). This is illustrated in the following
- script:</p>
-
- <p><font face="Courier New, Courier, mono" size="2" color=
- "#0033FF">>>> from smartcard.CardType import
- AnyCardType<br>
- >>> from smartcard.CardRequest import CardRequest<br>
- >>> from smartcard.CardConnectionObserver import
- ConsoleCardConnectionObserver<br>
- >>><br>
- >>> GET_RESPONSE = [0XA0, 0XC0, 00, 00 ]<br>
- >>> SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02]<br>
- >>> DF_TELECOM = [0x7F, 0x10]<br>
- >>><br>
- >>><br>
- >>> cardtype = AnyCardType()<br>
- >>> cardrequest = CardRequest( timeout=10,
- cardType=cardtype )<br>
- >>> cardservice = cardrequest.waitforcard()<br>
- >>><br>
- >>> observer=ConsoleCardConnectionObserver()<br>
- >>> cardservice.connection.addObserver( observer )<br>
- >>><br>
- >>> cardservice.connection.connect()<br>
- connecting to SchlumbergerSema Reflex USB v.2 0<br>
- >>><br>
- >>> apdu = SELECT+DF_TELECOM<br>
- >>> response, sw1, sw2 =
- cardservice.connection.transmit( apdu )<br>
- > A0 A4 00 00 02 7F 10<br>
- < [] 9F 1A<br>
- >>> if sw1 == 0x9F:<br>
- ... apdu = GET_RESPONSE + [sw2]<br>
- ... response, sw1, sw2 =
- cardservice.connection.transmit( apdu )<br>
- ... else:<br>
- ... print 'no DF_TELECOM'<br>
- ...<br>
- > A0 C0 00 00 1A<br>
- < 00 00 00 00 7F 10 02 00 00 00 00 00 0D 13 00 0A 04 00 83 8A
- 83 8A 00 01 00 00 90 0<br>
- >>></font></p>
-
- <p>In this script, a <a href=
- "epydoc/smartcard.CardConnectionObserver.ConsoleCardConnectionObserver-class.html">
- ConsoleCardConnectionObserver</a> is attached to the card service
- connection once the watiforcard() call returns.</p>
-
- <p><font face="Courier New, Courier, mono" size="2" color=
- "#0033FF">>>>
- observer=ConsoleCardConnectionObserver()<br>
- >>> cardservice.connection.addObserver( observer
- )<br></font></p>
-
- <p>On card connection events (connect, disconnect, transmit
- command apdu, receive response apdu), the card connection
- notifies its obersers with a <a href=
- "epydoc/smartcard.CardConnectionEvent.CardConnectionEvent-class.html">
- CarConnectionEvent</a> including the event type and the event
- data. The <a href=
- "epydoc/smartcard.CardConnectionObserver.ConsoleCardConnectionObserver-class.html">
- ConsoleCardConnectionObserver</a> is a simple observer that will
- print on the console the card connection events. The class
- definition is the following:</p>
-
- <p><font face="Courier New, Courier, mono" size="2" color=
- "#0033FF">class ConsoleCardConnectionObserver(
- CardConnectionObserver ):<br>
- def update( self, cardconnection, ccevent
- ):</font></p>
-
- <p><font face="Courier New, Courier, mono" size="2" color=
- "#0033FF"> if
- 'connect'==ccevent.type:<br>
- print
- 'connecting to ' + cardconnection.getReader()</font></p>
-
- <p><font face="Courier New, Courier, mono" size="2" color=
- "#0033FF"> elif
- 'disconnect'==ccevent.type:<br>
- print
- 'disconnecting from ' + cardconnection.getReader()</font></p>
-
- <p><font face="Courier New, Courier, mono" size="2" color=
- "#0033FF"> elif
- 'command'==ccevent.type:<br>
- print
- '> ', toHexString( ccevent.args[0] )</font></p>
-
- <p><font face="Courier New, Courier, mono" size="2" color=
- "#0033FF"> elif
- 'response'==ccevent.type:<br>
- if
- []==ccevent.args[0]:<br>
- print
- '< [] ', "%-2X %-2X" % tuple(ccevent.args[-2:])<br>
- else:<br>
-
- print '< ',
- toHexString(ccevent.args[0]), "%-2X %-2X" %
- tuple(ccevent.args[-2:])<br></font></p>
-
- <p>The console card connection observer is thus printing the
- connect, disconnect, command and response apdu events:</p>
-
- <p><font face="Courier New, Courier, mono" size="2" color=
- "#0033FF">>>> cardservice.connection.connect()<br>
- <b>connecting to SchlumbergerSema Reflex USB v.2 0</b><br>
- >>><br>
- >>> apdu = SELECT+DF_TELECOM<br>
- >>> response, sw1, sw2 =
- cardservice.connection.transmit( apdu )<br>
- <b>> A0 A4 00 00 02 7F 10<br>
- < [] 9F 1A<br></b> >>> if sw1 == 0x9F:<br>
- ... apdu = GET_RESPONSE + [sw2]<br>
- ... response, sw1, sw2 =
- cardservice.connection.transmit( apdu )<br>
- ... else:<br>
- ... print 'no DF_TELECOM'<br>
- ...<br>
- <b>> A0 C0 00 00 1A<br>
- < 00 00 00 00 7F 10 02 00 00 00 00 00 0D 13 00 0A 04 00 83 8A
- 83 8A 00 01 00 00 90 0<br></b></font></p>
-
- <p>A card connection observer's update methode is called upon
- card connection event, with the connection and the connection
- event as parameters. The <a href=
- "epydoc/smartcard.CardConnectionEvent.CardConnectionEvent-class.html">
- CardConnectionEvent</a> class definition is the following:</p>
-
- <p><font face="Courier New, Courier, mono" size="2" color=
- "#0033FF">class CardConnectionEvent:<br>
- """Base class for card connection
- events.<br>
- <br>
- This event is notified by CardConnection
- objects.</font></p>
-
- <p><font face="Courier New, Courier, mono" size="2" color=
- "#0033FF"> type: 'connect', 'disconnect',
- 'command', 'response'<br>
- args: None for 'connect' or 'disconnect'<br>
- command APDU byte list for 'command'<br>
- [response data, sw1, sw2] for 'response'<br>
- type: 'connect' args:"""<br>
- def __init__( self, type, args=None):<br>
- self.type=type<br>
- self.args=args<br></font></p>
-
- <p>You can write your own card connection observer, for example
- to perform fancy output in a wxWindows frame, or apdu
- interpretation. The following scripts defines a small SELECT and
- GET RESPONSE apdu interpreter:</p>
-
- <p><font face="Courier New, Courier, mono" size="2" color=
- "#0033FF">>>> from smartcard.CardType import
- AnyCardType<br>
- >>> from smartcard.CardRequest import CardRequest<br>
- >>> from smartcard.CardConnectionObserver import
- CardConnectionObserver<br>
- >>> from smartcard.util import toHexString<br>
- >>><br>
- >>> from string import replace<br>
- >>><br>
- >>> class TracerAndSELECTInterpreter(
- CardConnectionObserver ):<br>
- ... def update( self, cardconnection,
- ccevent ):<br>
- ... if
- 'connect'==ccevent.type:<br>
- ...
- print
- 'connecting to ' + cardconnection.getReader()<br>
- ... elif
- 'disconnect'==ccevent.type:<br>
- ...
- print
- 'disconnecting from ' + cardconnection.getReader()<br>
- ... elif
- 'command'==ccevent.type:<br>
- ...
- str=toHexString(ccevent.args[0])<br>
-
- ...
- str
- = replace( str , "A0 A4 00 00 02", "SELECT" )<br>
- ...
- str
- = replace( str , "A0 C0 00 00", "GET RESPONSE" )<br>
- ...
- print
- '> ', str<br>
- ... elif
- 'response'==ccevent.type:<br>
- ...
- if
- []==ccevent.args[0]:<br>
- ...
- print
- '< [] ', "%-2X %-2X" % tuple(ccevent.args[-2:])<br>
- ...
- else:<br>
-
- ...
- print
- '< ', toHexString(ccevent.args[0]), "%-2X %-2X" %
- tuple(ccevent.args[-2:])<br>
- ...<br>
- >>><br>
- >>> GET_RESPONSE = [0XA0, 0XC0, 00, 00 ]<br>
- >>> SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02]<br>
- >>> DF_TELECOM = [0x7F, 0x10]<br>
- >>><br>
- >>><br>
- >>> cardtype = AnyCardType()<br>
- >>> cardrequest = CardRequest( timeout=10,
- cardType=cardtype )<br>
- >>> cardservice = cardrequest.waitforcard()<br>
- >>><br>
- >>> observer=TracerAndSELECTInterpreter()<br>
- >>> cardservice.connection.addObserver( observer )<br>
- >>><br>
- >>> cardservice.connection.connect()<br>
- connecting to SchlumbergerSema Reflex USB v.2 0<br>
- >>><br>
- >>> apdu = SELECT+DF_TELECOM<br>
- >>> response, sw1, sw2 =
- cardservice.connection.transmit( apdu )<br>
- > <b>SELECT</b> 7F 10<br>
- < [] 9F 1A<br>
- >>> if sw1 == 0x9F:<br>
- ... apdu = GET_RESPONSE + [sw2]<br>
- ... response, sw1, sw2 =
- cardservice.connection.transmit( apdu )<br>
- ... else:<br>
- ... print 'no DF_TELECOM'<br>
- ...<br>
- > <b>GET RESPONSE</b> 1A<br>
- < 00 00 00 00 7F 10 02 00 00 00 00 00 0D 13 00 0A 04 00 83 8A
- 83 8A 00 01 00 00 90 0<br>
- >>></font></p>
-
- <p><a href="#top">to the top</a></p>
-
- <h2><a name="apduerror" id="apduerror"></a>Testing for APDU
- transmission errors</h2>
-
- <p>Upon transmission and processing of an APDU, the smart card
- returns a pair of status words, SW1 and SW2, to report various
- success or error codes following the required processing. Some of
- these success or error codes are standardized in ISO7816-4,
- ISO7816-8 or ISO7816-9, for example. Other status word codes are
- standardized by standardization bodies such as Open Platform
- (e.g. javacard), 3GPP (e.g. SIM or USIM cards), or
- Eurocard-Mastercard-Visa (EMV) (e.g. banking cards). Finally, any
- smart card application developper can defined application related
- proprietary codes; for example the <a href=
- "http://www.linuxnet.com/musclecard/index.html">MUSCLE applet</a>
- defines a set of prioprietary codes related to the MUSCLE applet
- features.</p>
-
- <p>Some of these status word codes are uniques, but others have a
- different meaning depending on the card type and its supported
- standards. For example, ISO7816-4 defines the error code 0x62
- 0x82 as "File Invalidated", whereas in Open Platform 2.1 the same
- error code is defined as "Card life cycle is CARD_LOCKED". As a
- result, the list of error codes that can be returned by a smart
- card and they interpretation depend on the card type. The
- following discussion outlines possible strategies to check and
- report smart card status word errors.</p>
-
- <h3><a name="bruteforceerror" id="bruteforceerror"></a>The brute
- force for testing APDU transmission errors</h3>
-
- <p>As for APDU tracing, a straightforward way of checking for
- errors in response APDUs during the execution of scripts is to
- insert testt statements after the transmit() method calls:</p>
-
- <p><font face="Courier New, Courier, mono" size="2" color=
- "#0033FF">>>> from smartcard.CardType import
- AnyCardType<br>
- >>> from smartcard.CardRequest import CardRequest<br>
- >>> from smartcard.CardConnectionObserver import
- ConsoleCardConnectionObserver<br>
- >>><br>
- >>> GET_RESPONSE = [0XA0, 0XC0, 00, 00 ]<br>
- >>> SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02]<br>
- >>> DF_TELECOM = [0x7F, 0x10]<br>
- >>><br>
- >>> cardtype = AnyCardType()<br>
- >>> cardrequest = CardRequest( timeout=10,
- cardType=cardtype )<br>
- >>> cardservice = cardrequest.waitforcard()<br>
- >>><br>
- >>> observer=ConsoleCardConnectionObserver()<br>
- >>> cardservice.connection.addObserver( observer )<br>
- >>><br>
- >>> cardservice.connection.connect()<br>
- connecting to Utimaco CardManUSB 0<br>
- >>><br>
- >>> apdu = SELECT+DF_TELECOM<br>
- >>> response, sw1, sw2 =
- cardservice.connection.transmit( apdu )<br>
- > A0 A4 00 00 02 7F 10<br>
- < [] 6E 0<br>
- >>><br>
- >>> if sw1 in range(0x61, 0x6f):<br>
- ... print "Error: sw1: %x sw2: %x" % (sw1, sw2)<br>
- ...<br>
- Error: sw1: 6e sw2: 0<br>
- >>> if sw1 == 0x9F:<br>
- ... apdu = GET_RESPONSE + [sw2]<br>
- ... response, sw1, sw2 = cardservice.connection.transmit( apdu
- )<br>
- ...<br>
- >>> cardservice.connection.disconnect()<br>
- disconnecting from Utimaco CardManUSB 0<br>
- >>></font></p>
-
- <p>Scripts written this way are quite difficult to read, because
- there are more error detection statements than actual apdu
- transmits.</p>
-
- <p>An improvement in visibility is to wrap the transmit
- instruction inside a function mytransmit, e.g.:</p>
-
- <p><font face="Courier New, Courier, mono" size="2" color=
- "#0033FF">>>> from smartcard.CardType import
- AnyCardType<br>
- >>> from smartcard.CardRequest import CardRequest<br>
- >>> from smartcard.CardConnectionObserver import
- ConsoleCardConnectionObserver<br>
- >>><br>
- >>> def mytransmit( connection, apdu ):<br>
- ... response, sw1, sw2 = connection.transmit( apdu )<br>
- ... if sw1 in range(0x61, 0x6f):<br>
- ... print "Error: sw1: %x sw2: %x" % (sw1, sw2)<br>
- ... return response, sw1, sw2<br>
- ...<br>
- >>><br>
- >>> GET_RESPONSE = [0XA0, 0XC0, 00, 00 ]<br>
- >>> SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02]<br>
- >>> DF_TELECOM = [0x7F, 0x10]<br>
- >>><br>
- >>><br>
- >>> cardtype = AnyCardType()<br>
- >>> cardrequest = CardRequest( timeout=10,
- cardType=cardtype )<br>
- >>> cardservice = cardrequest.waitforcard()<br>
- >>><br>
- >>> observer=ConsoleCardConnectionObserver()<br>
- >>> cardservice.connection.addObserver( observer )<br>
- >>><br>
- >>> cardservice.connection.connect()<br>
- connecting to Utimaco CardManUSB 0<br>
- >>><br>
- >>> apdu = SELECT+DF_TELECOM<br>
- >>> response, sw1, sw2 = mytransmit(
- cardservice.connection, apdu )<br>
- > A0 A4 00 00 02 7F 10<br>
- < [] 6E 0<br>
- Error: sw1: 6e sw2: 0<br>
- >>><br>
- >>> if sw1 == 0x9F:<br>
- ... apdu = GET_RESPONSE + [sw2]<br>
- ... response, sw1, sw2 = mytransmit( cardservice.connection, apdu
- )<br>
- ...<br>
- >>> cardservice.connection.disconnect()<br>
- disconnecting from Utimaco CardManUSB 0<br>
- >>></font></p>
-
- <p>The prefered solution is for testing errors is to use
- smarcard.sw.ErrorChecker, as described in the following
- section.</p>
-
- <p><a href="#top">to the top</a></p>
-
- <h3><a name="errorcheckingchains" id=
- "errorcheckingchains"></a>Checking APDU transmission errors with
- error checkers</h3>
-
- <p>Status word errors can occur from different sources. The
- ISO7816-4 standards defines status words for sw1 in the range
- 0x62 to 0x6F and some values of sw2, except for 0x66 which is
- reserved for security related issues. The ISO7816-8 standards
- define other status words, e.g. sw1=0x68 and sw2=0x83 or 0x84 for
- command chaining errors. Other standards, like Open Platform,
- define additional status words error, e.g. sw1=0x94 and
- sw2=0x84.</p>
-
- <p>The prefered strategy for status word error checking is based
- around individual error checkers (smartcard.sw.ErrorChecker) that
- can be chained into an error checking chain
- (smartcars.sw.ErrorCheckingChain).</p>
-
- <h4><a name="errorcheckers" id="errorcheckers"></a>Error
- checkers</h4>
-
- <p>An error checker is a class deriving from <a href=
- "epydoc/smartcard.sw.ErrorChecker.ErrorChecker-class.html">ErrorChecker</a>
- that checks for recognized sw1, sw2 error conditions when called,
- and raises an exception when finding such condition. This is
- illustrated in the following sample:</p>
-
- <p><font face="Courier New, Courier, mono" size="2" color=
- "#0033FF">>>> from smartcard.sw.ISO7816_4ErrorChecker
- import ISO7816_4ErrorChecker<br>
- >>><br>
- >>> errorchecker=ISO7816_4ErrorChecker()<br>
- >>> errorchecker( [], 0x90, 0x00 )<br>
- >>> errorchecker( [], 0x6A, 0x80 )<br>
- Traceback (most recent call last):<br>
- File "<stdin>", line 1, in ?<br>
- File
- "D:\projects\pyscard-install\factory\python\lib\site-packages\smartcard\sw\ISO7816_4ErrorChecker.py",
- line 137, in __call__<br>
- raise exception( data, sw1, sw2, message )<br>
- smartcard.sw.SWExceptions.CheckingErrorException: 'Status word
- exception: checking error - Incorrect parameters in the data
- field!'<br>
- >>></font></p>
-
- <p>The first call to error checker does not raise an exception,
- since 90 00 does not report any error. The second calls however
- raises a CheckingErrorException.</p>
-
- <p><a href="#top">to the top</a></p>
-
- <h4><a name="errorcheckingchains2" id=
- "errorcheckingchains2"></a>Error checking chains</h4>
-
- <p>Error checkers can be chained into <a href=
- "epydoc/smartcard.sw.ErrorCheckingChain.ErrorCheckingChain-class.html">
- error checking chain</a>. Each checker in the chain is called
- until an error condition is met, in which case an exception is
- raised. This is illustrated in the following sample:</p>
-
- <p><font face="Courier New, Courier, mono" size="2" color=
- "#0033FF">>>> from smartcard.sw.ISO7816_4ErrorChecker
- import ISO7816_4ErrorChecker<br>
- >>> from smartcard.sw.ISO7816_8ErrorChecker import
- ISO7816_8ErrorChecker<br>
- >>> from smartcard.sw.ISO7816_9ErrorChecker import
- ISO7816_9ErrorChecker<br>
- >>><br>
- >>> from smartcard.sw.ErrorCheckingChain import
- ErrorCheckingChain<br>
- >>><br>
- >>> errorchain = []<br>
- >>> errorchain=[ ErrorCheckingChain( errorchain,
- ISO7816_9ErrorChecker() ),<br>
- ... ErrorCheckingChain( errorchain, ISO7816_8ErrorChecker()
- ),<br>
- ... ErrorCheckingChain( errorchain, ISO7816_4ErrorChecker() )
- ]<br>
- >>><br>
- >>> errorchain[0]( [], 0x90, 0x00 )<br>
- >>> errorchain[0]( [], 0x6A, 0x8a )<br>
- Traceback (most recent call last):<br>
- File "<stdin>", line 1, in ?<br>
- File
- "D:\projects\pyscard-install\factory\python\lib\site-packages\smartcard\sw\ErrorCheckingChain.py",
- line 60,<br>
- in __call__<br>
- self.strategy( data, sw1, sw2 )<br>
- File
- "D:\projects\pyscard-install\factory\python\lib\site-packages\smartcard\sw\ISO7816_9ErrorChecker.py",
- line 74, in __call__<br>
- raise exception( data, sw1, sw2, message )<br>
- smartcard.sw.SWExceptions.CheckingErrorException: 'Status word
- exception: checking error - DF name already exists!'<br>
- >>></font></p>
-
- <p>In this sample, an error checking chain is created that will
- check first for iso 7816-9 errors, then iso7816-8 errors, and
- finally iso7816-4 errors.</p>
-
- <p>The first call to the error chain does not raise an exception,
- since 90 00 does not report any error. The second calls however
- raises a CheckingErrorException, caused by the iso7816-9 error
- checker.</p>
-
- <p><a href="#top">to the top</a></p>
-
- <h4><a name="filteringerrors" id="filteringerrors"></a>Filtering
- exceptions</h4>
-
- <p>You can filter undesired exceptions in a chain by adding a
- filtered exception to the error checking chain:</p>
-
- <...
[truncated message content] |