laforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/pysim/+/37010?usp=email )
Change subject: esim.saip: Add ProfileElementSequence.remove_naas_of_type ...................................................................... esim.saip: Add ProfileElementSequence.remove_naas_of_type This method allows the caller to remove all NAAs of a certain type, for example to remove all CSIM instances from a given profile. Change-Id: I64438bf0be58bad7a561c3744b7e9b1338a7857c --- M pySim/esim/saip/__init__.py M pySim/esim/saip/oid.py 2 files changed, 98 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/10/37010/1 diff --git a/pySim/esim/saip/__init__.py b/pySim/esim/saip/__init__.py index 938dc48..4d39b64 100644 --- a/pySim/esim/saip/__init__.py +++ b/pySim/esim/saip/__init__.py @@ -27,12 +27,57 @@ from pySim.construct import build_construct from pySim.esim import compile_asn1_subdir from pySim.esim.saip import templates +from pySim.esim.saip import oid from pySim.tlv import BER_TLV_IE from pySim.global_platform import KeyType, KeyUsageQualifier from pySim.global_platform.uicc import UiccSdInstallParams asn1 = compile_asn1_subdir('saip') +class Naa: + """A class defining a Network Access Application (NAA).""" + name = None + # AID prefix, as used for ADF and EF.DIR + aid = None + # the ProfileElement types used specifically in this NAA + pe_types = [] + # we only use the base DN of each OID; there may be subsequent versions underneath it + templates = [] + + @classmethod + def adf_name(cls): + return 'adf-' + cls.mandatory_services[0] + +class NaaCsim(Naa): + name = "csim" + aid = h2b("") + mandatory_services = ["csim"] + pe_types = ["csim", "opt-csim", "cdmaParameter"] + templates = [oid.ADF_CSIM_by_default, oid.ADF_CSIM_not_by_default] + +class NaaUsim(Naa): + name = "usim" + aid = h2b("") + mandatory_services = ["usim"] + pe_types = ["usim", "opt-usim"] + templates = [oid.ADF_USIM_by_default, oid.ADF_USIM_not_by_default, + oid.DF_PHONEBOOK_ADF_USIM, oid.DF_GSM_ACCESS_ADF_USIM, + oid.DF_EAP, oid.DF_5GS, oid.DF_SAIP, oid.DF_SNPN, + oid.DF_5GProSe] + +class NaaIsim(Naa): + name = "isim" + aid = h2b("") + mandatory_services = ["isim"] + pe_types = ["isim", "opt-isim"] + templates = [oid.ADF_ISIM_by_default, oid.ADF_ISIM_not_by_default] + +NAAs = { + NaaCsim.name: NaaCsim, + NaaUsim.name: NaaUsim, + NaaIsim.name: NaaIsim, +} + class File: """Internal representation of a file in a profile filesystem. @@ -513,6 +558,43 @@ self._process_pelist() self.renumber_identification() + def remove_naas_of_type(self, naa: Naa) -> None: + """Remove all instances of NAAs of given type. This can be used, for example, + to remove all CSIM NAAs from a profile. Will not just remove the PEs, but also + any records in 'eUICC-Mandatory-services' or 'eUICC-Mandatory-GFSTEList'.""" + hdr = self.pe_by_type['header'][0] + # remove any associated mandatory services + for service in naa.mandatory_services: + if service in hdr.decoded['eUICC-Mandatory-services']: + del hdr.decoded['eUICC-Mandatory-services'][service] + # remove any associaed mandatory filesystem templates + for template in naa.templates: + if template in hdr.decoded['eUICC-Mandatory-GFSTEList']: + hdr.decoded['eUICC-Mandatory-GFSTEList'] = [x for x in hdr.decoded['eUICC-Mandatory-GFSTEList'] if not template.prefix_match(x)] + # determine the ADF names (AIDs) of all NAA ADFs + naa_adf_names = [] + if naa.pe_types[0] in self.pe_by_type: + for pe in self.pe_by_type[naa.pe_types[0]]: + adf_name = naa.adf_name() + adf = File(adf_name, pe.decoded[adf_name]) + naa_adf_names.append(adf.fileDescriptor['dfName']) + # remove PEs of each NAA instance + if naa.name in self.pes_by_naa: + for inst in self.pes_by_naa[naa.name]: + # delete all the PEs of the NAA + self.pe_list = [pe for pe in self.pe_list if pe not in inst] + self._process_pelist() + # remove any RFM PEs for the just-removed ADFs + if 'rfm' in self.pe_by_type: + to_delete_pes = [] + for rfm_pe in self.pe_by_type['rfm']: + if 'adfRFMAccess' in rfm_pe.decoded: + if rfm_pe.decoded['adfRFMAccess']['adfAID'] in naa_adf_names: + to_delete_pes.append(rfm_pe) + self.pe_list = [pe for pe in self.pe_list if pe not in to_delete_pes] + self._process_pelist() + # TODO: remove any records related to the ADFs from EF.DIR + def __repr__(self) -> str: return "PESequence(%s)" % ', '.join([str(x) for x in self.pe_list]) diff --git a/pySim/esim/saip/oid.py b/pySim/esim/saip/oid.py index 238e49f..d33b786 100644 --- a/pySim/esim/saip/oid.py +++ b/pySim/esim/saip/oid.py @@ -38,6 +38,10 @@ def __repr__(self) -> str: return 'OID(%s)' % (str(self)) + def prefix_match(self, oid_str): + """determine if oid_str is equal or below our OID.""" + return oid_str.startswith(str(self)) + class eOID(OID): """OID helper for TCA eUICC prefix""" -- To view, visit https://gerrit.osmocom.org/c/pysim/+/37010?usp=email To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: pysim Gerrit-Branch: master Gerrit-Change-Id: I64438bf0be58bad7a561c3744b7e9b1338a7857c Gerrit-Change-Number: 37010 Gerrit-PatchSet: 1 Gerrit-Owner: laforge <lafo...@osmocom.org> Gerrit-MessageType: newchange