laforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/pysim/+/37417?usp=email )
Change subject: pySim.esim.saip: Add ProfileElementAKA constructor + methods ......................................................................
pySim.esim.saip: Add ProfileElementAKA constructor + methods
This helps us to construct an akaParameter PE from scratch.
Change-Id: I4cc42c98bf82aec085ab7f48aea4ff7efa0eae9e --- M pySim/esim/saip/__init__.py M tests/test_esim_saip.py 2 files changed, 61 insertions(+), 1 deletion(-)
git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/17/37417/1
diff --git a/pySim/esim/saip/__init__.py b/pySim/esim/saip/__init__.py index e35e1a5..2cddbe8 100644 --- a/pySim/esim/saip/__init__.py +++ b/pySim/esim/saip/__init__.py @@ -271,6 +271,7 @@ 'telecom': ProfileElementTelecom, 'usim': ProfileElementUSIM, 'isim': ProfileElementISIM, + 'akaParameter': ProfileElementAKA, } """Construct an instance from given raw, DER encoded bytes.""" pe_type, decoded = asn1.decode('ProfileElement', der) @@ -593,6 +594,54 @@ def adf_name(self) -> str: return b2h(self.decoded['adf-isim'][0][1]['dfName'])
+class ProfileElementAKA(ProfileElement): + type = 'akaParameter' + + def __init__(self, decoded: Optional[dict] = None): + super().__init__() + if decoded: + self.decoded = decoded + return + # provide some reasonable defaults for a MNO-SD + self.decoded = OrderedDict() + self.decoded['aka-header'] = { 'mandated': None, 'identification': None} + self.set_milenage(b'\x00'*16, b'\x00'*16) + + def set_milenage(self, k: bytes, opc: bytes): + """Configure akaParametes for MILENAGE.""" + self.decoded['algoConfiguration'] = ('algoParameter', { + 'algorithmID': 1, + 'algorithmOptions': b'\x00', # not relevant for milenage + 'key': k, + 'opc': opc, + }) + + def set_xor3g(self, k: bytes): + """Configure akaParametes for XOR-3G.""" + self.decoded['algoConfiguration'] = ('algoParameter', { + 'algorithmID': 3, + 'algorithmOptions': b'\x00', # not relevant for milenage + 'key': k, + 'opc': b'', # not used for MILENAGE + }) + + def set_tuak(self, k: bytes, topc: bytes, num_of_keccak: int = 1): + """Configure akaParametes for TUAK.""" + self.decoded['algoConfiguration'] = ('algoParameter', { + 'algorithmID': 2, + 'algorithmOptions': b'\x00', # not relevant for milenage + 'key': k, + 'opc': topc, + 'numberOfKeccak': bytes([num_of_keccak]), + }) + + def set_mapping(self, aid: bytes, options: int = 6): + """Configure akaParametes for a mapping from another AID.""" + self.decoded['algoConfiguration'] = ('mappingParamete', { + 'mappingOptions': bytes([options]), + 'mappingSource': aid, + }) + def bertlv_first_segment(binary: bytes) -> Tuple[bytes, bytes]: """obtain the first segment of a binary concatenation of BER-TLV objects. Returns: tuple of first TLV and remainder.""" diff --git a/tests/test_esim_saip.py b/tests/test_esim_saip.py index a43a139..704f513 100755 --- a/tests/test_esim_saip.py +++ b/tests/test_esim_saip.py @@ -66,7 +66,7 @@ def test_constructor_encode(self): """Test that DER-encoding of PE created by "empty" constructor works without raising exception.""" for cls in [ProfileElementMF, ProfileElementPuk, ProfileElementPin, ProfileElementTelecom, - ProfileElementUSIM, ProfileElementISIM]: + ProfileElementUSIM, ProfileElementISIM, ProfileElementAKA]: with self.subTest(cls.__name__): pes = ProfileElementSequence() inst = cls()