v3.28.3: the outfile ADM byte-pair rule

The review of v3.28.2 found the parser accepting an odd-length ADM (e.g.
12345), while /api/verify-adm requires byte pairs
((?:[0-9A-F]{2}){2,8}) - the stored value could never verify and was
refused with a misleading "adm must be 4-16 hex digits".

The parser now applies the verifier's exact rule: an odd length (a half
byte) or a value over 16 digits is dropped at import time with "ADM is
not 4-16 hex digits in byte pairs".

Docs: help EN/RU, api.md and the repo AGENTS say "4-16 hex digits in
byte pairs".  Tests: the odd-length and the over-16 drop cases (both
real samples are even-length and unaffected: BAP 3632333239463337,
AM0027 CFA3DD9C6B7F0F8C).  915 frontend + 925 Python; sw cache
simple-v441.
This commit is contained in:
2026-10-14 18:17:59 +03:00
parent 09d8a12add
commit b023719555
9 changed files with 33 additions and 13 deletions
+16
View File
@@ -262,6 +262,22 @@ class OptionTests(unittest.TestCase):
self.assertNotIn('adm', res['presets'][0])
self.assertTrue(any('ADM is not 4-16 hex digits' in s
for s in res['report']['skipped']))
# an odd length is a half byte: /api/verify-adm would always refuse the
# stored value, so it is dropped at import time (v3.28.3)
text = ('ICCID KIC1 KID1 ADM\n' + DIGITS_F + ' ' + K16A + ' ' + K16B +
' 12345\n')
res = outfile.parse_outfile(text)
self.assertNotIn('adm', res['presets'][0])
self.assertTrue(any('ADM is not 4-16 hex digits in byte pairs' in s
for s in res['report']['skipped']))
# ...and so is a value over the 16-digit limit (the verifier pads to 8
# CHV bytes, a longer value would overflow)
text = ('ICCID KIC1 KID1 ADM\n' + DIGITS_F + ' ' + K16A + ' ' + K16B +
' ' + 'AB' * 9 + '\n')
res = outfile.parse_outfile(text)
self.assertNotIn('adm', res['presets'][0])
self.assertTrue(any('ADM is not 4-16 hex digits in byte pairs' in s
for s in res['report']['skipped']))
# a present but invalid PIN is dropped, the card kept
text = ('ICCID KIC1 KID1 PIN1\n' + DIGITS_F + ' ' + K16A + ' ' + K16B + ' 12\n')
res = outfile.parse_outfile(text)