From 0e9ad7b5d472e09f9f5900328ae69294b5442671 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Thu, 1 Feb 2024 20:28:33 +0100 Subject: global_platform: add set_status command Using this command, one can change the life cycle status of on-card applications, specifically one can LOCK (disable) them and re-enable them as needed. Change-Id: Ie14297a119d01cad1284f315a2508aa92cb4633b --- docs/shell.rst | 6 ++++++ pySim/global_platform/__init__.py | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/docs/shell.rst b/docs/shell.rst index 96b04a7..aa301d8 100644 --- a/docs/shell.rst +++ b/docs/shell.rst @@ -947,6 +947,12 @@ get_status :module: pySim.global_platform :func: ADF_SD.AddlShellCommands.get_status_parser +set_status +~~~~~~~~~~ +.. argparse:: + :module: pySim.global_platform + :func: ADF_SD.AddlShellCommands.set_status_parser + store_data ~~~~~~~~~~ .. argparse:: diff --git a/pySim/global_platform/__init__.py b/pySim/global_platform/__init__.py index 5492e44..17be946 100644 --- a/pySim/global_platform/__init__.py +++ b/pySim/global_platform/__init__.py @@ -94,6 +94,12 @@ KeyType = Enum(Byte, des=0x80, ecc_key_parameters_reference=0xF0, # v2.3.1 Section 11.1.8 not_available=0xff) +# GlobalPlatform 2.3 Section 11.10.2.1 Table 11-86 +SetStatusScope = Enum(Byte, isd=0x80, app_or_ssd=0x40, isd_and_assoc_apps=0xc0) + +# GlobalPlatform 2.3 section 11.1.1 +CLifeCycleState = Enum(Byte, loaded=0x01, installed=0x03, selectable=0x07, personalized=0x0f, locked=0x83) + # GlobalPlatform 2.1.1 Section 9.3.3.1 class KeyInformationData(BER_TLV_IE, tag=0xc0): _test_de_encode = [ @@ -376,7 +382,7 @@ StatusSubset = Enum(Byte, isd=0x80, applications=0x40, files=0x20, files_and_mod # Section 11.4.3.1 Table 11-36 class LifeCycleState(BER_TLV_IE, tag=0x9f70): - _construct = Int8ub + _construct = CLifeCycleState # Section 11.4.3.1 Table 11-36 + Section 11.1.2 class Privileges(BER_TLV_IE, tag=0xc5): @@ -557,7 +563,7 @@ class ADF_SD(CardADF): @cmd2.with_argparser(get_status_parser) def do_get_status(self, opts): - """Perform GlobalPlatform GET STATUS command in order to retriev status information + """Perform GlobalPlatform GET STATUS command in order to retrieve status information on Issuer Security Domain, Executable Load File, Executable Module or Applications.""" grd_list = self.get_status(opts.subset, opts.aid) for grd in grd_list: @@ -584,6 +590,28 @@ class ADF_SD(CardADF): p2 |= 0x01 return grd_list + set_status_parser = argparse.ArgumentParser() + set_status_parser.add_argument('scope', choices=SetStatusScope.ksymapping.values(), + help='Defines the scope of the requested status change') + set_status_parser.add_argument('status', choices=CLifeCycleState.ksymapping.values(), + help='Specify the new intended status') + set_status_parser.add_argument('--aid', type=is_hexstr, + help='AID of the target Application or Security Domain') + + @cmd2.with_argparser(set_status_parser) + def do_set_status(self, opts): + """Perform GlobalPlatform SET STATUS command in order to change the life cycle state of the + Issuer Security Domain, Supplementary Security Domain or Application. This normally requires + prior authentication with a Secure Channel Protocol.""" + self.set_status(opts.scope, opts.status, opts.aid) + + def set_status(self, scope:str, status:str, aid:Hexstr = ''): + SetStatus = Struct(Const(0x80, Byte), Const(0xF0, Byte), + 'scope'/SetStatusScope, 'status'/CLifeCycleState, + 'aid'/HexAdapter(Prefixed(Int8ub, Optional(GreedyBytes)))) + apdu = build_construct(SetStatus, {'scope':scope, 'status':status, 'aid':aid}) + data, sw = self._cmd.lchan.scc.send_apdu_checksw(b2h(apdu)) + inst_perso_parser = argparse.ArgumentParser() inst_perso_parser.add_argument('application-aid', type=is_hexstr, help='Application AID') -- cgit v1.2.3