mirror of
https://gitea.osmocom.org/sim-card/pysim.git
synced 2026-03-26 15:28:35 +03:00
global_platform: Implement generic store_data command
Change-Id: If30c5d31b4e7dd60d3a5cfb1d1cbdcf61741a50e
This commit is contained in:
@@ -287,6 +287,12 @@ def decode_select_response(resp_hex: str) -> object:
|
|||||||
|
|
||||||
# Application Dedicated File of a Security Domain
|
# Application Dedicated File of a Security Domain
|
||||||
class ADF_SD(CardADF):
|
class ADF_SD(CardADF):
|
||||||
|
StoreData = BitStruct('last_block'/Flag,
|
||||||
|
'encryption'/Enum(BitsInteger(2), none=0, application_dependent=1, rfu=2, encrypted=3),
|
||||||
|
'structure'/Enum(BitsInteger(2), none=0, dgi=1, ber_tlv=2, rfu=3),
|
||||||
|
'_pad'/Padding(2),
|
||||||
|
'response'/Enum(Bit, not_expected=0, may_be_returned=1))
|
||||||
|
|
||||||
def __init__(self, aid: str, name: str, desc: str):
|
def __init__(self, aid: str, name: str, desc: str):
|
||||||
super().__init__(aid=aid, fid=None, sfid=None, name=name, desc=desc)
|
super().__init__(aid=aid, fid=None, sfid=None, name=name, desc=desc)
|
||||||
self.shell_commands += [self.AddlShellCommands()]
|
self.shell_commands += [self.AddlShellCommands()]
|
||||||
@@ -325,6 +331,41 @@ class ADF_SD(CardADF):
|
|||||||
index_dict = {1: data_dict}
|
index_dict = {1: data_dict}
|
||||||
return self._cmd.index_based_complete(text, line, begidx, endidx, index_dict=index_dict)
|
return self._cmd.index_based_complete(text, line, begidx, endidx, index_dict=index_dict)
|
||||||
|
|
||||||
|
store_data_parser = argparse.ArgumentParser()
|
||||||
|
store_data_parser.add_argument('--data-structure', type=str, choices=['none','dgi','ber_tlv','rfu'], default='none')
|
||||||
|
store_data_parser.add_argument('--encryption', type=str, choices=['none','application_dependent', 'rfu', 'encrypted'], default='none')
|
||||||
|
store_data_parser.add_argument('--response', type=str, choices=['not_expected','may_be_returned'], default='not_expected')
|
||||||
|
store_data_parser.add_argument('DATA', type=is_hexstr)
|
||||||
|
|
||||||
|
@cmd2.with_argparser(store_data_parser)
|
||||||
|
def do_store_data(self, opts):
|
||||||
|
"""Perform the GlobalPlatform GET DATA command in order to store some card-specific data.
|
||||||
|
See GlobalPlatform CardSpecification v2.3Section 11.11 for details."""
|
||||||
|
response_permitted = opts.response == 'may_be_returned'
|
||||||
|
self.store_data(h2b(opts.DATA), opts.data_structure, opts.encryption, response_permitted)
|
||||||
|
|
||||||
|
def store_data(self, data: bytes, structure:str = 'none', encryption:str = 'none', response_permitted: bool = False) -> bytes:
|
||||||
|
"""Perform the GlobalPlatform GET DATA command in order to store some card-specific data.
|
||||||
|
See GlobalPlatform CardSpecification v2.3Section 11.11 for details."""
|
||||||
|
# Table 11-89 of GP Card Specification v2.3
|
||||||
|
remainder = data
|
||||||
|
block_nr = 0
|
||||||
|
response = ''
|
||||||
|
while len(remainder):
|
||||||
|
chunk = remainder[:255]
|
||||||
|
remainder = remainder[255:]
|
||||||
|
p1b = build_construct(ADF_SD.StoreData,
|
||||||
|
{'last_block': len(remainder) == 0, 'encryption': encryption,
|
||||||
|
'structure': structure, 'response': response_permitted})
|
||||||
|
hdr = "80E2%02x%02x%02x" % (p1b[0], block_nr, len(chunk))
|
||||||
|
data, sw = self._cmd.lchan.scc._tp.send_apdu_checksw(hdr + b2h(chunk))
|
||||||
|
block_nr += 1
|
||||||
|
response += data
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Card Application of a Security Domain
|
# Card Application of a Security Domain
|
||||||
class CardApplicationSD(CardApplication):
|
class CardApplicationSD(CardApplication):
|
||||||
__intermediate = True
|
__intermediate = True
|
||||||
|
|||||||
Reference in New Issue
Block a user