aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@osmocom.org>2024-01-30 21:01:01 +0100
committerHarald Welte <laforge@osmocom.org>2024-01-30 21:33:41 +0100
commit8a39d00cc329b53cfd8b781fbffd79907c63559a (patch)
tree51c2747a144e1f4f56ac868a436de77845ae7794
parent3f3fd1a84153c7fa59b7cf75a02aee167dd67a94 (diff)
osmo-smdpp: Support multiple different profiles
Let's simply use the matchingId for filesystem lookup of the UPP file. This way we can have any number of profiles by simply creating the respeective files. Change-Id: I0bc3a14b9fdfcc6322917dd0c69d8295de486950
-rw-r--r--docs/osmo-smdpp.rst8
-rwxr-xr-xosmo-smdpp.py24
-rw-r--r--smdpp-data/upp/TS48v2_SAIP2.1_NoBERTLV.der (renamed from smdpp-data/upp/TS48 V2 eSIM_GTP_SAIP2.1_NoBERTLV.rename2der)bin12207 -> 12207 bytes
-rw-r--r--smdpp-data/upp/TS48v2_SAIP2.3_NoBERTLV.der (renamed from smdpp-data/upp/TS48 V2 eSIM_GTP_SAIP2.3_NoBERTLV.rename2der)bin12251 -> 12251 bytes
-rwxr-xr-xtests/test_esim_saip.py2
5 files changed, 29 insertions, 5 deletions
diff --git a/docs/osmo-smdpp.rst b/docs/osmo-smdpp.rst
index a84ebee..ad7d902 100644
--- a/docs/osmo-smdpp.rst
+++ b/docs/osmo-smdpp.rst
@@ -21,8 +21,9 @@ osmo-smdpp currently
* uses test certificates copied from GSMA SGP.26 into `./smdpp-data/certs`, assuming that your osmo-smdppp
would be running at the host name `testsmdpplus1.example.com`
-* always provides the exact same profile to every request. The profile always has the same IMSI and
- ICCID.
+* doesn't understand profile state. Any profile can always be downloaded any number of times, irrespective
+ of the EID or whether it was donwloaded before
+* doesn't perform any personalization, so the IMSI/ICCID etc. are always identical
* **is absolutely insecure**, as it
* does not perform any certificate verification
@@ -83,7 +84,8 @@ and it will bind its plain-HTTP ES9+ interface to local TCP port 8000.
The `smdpp-data/certs`` directory contains the DPtls, DPauth and DPpb as well as CI certificates
used; they are copied from GSMA SGP.26 v2.
-The `smdpp-data/upp` directory contains the UPP (Unprotected Profile Package) used.
+The `smdpp-data/upp` directory contains the UPP (Unprotected Profile Package) used. The file names (without
+.der suffix) are looked up by the matchingID parameter from the activation code presented by the LPA.
DNS setup for your LPA
diff --git a/osmo-smdpp.py b/osmo-smdpp.py
index cfcd5f8..8cb0082 100755
--- a/osmo-smdpp.py
+++ b/osmo-smdpp.py
@@ -135,6 +135,7 @@ class SmDppHttpServer:
def __init__(self, server_hostname: str, ci_certs_path: str, use_brainpool: bool = False):
self.server_hostname = server_hostname
+ self.upp_dir = os.path.realpath(os.path.join(DATA_DIR, 'upp'))
self.ci_certs = self.load_certs_from_path(ci_certs_path)
# load DPauth cert + key
self.dp_auth = CertAndPrivkey(oid.id_rspRole_dp_auth_v2)
@@ -344,6 +345,27 @@ class SmDppHttpServer:
if euiccSigned1['serverChallenge'] != ss.serverChallenge:
raise ApiError('8.1', '6.1', 'Verification failed')
+ # 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.
+ if euiccSigned1['ctxParams1'][0] == 'ctxParamsForCommonAuthentication':
+ cpca = euiccSigned1['ctxParams1'][1]
+ matchingId = cpca.get('matchingId', None)
+ if not matchingId:
+ # TODO: check if any pending profile downloads for the EID
+ raise ApiError('8.2.6', '3.8', 'Refused')
+ if matchingId:
+ # look up profile based on matchingID. We simply check if a given file exists for now..
+ path = os.path.join(self.upp_dir, matchingId) + '.der'
+ # prevent directory traversal attack
+ if os.path.commonprefix((os.path.realpath(path),self.upp_dir)) != self.upp_dir:
+ raise ApiError('8.2.6', '3.8', 'Refused')
+ if not os.path.isfile(path) or not os.access(path, os.R_OK):
+ raise ApiError('8.2.6', '3.8', 'Refused')
+ ss.matchingId = matchingId
+
+ # FIXME: we actually want to perform the profile binding herr, and read the profile metadat from the profile
+
# Put together profileMetadata + _bin
ss.profileMetadata = ProfileMetadata(iccid_bin= h2b(swap_nibbles('89000123456789012358')), spn="OsmocomSPN", profile_name="OsmocomProfile")
profileMetadata_bin = ss.profileMetadata.gen_store_metadata_request()
@@ -425,7 +447,7 @@ class SmDppHttpServer:
# TODO: Check if this order requires a Confirmation Code verification
# Perform actual protection + binding of profile package (or return pre-bound one)
- with open(os.path.join(DATA_DIR, 'upp', 'TS48 V2 eSIM_GTP_SAIP2.1_NoBERTLV.rename2der'), 'rb') as f:
+ with open(os.path.join(self.upp_dir, ss.matchingId)+'.der', 'rb') as f:
upp = UnprotectedProfilePackage.from_der(f.read(), metadata=ss.profileMetadata)
# HACK: Use empty PPP as we're still debuggin the configureISDP step, and we want to avoid
# cluttering the log with stuff happening after the failure
diff --git a/smdpp-data/upp/TS48 V2 eSIM_GTP_SAIP2.1_NoBERTLV.rename2der b/smdpp-data/upp/TS48v2_SAIP2.1_NoBERTLV.der
index 7800677..7800677 100644
--- a/smdpp-data/upp/TS48 V2 eSIM_GTP_SAIP2.1_NoBERTLV.rename2der
+++ b/smdpp-data/upp/TS48v2_SAIP2.1_NoBERTLV.der
Binary files differ
diff --git a/smdpp-data/upp/TS48 V2 eSIM_GTP_SAIP2.3_NoBERTLV.rename2der b/smdpp-data/upp/TS48v2_SAIP2.3_NoBERTLV.der
index 0a0bdff..0a0bdff 100644
--- a/smdpp-data/upp/TS48 V2 eSIM_GTP_SAIP2.3_NoBERTLV.rename2der
+++ b/smdpp-data/upp/TS48v2_SAIP2.3_NoBERTLV.der
Binary files differ
diff --git a/tests/test_esim_saip.py b/tests/test_esim_saip.py
index 14c086b..9e7afb2 100755
--- a/tests/test_esim_saip.py
+++ b/tests/test_esim_saip.py
@@ -26,7 +26,7 @@ from pprint import pprint as pp
class SaipTest(unittest.TestCase):
- with open('smdpp-data/upp/TS48 V2 eSIM_GTP_SAIP2.3_NoBERTLV.rename2der', 'rb') as f:
+ with open('smdpp-data/upp/TS48v2_SAIP2.3_NoBERTLV.der', 'rb') as f:
per_input = f.read()
pes = ProfileElementSequence.from_der(per_input)
expected_pet_list = ['header', 'mf', 'pukCodes', 'pinCodes', 'telecom', 'pinCodes', 'genericFileManagement', 'usim', 'opt-usim', 'pinCodes', 'akaParameter', 'gsm-access', 'df-5gs', 'df-saip','csim', 'opt-csim', 'pinCodes', 'cdmaParameter', 'isim', 'opt-isim', 'pinCodes', 'akaParameter', 'genericFileManagement', 'genericFileManagement', 'securityDomain', 'rfm', 'rfm', 'rfm', 'rfm', 'end']