neels has uploaded this change for review.
saip/personalization: add SUCI parameters for SAIP 2.3
Change-Id: I7c727b10a850651a631211e4f168df5fec1600e5
Jenkins: skip-card-test
---
M pySim/esim/saip/personalization.py
M tests/unittests/test_configurable_parameters.py
M tests/unittests/xo/test_configurable_parameters
3 files changed, 358 insertions(+), 3 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/65/43865/1
diff --git a/pySim/esim/saip/personalization.py b/pySim/esim/saip/personalization.py
index e9ed709..a81c61f 100644
--- a/pySim/esim/saip/personalization.py
+++ b/pySim/esim/saip/personalization.py
@@ -19,13 +19,14 @@
import enum
import io
import re
+import json
from typing import List, Tuple, Generator, Optional
from construct.core import StreamError
from osmocom.tlv import camel_to_snake
from osmocom.utils import hexstr
from pySim.utils import enc_iccid, dec_iccid, enc_imsi, dec_imsi, h2b, b2h, rpad, sanitize_iccid
-from pySim.ts_31_102 import EF_AD
+from pySim.ts_31_102 import EF_AD, EF_UST, EF_Routing_Indicator, EF_SUCI_Calc_Info
from pySim.ts_51_011 import EF_SMSP
from pySim.esim.saip import param_source
from pySim.esim.saip import ProfileElement, ProfileElementSD, ProfileElementSequence
@@ -1175,3 +1176,202 @@
max_val = 255
example_input = '1'
default_source = param_source.ConstantSource
+
+
+class EfUstServiceParam(EnumParam):
+ """superclass for EF-UST service flag parameters"""
+ service_idx = 0
+ value_map = { 'enabled': True, 'disabled': False }
+ default_source = param_source.ConstantSource
+ example_input = sorted(value_map.keys())[0]
+
+ @classmethod
+ def apply_val(cls, pes: ProfileElementSequence, val):
+ for pe in pes.get_pes_for_type('usim'):
+ f_ust = pe.files['ef-ust']
+ ef_ust = EF_UST()
+ ust = ef_ust.decode_bin(f_ust.body)
+
+ ust[cls.service_idx]['activated'] = val
+
+ f_ust.body = ef_ust.encode_bin(ust)
+ pe.file2pe(f_ust)
+
+ @classmethod
+ def get_values_from_pes(cls, pes: ProfileElementSequence):
+ for pe in pes.get_pes_for_type('usim'):
+ f_ust = pe.files.get('ef-ust', None)
+ if not f_ust:
+ continue
+ ef_ust = EF_UST()
+ try:
+ ust = ef_ust.decode_bin(f_ust.body)
+
+ service_flag = ust[cls.service_idx]['activated']
+ yield { cls.name: cls.map_val_to_name(service_flag) }
+ except:
+ pass
+
+class SuciActive(EfUstServiceParam):
+ """EF-UST service nr 124: enable or disable the SUCI service."""
+ service_idx = 124
+ name = '5G-SUCI-active'
+ value_map = { 'SUCI-off': False, 'SUCI-on': True }
+ example_input = 'SUCI-on'
+
+class SuciInUsim(EfUstServiceParam):
+ """EF-UST service nr 125: calculate SUCI in UE or in USIM"""
+ service_idx = 125
+ name = '5G-SUCI-in-USIM'
+ value_map = { 'SUCI-in-UE': False, 'SUCI-in-USIM': True }
+ example_input = 'SUCI-in-USIM'
+
+class SuciRi(ConfigurableParameter):
+ """SUCI Routing Indicator as in section 4.4.11.11 of 3GPP TS 31.102"""
+ name = '5G-SUCI-RI'
+ allow_chars = '0123456789'
+ min_len = 1
+ max_len = 4
+ allow_types = (str,)
+ example_input = '0'
+ default_source = param_source.ConstantSource
+
+ KEY_RI = "routing_indicator"
+
+ @classmethod
+ def apply_val(cls, pes: ProfileElementSequence, val):
+ for pe in pes.get_pes_for_type('df-5gs'):
+ f_ri = pe.files.get('ef-routing-indicator', None)
+ if f_ri is None:
+ continue
+ ef_ri = EF_Routing_Indicator()
+ ri = ef_ri.decode_bin(f_ri.body)
+
+ ri[cls.KEY_RI] = str(val)
+
+ f_ri.body = ef_ri.encode_bin(ri)
+ pe.file2pe(f_ri)
+
+ @classmethod
+ def get_values_from_pes(cls, pes: ProfileElementSequence):
+ for pe in pes.get_pes_for_type('df-5gs'):
+ f_ri = pe.files.get('ef-routing-indicator', None)
+ if f_ri is None:
+ continue
+ ef_ri = EF_Routing_Indicator()
+ try:
+ ri = ef_ri.decode_bin(f_ri.body)
+ yield { cls.name: ri.get(cls.KEY_RI) }
+ except:
+ pass
+
+class SuciCalcInfoParameter(ConfigurableParameter):
+ """SUCI Calculation Information as in section 4.4.11.8 of 3GPP TS 31.102"""
+ name = '5G-SUCI-CalcInfo'
+ default_source = param_source.ConstantSource
+ allow_types = (str,)
+ max_len = 4096 # to indicate a large input field to UI renderers
+ example_input = '{"prot_scheme_id_list": [], "hnet_pubkey_list": []}'
+
+ PE_IN_UE = ("df-5gs", "ef-suci-calc-info")
+ PE_IN_USIM = ("df-saip", "ef-suci-calc-info-usim")
+ suci_calc_info_pe = None
+
+ @classmethod
+ def validate_val(cls, val):
+ val = super().validate_val(val)
+
+ if not val:
+ val = "{}"
+
+ # check that it is a dict something like
+ # {
+ # "prot_scheme_id_list": [
+ # {"priority": 0, "identifier": 2, "key_index": 1},
+ # {"priority": 1, "identifier": 1, "key_index": 2},
+ # ],
+ # "hnet_pubkey_list": [
+ # {"hnet_pubkey_identifier": 27,
+ # "hnet_pubkey": "0472DA71976234CE833A6907425867B82E074D44EF907DFB4B3E21C1C2256EBCD15A7DED52FCBB097A4ED250E036C7B9C8C7004C4EEDC4F068CD7BF8D3F900E3B4"},
+ # {"hnet_pubkey_identifier": 30,
+ # "hnet_pubkey": "5A8D38864820197C3394B92613B20B91633CBD897119273BF8E4A6F4EEC0A650"},
+ # ],
+ # }
+
+ try:
+ d = json.loads(val)
+ except json.decoder.JSONDecodeError as e:
+ raise ValueError(f"Cannot parse SUCI Calc Info: {e}") from e
+
+ KEY_PSI_LIST = 'prot_scheme_id_list'
+ KEY_HPK_LIST = 'hnet_pubkey_list'
+ KEYS_D = set((KEY_HPK_LIST, KEY_PSI_LIST))
+ KEYS_PSI = set(('identifier', 'key_index', 'priority'))
+ KEYS_HPK = set(('hnet_pubkey_identifier', 'hnet_pubkey'))
+
+ if not d:
+ d = { KEY_PSI_LIST: [], KEY_HPK_LIST: [] }
+
+ if not (isinstance(d, dict)
+ and set(d.keys()) == KEYS_D):
+ raise ValueError(f"Unexpected structure in SUCI Calc Info: expected dict with entries {KEYS_D}")
+
+ psi = d.get(KEY_PSI_LIST, None)
+ if not all((set(e.keys()) == KEYS_PSI) for e in psi):
+ raise ValueError("Unexpected structure in SUCI Calc Info:"
+ f" in {KEY_PSI_LIST}, expected dict with entries {KEYS_PSI}")
+
+ hpk = d.get(KEY_HPK_LIST, None)
+ if not all((set(e.keys()) == KEYS_HPK) for e in hpk):
+ raise ValueError("Unexpected structure in SUCI Calc Info:"
+ f" in {KEY_HPK_LIST}, expected dict with entries {KEYS_HPK}")
+ return d
+
+ @classmethod
+ def _apply_suci(cls, pes: ProfileElementSequence, val, pe_type="df-5gs", pe_file="ef-suci-calc-info"):
+ for pe in pes.get_pes_for_type(pe_type):
+ f_sucici = pe.files.get(pe_file, None)
+ if not f_sucici:
+ continue
+ ef_sucici = EF_SUCI_Calc_Info()
+ f_sucici.body = ef_sucici.encode_bin(val)
+ pe.file2pe(f_sucici)
+
+ @classmethod
+ def apply_val(cls, pes: ProfileElementSequence, val):
+ cls._apply_suci(pes, val, *cls.suci_calc_info_pe)
+
+ @classmethod
+ def _get_suci(cls, pes: ProfileElementSequence, pe_type="df-5gs", pe_file="ef-suci-calc-info"):
+ for pe in pes.get_pes_for_type(pe_type):
+ f_sucici = pe.files.get(pe_file, None)
+ if not f_sucici:
+ continue
+ ef_sucici = EF_SUCI_Calc_Info()
+ sucici = ef_sucici.decode_bin(f_sucici.body)
+
+ if not sucici:
+ sucici = {}
+
+ # normalize to string (bytes cannot go into json)
+ for hnet_pubkey in sucici.get('hnet_pubkey_list', ()):
+ val = hnet_pubkey['hnet_pubkey']
+ if isinstance(val, bytes):
+ val = b2h(val)
+ hnet_pubkey['hnet_pubkey'] = val
+
+ yield { cls.name: json.dumps(sucici) }
+
+ @classmethod
+ def get_values_from_pes(cls, pes: ProfileElementSequence):
+ yield from cls._get_suci(pes, *cls.suci_calc_info_pe)
+
+class SuciCalcInfoUe(SuciCalcInfoParameter):
+ """SUCI Calculation Information as in section 4.4.11.8 of 3GPP TS 31.102, readable by UE (DF-5GS)"""
+ name = '5G-SUCI-CalcInfo-UE'
+ suci_calc_info_pe = SuciCalcInfoParameter.PE_IN_UE
+
+class SuciCalcInfoUsim(SuciCalcInfoParameter):
+ """SUCI Calculation Information as in section 4.4.11.8 of 3GPP TS 31.102, readable only by USIM (DF-SAIP)"""
+ name = '5G-SUCI-CalcInfo-USIM'
+ suci_calc_info_pe = SuciCalcInfoParameter.PE_IN_USIM
diff --git a/tests/unittests/test_configurable_parameters.py b/tests/unittests/test_configurable_parameters.py
index 0115640..33c7647 100755
--- a/tests/unittests/test_configurable_parameters.py
+++ b/tests/unittests/test_configurable_parameters.py
@@ -21,6 +21,7 @@
import io
import sys
import unittest
+import json
from importlib import resources
from osmocom.utils import hexstr
from pySim.esim.saip import ProfileElementSequence
@@ -58,11 +59,15 @@
)
class Paramtest:
- def __init__(self, param_cls, val, expect_val, expect_clean_val=None):
+ iff_present_default = False
+ def __init__(self, param_cls, val, expect_val, expect_clean_val=None, iff_present=None):
self.param_cls = param_cls
self.val = val
self.expect_clean_val = expect_clean_val
self.expect_val = expect_val
+ if iff_present is None:
+ iff_present = Paramtest.iff_present_default
+ self.iff_present = iff_present
param_tests = [
Paramtest(param_cls=p13n.Imsi, val='123456',
@@ -273,8 +278,61 @@
val=3,
expect_clean_val=3,
expect_val='3'),
+ ]
- ]
+ Paramtest.iff_present_default = True
+
+ sucici = {
+ "prot_scheme_id_list": [
+ {"priority": 0, "identifier": 2, "key_index": 1},
+ {"priority": 1, "identifier": 1, "key_index": 2},
+ ],
+ "hnet_pubkey_list": [
+ {"hnet_pubkey_identifier": 27,
+ "hnet_pubkey": "0472da71976234ce833a6907425867b82e074d44ef907dfb4b3e21c1c2256ebcd15a7ded52fcbb097a4ed250e036c7b9c8c7004c4eedc4f068cd7bf8d3f900e3b4"},
+ {"hnet_pubkey_identifier": 30,
+ "hnet_pubkey": "5a8d38864820197c3394b92613b20b91633cbd897119273bf8e4a6f4eec0a650"},
+ ],
+ }
+
+ param_tests.extend([
+ Paramtest(param_cls=p13n.SuciActive, val='SUCI-on',
+ expect_clean_val=True,
+ expect_val={'5G-SUCI-active': 'SUCI-on'}),
+ Paramtest(param_cls=p13n.SuciActive, val='SUCI-off',
+ expect_clean_val=False,
+ expect_val={'5G-SUCI-active': 'SUCI-off'}),
+
+ Paramtest(param_cls=p13n.SuciInUsim, val='SUCI-in-UE',
+ expect_clean_val=False,
+ expect_val={'5G-SUCI-in-USIM': 'SUCI-in-UE'}),
+ Paramtest(param_cls=p13n.SuciInUsim, val='SUCI-in-USIM',
+ expect_clean_val=True,
+ expect_val={'5G-SUCI-in-USIM': 'SUCI-in-USIM'}),
+
+ Paramtest(param_cls=p13n.SuciRi, val='123',
+ expect_clean_val='123',
+ expect_val={'5G-SUCI-RI': '123'}),
+ Paramtest(param_cls=p13n.SuciRi, val='0',
+ expect_clean_val='0',
+ expect_val={'5G-SUCI-RI': '0'}),
+ Paramtest(param_cls=p13n.SuciRi, val='9999',
+ expect_clean_val='9999',
+ expect_val={'5G-SUCI-RI': '9999'}),
+
+ Paramtest(param_cls=p13n.SuciCalcInfoUe,
+ val=json.dumps(sucici),
+ expect_clean_val=sucici,
+ expect_val={'5G-SUCI-CalcInfo-UE': json.dumps(sucici)}),
+
+ Paramtest(param_cls=p13n.SuciCalcInfoUsim,
+ val=json.dumps(sucici),
+ expect_clean_val=sucici,
+ expect_val={'5G-SUCI-CalcInfo-USIM': json.dumps(sucici)}),
+
+ ])
+
+ Paramtest.iff_present_default = False
for sdkey_cls in (
# thin out the number of tests, as a compromise between completeness and test runtime
@@ -391,6 +449,13 @@
found = list((t.param_cls.get_value_from_pes(pes) or {}).values())
testlog.append(f"previous value: {found}")
+ if t.iff_present and not found:
+ testlog.append("skipping, param not in template.")
+ output = "\nskip: " + "\n ".join(testlog)
+ outputs.append(output)
+ print(output)
+ continue
+
try:
param.apply(pes)
except ValueError as e:
diff --git a/tests/unittests/xo/test_configurable_parameters b/tests/unittests/xo/test_configurable_parameters
index b2c9a5b..822e33e 100644
--- a/tests/unittests/xo/test_configurable_parameters
+++ b/tests/unittests/xo/test_configurable_parameters
@@ -214,6 +214,51 @@
previous value: ['2']
read_back_val={'MNC-LEN': '3'}:{str}
+ok: TS48v5_SAIP2.1A_NoBERTLV.der SuciActive(val='SUCI-on':str)
+ clean_val=True:bool
+ previous value: ['SUCI-on']
+ read_back_val={'5G-SUCI-active': 'SUCI-on'}:{str}
+
+ok: TS48v5_SAIP2.1A_NoBERTLV.der SuciActive(val='SUCI-off':str)
+ clean_val=False:bool
+ previous value: ['SUCI-on']
+ read_back_val={'5G-SUCI-active': 'SUCI-off'}:{str}
+
+ok: TS48v5_SAIP2.1A_NoBERTLV.der SuciInUsim(val='SUCI-in-UE':str)
+ clean_val=False:bool
+ previous value: ['SUCI-in-UE']
+ read_back_val={'5G-SUCI-in-USIM': 'SUCI-in-UE'}:{str}
+
+ok: TS48v5_SAIP2.1A_NoBERTLV.der SuciInUsim(val='SUCI-in-USIM':str)
+ clean_val=True:bool
+ previous value: ['SUCI-in-UE']
+ read_back_val={'5G-SUCI-in-USIM': 'SUCI-in-USIM'}:{str}
+
+skip: TS48v5_SAIP2.1A_NoBERTLV.der SuciRi(val='123':str)
+ clean_val='123':str
+ previous value: []
+ skipping, param not in template.
+
+skip: TS48v5_SAIP2.1A_NoBERTLV.der SuciRi(val='0':str)
+ clean_val='0':str
+ previous value: []
+ skipping, param not in template.
+
+skip: TS48v5_SAIP2.1A_NoBERTLV.der SuciRi(val='9999':str)
+ clean_val='9999':str
+ previous value: []
+ skipping, param not in template.
+
+skip: TS48v5_SAIP2.1A_NoBERTLV.der SuciCalcInfoUe(val='{"prot_scheme_id_list": [{"priority": 0, "identifier": 2, "key_index": 1}, {"priority": 1, "identifier": 1, "key_index": 2}], "hnet_pubkey_list": [{"hnet_pubkey_identifier": 27, "hnet_pubkey": "0472da71976234ce833a6907425867b82e074d44ef907dfb4b3e21c1c2256ebcd15a7ded52fcbb097a4ed250e036c7b9c8c7004c4eedc4f068cd7bf8d3f900e3b4"}, {"hnet_pubkey_identifier": 30, "hnet_pubkey": "5a8d38864820197c3394b92613b20b91633cbd897119273bf8e4a6f4eec0a650"}]}':str)
+ clean_val={'prot_scheme_id_list': [{'priority': 0, 'identifier': 2, 'key_index': 1}, {'priority': 1, 'identifier': 1, 'key_index': 2}], 'hnet_pubkey_list': [{'hnet_pubkey_identifier': 27, 'hnet_pubkey': '0472da71976234ce833a6907425867b82e074d44ef907dfb4b3e21c1c2256ebcd15a7ded52fcbb097a4ed250e036c7b9c8c7004c4eedc4f068cd7bf8d3f900e3b4'}, {'hnet_pubkey_identifier': 30, 'hnet_pubkey': '5a8d38864820197c3394b92613b20b91633cbd897119273bf8e4a6f4eec0a650'}]}:{list, list}
+ previous value: []
+ skipping, param not in template.
+
+skip: TS48v5_SAIP2.1A_NoBERTLV.der SuciCalcInfoUsim(val='{"prot_scheme_id_list": [{"priority": 0, "identifier": 2, "key_index": 1}, {"priority": 1, "identifier": 1, "key_index": 2}], "hnet_pubkey_list": [{"hnet_pubkey_identifier": 27, "hnet_pubkey": "0472da71976234ce833a6907425867b82e074d44ef907dfb4b3e21c1c2256ebcd15a7ded52fcbb097a4ed250e036c7b9c8c7004c4eedc4f068cd7bf8d3f900e3b4"}, {"hnet_pubkey_identifier": 30, "hnet_pubkey": "5a8d38864820197c3394b92613b20b91633cbd897119273bf8e4a6f4eec0a650"}]}':str)
+ clean_val={'prot_scheme_id_list': [{'priority': 0, 'identifier': 2, 'key_index': 1}, {'priority': 1, 'identifier': 1, 'key_index': 2}], 'hnet_pubkey_list': [{'hnet_pubkey_identifier': 27, 'hnet_pubkey': '0472da71976234ce833a6907425867b82e074d44ef907dfb4b3e21c1c2256ebcd15a7ded52fcbb097a4ed250e036c7b9c8c7004c4eedc4f068cd7bf8d3f900e3b4'}, {'hnet_pubkey_identifier': 30, 'hnet_pubkey': '5a8d38864820197c3394b92613b20b91633cbd897119273bf8e4a6f4eec0a650'}]}:{list, list}
+ previous value: []
+ skipping, param not in template.
+
ok: TS48v5_SAIP2.1A_NoBERTLV.der SdKeyScp02Kvn20AesDek(val='01020304050607080910111213141516':str)
clean_val=b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytes
previous value: []
@@ -1089,6 +1134,51 @@
previous value: ['2']
read_back_val={'MNC-LEN': '3'}:{str}
+ok: TS48v5_SAIP2.3_BERTLV_SUCI.der SuciActive(val='SUCI-on':str)
+ clean_val=True:bool
+ previous value: ['SUCI-on']
+ read_back_val={'5G-SUCI-active': 'SUCI-on'}:{str}
+
+ok: TS48v5_SAIP2.3_BERTLV_SUCI.der SuciActive(val='SUCI-off':str)
+ clean_val=False:bool
+ previous value: ['SUCI-on']
+ read_back_val={'5G-SUCI-active': 'SUCI-off'}:{str}
+
+ok: TS48v5_SAIP2.3_BERTLV_SUCI.der SuciInUsim(val='SUCI-in-UE':str)
+ clean_val=False:bool
+ previous value: ['SUCI-in-USIM']
+ read_back_val={'5G-SUCI-in-USIM': 'SUCI-in-UE'}:{str}
+
+ok: TS48v5_SAIP2.3_BERTLV_SUCI.der SuciInUsim(val='SUCI-in-USIM':str)
+ clean_val=True:bool
+ previous value: ['SUCI-in-USIM']
+ read_back_val={'5G-SUCI-in-USIM': 'SUCI-in-USIM'}:{str}
+
+ok: TS48v5_SAIP2.3_BERTLV_SUCI.der SuciRi(val='123':str)
+ clean_val='123':str
+ previous value: ['0']
+ read_back_val={'5G-SUCI-RI': '123'}:{hexstr}
+
+ok: TS48v5_SAIP2.3_BERTLV_SUCI.der SuciRi(val='0':str)
+ clean_val='0':str
+ previous value: ['0']
+ read_back_val={'5G-SUCI-RI': '0'}:{hexstr}
+
+ok: TS48v5_SAIP2.3_BERTLV_SUCI.der SuciRi(val='9999':str)
+ clean_val='9999':str
+ previous value: ['0']
+ read_back_val={'5G-SUCI-RI': '9999'}:{hexstr}
+
+ok: TS48v5_SAIP2.3_BERTLV_SUCI.der SuciCalcInfoUe(val='{"prot_scheme_id_list": [{"priority": 0, "identifier": 2, "key_index": 1}, {"priority": 1, "identifier": 1, "key_index": 2}], "hnet_pubkey_list": [{"hnet_pubkey_identifier": 27, "hnet_pubkey": "0472da71976234ce833a6907425867b82e074d44ef907dfb4b3e21c1c2256ebcd15a7ded52fcbb097a4ed250e036c7b9c8c7004c4eedc4f068cd7bf8d3f900e3b4"}, {"hnet_pubkey_identifier": 30, "hnet_pubkey": "5a8d38864820197c3394b92613b20b91633cbd897119273bf8e4a6f4eec0a650"}]}':str)
+ clean_val={'prot_scheme_id_list': [{'priority': 0, 'identifier': 2, 'key_index': 1}, {'priority': 1, 'identifier': 1, 'key_index': 2}], 'hnet_pubkey_list': [{'hnet_pubkey_identifier': 27, 'hnet_pubkey': '0472da71976234ce833a6907425867b82e074d44ef907dfb4b3e21c1c2256ebcd15a7ded52fcbb097a4ed250e036c7b9c8c7004c4eedc4f068cd7bf8d3f900e3b4'}, {'hnet_pubkey_identifier': 30, 'hnet_pubkey': '5a8d38864820197c3394b92613b20b91633cbd897119273bf8e4a6f4eec0a650'}]}:{list, list}
+ previous value: ['{"prot_scheme_id_list": [{"priority": 0, "identifier": 0, "key_index": 0}], "hnet_pubkey_list": []}']
+ read_back_val={'5G-SUCI-CalcInfo-UE': '{"prot_scheme_id_list": [{"priority": 0, "identifier": 2, "key_index": 1}, {"priority": 1, "identifier": 1, "key_index": 2}], "hnet_pubkey_list": [{"hnet_pubkey_identifier": 27, "hnet_pubkey": "0472da71976234ce833a6907425867b82e074d44ef907dfb4b3e21c1c2256ebcd15a7ded52fcbb097a4ed250e036c7b9c8c7004c4eedc4f068cd7bf8d3f900e3b4"}, {"hnet_pubkey_identifier": 30, "hnet_pubkey": "5a8d38864820197c3394b92613b20b91633cbd897119273bf8e4a6f4eec0a650"}]}'}:{str}
+
+ok: TS48v5_SAIP2.3_BERTLV_SUCI.der SuciCalcInfoUsim(val='{"prot_scheme_id_list": [{"priority": 0, "identifier": 2, "key_index": 1}, {"priority": 1, "identifier": 1, "key_index": 2}], "hnet_pubkey_list": [{"hnet_pubkey_identifier": 27, "hnet_pubkey": "0472da71976234ce833a6907425867b82e074d44ef907dfb4b3e21c1c2256ebcd15a7ded52fcbb097a4ed250e036c7b9c8c7004c4eedc4f068cd7bf8d3f900e3b4"}, {"hnet_pubkey_identifier": 30, "hnet_pubkey": "5a8d38864820197c3394b92613b20b91633cbd897119273bf8e4a6f4eec0a650"}]}':str)
+ clean_val={'prot_scheme_id_list': [{'priority': 0, 'identifier': 2, 'key_index': 1}, {'priority': 1, 'identifier': 1, 'key_index': 2}], 'hnet_pubkey_list': [{'hnet_pubkey_identifier': 27, 'hnet_pubkey': '0472da71976234ce833a6907425867b82e074d44ef907dfb4b3e21c1c2256ebcd15a7ded52fcbb097a4ed250e036c7b9c8c7004c4eedc4f068cd7bf8d3f900e3b4'}, {'hnet_pubkey_identifier': 30, 'hnet_pubkey': '5a8d38864820197c3394b92613b20b91633cbd897119273bf8e4a6f4eec0a650'}]}:{list, list}
+ previous value: ['{"prot_scheme_id_list": [{"priority": 0, "identifier": 0, "key_index": 0}], "hnet_pubkey_list": []}']
+ read_back_val={'5G-SUCI-CalcInfo-USIM': '{"prot_scheme_id_list": [{"priority": 0, "identifier": 2, "key_index": 1}, {"priority": 1, "identifier": 1, "key_index": 2}], "hnet_pubkey_list": [{"hnet_pubkey_identifier": 27, "hnet_pubkey": "0472da71976234ce833a6907425867b82e074d44ef907dfb4b3e21c1c2256ebcd15a7ded52fcbb097a4ed250e036c7b9c8c7004c4eedc4f068cd7bf8d3f900e3b4"}, {"hnet_pubkey_identifier": 30, "hnet_pubkey": "5a8d38864820197c3394b92613b20b91633cbd897119273bf8e4a6f4eec0a650"}]}'}:{str}
+
ok: TS48v5_SAIP2.3_BERTLV_SUCI.der SdKeyScp02Kvn20AesDek(val='01020304050607080910111213141516':str)
clean_val=b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytes
previous value: []
To view, visit change 43865. To unsubscribe, or for help writing mail filters, visit settings.