laforge submitted this change.

View Change


Approvals: laforge: Looks good to me, approved Jenkins Builder: Verified
ts_31_102: Start to use construct for EF.SUCI_Calc_Info

We cannot fully switch to construct for all of it easily due to
the priority value and the ordering/sorting by priority implemented
in the hand-coded version. But we can at least migrate the
encode/decode of the hnet_pubkey_list via construct.

Change-Id: I4ad5ea57bab37c2dc218e7752d538aa4cdc36ee3
---
M pySim/ts_31_102.py
M tests/test_utils.py
2 files changed, 44 insertions(+), 62 deletions(-)

diff --git a/pySim/ts_31_102.py b/pySim/ts_31_102.py
index fdd8acf..4134650 100644
--- a/pySim/ts_31_102.py
+++ b/pySim/ts_31_102.py
@@ -286,17 +286,14 @@
_construct = GreedyRange(
Struct('identifier'/Enum(Byte, null=0, A=1, B=2), 'key_index'/Int8ub))

-
class HnetPubkeyIdentifier(BER_TLV_IE, tag=0x80):
# 3GPP TS 24.501 / 3GPP TS 23.003
_construct = Int8ub

-
class HnetPubkey(BER_TLV_IE, tag=0x81):
- # FIXME: RFC 5480
+ # contents according to RFC 7748 / RFC 5480
_construct = HexAdapter(GreedyBytes)

-
class HnetPubkeyList(BER_TLV_IE, tag=0xa1, nested=[HnetPubkeyIdentifier, HnetPubkey]):
pass

@@ -319,30 +316,35 @@

return out_bytes

- def _encode_hnet_pubkey_list(self, hnet_pubkey_list):
- out_bytes = [0xa1] # pubkey list tag
- out_bytes.append(0x00) # length filled later
- length = 0
+ @staticmethod
+ def _compact_pubkey_list(l: List[dict]) -> List[dict]:
+ """conversion method to generate list of {hnet_pubkey_identifier, hnet_pubkey} dicts
+ from flat [{hnet_pubkey_identifier: }, {net_pubkey: }, ...] list"""
+ out = []
+ while len(l):
+ a = l.pop(0)
+ b = l.pop(0)
+ z = {**a, **b}
+ out.append(z)
+ return out

- for key in hnet_pubkey_list:
- out_bytes.append(0x80) # identifier tag
- out_bytes.append(0x01) # TODO size, fixed to 1 byte
- out_bytes.append(key["hnet_pubkey_identifier"])
- out_bytes.append(0x81) # key tag
- out_bytes.append(len(key["hnet_pubkey"])//2)
- length += 5+len(key["hnet_pubkey"])//2
-
- pubkey_bytes = h2b(key["hnet_pubkey"])
- out_bytes += pubkey_bytes
-
- # fill length
- out_bytes[1] = length
- return out_bytes
+ @staticmethod
+ def _expand_pubkey_list(l: List[dict]) -> List[dict]:
+ """conversion method to generate flat [{hnet_pubkey_identifier: }, {net_pubkey: }, ...] list
+ from compacted list of {hnet_pubkey_identifier, hnet_pubkey} dicts"""
+ out = []
+ for d in l:
+ for k, v in d.items():
+ out.append({k: v})
+ return out

def _encode_hex(self, in_json):
out_bytes = self._encode_prot_scheme_id_list(
in_json['prot_scheme_id_list'])
- out_bytes += self._encode_hnet_pubkey_list(in_json['hnet_pubkey_list'])
+ d = self._expand_pubkey_list(in_json['hnet_pubkey_list'])
+ hpkl = EF_SUCI_Calc_Info.HnetPubkeyList()
+ hpkl.from_dict({'hnet_pubkey_list': d})
+ out_bytes += hpkl.to_tlv()
return "".join(["%02X" % i for i in out_bytes])

def _decode_prot_scheme_id_list(self, in_bytes):
@@ -359,42 +361,6 @@
prot_scheme_id_list.append(prot_scheme)
return prot_scheme_id_list

- def _decode_hnet_pubkey_list(self, in_bytes):
- hnet_pubkey_list = []
- pos = 0
- if in_bytes[pos] != 0xa1:
- print("missing Home Network Public Key List data object")
- return {}
- pos += 1
- hnet_pubkey_list_len = in_bytes[pos]
- pos += 1
-
- while pos < hnet_pubkey_list_len:
- if in_bytes[pos] != 0x80:
- print("missing Home Network Public Key Identifier tag")
- return {}
- pos += 1
- # TODO might be more than 1 byte?
- hnet_pubkey_id_len = in_bytes[pos]
- pos += 1
- hnet_pubkey_id = in_bytes[pos:pos+hnet_pubkey_id_len][0]
- pos += hnet_pubkey_id_len
- if in_bytes[pos] != 0x81:
- print("missing Home Network Public Key tag")
- return {}
- pos += 1
- hnet_pubkey_len = in_bytes[pos]
- pos += 1
- hnet_pubkey = in_bytes[pos:pos+hnet_pubkey_len]
- pos += hnet_pubkey_len
-
- hnet_pubkey_list.append({
- 'hnet_pubkey_identifier': hnet_pubkey_id,
- 'hnet_pubkey': b2h(hnet_pubkey)
- })
-
- return hnet_pubkey_list
-
def _decode_bin(self, in_bin):
return self._decode_hex(b2h(in_bin))

@@ -415,7 +381,9 @@
pos += prot_scheme_id_list_len

# remaining data holds Home Network Public Key Data Object
- hnet_pubkey_list = self._decode_hnet_pubkey_list(in_bytes[pos:])
+ hpkl = EF_SUCI_Calc_Info.HnetPubkeyList()
+ hpkl.from_tlv(in_bytes[pos:])
+ hnet_pubkey_list = self._compact_pubkey_list(hpkl.to_dict()['hnet_pubkey_list'])

return {
'prot_scheme_id_list': prot_scheme_id_list,
diff --git a/tests/test_utils.py b/tests/test_utils.py
index 062b614..ea1964b 100755
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -136,12 +136,12 @@

def testDecodeSuciCalcInfo(self):
suci_calc_info = EF_SUCI_Calc_Info()
- decoded = suci_calc_info._decode_hex(self.testfile_suci_calc_info)
+ decoded = suci_calc_info.decode_hex(self.testfile_suci_calc_info)
self.assertDictEqual(self.decoded_testfile_suci, decoded)

def testEncodeSuciCalcInfo(self):
suci_calc_info = EF_SUCI_Calc_Info()
- encoded = suci_calc_info._encode_hex(self.decoded_testfile_suci)
+ encoded = suci_calc_info.encode_hex(self.decoded_testfile_suci)
self.assertEqual(encoded.lower(), self.testfile_suci_calc_info.lower())

def testEnc_msisdn(self):

To view, visit change 35427. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: I4ad5ea57bab37c2dc218e7752d538aa4cdc36ee3
Gerrit-Change-Number: 35427
Gerrit-PatchSet: 6
Gerrit-Owner: laforge <laforge@osmocom.org>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: dexter <pmaier@sysmocom.de>
Gerrit-Reviewer: fixeria <vyanitskiy@sysmocom.de>
Gerrit-Reviewer: laforge <laforge@osmocom.org>
Gerrit-Reviewer: merlinchlosta <merlin.chlosta@rub.de>
Gerrit-MessageType: merged