From e065cd50eda029a5daa0c02719bfe20d520cf796 Mon Sep 17 00:00:00 2001 From: Neels Hofmeyr Date: Sun, 20 Apr 2025 03:37:14 +0200 Subject: [PATCH] personalization audit: optionally audit all (unknown) SD keys By a flag, allow to audit also all Security Domain KVN that we have *not* created ConfigurableParameter subclasses for. For example, SCP80 has reserved kvn 0x01..0x0f, but we offer only Scp80Kvn01, Scp80Kvn02, Scp80Kvn03. So we would not show kvn 0x03..0x0f in an audit. This patch includes audits of all SD key kvn there may be in the UPP. This will help to spot SD keys that may already be present in a UPP template, with unexpected / unusual kvn. Change-Id: Icaf6f7b589f117868633c0968a99f2f0252cf612 --- pySim/esim/saip/batch.py | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/pySim/esim/saip/batch.py b/pySim/esim/saip/batch.py index 236f6191..48e2d05d 100644 --- a/pySim/esim/saip/batch.py +++ b/pySim/esim/saip/batch.py @@ -19,10 +19,13 @@ # along with this program. If not, see . import copy -from typing import Generator +import pprint +from typing import List, Generator from pySim.esim.saip.personalization import ConfigurableParameter from pySim.esim.saip import param_source from pySim.esim.saip import ProfileElementSequence, ProfileElementSD +from pySim.global_platform import KeyUsageQualifier +from osmocom.utils import b2h class BatchPersonalization: """Produce a series of eSIM profiles from predefined parameters. @@ -125,7 +128,7 @@ class UppAudit(dict): """ @classmethod - def from_der(cls, der: bytes, params: List, der_size=False): + def from_der(cls, der: bytes, params: List, der_size=False, additional_sd_keys=False): '''return a dict of parameter name and set of selected parameter values found in a DER encoded profile. Note: some ConfigurableParameter implementations return more than one key-value pair, for example, Imsi returns both 'IMSI' and 'IMSI-ACC' parameters. @@ -142,6 +145,12 @@ class UppAudit(dict): For example, params = [Imsi, ] is equivalent to params = [Imsi(), ]. For der_size=True, also include a {'der_size':12345} entry. + + For additional_sd_keys=True, output also all Security Domain KVN that there are *no* ConfigurableParameter + subclasses for. For example, SCP80 has reserved kvn 0x01..0x0f, but we offer only Scp80Kvn01, Scp80Kvn02, + Scp80Kvn03. So we would not show kvn 0x04..0x0f in an audit. additional_sd_keys=True includes audits of all SD + key KVN there may be in the UPP. This helps to spot SD keys that may already be present in a UPP template, with + unexpected / unusual kvn. ''' # make an instance of this class @@ -157,6 +166,22 @@ class UppAudit(dict): upp_audit.add_values(valdict) except (TypeError, ValueError) as e: raise ValueError(f'Error during audit for parameter {param}: {e}') from e + + if not additional_sd_keys: + return upp_audit + + # additional_sd_keys + for pe in pes.pe_list: + if pe.type != 'securityDomain': + continue + assert isinstance(pe, ProfileElementSD) + + for key in pe.keys: + audit_key = f'SdKey_KVN{key.key_version_number:02x}_ID{key.key_identifier:02x}' + kuq_bin = KeyUsageQualifier.build(key.key_usage_qualifier).hex() + audit_val = f'{key.key_components=!r} key_usage_qualifier=0x{kuq_bin}={key.key_usage_qualifier!r}' + upp_audit[audit_key] = set((audit_val, )) + return upp_audit def get_single_val(self, key, validate=True, allow_absent=False, absent_val=None):