Johannes Waigel has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/pysim/+/43205?usp=email )


Change subject: osmo-smdpp: derive the Profile Metadata from the Profile
......................................................................

osmo-smdpp: derive the Profile Metadata from the Profile

The metadata was invented: a hardcoded SPN, the MatchingID as
profileName, and always 'operational' as profileClass.  Test Profiles
were therefore sent as operational ones, which SGP.22 section 2.4.5.3
forbids.

Add ProfileMetadata.from_pes() to read these fields from the Profile.
An LPA now shows Test Profiles only in Device Test Mode.

Change-Id: Ie24dd5ac0ef541c1899dd923a9db568209bbfa62
---
M osmo-smdpp.py
M pySim/esim/es8p.py
2 files changed, 35 insertions(+), 5 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/05/43205/1

diff --git a/osmo-smdpp.py b/osmo-smdpp.py
index 2a8e478..0346afc 100755
--- a/osmo-smdpp.py
+++ b/osmo-smdpp.py
@@ -629,7 +629,7 @@
         # If ctxParams1 contains a ctxParamsForCommonAuthentication data 
object, the SM-DP+ Shall [...]
         # TODO: We really do a very simplistic job here, this needs to be 
properly implemented later,
         # considering all the various cases, profile state, etc.
-        iccid_str = None
+        pes = None
         if euiccSigned1['ctxParams1'][0] == 'ctxParamsForCommonAuthentication':
             cpca = euiccSigned1['ctxParams1'][1]
             matchingId = cpca.get('matchingId', None)
@@ -647,15 +647,14 @@
                 ss.matchingId = matchingId
                 with open(path, 'rb') as f:
                     pes = saip.ProfileElementSequence.from_der(f.read())
-                    iccid_str = 
b2h(pes.get_pe_for_type('header').decoded['iccid'])
         else:
             # there's currently no other option in the ctxParams1 choice, so 
this cannot happen
             raise ApiError('1.3.1', '2.2', 'ctxParams1 missing mandatory 
ctxParamsForCommonAuthentication')

-        # FIXME: we actually want to perform the profile binding herr, and 
read the profile metadata from the profile
+        # FIXME: we actually want to perform the profile binding here

         # Put together profileMetadata + _bin
-        ss.profileMetadata = 
ProfileMetadata(iccid_bin=h2b(swap_nibbles(iccid_str)), spn="OsmocomSPN", 
profile_name=matchingId)
+        ss.profileMetadata = ProfileMetadata.from_pes(pes, 
profile_name=matchingId)
         # enable notifications for all operations
         for event in ['enable', 'disable', 'delete']:
             ss.profileMetadata.add_notification(event, self.server_hostname)
diff --git a/pySim/esim/es8p.py b/pySim/esim/es8p.py
index 6926cae..48ecfdd 100644
--- a/pySim/esim/es8p.py
+++ b/pySim/esim/es8p.py
@@ -17,13 +17,14 @@

 from typing import Dict, List, Optional
 from cryptography.hazmat.primitives.asymmetric import ec
-from osmocom.utils import b2h, h2b
+from osmocom.utils import b2h, h2b, swap_nibbles
 from osmocom.tlv import bertlv_encode_tag, bertlv_encode_len, 
bertlv_parse_one_rawtag
 from osmocom.tlv import bertlv_return_one_rawtlv

 import pySim.esim.rsp as rsp
 from pySim.esim.bsp import BspInstance
 from pySim.esim import PMO
+from pySim.ts_51_011 import EF_SPN

 import logging
 logger = logging.getLogger(__name__)
@@ -73,6 +74,18 @@
     return rsp.asn1.encode('ReplaceSessionKeysRequest', rsk)


+def spn_from_pes(pes) -> Optional[str]:
+    """Read the Service Provider Name from EF.SPN of the given Profile, or 
None if it has none."""
+    for pe_type in ['usim', 'gsm-access']:
+        pe = pes.get_pe_for_type(pe_type)
+        if not pe or 'ef-spn' not in getattr(pe, 'files', {}):
+            continue
+        content = 
pe.files['ef-spn'].file_content_from_tuples(pe.decoded['ef-spn'])
+        if content:
+            return EF_SPN().decode_hex(b2h(content))['spn']
+    return None
+
+
 class ProfileMetadata:
     """Representation of Profile metadata. Right now only the mandatory bits 
are
     supported, but in general this should follow the StoreMetadataRequest of 
SGP.22 5.5.3"""
@@ -85,6 +98,24 @@
         self.icon_type = None
         self.notifications = []

+    @classmethod
+    def from_pes(cls, pes, profile_name: Optional[str] = None) -> 
'ProfileMetadata':
+        """Derive Profile metadata from the Profile itself, rather than from a 
separate source that
+        can disagree with it.  profile_name is only used if the Profile header 
has no profileType."""
+        header = pes.get_pe_for_type('header').decoded
+
+        # SGP.22 Section 2.4.5.3: a Test Profile SHALL have its Profile Class 
set to 'test'.  A
+        # Profile requiring the USIM test algorithm is one; that is condition 
3 of that section.
+        if 'usim-test-algorithm' in header.get('eUICC-Mandatory-services', {}):
+            profile_class = 'test'
+        else:
+            profile_class = 'operational'
+
+        return cls(iccid_bin=h2b(swap_nibbles(b2h(header['iccid']))),
+                   spn=spn_from_pes(pes) or '',
+                   profile_name=header.get('profileType', profile_name) or '',
+                   profile_class=profile_class)
+
     def set_icon(self, is_png: bool, icon_data: bytes):
         """Set the icon that is part of the metadata."""
         if len(icon_data) > 1024:

--
To view, visit https://gerrit.osmocom.org/c/pysim/+/43205?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings?usp=email

Gerrit-MessageType: newchange
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: Ie24dd5ac0ef541c1899dd923a9db568209bbfa62
Gerrit-Change-Number: 43205
Gerrit-PatchSet: 1
Gerrit-Owner: Johannes Waigel <[email protected]>

Reply via email to