Change in pysim[master]: integrate 'construct' python library

laforge gerrit-no-reply at lists.osmocom.org
Sat Apr 10 16:41:28 UTC 2021


laforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/pysim/+/23705 )


Change subject: integrate 'construct' python library
......................................................................

integrate 'construct' python library

'construct' is a declarative symmetric encoder/decoder for user
specified binary formats.  It should come in extremely handy in
tools like pySim.

We start the integration by adding transport methods for transceiving
APDUs with built-in encoding of the command data and decoding of the
response data.

Change-Id: Ibf457aa8b9480a8db5979defcfafd67674303f6c
---
M docs/library.rst
A pySim/construct.py
M pySim/transport/__init__.py
M requirements.txt
M setup.py
5 files changed, 102 insertions(+), 2 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/05/23705/1

diff --git a/docs/library.rst b/docs/library.rst
index 656a780..e2e24a7 100644
--- a/docs/library.rst
+++ b/docs/library.rst
@@ -73,6 +73,14 @@
 .. automodule:: pySim.transport.serial
    :members:
 
+
+pySim construct utilities
+-------------------------
+
+.. automodule:: pySim.construct
+   :members:
+
+
 pySim utility functions
 -----------------------
 
diff --git a/pySim/construct.py b/pySim/construct.py
new file mode 100644
index 0000000..03d284e
--- /dev/null
+++ b/pySim/construct.py
@@ -0,0 +1,42 @@
+from construct import *
+from pySim.utils import b2h, h2b
+
+"""Utility code related to the integration of the 'construct' declarative parser."""
+
+# (C) 2021 by Harald Welte <laforge at osmocom.org>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+class HexAdapter(Adapter):
+    """convert a bytes() type to a string of hex nibbles."""
+    def _decode(self, obj, context, path):
+        return b2h(obj)
+    def _encode(self, obj, context, path):
+        return h2b(obj)
+
+def filter_dict(d, exclude_prefix='_'):
+    """filter the input dict to ensure no keys starting with 'exclude_prefix' remain."""
+    res = {}
+    for (key, value) in d.items():
+        if key.startswith(exclude_prefix):
+            continue
+        if type(value) is dict:
+            res[key] = filter_dict(value)
+        else:
+            res[key] = value
+    return res
+
+# here we collect some shared / common definitions of data types
+LV = Prefixed(Int8ub, HexAdapter(GreedyBytes))
diff --git a/pySim/transport/__init__.py b/pySim/transport/__init__.py
index 96ad974..290bc7c 100644
--- a/pySim/transport/__init__.py
+++ b/pySim/transport/__init__.py
@@ -6,10 +6,12 @@
 from typing import Optional
 
 from pySim.exceptions import *
-from pySim.utils import sw_match
+from pySim.construct import filter_dict
+from pySim.utils import sw_match, b2h, h2b, i2h
 
 #
 # Copyright (C) 2009-2010  Sylvain Munaut <tnt at 246tNt.com>
+# Copyright (C) 2021 Harald Welte <laforge at osmocom.org>
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -127,6 +129,52 @@
 			raise SwMatchError(rv[1], sw.lower(), self.sw_interpreter)
 		return rv
 
+	def send_apdu_constr(self, cla, ins, p1, p2, cmd_constr, cmd_data, resp_constr):
+		"""Build and sends an APDU using a 'construct' definition; parses response.
+
+		Args:
+			cla : string (in hex) ISO 7816 class byte
+			ins : string (in hex) ISO 7816 instruction byte
+			p1 : string (in hex) ISO 7116 Parameter 1 byte
+			p2 : string (in hex) ISO 7116 Parameter 2 byte
+			cmd_cosntr : defining how to generate binary APDU command data
+			cmd_data : command data passed to cmd_constr
+			resp_cosntr : defining how to decode  binary APDU response data
+		Returns:
+			Tuple of (decoded_data, sw)
+		"""
+		cmd = cmd_constr.build(cmd_data) if cmd_data else ''
+		p3 = i2h([len(cmd)])
+		pdu = ''.join([cla, ins, p1, p2, p3, b2h(cmd)])
+		(data, sw) = self.send_apdu(pdu)
+		if data:
+			# filter the resulting dict to avoid '_io' members inside
+			rsp = filter_dict(resp_constr.parse(h2b(data)))
+		else:
+			rsp = None
+		return (rsp, sw)
+
+	def send_apdu_constr_checksw(self, cla, ins, p1, p2, cmd_constr, cmd_data, resp_constr,
+								 sw_exp="9000"):
+		"""Build and sends an APDU using a 'construct' definition; parses response.
+
+		Args:
+			cla : string (in hex) ISO 7816 class byte
+			ins : string (in hex) ISO 7816 instruction byte
+			p1 : string (in hex) ISO 7116 Parameter 1 byte
+			p2 : string (in hex) ISO 7116 Parameter 2 byte
+			cmd_cosntr : defining how to generate binary APDU command data
+			cmd_data : command data passed to cmd_constr
+			resp_cosntr : defining how to decode  binary APDU response data
+			exp_sw : string (in hex) of status word (ex. "9000")
+		Returns:
+			Tuple of (decoded_data, sw)
+		"""
+		(rsp, sw) = self.send_apdu_constr(cla, ins, p1, p2, cmd_constr, cmd_data, resp_constr)
+		if not sw_match(sw, sw_exp):
+			raise SwMatchError(sw, sw_exp.lower(), self.sw_interpreter)
+		return (rsp, sw)
+
 def init_reader(opts, **kwargs) -> Optional[LinkBase]:
 	"""
 	Init card reader driver
diff --git a/requirements.txt b/requirements.txt
index f203ed1..6da27cc 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -3,3 +3,4 @@
 pytlv
 cmd2
 jsonpath-ng
+construct
diff --git a/setup.py b/setup.py
index e7ab1c9..0fa3f1a 100644
--- a/setup.py
+++ b/setup.py
@@ -13,7 +13,8 @@
         "serial",
         "pytlv",
         "cmd2",
-        "jsonpath-ng"
+        "jsonpath-ng",
+        "construct",
     ],
     scripts=[
         'pySim-prog.py',

-- 
To view, visit https://gerrit.osmocom.org/c/pysim/+/23705
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: Ibf457aa8b9480a8db5979defcfafd67674303f6c
Gerrit-Change-Number: 23705
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <laforge at osmocom.org>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210410/7a030c5b/attachment.htm>


More information about the gerrit-log mailing list