better handling of non-T=0 APDUs. may still be buggy
git-svn-id: svn+ssh://localhost/home/henryk/svn/cyberflex-shell/trunk@46 f711b948-2313-0410-aaa9-d29f33439f0b
This commit is contained in:
parent
df4e90ea9e
commit
a2d6c6a624
|
@ -20,6 +20,7 @@ class Card:
|
|||
STATUS_WORDS = {
|
||||
SW_OK: "Normal execution",
|
||||
'61??': "%(SW2)i (0x%(SW2)02x) bytes of response data can be retrieved with GetResponse.",
|
||||
'6700': "Wrong length",
|
||||
'6C??': "Bad value for LE, 0x%(SW2)02x is the correct value.",
|
||||
'63C?': lambda SW1,SW2: "The counter has reached the value '%i'" % (SW2%16)
|
||||
}
|
||||
|
@ -60,6 +61,7 @@ class Card:
|
|||
}
|
||||
|
||||
def _check_apdu(apdu):
|
||||
return True
|
||||
if len(apdu) < 4 or ((len(apdu) > 5) and len(apdu) != (ord(apdu[4])+5)):
|
||||
print "Cowardly refusing to send invalid APDU:\n ", utils.hexdump(apdu, indent=2)
|
||||
return False
|
||||
|
@ -81,7 +83,7 @@ class Card:
|
|||
|
||||
def send_apdu(self, apdu):
|
||||
if isinstance(apdu, APDU):
|
||||
apdu = apdu.get_string() ## FIXME
|
||||
apdu = apdu.get_string(protocol = self.get_protocol()) ## FIXME
|
||||
if not Card._check_apdu(apdu):
|
||||
raise Exception, "Invalid APDU"
|
||||
if DEBUG:
|
||||
|
@ -92,7 +94,7 @@ class Card:
|
|||
|
||||
result = self._real_send(apdu)
|
||||
|
||||
if result[0] == '\x61':
|
||||
if len(result) == 2 and result[0] == '\x61':
|
||||
## Need to call GetResponse
|
||||
gr_apdu = APDU(self.APDU_GET_RESPONSE, le = result[1]).get_string()
|
||||
result = self._real_send(gr_apdu)
|
||||
|
@ -136,3 +138,6 @@ class Card:
|
|||
ord(self.last_sw[1]) )
|
||||
|
||||
return "Unknown SW: %s" % binascii.b2a_hex(self.last_sw)
|
||||
|
||||
def get_protocol(self):
|
||||
return ((self.card.status()["Protocol"] == pycsc.SCARD_PROTOCOL_T0) and (0,) or (1,))[0]
|
||||
|
|
58
utils.py
58
utils.py
|
@ -142,27 +142,30 @@ class APDU:
|
|||
|
||||
lc_was_set = False
|
||||
|
||||
if len(initbuff) == 4: ## ISO case 1
|
||||
self.le = 0
|
||||
self.lc = 0
|
||||
self.content = list()
|
||||
elif len(initbuff) == 5: ## ISO case 2
|
||||
self.le = initbuff[self.OFFSET_LE]
|
||||
self.lc = 0
|
||||
self.content = list()
|
||||
elif len(initbuff) > 5:
|
||||
self.lc = initbuff[self.OFFSET_LC]
|
||||
lc_was_set = True
|
||||
if len(initbuff) == 5 + self.lc: ## ISO case 3
|
||||
self.le = 0
|
||||
self.content = initbuff[5:5+self.lc]
|
||||
elif len(initbuff) == 5 + self.lc + 1: ## ISO case 4
|
||||
self.le = initbuff[-1]
|
||||
self.content = initbuff[5:5+self.lc]
|
||||
else:
|
||||
raise ValueError, "Invalid APDU, length(%i) != 4 + 1 + lc(%i) + 1" % (len(initbuff), self.lc)
|
||||
else:
|
||||
raise ValueError, "Invalid APDU, impossible"
|
||||
## if len(initbuff) == 4: ## ISO case 1
|
||||
## self.le = 0
|
||||
## self.lc = 0
|
||||
## self.content = list()
|
||||
## elif len(initbuff) == 5: ## ISO case 2
|
||||
## self.le = initbuff[self.OFFSET_LE]
|
||||
## self.lc = 0
|
||||
## self.content = list()
|
||||
## elif len(initbuff) > 5:
|
||||
## self.lc = initbuff[self.OFFSET_LC]
|
||||
## lc_was_set = True
|
||||
## if len(initbuff) == 5 + self.lc: ## ISO case 3
|
||||
## self.le = 0
|
||||
## self.content = initbuff[5:5+self.lc]
|
||||
## elif len(initbuff) == 5 + self.lc + 1: ## ISO case 4
|
||||
## self.le = initbuff[-1]
|
||||
## self.content = initbuff[5:5+self.lc]
|
||||
## else:
|
||||
## raise ValueError, "Invalid APDU, length(%i) != 4 + 1 + lc(%i) + 1" % (len(initbuff), self.lc)
|
||||
## else:
|
||||
## raise ValueError, "Invalid APDU, impossible"
|
||||
self.le = 0
|
||||
self.lc = len(initbuff)-4
|
||||
self.content = initbuff[4:]
|
||||
|
||||
for (kw_orig, arg) in kwargs.items():
|
||||
kw = kw_orig.lower()
|
||||
|
@ -255,13 +258,16 @@ class APDU:
|
|||
else:
|
||||
self.__dict__[name] = value
|
||||
|
||||
def get_string(self):
|
||||
def get_string(self, protocol=0):
|
||||
"""Return the contents of this APDU as a binary string."""
|
||||
contents = [self.cla, self.ins, self.p1, self.p2]
|
||||
if self.lc > 0:
|
||||
contents.extend( [self.lc] + self.content)
|
||||
if self.le > 0:
|
||||
contents.append( self.le )
|
||||
if protocol == 0:
|
||||
if self.lc > 0:
|
||||
contents.extend( [self.lc] + self.content)
|
||||
if self.le > 0:
|
||||
contents.append( self.le )
|
||||
else:
|
||||
contents.extend( self.content )
|
||||
return "".join([i is not None and chr(i) or "?" for i in contents])
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
Loading…
Reference in New Issue