From 779092b0cd46b493faa6a40d2ecfb9d1df659750 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Fri, 22 Nov 2024 15:55:35 +0100 Subject: [PATCH] esim.saip: Fix computation of file content When generating the file content (body), we need to proceed in the following order: 1a) If FCP contains fillPattern/repeatPattern, compute file content from those 1b) If FCP doesn't contain fillPattern/repeatPattern but template exists, compute file content from template 2) Apply any fillFileConten / fillFileOffset from the SAIP File on top of the above Change-Id: I822bb5fbec11a3be35910a496af7168458fd949c Closes: OS#6642 --- pySim/esim/saip/__init__.py | 21 +++++++++++++++++---- pySim/ts_102_222.py | 10 ++++++++++ 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/pySim/esim/saip/__init__.py b/pySim/esim/saip/__init__.py index 3490f64c..355e6b9d 100644 --- a/pySim/esim/saip/__init__.py +++ b/pySim/esim/saip/__init__.py @@ -18,6 +18,7 @@ import logging import abc import io +import os from typing import Tuple, List, Optional, Dict, Union from collections import OrderedDict import asn1tools @@ -25,6 +26,7 @@ from osmocom.utils import b2h, h2b, Hexstr from osmocom.tlv import BER_TLV_IE, bertlv_parse_tag, bertlv_parse_len from osmocom.construct import build_construct, parse_construct, GreedyInteger +from pySim import ts_102_222 from pySim.utils import dec_imsi from pySim.ts_102_221 import FileDescriptor from pySim.filesystem import CardADF, Path @@ -352,18 +354,29 @@ class File: ret += self.file_content_to_tuples() return ret - @staticmethod - def file_content_from_tuples(l: List[Tuple]) -> Optional[bytes]: + def expand_fill_pattern(self) -> bytes: + """Expand the fill/repeat pattern as per TS 102 222 Section 6.3.2.2.2""" + return ts_102_222.expand_pattern(self.fill_pattern, self.fill_pattern_repeat, self.file_size) + + def file_content_from_tuples(self, l: List[Tuple]) -> Optional[bytes]: """linearize a list of fillFileContent / fillFileOffset tuples into a stream of bytes.""" stream = io.BytesIO() + # Providing file content within "fillFileContent" / "fillFileOffset" shall have the same effect as + # creating a file with a fill/repeat pattern and thereafter updating the content via Update. + # Step 1: Fill with pattern from Fcp or Template + if self.fill_pattern: + stream.write(self.expand_fill_pattern()) + elif self.template and self.template.default_val: + stream.write(self.template.expand_default_value_pattern(self.file_size)) + stream.seek(0) + # then process the fillFileContent/fillFileOffset for k, v in l: if k == 'doNotCreate': return None if k == 'fileDescriptor': pass elif k == 'fillFileOffset': - # FIXME: respect the fillPattern! - stream.write(b'\xff' * v) + stream.seek(v, os.SEEK_CUR) elif k == 'fillFileContent': stream.write(v) else: diff --git a/pySim/ts_102_222.py b/pySim/ts_102_222.py index e54c1969..74eb2c3a 100644 --- a/pySim/ts_102_222.py +++ b/pySim/ts_102_222.py @@ -25,6 +25,16 @@ from osmocom.utils import b2h, auto_uint8, auto_uint16, is_hexstr from pySim.ts_102_221 import * +def expand_pattern(pattern: bytes, repeat: bool, size: int) -> bytes: + """Expand the fill/repeat pattern as per TS 102 222 Section 6.3.2.2.2 Tags C1/C2.""" + if not repeat: + pad_len = size - len(pattern) + return pattern + pattern[-1:] * pad_len + else: + count = size // len(pattern) + part_len = size - count * len(pattern) + return pattern * count + pattern[:part_len] + @with_default_category('TS 102 222 Administrative Commands') class Ts102222Commands(CommandSet): """Administrative commands for telecommunication applications."""