neels has uploaded this change for review. (
https://gerrit.osmocom.org/c/pysim/+/39744?usp=email )
Change subject: [4/7] personalization: refactor Pin, Adm
......................................................................
[4/7] personalization: refactor Pin, Adm
Refactor Pin1, Pin2, Adm1 and Adm2 to the new ConfigurableParameter
implementation style.
Change-Id: I54aef10b6d4309398d4b779a3740a7d706d68603
---
M pySim/esim/saip/personalization.py
1 file changed, 55 insertions(+), 57 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/44/39744/1
diff --git a/pySim/esim/saip/personalization.py b/pySim/esim/saip/personalization.py
index abcca61..36baf43 100644
--- a/pySim/esim/saip/personalization.py
+++ b/pySim/esim/saip/personalization.py
@@ -317,6 +317,9 @@
key_usage_qual = 0x48
+def obtain_all_pe_from_pelist(l: List[ProfileElement], wanted_type: str) ->
ProfileElement:
+ return (pe for pe in l if pe.type == wanted_type)
+
def obtain_singleton_pe_from_pelist(l: List[ProfileElement], wanted_type: str) ->
ProfileElement:
filtered = list(filter(lambda x: x.type == wanted_type, l))
assert len(filtered) == 1
@@ -364,70 +367,65 @@
class Puk2(Puk):
keyReference = 0x81
-
-class Pin(ConfigurableParameter):
+class Pin(DecimalHexParam):
"""Configurable PIN (Personal Identification Number). String of
digits."""
+ rpad = 16
+ min_len = 4
+ max_len = 8
keyReference = None
- def validate(self):
- if isinstance(self.input_value, int):
- self.value = '%04d' % self.input_value
- else:
- self.value = self.input_value
- if len(self.value) < 4 or len(self.value) > 8:
- raise ValueError('PIN mus be 4..8 digits long')
- if not self.value.isdecimal():
- raise ValueError('PIN must only contain decimal digits')
- def apply(self, pes: ProfileElementSequence):
- pin = ''.join(['%02x' % (ord(x)) for x in self.value])
- padded_pin = rpad(pin, 16)
- mf_pes = pes.pes_by_naa['mf'][0]
- pinCodes = obtain_first_pe_from_pelist(mf_pes, 'pinCodes')
- if pinCodes.decoded['pinCodes'][0] != 'pinconfig':
- return
- for pinCode in pinCodes.decoded['pinCodes'][1]:
- if pinCode['keyReference'] == self.keyReference:
- pinCode['pinValue'] = h2b(padded_pin)
- return
- raise ValueError('cannot find pinCode')
-class AppPin(ConfigurableParameter):
- """Configurable PIN (Personal Identification Number). String of
digits."""
- keyReference = None
- def validate(self):
- if isinstance(self.input_value, int):
- self.value = '%04d' % self.input_value
- else:
- self.value = self.input_value
- if len(self.value) < 4 or len(self.value) > 8:
- raise ValueError('PIN mus be 4..8 digits long')
- if not self.value.isdecimal():
- raise ValueError('PIN must only contain decimal digits')
- def _apply_one(self, pe: ProfileElement):
- pin = ''.join(['%02x' % (ord(x)) for x in self.value])
- padded_pin = rpad(pin, 16)
- pinCodes = obtain_first_pe_from_pelist(pe, 'pinCodes')
- if pinCodes.decoded['pinCodes'][0] != 'pinconfig':
- return
- for pinCode in pinCodes.decoded['pinCodes'][1]:
- if pinCode['keyReference'] == self.keyReference:
- pinCode['pinValue'] = h2b(padded_pin)
- return
- raise ValueError('cannot find pinCode')
- def apply(self, pes: ProfileElementSequence):
+ @staticmethod
+ def _apply_pinvalue(pe: ProfileElement, keyReference, val_bytes):
+ for pinCodes in obtain_all_pe_from_pelist(pe, 'pinCodes'):
+ if pinCodes.decoded['pinCodes'][0] != 'pinconfig':
+ continue
+
+ for pinCode in pinCodes.decoded['pinCodes'][1]:
+ if pinCode['keyReference'] == keyReference:
+ pinCode['pinValue'] = val_bytes
+ return True
+ return False
+
+ @classmethod
+ def apply_val(cls, pes: ProfileElementSequence, val):
+ val_bytes = val
+ if not cls._apply_pinvalue(pes.pes_by_naa['mf'][0], cls.keyReference,
val_bytes):
+ raise ValueError('input template UPP has unexpected structure:'
+ + f' {cls.name} cannot find pinCode with
keyReference={cls.keyReference}')
+
+ @classmethod
+ def _read_all_pinvalues_from_pe(cls, pe: ProfileElement):
+ for pinCodes in obtain_all_pe_from_pelist(pe, 'pinCodes'):
+ if pinCodes.decoded['pinCodes'][0] != 'pinconfig':
+ continue
+
+ for pinCode in pinCodes.decoded['pinCodes'][1]:
+ if pinCode['keyReference'] == cls.keyReference:
+ yield cls.decimal_hex_to_str(pinCode['pinValue'])
+
+class Pin1(Pin):
+ keyReference = 0x01
+
+class Pin2(Pin):
+ keyReference = 0x81
+
+ @classmethod
+ def apply_val(cls, pes: ProfileElementSequence, val):
+ val_bytes = val
+ # PIN2 is special: telecom + usim + isim + csim
for naa in pes.pes_by_naa:
if naa not in
['usim','isim','csim','telecom']:
continue
for instance in pes.pes_by_naa[naa]:
- self._apply_one(instance)
-class Pin1(Pin, keyReference=0x01):
- pass
-# PIN2 is special: telecom + usim + isim + csim
-class Pin2(AppPin, keyReference=0x81):
- pass
-class Adm1(Pin, keyReference=0x0A):
- pass
-class Adm2(Pin, keyReference=0x0B):
- pass
+ if not cls._apply_pinvalue(instance, cls.keyReference, val_bytes):
+ raise ValueError('input template UPP has unexpected
structure:'
+ + f' {cls.name} cannot find pinCode with
keyReference={cls.keyReference} in {naa=}')
+
+class Adm1(Pin):
+ keyReference = 0x0A
+
+class Adm2(Pin):
+ keyReference = 0x0B
class AlgoConfig(ConfigurableParameter):
--
To view, visit
https://gerrit.osmocom.org/c/pysim/+/39744?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: I54aef10b6d4309398d4b779a3740a7d706d68603
Gerrit-Change-Number: 39744
Gerrit-PatchSet: 1
Gerrit-Owner: neels <nhofmeyr(a)sysmocom.de>