aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhploetz <hploetz@f711b948-2313-0410-aaa9-d29f33439f0b>2007-06-16 06:56:57 +0000
committerhploetz <hploetz@f711b948-2313-0410-aaa9-d29f33439f0b>2007-06-16 06:56:57 +0000
commitc92a60fb101bec9e24e4593b33cea2bc1aaaa8c1 (patch)
tree09bb3022819c349022b88e138b179c2757bee7a0
parent326fd9a7bea263c9c9603956b9b9e0aa3ff8b4ea (diff)
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
-rwxr-xr-xbrutefid.py5
-rw-r--r--cards/generic_card.py43
-rwxr-xr-xcyberflex-shell.py6
-rwxr-xr-xfingerpass.py5
-rwxr-xr-xreadpass.py5
-rw-r--r--utils.py95
6 files changed, 83 insertions, 76 deletions
diff --git a/brutefid.py b/brutefid.py
index 4161ba8..4ec18b7 100755
--- a/brutefid.py
+++ b/brutefid.py
@@ -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
diff --git a/cards/generic_card.py b/cards/generic_card.py
index 023cbfa..f54d0d6 100644
--- a/cards/generic_card.py
+++ b/cards/generic_card.py
@@ -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
+
diff --git a/cyberflex-shell.py b/cyberflex-shell.py
index 1f28cca..b775f55 100755
--- a/cyberflex-shell.py
+++ b/cyberflex-shell.py
@@ -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)
diff --git a/fingerpass.py b/fingerpass.py
index 6f689c8..b87a038 100755
--- a/fingerpass.py
+++ b/fingerpass.py
@@ -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
diff --git a/readpass.py b/readpass.py
index 1e36ba2..ad38508 100755
--- a/readpass.py
+++ b/readpass.py
@@ -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
diff --git a/utils.py b/utils.py
index 430f219..0162c46 100644
--- a/utils.py
+++ b/utils.py
@@ -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
-
- newState = pycsc.getStatusChange(ReaderStates=[
- {'Reader': readerName, 'CurrentState':pycsc.SCARD_STATE_UNAWARE}
- ]
- )
-
- 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:
-
- 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
+ for r in smartcard.System.readers():
+ if str(r).startswith(reader):
+ readerObject = r
+
+ if readerObject is None:
+ readerObject = smartcard.System.readers()[0]
+
+ 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 )
- 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=[]):