laforge has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/pysim/+/41691?usp=email )


Change subject: esim.saip.data_source: Different source of data for 
personalization
......................................................................

esim.saip.data_source: Different source of data for personalization

When personalizing eSIM profiles (or even USIM cards), there is often a
need for a data source of fixed / incrementing or random data.  This
commit introduces the fundamental infrastructure for this.

Change-Id: Ia6f70ff467ba58024d94742ba5cecd8141b93ad6
---
A pySim/esim/saip/data_source.py
M tests/unittests/test_esim_saip.py
2 files changed, 133 insertions(+), 0 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/91/41691/1

diff --git a/pySim/esim/saip/data_source.py b/pySim/esim/saip/data_source.py
new file mode 100644
index 0000000..0e14ad8
--- /dev/null
+++ b/pySim/esim/saip/data_source.py
@@ -0,0 +1,90 @@
+# Data sources: Provding data for profile personalization
+#
+# (C) 2024 by Harald Welte <[email protected]>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import abc
+import secrets
+
+from Cryptodome.Random import get_random_bytes
+
+class DataSource(abc.ABC):
+    """Base class for something that can provide data during a personalization 
process."""
+
+    @abc.abstractmethod
+    def generate_one(self):
+        pass
+
+
+class DataSourceFixed(DataSource):
+    """A data source that provides a fixed value (of any type).
+
+    Parameters:
+        fixed_value: The fixed value that shall be used during each data 
generation
+    """
+    def __init__(self, fixed_value, **kwargs):
+        self.fixed_value = fixed_value
+        super().__init__(**kwargs)
+
+    def generate_one(self):
+        return self.fixed_value
+
+
+class DataSourceIncrementing(DataSource):
+    """A data source that provides incrementing integer numbers.
+
+    Parameters:
+        base_value: The start value (value returned during first data 
generation)
+        step_size: Increment step size (Default: 1)
+    """
+    def __init__(self, base_value: int, **kwargs):
+        self.base_value = int(base_value)
+        self.step_size = kwargs.pop('step_size', 1)
+        self.i = 0
+        super().__init__(**kwargs)
+
+    def generate_one(self):
+        val = self.base_value + self.i
+        self.i += self.step_size
+        return val
+
+
+class DataSourceRandomBytes(DataSource):
+    """A data source that provides a configurable number of random bytes.
+
+    Parameters:
+        size: Number of bytes to generate each turn
+    """
+    def __init__(self, size: int, **kwargs):
+        self.size = size
+        super().__init__(**kwargs)
+
+    def generate_one(self):
+        return get_random_bytes(self.size)
+
+
+class DataSourceRandomUInt(DataSource):
+    """A data source that provides a configurable unsigned integer value.
+
+    Parameters:
+        below: Number one greater than the maximum permitted random unsigned 
integer
+    """
+    def __init__(self, below: int, **kwargs):
+        self.below = below
+        super().__init__(**kwargs)
+
+    def generate_one(self):
+        return secrets.randbelow(self.below)
+
diff --git a/tests/unittests/test_esim_saip.py 
b/tests/unittests/test_esim_saip.py
index e7e324d..2796a83 100755
--- a/tests/unittests/test_esim_saip.py
+++ b/tests/unittests/test_esim_saip.py
@@ -21,6 +21,7 @@
 from osmocom.utils import h2b, b2h

 from pySim.esim.saip import *
+from pySim.esim.saip.data_source import *
 from pySim.esim.saip.personalization import *
 from pprint import pprint as pp

@@ -90,5 +91,47 @@
         self.assertTrue(oid.OID('1.0.1') > oid.OID('1.0'))
         self.assertTrue(oid.OID('1.0.2') > oid.OID('1.0.1'))

+class DataSourceTest(unittest.TestCase):
+    def test_fixed(self):
+        FIXED = b'\x01\x02\x03'
+        ds = DataSourceFixed(FIXED)
+        self.assertEqual(ds.generate_one(), FIXED)
+        self.assertEqual(ds.generate_one(), FIXED)
+        self.assertEqual(ds.generate_one(), FIXED)
+
+    def test_incrementing(self):
+        BASE_VALUE = 100
+        ds = DataSourceIncrementing(BASE_VALUE)
+        self.assertEqual(ds.generate_one(), BASE_VALUE)
+        self.assertEqual(ds.generate_one(), BASE_VALUE+1)
+        self.assertEqual(ds.generate_one(), BASE_VALUE+2)
+        self.assertEqual(ds.generate_one(), BASE_VALUE+3)
+
+    def test_incrementing_step3(self):
+        BASE_VALUE = 300
+        ds = DataSourceIncrementing(BASE_VALUE, step_size=3)
+        self.assertEqual(ds.generate_one(), BASE_VALUE)
+        self.assertEqual(ds.generate_one(), BASE_VALUE+3)
+        self.assertEqual(ds.generate_one(), BASE_VALUE+6)
+
+    def test_random(self):
+        ds = DataSourceRandomBytes(8)
+        res = []
+        for i in range(0,100):
+            res.append(ds.generate_one())
+        for r in res:
+            self.assertEqual(len(r), 8)
+        # ensure no duplicates exist
+        self.assertEqual(len(set(res)), len(res))
+
+    def test_random_int(self):
+        ds = DataSourceRandomUInt(below=256)
+        res = []
+        for i in range(0,100):
+            res.append(ds.generate_one())
+        for r in res:
+            self.assertTrue(r < 256)
+
+
 if __name__ == "__main__":
        unittest.main()

--
To view, visit https://gerrit.osmocom.org/c/pysim/+/41691?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings?usp=email

Gerrit-MessageType: newchange
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: Ia6f70ff467ba58024d94742ba5cecd8141b93ad6
Gerrit-Change-Number: 41691
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <[email protected]>

Reply via email to