aboutsummaryrefslogtreecommitdiffstats
path: root/cards/iso_7816_4_card.py
diff options
context:
space:
mode:
authorhploetz <hploetz@f711b948-2313-0410-aaa9-d29f33439f0b>2006-05-21 13:04:48 +0000
committerhploetz <hploetz@f711b948-2313-0410-aaa9-d29f33439f0b>2006-05-21 13:04:48 +0000
commit77659befd1e3e9e81eda71878af58167ab2e1138 (patch)
tree18b328f60cf679504c04274cdf15c60dc8d146e9 /cards/iso_7816_4_card.py
parent1d3b76657fee7eba81fc756e4e7a856599d58a02 (diff)
generalize file operations, specialise for starcos
git-svn-id: svn+ssh://localhost/home/henryk/svn/cyberflex-shell/trunk@67 f711b948-2313-0410-aaa9-d29f33439f0b
Diffstat (limited to 'cards/iso_7816_4_card.py')
-rw-r--r--cards/iso_7816_4_card.py70
1 files changed, 70 insertions, 0 deletions
diff --git a/cards/iso_7816_4_card.py b/cards/iso_7816_4_card.py
index cb49202..c9b6410 100644
--- a/cards/iso_7816_4_card.py
+++ b/cards/iso_7816_4_card.py
@@ -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,
} )