From b349149a88991d18ffc6ddf12fae29f9a309940e Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sat, 17 Aug 2024 09:58:33 +0200 Subject: [PATCH] pySim.esim.saip: Back-reference from ProfileElement to ProfileElementSequence Store a back-reference to the PE-Sequence in the PE object; this is neccessary for some upcoming patches, e.g. to determine the position in the sequence, access the global filesystem hierarchy, etc. Change-Id: I24b692e47e4dd0afb5a17b04d5e0251dded3d611 --- pySim/esim/saip/__init__.py | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/pySim/esim/saip/__init__.py b/pySim/esim/saip/__init__.py index 7898f474..45ca48ef 100644 --- a/pySim/esim/saip/__init__.py +++ b/pySim/esim/saip/__init__.py @@ -225,7 +225,19 @@ class ProfileElement: 'securityDomain': 'sd-Header', } - def __init__(self, decoded = None, mandated: bool = True): + def __init__(self, decoded = None, mandated: bool = True, + pe_sequence: Optional['ProfileElementSequence'] = None): + """ + Instantiate a new ProfileElement. This is usually either called with the 'decoded' argument after + reading a SAIP-DER-encoded PE. Alternatively, when constructing a PE from scratch, decoded is None, + and a minimal PE-Header is generated. + + Args: + decoded: asn1tools-generated decoded structure for this PE + mandated: Whether or not the PE-Header should contain the mandated attribute + pe_sequence: back-reference to the PE-Sequence of which we're part of + """ + self.pe_sequence = pe_sequence if decoded: self.decoded = decoded else: @@ -301,14 +313,20 @@ class ProfileElement: return None @classmethod - def from_der(cls, der: bytes) -> 'ProfileElement': - """Construct an instance from given raw, DER encoded bytes.""" + def from_der(cls, der: bytes, + pe_sequence: Optional['ProfileElementSequence'] = None) -> 'ProfileElement': + """Construct an instance from given raw, DER encoded bytes. + + Args: + der: raw, DER-encoded bytes of a single PE + pe_sequence: back-reference to the PE-Sequence of which this PE is part of + """ pe_type, decoded = asn1.decode('ProfileElement', der) pe_cls = cls.class_for_petype(pe_type) if pe_cls: - inst = pe_cls(decoded) + inst = pe_cls(decoded, pe_sequence=pe_sequence) else: - inst = ProfileElement(decoded) + inst = ProfileElement(decoded, pe_sequence=pe_sequence) inst.type = pe_type # run any post-decoder a derived class may have if hasattr(inst, '_post_decode'): @@ -984,7 +1002,7 @@ class ProfileElementSequence: remainder = der while len(remainder): first_tlv, remainder = bertlv_first_segment(remainder) - self.pe_list.append(ProfileElement.from_der(first_tlv)) + self.pe_list.append(ProfileElement.from_der(first_tlv, pe_sequence=self)) self._process_pelist() def _process_pelist(self) -> None: