runtime: integrate escape route for applications without ADF support

the select_parent method in RuntimeLchan currently implements a way
to escape from an application that has no filesystem support. However,
this escape route can be integrated directly into the select_file
method. This will give us the benefit that it will work transparently
in all code locations.

(This also means we can get rid of the select_parent method again)

Related: OS#6120
Change-Id: Ie6f37d13af880d24a9c7a8a95cef436b603587c7
This commit is contained in:
Philipp Maier
2024-08-05 17:43:27 +02:00
parent 2d235f8143
commit 8597b64ee6
2 changed files with 19 additions and 31 deletions

View File

@@ -534,7 +534,7 @@ class PySimCommands(CommandSet):
# below, so we must not move up. # below, so we must not move up.
if skip_df == False: if skip_df == False:
self.walk(indent + 1, action_ef, action_df, context, **kwargs) self.walk(indent + 1, action_ef, action_df, context, **kwargs)
self._cmd.lchan.select_parent(self._cmd) self._cmd.lchan.select_file(self._cmd.lchan.selected_file.parent, self._cmd)
elif action_ef: elif action_ef:
df_before_action = self._cmd.lchan.selected_file df_before_action = self._cmd.lchan.selected_file

View File

@@ -320,6 +320,24 @@ class RuntimeLchan:
file : CardFile [or derived class] instance file : CardFile [or derived class] instance
cmd_app : Command Application State (for unregistering old file commands) cmd_app : Command Application State (for unregistering old file commands)
""" """
if not isinstance(file, CardADF) and self.selected_adf and self.selected_adf.has_fs == False:
# Not every application that may be present on a GlobalPlatform card will support the SELECT
# command as we know it from ETSI TS 102 221, section 11.1.1. In fact the only subset of
# SELECT we may rely on is the OPEN SELECT command as specified in GlobalPlatform Card
# Specification, section 11.9. Unfortunately the OPEN SELECT command only supports the
# "select by name" method, which means we can only select an application and not a file.
# The consequence of this is that we may get trapped in an application that does not have
# ISIM/USIM like file system support and the only way to leave that application is to select
# an ISIM/USIM application in order to get the file system access back.
#
# To automate this escape-route we will first select an arbitrary ADF that has file system support first
# and then continue normally.
for selectable in self.rs.mf.get_selectables().items():
if isinstance(selectable[1], CardADF) and selectable[1].has_fs == True:
self.select(selectable[1].name, cmd_app)
break
# we need to find a path from our self.selected_file to the destination # we need to find a path from our self.selected_file to the destination
inter_path = self.selected_file.build_select_path_to(file) inter_path = self.selected_file.build_select_path_to(file)
if not inter_path: if not inter_path:
@@ -394,36 +412,6 @@ class RuntimeLchan:
return self.selected_file_fcp return self.selected_file_fcp
def select_parent(self, cmd_app=None):
"""Select the parent file of the currently selected file. This method also works in case the currently selected
file is an ADF without UICC file system support and can be used to exit those ADFs.
"""
parent = self.selected_file.parent
df = self.selected_file
adf = self.selected_adf
if adf and adf.has_fs == False:
# Not every application that may be present on a GlobalPlatform card will support the SELECT
# command as we know it from ETSI TS 102 221, section 11.1.1. In fact the only subset of
# SELECT we may rely on is the OPEN SELECT command as specified in GlobalPlatform Card
# Specification, section 11.9. Unfortunately the OPEN SELECT command only supports the
# "select by name" method, which means we can only select an application and not a file.
# The consequence of this is that we may get trapped in an application that does not have
# ISIM/USIM like file system support and the only way to leave that application is to select
# an ISIM/USIM application in order to get the file system access back.
#
# To automate this escape-route while traversing the file system we will check whether
# the parent file is the MF. When this is the case and the selected ADF has no file system
# support, we will select an arbitrary ADF that has file system support first and from there
# we will then select the MF.
for selectable in parent.get_selectables().items():
if isinstance(selectable[1], CardADF) and selectable[1].has_fs == True:
self.select(selectable[1].name, cmd_app)
break
self.select_file(parent, cmd_app)
# Select the parent file normally
self.select_file(parent, cmd_app)
def status(self): def status(self):
"""Request STATUS (current selected file FCP) from card.""" """Request STATUS (current selected file FCP) from card."""
(data, _sw) = self.scc.status() (data, _sw) = self.scc.status()