laforge has submitted this change. (
https://gerrit.osmocom.org/c/pysim/+/42441?usp=email )
Change subject: transport: change APDU format paradigm
......................................................................
transport: change APDU format paradigm
Unfortunately we have mixed up the concept of TPDUs and APDUs in
earlier versions of pySim-shell. This lead to problems with
detecteding the APDU case properly (see also ISO/IEC 7816-3) and
also prevented us from adding support for T=1.
This problem has been fixed long time ago and all APDUs sent from
the pySim-shell code should be well formed and valid according to
ISO/IEC 7816-3.
To ensure that we continue to format APDUs correctly as APDUs (and
not TPDUs) we have added a mechanism to the LinkBase class that
would either raise an exception or print a warning if someone
mistakenly tries to send an APDU that is really a TPDU. Whether a
warning is printed or an exception is raised is controlled via the
apdu_strict member in the LinkBase class, which is false (print
warning only) by default.
The reason why we have implemneted the mechanism this way was
because we wanted to ensure that existing APDU scripts (pySim-shell
apdu command) keep working, even though when those scripts uses
APDUs which are formally invalid.
Sending a TPDU instead of an APDU via a T=0 link will still work
in almost all cases. This is also the reason why this problem
slipped through unnoticed for long time. However, there may still
be subtile problems araising from this practice. The root of the
problem is that it is impossible to distinguish between APDU case
3 and 4 when a TPDU instead of an APDU is sent. However in order
to handle a case 4 APDU correctly we must be able to distinguish
the APDU case correctly to handle the case correctly.
ETSI TS 102 221, section 7.3.1.1.4, clause 4 is very clear about
the fact that not (only) the status word (e.g. 61xx) but the
APDU case is what matters.
To complete the logic in LinkBaseTpdu and to maintain compatibility
(older APDU scripts), we must still be able to switch between the
'apdu_strict' mode and the non-strict mode. However, since
pySim-shell, pySim-prog and pySim-read internally use proper APDUs,
we may enable the 'apdu_strict' mode by default.
At the same time we will limit the effect of pySim-shell's
apdu_strict setable to the apdu command only. By doing so, the
bahviour of the apdu command is not altered. Users will still
have to enable the 'strict' mode explicitly. At the same time
all the internal functionality of pySim-shell will always use
the 'strict' mode.
Related: OS#6970
Change-Id: I9a531a825def318b28bf58291d811cf119003fab
---
M pySim-shell.py
M pySim/transport/__init__.py
2 files changed, 12 insertions(+), 11 deletions(-)
Approvals:
laforge: Looks good to me, approved
Jenkins Builder: Verified
diff --git a/pySim-shell.py b/pySim-shell.py
index 50deea2..2bfc720 100755
--- a/pySim-shell.py
+++ b/pySim-shell.py
@@ -136,8 +136,7 @@
self.add_settable(Settable2Compat('apdu_trace', bool, 'Trace and
display APDUs exchanged with card', self,
onchange_cb=self._onchange_apdu_trace))
self.add_settable(Settable2Compat('apdu_strict', bool,
- 'Enforce APDU responses according to
ISO/IEC 7816-3, table 12', self,
-
onchange_cb=self._onchange_apdu_strict))
+ 'Strictly apply APDU format
according to ISO/IEC 7816-3, table 12', self))
self.add_settable(Settable2Compat('verbose', bool,
'Enable/disable verbose logging',
self,
onchange_cb=self._onchange_verbose))
@@ -218,13 +217,6 @@
else:
self.card._scc._tp.apdu_tracer = None
- def _onchange_apdu_strict(self, param_name, old, new):
- if self.card:
- if new == True:
- self.card._scc._tp.apdu_strict = True
- else:
- self.card._scc._tp.apdu_strict = False
-
def _onchange_verbose(self, param_name, old, new):
PySimLogger.set_verbose(new)
if new == True:
@@ -281,7 +273,7 @@
apdu_cmd_parser.add_argument('--expect-sw', help='expect a specified
status word', type=str, default=None)
apdu_cmd_parser.add_argument('--expect-response-regex', help='match
response against regex', type=str, default=None)
apdu_cmd_parser.add_argument('--raw', help='Bypass the logical channel
(and secure channel)', action='store_true')
- apdu_cmd_parser.add_argument('APDU', type=is_hexstr, help='APDU as hex
string')
+ apdu_cmd_parser.add_argument('APDU', type=is_hexstr, help='APDU as hex
string (see also: ISO/IEC 7816-3, section 12.1')
@cmd2.with_argparser(apdu_cmd_parser)
def do_apdu(self, opts):
@@ -290,14 +282,23 @@
tracked. Depending on the raw APDU sent, pySim-shell may not continue
to work as expected if you e.g. select
a different file."""
+ if not hasattr(self, 'apdu_strict_warning_displayed') and
self.apdu_strict is False:
+ self.poutput("Warning: The default for the setable parameter
`apdu_strict` will be changed from")
+ self.poutput(" `False` to `True` in future pySim-shell
releases. In case you are using")
+ self.poutput(" the `apdu` command from a script that still
mixes APDUs with TPDUs, consider")
+ self.poutput(" fixing or adding a `set apdu_strict false`
line at the beginning.")
+ self.apdu_strict_warning_displayed = True;
+
# When sending raw APDUs we access the scc object through _scc member
of the card object. It should also be
# noted that the apdu command plays an exceptional role since it is
the only card accessing command that
# can be executed without the presence of a runtime state (self.rs)
object. However, this also means that
# self.lchan is also not present (see method equip).
+ self.card._scc._tp.apdu_strict = self.apdu_strict
if opts.raw or self.lchan is None:
data, sw = self.card._scc.send_apdu(opts.APDU, apply_lchan = False)
else:
data, sw = self.lchan.scc.send_apdu(opts.APDU, apply_lchan = False)
+ self.card._scc._tp.apdu_strict = True
if data:
self.poutput("SW: %s, RESP: %s" % (sw, data))
else:
diff --git a/pySim/transport/__init__.py b/pySim/transport/__init__.py
index f19790c..6833a90 100644
--- a/pySim/transport/__init__.py
+++ b/pySim/transport/__init__.py
@@ -90,7 +90,7 @@
self.sw_interpreter = sw_interpreter
self.apdu_tracer = apdu_tracer
self.proactive_handler = proactive_handler
- self.apdu_strict = False
+ self.apdu_strict = True
@abc.abstractmethod
def __str__(self) -> str:
--
To view, visit https://gerrit.osmocom.org/c/pysim/+/42441?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: merged
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: I9a531a825def318b28bf58291d811cf119003fab
Gerrit-Change-Number: 42441
Gerrit-PatchSet: 3
Gerrit-Owner: dexter <[email protected]>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: daniel <[email protected]>
Gerrit-Reviewer: laforge <[email protected]>
Gerrit-Reviewer: neels <[email protected]>
Gerrit-CC: fixeria <[email protected]>