"""The CardConnection abstract class manages connections with a card and apdu transmission. __author__ = "http://www.gemalto.com" Copyright 2001-2008 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. 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. 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. 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 """ from smartcard.CardConnectionEvent import CardConnectionEvent from smartcard.Exceptions import SmartcardException from smartcard.Observer import Observer from smartcard.Observer import Observable class CardConnection(Observable): """Card connection abstract class. Known subclasses: smartcard.pcsc.PCSCCardConnection """ T0_protocol = 0x00000001 T1_protocol = 0x00000002 RAW_protocol = 0x00010000 T15_protocol = 0x00000008 def __init__( self, reader ): """Construct a new card connection. readerName: name of the reader in which the smartcard to connect to is located. """ Observable.__init__(self) self.reader = reader self.errorcheckingchain=None self.defaultprotocol = CardConnection.T0_protocol | CardConnection.T1_protocol def __del__( self ): """Connect to card.""" pass def addSWExceptionToFilter( self, exClass ): """Add a status word exception class to be filtered. exClass: the class to filter, e.g. smartcard.sw.SWException.WarningProcessingException Filtered exceptions will not be raised when encountered in the error checking chain.""" if None!=self.errorcheckingchain: self.errorcheckingchain[0].addFilterException( exClass ) def addObserver(self, observer): """Add a CardConnection observer.""" Observable.addObserver( self, observer ) def deleteObserver(self, observer): """Remove a CardConnection observer.""" Observable.deleteObserver( self, observer ) def connect( self, protocol=None ): """Connect to card. protocol: a bit mask of the protocols to use, from CardConnection.T0_protocol, CardConnection.T1_protocol, CardConnection.RAW_protocol, CardConnection.T15_protocol """ Observable.setChanged( self ) Observable.notifyObservers( self, CardConnectionEvent('connect') ) def disconnect( self ): """Disconnect from card.""" Observable.setChanged( self ) Observable.notifyObservers( self, CardConnectionEvent('disconnect') ) def getATR( self ): """Return card ATR""" pass def getProtocol( self ): """Return bit mask for the protocol of connection, or None if no protocol set. The return value is a bit mask of CardConnection.T0_protocol, CardConnection.T1_protocol, CardConnection.RAW_protocol, CardConnection.T15_protocol """ return self.defaultprotocol def getReader( self ): """Return card connection reader""" return self.reader def setErrorCheckingChain( self, errorcheckingchain ): """Add an error checking chain. errorcheckingchain: a smartcard.sw.ErrorCheckingChain object The error checking strategies in errorchecking chain will be tested with each received response APDU, and a smartcard.sw.SWException.SWException will be raised upon error.""" self.errorcheckingchain=errorcheckingchain def setProtocol( self, protocol ): """Set protocol for card connection. protocol: a bit mask of CardConnection.T0_protocol, CardConnection.T1_protocol, CardConnection.RAW_protocol, CardConnection.T15_protocol e.g. setProtocol( CardConnection.T1_protocol | CardConnection.T0_protocol ) """ self.defaultprotocol = protocol def transmit( self, bytes, protocol=None ): """Transmit an apdu. Internally calls doTransmit() class method and notify observers upon command/response APDU events. Subclasses must override the doTransmit() class method. bytes: list of bytes to transmit protocol: the transmission protocol, from CardConnection.T0_protocol, CardConnection.T1_protocol, or CardConnection.RAW_protocol """ Observable.setChanged( self ) Observable.notifyObservers( self, CardConnectionEvent('command', [bytes, protocol] ) ) data, sw1, sw2 = self.doTransmit( bytes, protocol ) Observable.setChanged( self ) Observable.notifyObservers( self, CardConnectionEvent( 'response', [data, sw1, sw2 ] ) ) if None!=self.errorcheckingchain: self.errorcheckingchain[0]( data, sw1, sw2 ) return data, sw1, sw2 def doTransmit( self, bytes, protocol ): """Performs the command APDU transmission. Subclasses must override this method for implementing apdu transmission.""" pass
"""Card Names class __author__ = "http://www.gemalto.com" Copyright 2001-2008 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. 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. 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. 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 """ from _bsddb import DBNotFoundError from bsddb import hashopen from os import environ from os.path import join from pickle import dumps, loads, HIGHEST_PROTOCOL from smartcard.Synchronization import Synchronization, synchronize from smartcard.util import toBytes class __CardNames__(Synchronization): """__CardNames__ inner class. Stores card names and card types into a bsddb hash database. The smartcard.CardNames.CardNames singleton manages the creation of the unique instance of this class. """ def __init__( self ): Synchronization.__init__(self) carddb_dir=environ['ALLUSERSPROFILE'] carddb_file='cardnames.bdb' carddb_file=join( carddb_dir, carddb_file ) self.db=hashopen( carddb_file, 'w' ) def __del__(self): self.db.sync() self.db.close() def add( self, cardname, cardtype ): self.db[cardname]=dumps(cardtype, HIGHEST_PROTOCOL ) self.db.sync() def delete( self, cardname ): try: del self.db[cardname] except DBNotFoundError: pass def dump( self ): for k,v in self.db.iteritems(): print k, `loads(v)` def find( self, atr, reader=None ): for k,v in self.db.iteritems(): if loads(v).matches( atr, reader ): return k synchronize( __CardNames__, "add delete dump find" ) class CardNames: """The CardNames organizes cards by a unique name and an associated smartcard.CardType.CardType.""" """The single instance of __CardNames__""" instance = None """Constructor: create a single instance of __readergroups on first call""" def __init__(self ): if None==CardNames.instance: CardNames.instance = __CardNames__() """All operators redirected to inner class.""" def __getattr__(self, name): return getattr(self.instance, name) if __name__ == '__main__': from smartcard.CardType import ATRCardType # define a card by its ATR ct = ATRCardType( [0x3B, 0x16, 0x94, 0x20, 0x02, 0x01, 0x00, 0x00, 0x0D] ) # create CardName cn=CardNames() cn.add( "Palmera Protect V2", ct ) cn.dump() print cn.find( [0x3B, 0x16, 0x94, 0x20, 0x02, 0x01, 0x00, 0x00, 0x0D] ) print cn.find( [0x3B, 0x16, 0x94, 0x20, 0x02, 0x01, 0x00, 0x00] ) cn.delete( "Palmera Protect V2" ) print '---------' cn.dump()
"""ATR class managing some of the Answer To Reset content. __author__ = "http://www.gemalto.com" Copyright 2001-2008 gemalto Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com This file is part of pyscard. 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. 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. 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 """ class ATR: clockrateconversion=[ 372, 372, 558, 744, 1116, 1488, 1860, 'RFU', 'RFU', 512, 768, 1024, 1536, 2048, 'RFU', 'RFU', 'RFU' ] bitratefactor=['RFU', 1, 2, 4, 8, 16, 32, 'RFU', 12, 20, 'RFU', 'RFU', 'RFU', 'RFU', 'RFU', 'RFU' ] currenttable=[ 25, 50, 100, 'RFU' ] """ATR class.""" def __init__( self, bytes ): """Construct a new atr from bytes.""" self.bytes = bytes self.__initInstance__() def __checksyncbyte__( self ): """Check validity of TS.""" if not 0x3b==self.bytes[0] and not 0x03f==self.bytes[0]: raise 'invalid TS',"0x%-0.2x"%self.bytes[0] def __initInstance__( self ): """Parse ATR and initialize members: TS: initial character T0: format character TA[n], TB[n], TC[n], TD[n], for n=0,1,...: protocol parameters note: protocol parameters indices start at 0, e.g. TA[0], TA[1] correspond to the ISO standard TA1, TA2 parameters historicalBytes: the ATR T1, T2, ..., TK historical bytes TCK: checksum byte (only for protocols different than T=0 FI: clock rate conversion factor DI: voltage adjustment factor PI1: programming voltage factor II: maximum programming current factor N: extra guard time """ self.__checksyncbyte__() # initial character self.TS = self.bytes[0] # format character self.T0 = self.bytes[1] # count of historical bytes self.K = self.T0 & 0x0f # initialize optional characters lists self.TA = [] self.TB = [] self.TC = [] self.TD = [] self.Y = [] self.hasTA = [] self.hasTB = [] self.hasTC = [] self.hasTD = [] TD=self.T0 hasTD=1 n=0 offset=1 self.interfaceBytesCount=0 while hasTD: self.Y += [TD>>4 & 0x0f] self.hasTD += [(self.Y[n] & 0x08)!=0 ] self.hasTC += [(self.Y[n] & 0x04)!=0 ] self.hasTB += [(self.Y[n] & 0x02)!=0 ] self.hasTA += [(self.Y[n] & 0x01)!=0 ] self.TA += [None] self.TB += [None] self.TC += [None] self.TD += [None] if self.hasTA[n]: self.TA[n]=self.bytes[ offset+self.hasTA[n] ] if self.hasTB[n]: self.TB[n]=self.bytes[ offset+self.hasTA[n]+self.hasTB[n] ] if self.hasTC[n]: self.TC[n]=self.bytes[ offset+self.hasTA[n]+self.hasTB[n]+self.hasTC[n] ] if self.hasTD[n]: self.TD[n]=self.bytes[ offset+self.hasTA[n]+self.hasTB[n]+self.hasTC[n]+self.hasTD[n] ] self.interfaceBytesCount += self.hasTA[n]+self.hasTB[n]+self.hasTC[n]+self.hasTD[n] TD=self.TD[n] hasTD=self.hasTD[n] offset=offset+self.hasTA[n]+self.hasTB[n]+self.hasTC[n]+self.hasTD[n] n=n+1 # historical bytes self.historicalBytes=self.bytes[offset+1:offset+1+self.K] # checksum self.hasChecksum = (len(self.bytes)==offset+1+self.K+1) if self.hasChecksum: self.TCK=self.bytes[-1] checksum=0 for b in self.bytes[1:]: checksum = checksum ^ b self.checksumOK = (checksum==0) else: self.TCK = None # clock-rate conversion factor if self.hasTA[0]: self.FI = self.TA[0]>>4 & 0x0f else: self.FI = None # bit-rate adjustment factor if self.hasTA[0]: self.DI = self.TA[0] & 0x0f else: self.DI = None # maximum programming current factor if self.hasTB[0]: self.II = self.TB[0]>>5 & 0x03 else: self.II = None # programming voltage factor if self.hasTB[0]: self.PI1 = self.TB[0] & 0x1f else: self.PI1 = None # extra guard time self.N = self.TC[0] def getChecksum( self ): """Return the checksum of the ATR. Checksum is mandatory only for T=1.""" return self.TCK def getHistoricalBytes( self ): """Return historical bytes.""" return self.historicalBytes def getHistoricalBytesCount( self ): """Return count of historical bytes.""" return len( self.historicalBytes ) def getInterfaceBytesCount( self ): """Return count of interface bytes.""" return self.interfaceBytesCount def getTA1( self ): """Return TA1 byte.""" return self.TA[0] def getTB1( self ): """Return TB1 byte.""" return self.TB[0] def getTC1( self ): """Return TC1 byte.""" return self.TC[0] def getTD1(self): """Return TD1 byte.""" return self.TD[0] def getBitRateFactor( self ): """Return bit rate factor.""" if self.DI!=None: return ATR.bitratefactor[ self.DI ] else: return 1 def getClockRateConversion( self ): """Return clock rate conversion.""" if self.FI!=None: return ATR.clockrateconversion[ self.FI ] else: return 372 def getProgrammingCurrent( self ): """Return maximum programming current.""" if self.II!=None: return ATR.currenttable[ self.II ] else: return 50 def getProgrammingVoltage( self ): """Return programming voltage.""" if self.PI1!=None: return 5*(1+self.PI1) else: return 5 def getGuardTime( self ): """Return extra guard time.""" return self.N def getSupportedProtocols( self ): """Returns a dictionnary of supported protocols.""" protocols={} for td in self.TD: if td!=None: strprotocol = "T=%d" % (td & 0x0F) protocols[strprotocol]=True if not self.hasTD[0]: protocols['T=0']=True return protocols def isT0Supported( self ): """Return True if T=0 is supported.""" protocols=self.getSupportedProtocols() return protocols.has_key( 'T=0' ) def isT1Supported( self ): """Return True if T=1 is supported.""" protocols=self.getSupportedProtocols() return protocols.has_key( 'T=1' ) def isT15Supported( self ): """Return True if T=15 is supported.""" protocols=self.getSupportedProtocols() return protocols.has_key( 'T=15' ) def dump( self ): """Dump the details of an ATR.""" for i in range( 0, len(self.TA) ): if self.TA[i]!=None: print "TA%d: %x" % (i+1,self.TA[i]) if self.TB[i]!=None: print "TB%d: %x" % (i+1,self.TB[i]) if self.TC[i]!=None: print "TC%d: %x" % (i+1,self.TC[i]) if self.TD[i]!=None: print "TD%d: %x" % (i+1,self.TD[i]) print 'supported protocols', self.getSupportedProtocols() print 'T=0 supported', self.isT0Supported() print 'T=1 supported', self.isT1Supported() print 'checksum:', self.getChecksum() print '\tclock rate conversion factor:', self.getClockRateConversion() print '\tbit rate adjustment factor:', self.getBitRateFactor() print '\tmaximum programming current:', self.getProgrammingCurrent() print '\tprogramming voltage:', self.getProgrammingVoltage() print '\tguard time:', self.getGuardTime() print 'nb of interface bytes:', self.getInterfaceBytesCount() print 'nb of historical bytes:', self.getHistoricalBytesCount() def __str__( self ): """Returns a string representation of the ATR as a strem of bytes.""" return reduce( lambda a, b: a+"%-0.2X " % ((b+256)%256), self.bytes, '' ) if __name__ == '__main__': """Small sample illustrating the use of ATR.""" atrs = [ [ 0x3F, 0x65, 0x25, 0x00, 0x2C, 0x09, 0x69, 0x90, 0x00 ], [ 0x3F, 0x65, 0x25, 0x08, 0x93, 0x04, 0x6C, 0x90, 0x00 ], [ 0x3B, 0x16, 0x94, 0x7C, 0x03, 0x01, 0x00, 0x00, 0x0D ], [ 0x3B, 0x65, 0x00, 0x00, 0x9C, 0x11, 0x01, 0x01, 0x03 ], [ 0x3B, 0xE3, 0x00, 0xFF, 0x81, 0x31, 0x52, 0x45, 0xA1, 0xA2, 0xA3, 0x1B], [ 0x3B, 0xE5, 0x00, 0x00, 0x81, 0x21, 0x45, 0x9C, 0x10, 0x01, 0x00, 0x80, 0x0D ] ] for atr in atrs: a=ATR( atr ) print 80*'-' print a a.dump() print reduce( lambda a, b: a+"%-0.2X " % ((b+256)%256), a.getHistoricalBytes(), '' )
если возможно накидайте рабочий код на подключение карты, дальше по примеру надеюсь смогу разобраться