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/.

dexter gerrit-no-reply at lists.osmocom.org
Mon Nov 8 15:46:24 UTC 2021


dexter has uploaded this change for review. ( 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/ts_102_221.py
M pySim/ts_51_011.py
3 files changed, 63 insertions(+), 16 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/61/26161/1

diff --git a/pySim/filesystem.py b/pySim/filesystem.py
index dcc2608..d427ded 100644
--- a/pySim/filesystem.py
+++ b/pySim/filesystem.py
@@ -44,6 +44,9 @@
 from pySim.jsonpath import js_path_find, js_path_modify
 from pySim.commands import SimCardCommands
 
+import pySim.ts_102_221_select
+import pySim.ts_51_011
+
 class CardFile(object):
     """Base class for all objects in the smart card filesystem.
     Serve as a common ancestor to all other file types; rarely used directly.
@@ -52,7 +55,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 +63,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 +76,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 +178,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 +360,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 +1064,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 +1472,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/ts_102_221.py b/pySim/ts_102_221.py
index 8b1f7da..b763f0f 100644
--- a/pySim/ts_102_221.py
+++ b/pySim/ts_102_221.py
@@ -535,3 +535,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 pySim.ts_102_221_select.decode_select_response(data_hex)
diff --git a/pySim/ts_51_011.py b/pySim/ts_51_011.py
index c7168e8..a00cf0d 100644
--- a/pySim/ts_51_011.py
+++ b/pySim/ts_51_011.py
@@ -332,8 +332,6 @@
 import enum
 
 from pySim.filesystem import *
-import pySim.ts_102_221
-import pySim.ts_102_221_select
 
 ######################################################################
 # DF.TELECOM
@@ -452,9 +450,6 @@
           ]
         self.add_files(files)
 
-    def decode_select_response(self, data_hex):
-        return decode_select_response(data_hex)
-
 ######################################################################
 # DF.GSM
 ######################################################################
@@ -937,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_select.decode_select_response(resp_hex)
     struct_of_file_map = {
         0: 'transparent',
         1: 'linear_fixed',
@@ -984,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: 1
Gerrit-Owner: dexter <pmaier at sysmocom.de>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20211108/18dc2ec1/attachment.htm>


More information about the gerrit-log mailing list