aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@osmocom.org>2024-02-01 20:28:33 +0100
committerHarald Welte <laforge@osmocom.org>2024-02-04 14:53:07 +0100
commit0e9ad7b5d472e09f9f5900328ae69294b5442671 (patch)
tree37e2e491a0b348905c9ce5c54d660d41bc6b79cd
parent5dc8471526c099849bffd892477464c85fbd9364 (diff)
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
-rw-r--r--docs/shell.rst6
-rw-r--r--pySim/global_platform/__init__.py32
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')