mirror of
https://gitea.osmocom.org/sim-card/pysim.git
synced 2026-05-05 02:57:27 +03:00
Compare commits
2 Commits
neels/smsp
...
pmaier/fix
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c74d7fbd0d | ||
|
|
d7f4d20471 |
@@ -301,24 +301,55 @@ class LinkBaseTpdu(LinkBase):
|
|||||||
|
|
||||||
prev_tpdu = tpdu
|
prev_tpdu = tpdu
|
||||||
data, sw = self.send_tpdu(tpdu)
|
data, sw = self.send_tpdu(tpdu)
|
||||||
|
log.debug("T0: case #%u TPDU: %s => %s %s", case, tpdu, data or "(no data)", sw or "(no status word)")
|
||||||
|
if sw is None:
|
||||||
|
raise ValueError("no status word received")
|
||||||
|
|
||||||
# When we have sent the first APDU, the SW may indicate that there are response bytes
|
# After sending the APDU/TPDU the UICC/eUICC or SIM may response with a status word that indicates that further
|
||||||
# available. There are two SWs commonly used for this 9fxx (sim) and 61xx (usim), where
|
# TPDUs have to be sent in order to complete the task.
|
||||||
# xx is the number of response bytes available.
|
|
||||||
# See also:
|
|
||||||
if sw is not None:
|
if sw is not None:
|
||||||
while (sw[0:2] in ['9f', '61', '62', '63']):
|
if case == 4 or self.apdu_strict == False:
|
||||||
# SW1=9F: 3GPP TS 51.011 9.4.1, Responses to commands which are correctly executed
|
# In case the APDU is a case #4 APDU, the UICC/eUICC/SIM may indicate that there is response data
|
||||||
# SW1=61: ISO/IEC 7816-4, Table 5 — General meaning of the interindustry values of SW1-SW2
|
# available which has to be retrieved using a GET RESPONSE command TPDU.
|
||||||
# SW1=62: ETSI TS 102 221 7.3.1.1.4 Clause 4b): 62xx, 63xx, 9xxx != 9000
|
#
|
||||||
tpdu_gr = tpdu[0:2] + 'c00000' + sw[2:4]
|
# ETSI TS 102 221, section 7.3.1.1.4 is very cleare about the fact that the GET RESPONSE mechanism
|
||||||
prev_tpdu = tpdu_gr
|
# shall only apply on case #4 APDUs but unfortunately it is impossible to distinguish between case #3
|
||||||
d, sw = self.send_tpdu(tpdu_gr)
|
# and case #4 when the APDU format is not strictly followed. In order to be able to detect case #4
|
||||||
data += d
|
# correctly the Le byte (usually 0x00) must be present, is often forgotten. To avoid problems with
|
||||||
|
# legacy scripts that use raw APDU strings, we will still loosely apply GET RESPONSE based on what
|
||||||
|
# the status word indicates. Unless the user explicitly enables the strict mode (set apdu_strict true)
|
||||||
|
while True:
|
||||||
|
if sw in ['9000', '9100']:
|
||||||
|
# A status word of 9000 (or 9100 in case there is pending data from a proactive SIM command)
|
||||||
|
# indicates that either no response data was returnd or all response data has been retrieved
|
||||||
|
# successfully. We may discontinue the processing at this point.
|
||||||
|
break;
|
||||||
|
if sw[0:2] in ['61', '9f']:
|
||||||
|
# A status word of 61xx or 9fxx indicates that there is (still) response data available. We
|
||||||
|
# send a GET RESPONSE command with the length value indicated in the second byte of the status
|
||||||
|
# word. (see also ETSI TS 102 221, section 7.3.1.1.4, clause 4a and 3GPP TS 51.011 9.4.1 and
|
||||||
|
# ISO/IEC 7816-4, Table 5)
|
||||||
|
le_gr = sw[2:4]
|
||||||
|
elif sw[0:2] in ['62', '63']:
|
||||||
|
# There are corner cases (status word is 62xx or 63xx) where the UICC/eUICC/SIM asks us
|
||||||
|
# to send a dummy GET RESPONSE command. We send a GET RESPONSE command with a length of 0.
|
||||||
|
# (see also ETSI TS 102 221, section 7.3.1.1.4, clause 4b and ETSI TS 151 011, section 9.4.1)
|
||||||
|
le_gr = '00'
|
||||||
|
else:
|
||||||
|
# A status word other then the ones covered by the above logic may indicate an error. In this
|
||||||
|
# case we will discontinue the processing as well.
|
||||||
|
# (see also ETSI TS 102 221, section 7.3.1.1.4, clause 4c)
|
||||||
|
break
|
||||||
|
tpdu_gr = tpdu[0:2] + 'c00000' + le_gr
|
||||||
|
prev_tpdu = tpdu_gr
|
||||||
|
data_gr, sw = self.send_tpdu(tpdu_gr)
|
||||||
|
log.debug("T0: GET RESPONSE TPDU: %s => %s %s", tpdu_gr, data_gr or "(no data)", sw or "(no status word)")
|
||||||
|
data += data_gr
|
||||||
if sw[0:2] == '6c':
|
if sw[0:2] == '6c':
|
||||||
# SW1=6C: ETSI TS 102 221 Table 7.1: Procedure byte coding
|
# SW1=6C: ETSI TS 102 221 Table 7.1: Procedure byte coding
|
||||||
tpdu_gr = prev_tpdu[0:8] + sw[2:4]
|
tpdu_gr = prev_tpdu[0:8] + sw[2:4]
|
||||||
data, sw = self.send_tpdu(tpdu_gr)
|
data, sw = self.send_tpdu(tpdu_gr)
|
||||||
|
log.debug("T0: repated case #%u TPDU: %s => %s %s", case, tpdu_gr, data or "(no data)", sw or "(no status word)")
|
||||||
|
|
||||||
return data, sw
|
return data, sw
|
||||||
|
|
||||||
|
|||||||
@@ -7,10 +7,24 @@ set apdu_strict true
|
|||||||
# No command data field, No response data field present
|
# No command data field, No response data field present
|
||||||
apdu 00700001 --expect-sw 9000 --expect-response-regex '^$'
|
apdu 00700001 --expect-sw 9000 --expect-response-regex '^$'
|
||||||
|
|
||||||
|
# Case #1: (verify pin)
|
||||||
|
# This command returns the number of remaining authentication attempts in the
|
||||||
|
# form of a status that has the form 63cX, where X is the number of remaining
|
||||||
|
# attempts. Such a status word can be easily confused with the response to a
|
||||||
|
# case #4 APDU. This test checks if the transport layer correctly distinguishes
|
||||||
|
# the between APDU case #1 and APDU case #4.
|
||||||
|
apdu 0020000A --expect-sw 63c? --expect-response-regex '^$'
|
||||||
|
|
||||||
# Case #2: (status)
|
# Case #2: (status)
|
||||||
# No command data field, Response data field present
|
# No command data field, Response data field present
|
||||||
apdu 80F2000000 --expect-sw 9000 --expect-response-regex '^[a-fA-F0-9]+$'
|
apdu 80F2000000 --expect-sw 9000 --expect-response-regex '^[a-fA-F0-9]+$'
|
||||||
|
|
||||||
|
# Case #2: (verify pin)
|
||||||
|
# (see also above). This test checks if the transport layer is also able to
|
||||||
|
# distinguish correctly between APDU case #2 (with zero length response) and
|
||||||
|
# APDU case #4.
|
||||||
|
apdu 0020000A00 --expect-sw 63c? --expect-response-regex '^$'
|
||||||
|
|
||||||
# Case #3: (terminal capability)
|
# Case #3: (terminal capability)
|
||||||
# Command data field present, No response data field
|
# Command data field present, No response data field
|
||||||
apdu 80AA000005a903830180 --expect-sw 9000 --expect-response-regex '^$'
|
apdu 80AA000005a903830180 --expect-sw 9000 --expect-response-regex '^$'
|
||||||
|
|||||||
Reference in New Issue
Block a user