Switch smartcard interface to pyscard from http://pyscard.sourceforge.net/

pycsc no longer supported
API change: utils doesn't export "pycsc" anymore
API change: utils.CommandLineArgumentHelper.connect now returns smartcard.CardService.CardService instance
API change: cards.generic_card.Card.__init__ and ...can_handle (and therefore cards.new_card_object) now expect CardService or CardConnection instance


git-svn-id: svn+ssh://localhost/home/henryk/svn/cyberflex-shell/trunk@247 f711b948-2313-0410-aaa9-d29f33439f0b
This commit is contained in:
hploetz 2007-06-16 06:56:57 +00:00
parent 326fd9a7be
commit c92a60fb10
6 changed files with 81 additions and 74 deletions

View File

@ -1,7 +1,6 @@
#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-
from utils import pycsc
import utils, cards, TLV_utils, sys, binascii, time, traceback
STATUS_INTERVAL = 10
@ -21,8 +20,8 @@ if __name__ == "__main__":
top_level = ("".join( ["".join(e.split()) for e in arguments] )).split("/")
top_level = [binascii.unhexlify(e) for e in top_level]
pycsc_card = c.connect()
card = cards.new_card_object(pycsc_card)
card_object = c.connect()
card = cards.new_card_object(card_object)
cards.generic_card.DEBUG = False
print >>sys.stderr, "Using %s" % card.DRIVER_NAME

View File

@ -1,4 +1,4 @@
from utils import pycsc
import smartcard
import TLV_utils, crypto_utils, utils, binascii, fnmatch, re
from utils import C_APDU, R_APDU
@ -122,14 +122,12 @@ class Card:
}
TLV_OBJECTS[TLV_utils.context_FCI] = TLV_OBJECTS[TLV_utils.context_FCP]
def __init__(self, card = None, reader = None):
if card is None:
if reader is None:
self.card = pycsc.pycsc(protocol = pycsc.SCARD_PROTOCOL_ANY)
else:
self.card = pycsc.pycsc(protocol = pycsc.SCARD_PROTOCOL_ANY, reader = reader)
else:
def __init__(self, card):
if not hasattr(card, "connection"):
self.card = card
else:
self.card = card.connection
self.cardservice = card
self._i = 0
self.last_apdu = None
@ -156,7 +154,8 @@ class Card:
def cmd_reset(self):
"""Reset the card."""
self.card.reconnect(init=pycsc.SCARD_RESET_CARD)
# FIXME
raise NotImplementedException
def cmd_parsetlv(self, start = None, end = None):
"Decode the TLV data in the last response, start and end are optional"
@ -190,14 +189,20 @@ class Card:
"parse_tlv": cmd_parsetlv,
"show_applications": cmd_show_applications,
}
PROTOMAP = {
0: smartcard.scard.SCARD_PCI_T0,
1: smartcard.scard.SCARD_PCI_T1,
}
def _real_send(self, apdu):
apdu_binary = apdu.render()
if DEBUG:
print ">> " + utils.hexdump(apdu_binary, indent = 3)
result_binary = self.card.transmit(apdu_binary)
apdu_bytes = map(lambda x: ord(x), apdu_binary)
data, sw1, sw2 = self.card.transmit(apdu_bytes, protocol=self.PROTOMAP[self.get_protocol()])
result_binary = map(lambda x: chr(x), data + [sw1,sw2])
result = R_APDU(result_binary)
self.last_apdu = apdu
@ -249,8 +254,11 @@ class Card:
return self.card.status().get("ATR","")
def can_handle(cls, card):
"""Determine whether this class can handle a given pycsc object."""
ATR = card.status().get("ATR","")
"""Determine whether this class can handle a given card/connection object."""
if hasattr(card, "connection"):
ATR = smartcard.util.toASCIIString(card.connection.getATR())
else:
ATR = smartcard.util.toASCIIString(card.getATR())
def match_list(atr, list):
for (knownatr, mask) in list:
if mask is None:
@ -310,7 +318,8 @@ class Card:
return "%s (SW %s)" % (retval, binascii.b2a_hex(self.last_sw))
def get_protocol(self):
return ((self.card.status()["Protocol"] == pycsc.SCARD_PROTOCOL_T0) and (0,) or (1,))[0]
hresult, reader, state, protocol, atr = smartcard.scard.SCardStatus( self.card.component.hcard )
return ((protocol == smartcard.scard.SCARD_PROTOCOL_T0) and (0,) or (1,))[0]
def get_driver_name(self):
if len(self.DRIVER_NAME) > 1:
@ -321,4 +330,8 @@ class Card:
def close_card(self):
"Disconnect from a card"
del self.card # FIXME: anything else to do?
self.card.disconnect()
if hasattr(self, "cardservice"):
del self.cardservice
del self.card

View File

@ -1,8 +1,6 @@
#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-
from utils import pycsc
import crypto_utils, utils, cards, os, re, binascii, sys, exceptions, traceback, getopt, datetime
from shell import Shell
@ -342,8 +340,8 @@ class Cyberflex_Shell(Shell):
if reader is None:
reader = self.reader
pycsc_card = utils.CommandLineArgumentHelper.connect_to(reader)
self.card = cards.new_card_object(pycsc_card)
card_object = utils.CommandLineArgumentHelper.connect_to(reader)
self.card = cards.new_card_object(card_object)
self.unregister_commands(self, self.NOCARD_COMMANDS)
self.register_commands(self, self.CARD_COMMANDS)

View File

@ -1,7 +1,6 @@
#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-
from utils import pycsc
import utils, cards, TLV_utils, sys, binascii, time, traceback, re
def fingerprint_rfid(card):
@ -184,8 +183,8 @@ if __name__ == "__main__":
c = utils.CommandLineArgumentHelper()
(options, arguments) = c.getopt(sys.argv[1:])
pycsc_card = c.connect()
card = cards.new_card_object(pycsc_card)
card_object = c.connect()
card = cards.new_card_object(card_object)
cards.generic_card.DEBUG = False
print >>sys.stderr, "Using %s" % card.DRIVER_NAME

View File

@ -1,7 +1,6 @@
#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-
from utils import pycsc
import utils, cards, TLV_utils, sys, binascii, time, traceback
OPTIONS = "GW:R:"
@ -25,8 +24,8 @@ if __name__ == "__main__":
read_files = value
if read_files is None:
pycsc_card = c.connect()
card = cards.new_card_object(pycsc_card)
card_object = c.connect()
card = cards.new_card_object(card_object)
cards.generic_card.DEBUG = False
print >>sys.stderr, "Using %s" % card.DRIVER_NAME

View File

@ -1,14 +1,13 @@
try:
import pycsc
except ImportError,e:
try:
import PyCSC
from PyCSC import pycsc # Windows
pycsc.SCARD_PROTOCOL_ANY = PyCSC.SCARD_PROTOCOL_ANY
except ImportError:
raise e # raise the original exception, masking the windows-only attempt
import string, binascii, sys, re, getopt
try:
import smartcard, smartcard.CardRequest
except ImportError:
print >>sys.stderr, """Could not import smartcard module. Please install pyscard
from http://pyscard.sourceforge.net/
If you can't install pyscard and want to continue using
pycsc you'll need to downgrade to SVN revision 246.
"""
raise
class CommandLineArgumentHelper:
OPTIONS = "r:l"
@ -17,7 +16,7 @@ class CommandLineArgumentHelper:
reader = None
def list_readers():
for index, name in enumerate(pycsc.listReader()):
for index, name in enumerate(smartcard.System.readers()):
print "%i: %s" % (index, name)
list_readers = staticmethod(list_readers)
@ -32,48 +31,48 @@ class CommandLineArgumentHelper:
def connect_to(reader):
"Open the connection to a reader"
readerObject = None
if isinstance(reader, int) or reader.isdigit():
reader = int(reader)
readerName = pycsc.listReader()[reader]
readerObject = smartcard.System.readers()[reader]
else:
readerName = reader
for r in smartcard.System.readers():
if str(r).startswith(reader):
readerObject = r
newState = pycsc.getStatusChange(ReaderStates=[
{'Reader': readerName, 'CurrentState':pycsc.SCARD_STATE_UNAWARE}
]
)
if readerObject is None:
readerObject = smartcard.System.readers()[0]
print "Using reader: %s" % readerName
print "Card present: %s" % ((newState[0]['EventState'] & pycsc.SCARD_STATE_PRESENT) and "yes" or "no")
if not newState[0]['EventState'] & pycsc.SCARD_STATE_PRESENT:
print "Please insert card ..."
last_was_mute = False
while not newState[0]['EventState'] & pycsc.SCARD_STATE_PRESENT \
or newState[0]['EventState'] & pycsc.SCARD_STATE_MUTE:
print "Using reader: %s" % readerObject
unpatched = False
printed = False
while True:
try:
if not unpatched:
cardrequest = smartcard.CardRequest.CardRequest( readers=[readerObject], timeout=0.1 )
else:
cardrequest = smartcard.CardRequest.CardRequest( readers=[readerObject], timeout=1 )
try:
newState = pycsc.getStatusChange(ReaderStates=[
{'Reader': readerName, 'CurrentState':newState[0]['EventState']}
], Timeout = 100
) ## 100 ms latency from Ctrl-C to abort should be almost unnoticeable by the user
except pycsc.PycscException, e:
if e.args[0] == 'Command timeout.': pass ## ugly
else: raise
if newState[0]['EventState'] & pycsc.SCARD_STATE_MUTE:
if not last_was_mute:
print "Card is mute, please retry ..."
last_was_mute = True
else:
last_was_mute = False
print "Card present: %s" % ((newState[0]['EventState'] & pycsc.SCARD_STATE_PRESENT) and "yes" or "no")
cardservice = cardrequest.waitforcard()
cardservice.connection.connect()
break
except TypeError:
unpatched = True
except (KeyboardInterrupt, SystemExit):
raise
except smartcard.Exceptions.CardRequestException:
if sys.exc_info()[1].message.endswith("Command timeout."):
if not printed:
print "Please insert card ..."
printed = True
else:
raise
except smartcard.Exceptions.NoCardException:
print "Card is mute or absent. Please retry."
print "ATR: %s" % hexdump(newState[0]['Atr'], short = True)
return pycsc.pycsc(reader = readerName, protocol = pycsc.SCARD_PROTOCOL_ANY)
print "ATR: %s" % hexdump(smartcard.util.toASCIIString(cardservice.connection.getATR()), short = True)
return cardservice
connect_to = staticmethod(connect_to)
def getopt(self, argv, opts="", long_opts=[]):