[1/6] personalization: refactor: drop ClassVarMeta use
Drop the ClassVarMeta/metaclass/ABCMeta stuff -- it doesn't seem to serve any purpose that is not similarly achieved with plain python inheritance. Upcoming patches will use normal inheritance a lot more. Note that most use of the ClassVarMeta was in the SdKey subclasses, and that these currently don't actually work. See the fix in patch I07dfc378705eba1318e9e8652796cbde106c6a52 . name: set a default name from the python class, as ClassVarMeta did. Also allow setting an explicit string as name instead, per subclass implementation (see I31f390d634e58c384589c50a33ca45d6f86d4e10). Related: SYS#6768 Change-Id: I60ea8fd11fb438ec90ddb08b17b658cbb789c051
This commit is contained in:
@@ -34,24 +34,34 @@ def file_replace_content(file: List[Tuple], new_content: bytes):
|
||||
file.append(('fillFileContent', new_content))
|
||||
return file
|
||||
|
||||
class ClassVarMeta(abc.ABCMeta):
|
||||
"""Metaclass that puts all additional keyword-args into the class. We use this to have one
|
||||
class definition for something like a PIN, and then have derived classes for PIN1, PIN2, ..."""
|
||||
def __new__(metacls, name, bases, namespace, **kwargs):
|
||||
#print("Meta_new_(metacls=%s, name=%s, bases=%s, namespace=%s, kwargs=%s)" % (metacls, name, bases, namespace, kwargs))
|
||||
x = super().__new__(metacls, name, bases, namespace)
|
||||
for k, v in kwargs.items():
|
||||
setattr(x, k, v)
|
||||
setattr(x, 'name', camel_to_snake(name))
|
||||
return x
|
||||
|
||||
class ConfigurableParameter(abc.ABC, metaclass=ClassVarMeta):
|
||||
class ConfigurableParameter:
|
||||
"""Base class representing a part of the eSIM profile that is configurable during the
|
||||
personalization process (with dynamic data from elsewhere)."""
|
||||
|
||||
# A subclass can set an explicit string as name (like name = "PIN1").
|
||||
# If name is left None, then __init__() will set self.name to a name derived from the python class name (like
|
||||
# "pin1"). See also the get_name() classmethod when you have no instance at hand.
|
||||
name = None
|
||||
|
||||
def __init__(self, input_value):
|
||||
self.input_value = input_value # the raw input value as given by caller
|
||||
self.value = None # the processed input value (e.g. with check digit) as produced by validate()
|
||||
|
||||
# set the instance's name to either an explicit name string, or to a name derived from the class name.
|
||||
if self.name is None:
|
||||
self.name = self.get_name()
|
||||
|
||||
@classmethod
|
||||
def get_name(cls):
|
||||
"""Return cls.name when it is set, otherwise return the python class name converted from 'CamelCase' to
|
||||
'snake_case'.
|
||||
When using class *instances*, you can just use my_instance.name.
|
||||
When using *classes*, cls.get_name() returns the same name a class instance would have.
|
||||
"""
|
||||
if cls.name:
|
||||
return cls.name
|
||||
return camel_to_snake(cls.__name__)
|
||||
|
||||
def validate(self):
|
||||
"""Optional validation method. Can be used by derived classes to perform validation
|
||||
of the input value (self.value). Will raise an exception if validation fails."""
|
||||
@@ -105,7 +115,7 @@ class Imsi(ConfigurableParameter):
|
||||
# TODO: DF.GSM_ACCESS if not linked?
|
||||
|
||||
|
||||
class SdKey(ConfigurableParameter, metaclass=ClassVarMeta):
|
||||
class SdKey(ConfigurableParameter):
|
||||
"""Configurable Security Domain (SD) Key. Value is presented as bytes."""
|
||||
# these will be set by derived classes
|
||||
key_type = None
|
||||
@@ -144,59 +154,108 @@ class SdKey(ConfigurableParameter, metaclass=ClassVarMeta):
|
||||
for pe in pes.get_pes_for_type('securityDomain'):
|
||||
self._apply_sd(pe)
|
||||
|
||||
class SdKeyScp80_01(SdKey, kvn=0x01, key_type=0x88, permitted_len=[16,24,32]): # AES key type
|
||||
pass
|
||||
class SdKeyScp80_01Kic(SdKeyScp80_01, key_id=0x01, key_usage_qual=0x18): # FIXME: ordering?
|
||||
pass
|
||||
class SdKeyScp80_01Kid(SdKeyScp80_01, key_id=0x02, key_usage_qual=0x14):
|
||||
pass
|
||||
class SdKeyScp80_01Kik(SdKeyScp80_01, key_id=0x03, key_usage_qual=0x48):
|
||||
pass
|
||||
class SdKeyScp80_01(SdKey):
|
||||
kvn = 0x01
|
||||
key_type = 0x88 # AES key type
|
||||
allow_len = (16,24,32)
|
||||
|
||||
class SdKeyScp81_01(SdKey, kvn=0x81): # FIXME
|
||||
pass
|
||||
class SdKeyScp81_01Psk(SdKeyScp81_01, key_id=0x01, key_type=0x85, key_usage_qual=0x3C):
|
||||
pass
|
||||
class SdKeyScp81_01Dek(SdKeyScp81_01, key_id=0x02, key_type=0x88, key_usage_qual=0x48):
|
||||
pass
|
||||
class SdKeyScp80_01Kic(SdKeyScp80_01):
|
||||
key_id = 0x01
|
||||
key_usage_qual = 0x18 # FIXME: ordering?
|
||||
|
||||
class SdKeyScp02_20(SdKey, kvn=0x20, key_type=0x88, permitted_len=[16,24,32]): # AES key type
|
||||
pass
|
||||
class SdKeyScp02_20Enc(SdKeyScp02_20, key_id=0x01, key_usage_qual=0x18):
|
||||
pass
|
||||
class SdKeyScp02_20Mac(SdKeyScp02_20, key_id=0x02, key_usage_qual=0x14):
|
||||
pass
|
||||
class SdKeyScp02_20Dek(SdKeyScp02_20, key_id=0x03, key_usage_qual=0x48):
|
||||
pass
|
||||
class SdKeyScp80_01Kid(SdKeyScp80_01):
|
||||
key_id = 0x02
|
||||
key_usage_qual = 0x14
|
||||
|
||||
class SdKeyScp03_30(SdKey, kvn=0x30, key_type=0x88, permitted_len=[16,24,32]): # AES key type
|
||||
pass
|
||||
class SdKeyScp03_30Enc(SdKeyScp03_30, key_id=0x01, key_usage_qual=0x18):
|
||||
pass
|
||||
class SdKeyScp03_30Mac(SdKeyScp03_30, key_id=0x02, key_usage_qual=0x14):
|
||||
pass
|
||||
class SdKeyScp03_30Dek(SdKeyScp03_30, key_id=0x03, key_usage_qual=0x48):
|
||||
pass
|
||||
|
||||
class SdKeyScp03_31(SdKey, kvn=0x31, key_type=0x88, permitted_len=[16,24,32]): # AES key type
|
||||
pass
|
||||
class SdKeyScp03_31Enc(SdKeyScp03_31, key_id=0x01, key_usage_qual=0x18):
|
||||
pass
|
||||
class SdKeyScp03_31Mac(SdKeyScp03_31, key_id=0x02, key_usage_qual=0x14):
|
||||
pass
|
||||
class SdKeyScp03_31Dek(SdKeyScp03_31, key_id=0x03, key_usage_qual=0x48):
|
||||
pass
|
||||
|
||||
class SdKeyScp03_32(SdKey, kvn=0x32, key_type=0x88, permitted_len=[16,24,32]): # AES key type
|
||||
pass
|
||||
class SdKeyScp03_32Enc(SdKeyScp03_32, key_id=0x01, key_usage_qual=0x18):
|
||||
pass
|
||||
class SdKeyScp03_32Mac(SdKeyScp03_32, key_id=0x02, key_usage_qual=0x14):
|
||||
pass
|
||||
class SdKeyScp03_32Dek(SdKeyScp03_32, key_id=0x03, key_usage_qual=0x48):
|
||||
pass
|
||||
class SdKeyScp80_01Kik(SdKeyScp80_01):
|
||||
key_id = 0x03
|
||||
key_usage_qual = 0x48
|
||||
|
||||
|
||||
class SdKeyScp81_01(SdKey):
|
||||
kvn = 0x81 # FIXME
|
||||
|
||||
class SdKeyScp81_01Psk(SdKeyScp81_01):
|
||||
key_id = 0x01
|
||||
key_type = 0x85
|
||||
key_usage_qual = 0x3C
|
||||
|
||||
class SdKeyScp81_01Dek(SdKeyScp81_01):
|
||||
key_id = 0x02
|
||||
key_type = 0x88
|
||||
key_usage_qual = 0x48
|
||||
|
||||
|
||||
class SdKeyScp02_20(SdKey):
|
||||
kvn = 0x20
|
||||
key_type = 0x88 # AES key type
|
||||
allow_len = (16,24,32)
|
||||
|
||||
class SdKeyScp02_20Enc(SdKeyScp02_20):
|
||||
key_id = 0x01
|
||||
key_usage_qual = 0x18
|
||||
|
||||
class SdKeyScp02_20Mac(SdKeyScp02_20):
|
||||
key_id = 0x02
|
||||
key_usage_qual = 0x14
|
||||
|
||||
class SdKeyScp02_20Dek(SdKeyScp02_20):
|
||||
key_id = 0x03
|
||||
key_usage_qual = 0x48
|
||||
|
||||
|
||||
class SdKeyScp03_30(SdKey):
|
||||
kvn = 0x30
|
||||
key_type = 0x88 # AES key type
|
||||
allow_len = (16,24,32)
|
||||
|
||||
class SdKeyScp03_30Enc(SdKeyScp03_30):
|
||||
key_id = 0x01
|
||||
key_usage_qual = 0x18
|
||||
|
||||
class SdKeyScp03_30Mac(SdKeyScp03_30):
|
||||
key_id = 0x02
|
||||
key_usage_qual = 0x14
|
||||
|
||||
class SdKeyScp03_30Dek(SdKeyScp03_30):
|
||||
key_id = 0x03
|
||||
key_usage_qual = 0x48
|
||||
|
||||
|
||||
class SdKeyScp03_31(SdKey):
|
||||
kvn = 0x31
|
||||
key_type = 0x88 # AES key type
|
||||
allow_len = (16,24,32)
|
||||
|
||||
class SdKeyScp03_31Enc(SdKeyScp03_31):
|
||||
key_id = 0x01
|
||||
key_usage_qual = 0x18
|
||||
|
||||
class SdKeyScp03_31Mac(SdKeyScp03_31):
|
||||
key_id = 0x02
|
||||
key_usage_qual = 0x14
|
||||
|
||||
class SdKeyScp03_31Dek(SdKeyScp03_31):
|
||||
key_id = 0x03
|
||||
key_usage_qual = 0x48
|
||||
|
||||
|
||||
class SdKeyScp03_32(SdKey):
|
||||
kvn = 0x32
|
||||
key_type = 0x88 # AES key type
|
||||
allow_len = (16,24,32)
|
||||
|
||||
class SdKeyScp03_32Enc(SdKeyScp03_32):
|
||||
key_id = 0x01
|
||||
key_usage_qual = 0x18
|
||||
|
||||
class SdKeyScp03_32Mac(SdKeyScp03_32):
|
||||
key_id = 0x02
|
||||
key_usage_qual = 0x14
|
||||
|
||||
class SdKeyScp03_32Dek(SdKeyScp03_32):
|
||||
key_id = 0x03
|
||||
key_usage_qual = 0x48
|
||||
|
||||
|
||||
def obtain_singleton_pe_from_pelist(l: List[ProfileElement], wanted_type: str) -> ProfileElement:
|
||||
@@ -208,7 +267,7 @@ 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, metaclass=ClassVarMeta):
|
||||
class Puk(ConfigurableParameter):
|
||||
"""Configurable PUK (Pin Unblock Code). String ASCII-encoded digits."""
|
||||
keyReference = None
|
||||
def validate(self):
|
||||
@@ -230,12 +289,14 @@ class Puk(ConfigurableParameter, metaclass=ClassVarMeta):
|
||||
pukCode['pukValue'] = h2b(padded_puk)
|
||||
return
|
||||
raise ValueError('cannot find pukCode')
|
||||
class Puk1(Puk, keyReference=0x01):
|
||||
pass
|
||||
class Puk2(Puk, keyReference=0x81):
|
||||
pass
|
||||
|
||||
class Pin(ConfigurableParameter, metaclass=ClassVarMeta):
|
||||
class Puk1(Puk):
|
||||
keyReference = 0x01
|
||||
|
||||
class Puk2(Puk):
|
||||
keyReference = 0x81
|
||||
|
||||
class Pin(ConfigurableParameter):
|
||||
"""Configurable PIN (Personal Identification Number). String of digits."""
|
||||
keyReference = None
|
||||
def validate(self):
|
||||
@@ -259,7 +320,8 @@ class Pin(ConfigurableParameter, metaclass=ClassVarMeta):
|
||||
pinCode['pinValue'] = h2b(padded_pin)
|
||||
return
|
||||
raise ValueError('cannot find pinCode')
|
||||
class AppPin(ConfigurableParameter, metaclass=ClassVarMeta):
|
||||
|
||||
class AppPin(ConfigurableParameter):
|
||||
"""Configurable PIN (Personal Identification Number). String of digits."""
|
||||
keyReference = None
|
||||
def validate(self):
|
||||
@@ -288,18 +350,21 @@ class AppPin(ConfigurableParameter, metaclass=ClassVarMeta):
|
||||
continue
|
||||
for instance in pes.pes_by_naa[naa]:
|
||||
self._apply_one(instance)
|
||||
class Pin1(Pin, keyReference=0x01):
|
||||
pass
|
||||
class Pin1(Pin):
|
||||
keyReference = 0x01
|
||||
|
||||
# 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
|
||||
class Pin2(AppPin):
|
||||
keyReference = 0x81
|
||||
|
||||
class Adm1(Pin):
|
||||
keyReference = 0x0A
|
||||
|
||||
class Adm2(Pin):
|
||||
keyReference = 0x0B
|
||||
|
||||
|
||||
class AlgoConfig(ConfigurableParameter, metaclass=ClassVarMeta):
|
||||
class AlgoConfig(ConfigurableParameter):
|
||||
"""Configurable Algorithm parameter."""
|
||||
key = None
|
||||
def validate(self):
|
||||
@@ -313,11 +378,13 @@ class AlgoConfig(ConfigurableParameter, metaclass=ClassVarMeta):
|
||||
continue
|
||||
algoConfiguration[1][self.key] = self.value
|
||||
|
||||
class K(AlgoConfig, key='key'):
|
||||
pass
|
||||
class Opc(AlgoConfig, key='opc'):
|
||||
pass
|
||||
class AlgorithmID(AlgoConfig, key='algorithmID'):
|
||||
class K(AlgoConfig):
|
||||
key = 'key'
|
||||
class Opc(AlgoConfig):
|
||||
key = 'opc'
|
||||
|
||||
class AlgorithmID(AlgoConfig):
|
||||
key = 'algorithmID'
|
||||
def validate(self):
|
||||
if self.input_value not in [1, 2, 3]:
|
||||
raise ValueError('Invalid algorithmID %s' % (self.input_value))
|
||||
|
||||
Reference in New Issue
Block a user