mirror of
https://gitea.osmocom.org/sim-card/pysim.git
synced 2026-03-19 11:58:34 +03:00
pySim/transport add support for T=1 protocol and fix APDU/TPDU layer conflicts
ETSI TS 102 221, section 7.3 specifies that UICCs (and eUICCs) may support two different transport protocols: T=0 or T=1 or both. The spec also says that the terminal must support both protocols. This patch adds the necessary functionality to support the T=1 protocol alongside the T=0 protocol. However, this also means that we have to sharpen the lines between APDUs and TPDUs. As this patch also touches the low level interface to readers it was also manually tested with a classic serial reader. Calypso and AT command readers were not tested. Change-Id: I8b56d7804a2b4c392f43f8540e0b6e70001a8970 Related: OS#6367
This commit is contained in:
@@ -539,6 +539,52 @@ def boxed_heading_str(heading, width=80):
|
||||
return res
|
||||
|
||||
|
||||
def parse_command_apdu(apdu: bytes) -> int:
|
||||
"""Parse a given command APDU and return case (see also ISO/IEC 7816-3, Table 12 and Figure 26),
|
||||
lc, le and the data field.
|
||||
|
||||
Args:
|
||||
apdu : hexstring that contains the command APDU
|
||||
Returns:
|
||||
tuple containing case, lc and le values of the APDU (case, lc, le, data)
|
||||
"""
|
||||
|
||||
if len(apdu) == 4:
|
||||
# Case #1, No command data field, no response data field
|
||||
lc = 0
|
||||
le = 0
|
||||
data = b''
|
||||
return (1, lc, le, data)
|
||||
elif len(apdu) == 5:
|
||||
# Case #2, No command data field, response data field present
|
||||
lc = 0
|
||||
le = apdu[4]
|
||||
if le == 0:
|
||||
le = 256
|
||||
data = b''
|
||||
return (2, lc, le, data)
|
||||
elif len(apdu) > 5:
|
||||
lc = apdu[4];
|
||||
if lc == 0:
|
||||
lc = 256
|
||||
data = apdu[5:lc+5]
|
||||
if len(apdu) == 5 + lc:
|
||||
# Case #3, Command data field present, no response data field
|
||||
le = 0
|
||||
return (3, lc, le, data)
|
||||
elif len(apdu) == 5 + lc + 1:
|
||||
# Case #4, Command data field present, no response data field
|
||||
le = apdu[5 + lc]
|
||||
if le == 0:
|
||||
le = 256
|
||||
return (4, lc, le, data)
|
||||
else:
|
||||
raise ValueError('invalid APDU (%s), Lc=0x%02x (%d) does not match the length (%d) of the data field'
|
||||
% (b2h(apdu), lc, lc, len(apdu[5:])))
|
||||
else:
|
||||
raise ValueError('invalid APDU (%s), too short!' % b2h(apdu))
|
||||
|
||||
|
||||
class DataObject(abc.ABC):
|
||||
"""A DataObject (DO) in the sense of ISO 7816-4. Contrary to 'normal' TLVs where one
|
||||
simply has any number of different TLVs that may occur in any order at any point, ISO 7816
|
||||
|
||||
Reference in New Issue
Block a user