v3.28.2: the outfile ADM encoding fix
The ADM column carries the key's hex value (the length varies, 4-16 hex
digits) - the form the preset store and /api/verify-adm use (pySim pads
it with 'f' to the 8 CHV bytes). The parser treated it as an ASCII
string hex-encoded and either mangled it (3632333239463337 -> 62329F37,
a wrong ADM that would fail VERIFY and consume an attempt) or dropped it
(CFA3DD9C6B7F0F8C - the live report with AM0027_alfa_dsa.out).
- The ADM is stored as-is: non-hex stripped, uppercased, [0-9A-F]{4,16};
a non-hex or too-short value is dropped with "ADM is not 4-16 hex
digits".
- _ascii_from_hex() is gone (its only user was the ADM column).
- Docs: help EN/RU, api.md and the repo AGENTS now say "the key's hex
value, 4-16 hex digits (the length varies)".
Note: presets imported from a BAP-style file before this fix hold the
mangled ADM - re-import or correct them.
Tests: the BAP fixture (the hex as-is), the AM0027 shape, a
short/lowercase value and the drop cases. Both real samples verified
(BAP 3632333239463337, AM0027 CFA3DD9C6B7F0F8C; the ALFA sample has no
ADM column and is unchanged). 915 frontend + 925 Python; sw cache
simple-v440.
This commit is contained in:
@@ -8,8 +8,9 @@ prefix) - and continues with one whitespace-separated row per card. The
|
||||
header and every column the presets do not use are ignored.
|
||||
|
||||
Recognised columns (case-insensitive): ``ICCID``, ``PIN1``/``PIN2``,
|
||||
``PUK1``/``PUK2``, ``ADM`` (the ASCII string, hex-encoded - the vendors print
|
||||
``3632333239463337`` for ``62329F37``), ``PSK`` (the SCP81 key, 16 bytes; an
|
||||
``PUK1``/``PUK2``, ``ADM`` (the key's hex value - the length varies, e.g. 8 or
|
||||
16 hex digits; this is the form the preset store and ``/api/verify-adm`` use,
|
||||
where pySim pads it with 'f' to the 8 CHV bytes), ``PSK`` (the SCP81 key, 16 bytes; an
|
||||
optional ``PSKID``/``PSK_ID`` column names its identity, defaulting to the
|
||||
card's ICCID) and ``KICn``/``KIDn`` - one keyset per numbered pair, up to 15.
|
||||
Everything else (``IMSI*``, ``EKI``, ``KIKn`` - the key-management key, no
|
||||
@@ -175,14 +176,6 @@ def _hex_value(tok):
|
||||
return v if v and len(v) % 2 == 0 else ''
|
||||
|
||||
|
||||
def _ascii_from_hex(v):
|
||||
"""The ADM column: an ASCII string hex-encoded. '' when it is not."""
|
||||
try:
|
||||
return bytes.fromhex(v).decode('ascii')
|
||||
except (ValueError, UnicodeDecodeError):
|
||||
return ''
|
||||
|
||||
|
||||
def parse_outfile(text, name='', algorithm16='3des2', tars=None, tar_keyset=None):
|
||||
"""Parse an outfile into preset dicts (the store's shape).
|
||||
|
||||
@@ -273,11 +266,13 @@ def parse_outfile(text, name='', algorithm16='3des2', tars=None, tar_keyset=None
|
||||
% (row_no, col, raw))
|
||||
i = idx['ADM']
|
||||
if 0 <= i < len(toks) and toks[i]:
|
||||
adm = _ascii_from_hex(_hex_value(toks[i]))
|
||||
if re.fullmatch(r'[0-9A-Fa-f]{4,16}', adm or ''):
|
||||
entry['adm'] = adm.upper()
|
||||
# The ADM column carries the key's hex value itself (the length
|
||||
# varies) - the form the preset store and /api/verify-adm use.
|
||||
adm = re.sub(r'[^0-9A-Fa-f]', '', str(toks[i])).upper()
|
||||
if re.fullmatch(r'[0-9A-F]{4,16}', adm):
|
||||
entry['adm'] = adm
|
||||
else:
|
||||
skip('line %d: ADM is not an ASCII-hex key - dropped' % row_no)
|
||||
skip('line %d: ADM is not 4-16 hex digits - dropped' % row_no)
|
||||
i = idx['PSK']
|
||||
if 0 <= i < len(toks) and toks[i]:
|
||||
psk = _hex_value(toks[i])
|
||||
|
||||
Reference in New Issue
Block a user