Change in pysim[master]: filesystem: fix decode_select_response

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

laforge gerrit-no-reply at lists.osmocom.org
Wed Nov 10 17:26:12 UTC 2021


laforge has submitted this change. ( https://gerrit.osmocom.org/c/pysim/+/26161 )

Change subject: filesystem: fix decode_select_response
......................................................................

filesystem: fix decode_select_response

There are some problems with the usage of decode_select_response. At the
moment the ADF files overload the related method to provide decoding of
the select responses as per 3gpp TS 102 221. However, this also means
that the decoder is only available under ADF.USIM and ADF.ISIM. DF.GSM
and DF.TELECOM also overload the decoder method, just like an ADF would
do. This decoding method is then implemented as per 3gpp TS 51 011.
Since this a a problem on UICCs, the method detects the magic byte 0x62
that can be found at the beginning on every select response of an UICC
to defer to the TS 102 221 decoding method. TS 51 011 defines the first
two bytes of the select response as RFU. This at least problematic.

To solve this there should be a default method for
decode_select_response in the profile, which can be used if no file
overloads it with a specific decoder. ADFs use specific decoders, but
everything else should use the default decoder. When we deal with an
UICC, we expect the select response to be consistantly conform to TS
102 221, if we deal with a clasic sim we expect responses as per TS 51
011 only.

Since it is still possible to replace the select response decoder we
still have the opportunity to have custom select response in cartain
DFs and ADFs should we need them.

Change-Id: I95e33ec1755727dc9bbbc6016ce2d99a9e66f214
Related: OS#5274
---
M pySim/filesystem.py
M pySim/gsm_r.py
M pySim/ts_102_221.py
M pySim/ts_51_011.py
4 files changed, 60 insertions(+), 18 deletions(-)

Approvals:
  Jenkins Builder: Verified
  laforge: Looks good to me, approved



diff --git a/pySim/filesystem.py b/pySim/filesystem.py
index dcc2608..3caa470 100644
--- a/pySim/filesystem.py
+++ b/pySim/filesystem.py
@@ -52,7 +52,7 @@
     RESERVED_FIDS = ['3f00']
 
     def __init__(self, fid:str=None, sfid:str=None, name:str=None, desc:str=None,
-                 parent:Optional['CardDF']=None):
+                 parent:Optional['CardDF']=None, profile:Optional['CardProfile']=None):
         """
         Args:
             fid : File Identifier (4 hex digits)
@@ -60,6 +60,7 @@
             name : Brief name of the file, lik EF_ICCID
             desc : Description of the file
             parent : Parent CardFile object within filesystem hierarchy
+            profile : Card profile that this file should be part of
         """
         if not isinstance(self, CardADF) and fid == None:
             raise ValueError("fid is mandatory")
@@ -72,6 +73,7 @@
         self.parent = parent
         if self.parent and self.parent != self and self.fid:
             self.parent.add_file(self)
+        self.profile = profile
         self.shell_commands = [] # type: List[CommandSet]
 
 	# Note: the basic properties (fid, name, ect.) are verified when
@@ -173,10 +175,34 @@
         return list(sels.keys())
 
     def decode_select_response(self, data_hex:str):
-        """Decode the response to a SELECT command."""
+        """Decode the response to a SELECT command.
+
+        Args:
+	    data_hex: Hex string of the select response
+	"""
+
+	# When the current file does not implement a custom select response decoder,
+	# we just ask the parent file to decode the select response. If this method
+	# is not overloaded by the current file we will again ask the parent file.
+	# This way we recursively travel up the file system tree until we hit a file
+	# that does implement a concrete decoder.
         if self.parent:
             return self.parent.decode_select_response(data_hex)
 
+    def get_profile(self):
+        """Get the profile associated with this file. If this file does not have any
+        profile assigned, try to find a file above (usually the MF) in the filesystem
+        hirarchy that has a profile assigned
+        """
+
+        # If we have a profile set, return it
+        if self.profile:
+            return self.profile
+
+        # Walk up recursively until we hit a parent that has a profile set
+        if self.parent:
+            return self.parent.get_profile()
+        return None
 
 class CardDF(CardFile):
     """DF (Dedicated File) in the smart card filesystem.  Those are basically sub-directories."""
@@ -331,12 +357,18 @@
     def decode_select_response(self, data_hex:str) -> Any:
         """Decode the response to a SELECT command.
 
-        This is the fall-back method which doesn't perform any decoding. It mostly
-        exists so specific derived classes can overload it for actual decoding.
+        This is the fall-back method which automatically defers to the standard decoding
+        method defined by the card profile. When no profile is set, then no decoding is
+	performed. Specific derived classes (usually ADF) can overload this method to
+	install specific decoding.
         """
-        return data_hex
 
+        profile = self.get_profile()
 
+        if profile:
+            return profile.decode_select_response(data_hex)
+        else:
+            return data_hex
 
 class CardADF(CardDF):
     """ADF (Application Dedicated File) in the smart card filesystem"""
@@ -1029,7 +1061,7 @@
             card : pysim.cards.Card instance
             profile : CardProfile instance
         """
-        self.mf = CardMF()
+        self.mf = CardMF(profile=profile)
         self.card = card
         self.selected_file = self.mf # type: CardDF
         self.profile = profile
@@ -1437,6 +1469,19 @@
         """
         return interpret_sw(self.sw, sw)
 
+    def decode_select_response(self, data_hex:str) -> Any:
+        """Decode the response to a SELECT command.
+
+        This is the fall-back method which doesn't perform any decoding. It mostly
+        exists so specific derived classes can overload it for actual decoding.
+        This method is implemented in the profile and is only used when application
+        specific decoding cannot be performed (no ADF is selected).
+
+        Args:
+	    data_hex: Hex string of the select response
+        """
+        return data_hex
+
 
 class CardModel(abc.ABC):
     """A specific card model, typically having some additional vendor-specific files. All
diff --git a/pySim/gsm_r.py b/pySim/gsm_r.py
index 7cd7529..22b88fe 100644
--- a/pySim/gsm_r.py
+++ b/pySim/gsm_r.py
@@ -253,6 +253,3 @@
             EF_DialledVals(fid='6f87', name='EF.FreeNumber', desc='Free Number Call Type 0 and 8'),
           ]
         self.add_files(files)
-
-    def decode_select_response(self, data_hex):
-        return pySim.ts_51_011.decode_select_response(data_hex)
diff --git a/pySim/ts_102_221.py b/pySim/ts_102_221.py
index 3665939..3c99c4d 100644
--- a/pySim/ts_102_221.py
+++ b/pySim/ts_102_221.py
@@ -684,3 +684,6 @@
           }
 
         super().__init__('UICC', desc='ETSI TS 102 221', files_in_mf=files, sw=sw)
+
+    def decode_select_response(self, data_hex:str) -> Any:
+        return decode_select_response(data_hex)
diff --git a/pySim/ts_51_011.py b/pySim/ts_51_011.py
index 743c14b..a00cf0d 100644
--- a/pySim/ts_51_011.py
+++ b/pySim/ts_51_011.py
@@ -332,7 +332,6 @@
 import enum
 
 from pySim.filesystem import *
-import pySim.ts_102_221
 
 ######################################################################
 # DF.TELECOM
@@ -451,9 +450,6 @@
           ]
         self.add_files(files)
 
-    def decode_select_response(self, data_hex):
-        return decode_select_response(data_hex)
-
 ######################################################################
 # DF.GSM
 ######################################################################
@@ -936,13 +932,11 @@
           ]
         self.add_files(files)
 
-    def decode_select_response(self, data_hex):
-        return decode_select_response(data_hex)
 
-def decode_select_response(resp_hex):
+
+def _decode_select_response(resp_hex):
+
     resp_bin = h2b(resp_hex)
-    if resp_bin[0] == 0x62:
-        return pySim.ts_102_221.decode_select_response(resp_hex)
     struct_of_file_map = {
         0: 'transparent',
         1: 'linear_fixed',
@@ -983,3 +977,6 @@
 class CardProfileSIM(CardProfile):
     def __init__(self):
         super().__init__('SIM', desc='GSM SIM Card', files_in_mf=[DF_TELECOM(), DF_GSM()])
+
+    def decode_select_response(self, data_hex:str) -> Any:
+	    return _decode_select_response(data_hex)

-- 
To view, visit https://gerrit.osmocom.org/c/pysim/+/26161
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: I95e33ec1755727dc9bbbc6016ce2d99a9e66f214
Gerrit-Change-Number: 26161
Gerrit-PatchSet: 6
Gerrit-Owner: dexter <pmaier at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: daniel <dwillmann at sysmocom.de>
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-Reviewer: osmith <osmith at sysmocom.de>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20211110/a07fb1d3/attachment.htm>


More information about the gerrit-log mailing list