personalization: refactor Pin, Adm

Refactor Pin1, Pin2, Adm1 and Adm2 to the new ConfigurableParameter
implementation style.

Change-Id: I54aef10b6d4309398d4b779a3740a7d706d68603
This commit is contained in:
Neels Hofmeyr
2025-03-01 01:28:23 +01:00
committed by laforge
parent 21641816ea
commit d5b570b01d

View File

@@ -427,6 +427,9 @@ class SdKeyScp03_32Dek(SdKeyScp03_32, key_id=0x03, 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: def obtain_singleton_pe_from_pelist(l: List[ProfileElement], wanted_type: str) -> ProfileElement:
filtered = list(filter(lambda x: x.type == wanted_type, l)) filtered = list(filter(lambda x: x.type == wanted_type, l))
assert len(filtered) == 1 assert len(filtered) == 1
@@ -460,69 +463,55 @@ class Puk1(Puk):
class Puk2(Puk): class Puk2(Puk):
keyReference = 0x81 keyReference = 0x81
class Pin(DecimalHexParam):
"""Configurable PIN (Personal Identification Number). String of digits."""
rpad = 16
min_len = 4
max_len = 8
keyReference = None
class Pin(ConfigurableParameter,metaclass=ClassVarMeta): @staticmethod
"""Configurable PIN (Personal Identification Number). String of digits.""" def _apply_pinvalue(pe: ProfileElement, keyReference, val_bytes):
keyReference = None for pinCodes in obtain_all_pe_from_pelist(pe, 'pinCodes'):
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': if pinCodes.decoded['pinCodes'][0] != 'pinconfig':
return continue
for pinCode in pinCodes.decoded['pinCodes'][1]: for pinCode in pinCodes.decoded['pinCodes'][1]:
if pinCode['keyReference'] == self.keyReference: if pinCode['keyReference'] == keyReference:
pinCode['pinValue'] = h2b(padded_pin) pinCode['pinValue'] = val_bytes
return return True
raise ValueError('cannot find pinCode') return False
class AppPin(ConfigurableParameter, metaclass=ClassVarMeta):
"""Configurable PIN (Personal Identification Number). String of digits.""" @classmethod
keyReference = None def apply_val(cls, pes: ProfileElementSequence, val):
def validate(self): val_bytes = val
if isinstance(self.input_value, int): if not cls._apply_pinvalue(pes.pes_by_naa['mf'][0], cls.keyReference, val_bytes):
self.value = '%04d' % self.input_value raise ValueError('input template UPP has unexpected structure:'
else: + f' {cls.get_name()} cannot find pinCode with keyReference={cls.keyReference}')
self.value = self.input_value
if len(self.value) < 4 or len(self.value) > 8: class Pin1(Pin):
raise ValueError('PIN mus be 4..8 digits long') keyReference = 0x01
if not self.value.isdecimal():
raise ValueError('PIN must only contain decimal digits') class Pin2(Pin):
def _apply_one(self, pe: ProfileElement): keyReference = 0x81
pin = ''.join(['%02x' % (ord(x)) for x in self.value])
padded_pin = rpad(pin, 16) @classmethod
pinCodes = obtain_first_pe_from_pelist(pe, 'pinCodes') def apply_val(cls, pes: ProfileElementSequence, val):
if pinCodes.decoded['pinCodes'][0] != 'pinconfig': val_bytes = val
return # PIN2 is special: telecom + usim + isim + csim
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):
for naa in pes.pes_by_naa: for naa in pes.pes_by_naa:
if naa not in ['usim','isim','csim','telecom']: if naa not in ['usim','isim','csim','telecom']:
continue continue
for instance in pes.pes_by_naa[naa]: for instance in pes.pes_by_naa[naa]:
self._apply_one(instance) if not cls._apply_pinvalue(instance, cls.keyReference, val_bytes):
class Pin1(Pin, keyReference=0x01): raise ValueError('input template UPP has unexpected structure:'
pass + f' {cls.get_name()} cannot find pinCode with keyReference={cls.keyReference} in {naa=}')
# PIN2 is special: telecom + usim + isim + csim
class Pin2(AppPin, keyReference=0x81): class Adm1(Pin):
pass keyReference = 0x0A
class Adm1(Pin, keyReference=0x0A):
pass class Adm2(Pin):
class Adm2(Pin, keyReference=0x0B): keyReference = 0x0B
pass
class AlgoConfig(ConfigurableParameter, metaclass=ClassVarMeta): class AlgoConfig(ConfigurableParameter, metaclass=ClassVarMeta):