generalize file operations, specialise for starcos

git-svn-id: svn+ssh://localhost/home/henryk/svn/cyberflex-shell/trunk@67 f711b948-2313-0410-aaa9-d29f33439f0b
This commit is contained in:
hploetz 2006-05-21 13:04:48 +00:00
parent 1d3b76657f
commit 77659befd1
4 changed files with 91 additions and 48 deletions

View File

@ -3,7 +3,9 @@ from generic_card import *
class ISO_7816_4_Card(Card):
APDU_SELECT_FILE = C_APDU("\x00\xa4\x00\x00")
APDU_READ_BINARY = C_APDU("\x00\xb0\x00\x00\x00")
DRIVER_NAME = "ISO 7816-4"
FID_MF = "\x3f\x00"
## def can_handle(cls, card):
## return True
@ -16,6 +18,71 @@ class ISO_7816_4_Card(Card):
data = fid, le = 0) )
return result
def change_dir(self, fid = None):
"Change to a child DF. Alternatively, change to MF if fid is None."
if fid is None:
return self.select_file(0x00, 0x00, "")
else:
return self.select_file(0x01, 0x00, fid)
def cmd_cd(self, dir = None):
"Change into a DF, or into the MF if no dir is given"
if dir is None:
result = self.change_dir()
else:
fid = binascii.a2b_hex("".join(dir.split()))
result = self.change_dir(fid)
if len(result.data) > 0:
print utils.hexdump(result.data)
print TLV_utils.decode(result.data)
def open_file(self, fid):
"Open an EF under the current DF"
return self.select_file(0x02, 0x00, fid)
def cmd_open(self, file):
"Open a file"
fid = binascii.a2b_hex("".join(file.split()))
result = self.open_file(fid)
if len(result.data) > 0:
print utils.hexdump(result.data)
print TLV_utils.decode(result.data)
def read_binary_file(self, offset = 0):
"""Read from the currently selected EF.
Repeat calls to READ BINARY as necessary to get the whole EF."""
if offset >= 1<<15:
raise ValueError, "offset is limited to 15 bits"
contents = ""
had_one = False
while True:
command = C_APDU(self.APDU_READ_BINARY, p1 = offset >> 8, p2 = (offset & 0xff))
result = self.send_apdu(command)
if len(result.data) > 0:
contents = contents + result.data
offset = offset + len(result.data)
if result.sw != self.SW_OK:
break
else:
had_one = True
if had_one: ## If there was at least one successful pass, ignore any error SW. It probably only means "end of file"
self.sw_changed = False
return contents
def cmd_cat(self):
"Print a hexdump of the currently selected file (e.g. consecutive READ BINARY)"
contents = self.read_binary_file()
self.last_result = R_APDU(contents + self.last_sw)
print utils.hexdump(contents)
def cmd_selectfile(self, p1, p2, fid):
"""Select a file on the card."""
@ -40,6 +107,9 @@ class ISO_7816_4_Card(Card):
COMMANDS = dict(Card.COMMANDS)
COMMANDS.update( {
"select_file": cmd_selectfile,
"cd": cmd_cd,
"cat": cmd_cat,
"open": cmd_open,
"parse_tlv": cmd_parsetlv,
} )

19
cards/starcos_card.py Normal file
View File

@ -0,0 +1,19 @@
import utils
from iso_7816_4_card import *
class Starcos_Card(ISO_7816_4_Card):
DRIVER_NAME = "Starcos"
APDU_READ_BINARY = C_APDU("\x00\xb0\x00\x00\xfe")
def change_dir(self, fid = None):
"Change to a child DF. Alternatively, change to MF if fid is None."
if fid is None:
return self.select_file(0x00, 0x0C, self.FID_MF)
else:
return self.select_file(0x00, 0x0C, fid)
ATRS = list(Card.ATRS)
ATRS.extend( [
("3bb794008131fe6553504b32339000d1", None),
] )

View File

@ -4,7 +4,6 @@ from iso_7816_4_card import *
class TCOS_Card(ISO_7816_4_Card):
DRIVER_NAME = "TCOS"
APDU_LIST_X = C_APDU("\x80\xaa\x01\x00\x00")
APDU_READ_BINARY = C_APDU("\x00\xb0\x00\x00")
def list_x(self, x):
"Get a list of x objects, where x is one of 1 (DFs) or 2 (EFs)"
@ -17,32 +16,6 @@ class TCOS_Card(ISO_7816_4_Card):
result_list.append(head)
return result_list
def read_binary_file(self, offset = 0):
"""Read from the currently selected EF.
Repeat calls to READ BINARY as necessary to get the whole EF."""
if offset >= 1<<15:
raise ValueError, "offset is limited to 15 bits"
contents = ""
had_one = False
while True:
command = C_APDU(self.APDU_READ_BINARY, p1 = offset >> 8, p2 = (offset & 0xff), le = 0)
result = self.send_apdu(command)
if len(result.data) > 0:
contents = contents + result.data
offset = offset + len(result.data)
if result.sw != self.SW_OK:
break
else:
had_one = True
if had_one: ## If there was at least one successful pass, ignore any error SW. It probably only means "end of file"
self.sw_changed = False
return contents
def cmd_listdirs(self):
"List DFs in current DF"
result = self.list_x(1)
@ -61,23 +34,6 @@ class TCOS_Card(ISO_7816_4_Card):
print "\n".join( ["[%s]" % utils.hexdump(a, short=True) for a in dirs]
+ [" %s " % utils.hexdump(a, short=True) for a in files] )
def cmd_cd(self, dir = None):
"Change into a DF, or into the MF if no dir is given"
if dir is None:
return self.cmd_selectfile("00", "00", "")
else:
return self.cmd_selectfile("01", "00", dir)
def cmd_open(self, file):
"Shortcut for 'select_file 02 00 file'"
return self.cmd_selectfile("02", "00", file)
def cmd_cat(self):
"Print a hexdump of the currently selected file (e.g. consecutive READ BINARY)"
contents = self.read_binary_file()
self.last_result = R_APDU(contents + self.last_sw)
print utils.hexdump(contents)
ATRS = list(Card.ATRS)
ATRS.extend( [
("3bba96008131865d0064057b0203318090007d", None),
@ -88,7 +44,4 @@ class TCOS_Card(ISO_7816_4_Card):
"list_dirs": cmd_listdirs,
"list_files": cmd_listfiles,
"ls": cmd_list,
"cd": cmd_cd,
"open": cmd_open,
"cat": cmd_cat,
} )

View File

@ -172,7 +172,8 @@ class APDU(object):
self.parse( initbuff )
for (name, value) in kwargs.items():
setattr(self, name, value)
if value is not None:
setattr(self, name, value)
def _getdata(self):
return self._data