[3/6] personalization: refactor Puk
Implement abstract DecimalHexParam, and use it to refactor Puk1 and Puk2 to the new ConfigurableParameter implementation style. DecimalHexParam will also be used for Pin and Adm soon. Change-Id: I271e6c030c890778ab7af9ab3bc7997e22018f6a
This commit is contained in:
@@ -224,6 +224,27 @@ class DecimalParam(ConfigurableParameter):
|
||||
return super().validate_val(val)
|
||||
|
||||
|
||||
class DecimalHexParam(DecimalParam):
|
||||
"""The input value is decimal digits. The decimal value is stored such that each hexadecimal digit represents one
|
||||
decimal digit, useful for various PIN type parameters.
|
||||
|
||||
Optionally, the value is stored with padding, for example: rpad = 8 would store '123' as '123fffff'. This is also
|
||||
common in PIN type parameters.
|
||||
"""
|
||||
rpad = None
|
||||
rpad_char = 'f'
|
||||
|
||||
@classmethod
|
||||
def validate_val(cls, val):
|
||||
val = super().validate_val(val)
|
||||
val = ''.join('%02x' % ord(x) for x in val)
|
||||
if cls.rpad is not None:
|
||||
c = cls.rpad_char
|
||||
val = rpad(val, cls.rpad, c)
|
||||
# a DecimalHexParam subclass expects the apply_val() input to be a bytes instance ready for the pes
|
||||
return h2b(val)
|
||||
|
||||
|
||||
class Iccid(DecimalParam):
|
||||
"""ICCID Parameter. Input: string of decimal digits.
|
||||
If the string of digits is only 18 digits long, add a Luhn check digit."""
|
||||
@@ -412,28 +433,24 @@ def obtain_first_pe_from_pelist(l: List[ProfileElement], wanted_type: str) -> Pr
|
||||
filtered = list(filter(lambda x: x.type == wanted_type, l))
|
||||
return filtered[0]
|
||||
|
||||
class Puk(ConfigurableParameter):
|
||||
"""Configurable PUK (Pin Unblock Code). String ASCII-encoded digits."""
|
||||
keyReference = None
|
||||
def validate(self):
|
||||
if isinstance(self.input_value, int):
|
||||
self.value = '%08d' % self.input_value
|
||||
else:
|
||||
self.value = self.input_value
|
||||
# FIXME: valid length?
|
||||
if not self.value.isdecimal():
|
||||
raise ValueError('PUK must only contain decimal digits')
|
||||
|
||||
def apply(self, pes: ProfileElementSequence):
|
||||
puk = ''.join(['%02x' % (ord(x)) for x in self.value])
|
||||
padded_puk = rpad(puk, 16)
|
||||
class Puk(DecimalHexParam):
|
||||
"""Configurable PUK (Pin Unblock Code). String ASCII-encoded digits."""
|
||||
allow_len = 8
|
||||
rpad = 16
|
||||
keyReference = None
|
||||
|
||||
@classmethod
|
||||
def apply_val(cls, pes: ProfileElementSequence, val):
|
||||
val_bytes = val
|
||||
mf_pes = pes.pes_by_naa['mf'][0]
|
||||
pukCodes = obtain_singleton_pe_from_pelist(mf_pes, 'pukCodes')
|
||||
for pukCode in pukCodes.decoded['pukCodes']:
|
||||
if pukCode['keyReference'] == self.keyReference:
|
||||
pukCode['pukValue'] = h2b(padded_puk)
|
||||
if pukCode['keyReference'] == cls.keyReference:
|
||||
pukCode['pukValue'] = val_bytes
|
||||
return
|
||||
raise ValueError('cannot find pukCode')
|
||||
raise ValueError("input template UPP has unexpected structure:"
|
||||
f" cannot find pukCode with keyReference={cls.keyReference}")
|
||||
|
||||
class Puk1(Puk):
|
||||
keyReference = 0x01
|
||||
@@ -441,6 +458,7 @@ class Puk1(Puk):
|
||||
class Puk2(Puk):
|
||||
keyReference = 0x81
|
||||
|
||||
|
||||
class Pin(ConfigurableParameter):
|
||||
"""Configurable PIN (Personal Identification Number). String of digits."""
|
||||
keyReference = None
|
||||
|
||||
Reference in New Issue
Block a user