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] |