The import created presets with the store's default counter (1). Cards whose counters are already past it had to be edited preset by preset afterwards. - The outfile preview form gains a "Start counter value" field (default 1, the store's value). The value is written into every created keyset of every imported card - parse_outfile's `start_counter`, 1-10 hex digits, whitespace stripped and uppercased; a bad value raises and the endpoint answers 400. Without it the store's default still applies (the field is omitted), so the API keeps its old behaviour. - The preview shows the counter; an import stores the protocol's 10-digit form (counter_hex). - Docs: api.md (the field), help EN/RU (the form). - Version strings + the PWA cache bumped together (simple-v459). Tests: the parser (every keyset, normalisation, unset, the bad values), the endpoint (the preview's keysets, the 400, the stored padded form), the PWA (the field's default, the controls' normalisation, both bodies). 1008 Python + 953 frontend green.
This commit is contained in:
@@ -184,13 +184,23 @@ def _hex_value(tok):
|
||||
return v if v and len(v) % 2 == 0 else ''
|
||||
|
||||
|
||||
def parse_outfile(text, name='', algorithm16='3des2', tars=None, tar_keyset=None):
|
||||
def parse_outfile(text, name='', algorithm16='3des2', tars=None, tar_keyset=None,
|
||||
start_counter=None):
|
||||
"""Parse an outfile into preset dicts (the store's shape).
|
||||
|
||||
Returns ``{'presets': [...], 'report': {...}}``. Every skipped row or key
|
||||
is named in the report (up to ``SKIP_REPORT_MAX`` lines, then counted) -
|
||||
nothing is silently dropped. Raises ValueError on a malformed TAR table.
|
||||
``start_counter`` (1-10 hex digits) is written into every created keyset -
|
||||
the counter an operation against that keyset starts from; without it the
|
||||
store's default ('1') applies. Returns
|
||||
``{'presets': [...], 'report': {...}}``. Every skipped row or key is named
|
||||
in the report (up to ``SKIP_REPORT_MAX`` lines, then counted) - nothing is
|
||||
silently dropped. Raises ValueError on a malformed TAR table or counter.
|
||||
"""
|
||||
counter = None
|
||||
if start_counter not in (None, ''):
|
||||
counter = re.sub(r'\s', '', str(start_counter)).upper()
|
||||
if not re.fullmatch(r'[0-9A-F]{1,10}', counter):
|
||||
raise ValueError('start_counter must be 1-10 hex digits: %r'
|
||||
% (start_counter,))
|
||||
columns, line_index = find_columns(text)
|
||||
report = {'columns': columns or [], 'header_lines': max(line_index, 0),
|
||||
'rows': 0, 'cards': 0, 'keysets': [], 'tars': 0,
|
||||
@@ -256,8 +266,11 @@ def parse_outfile(text, name='', algorithm16='3des2', tars=None, tar_keyset=None
|
||||
% (row_no, n, len(kic_key) // 2))
|
||||
continue
|
||||
byte = '%02X' % ((n << 4) | algo)
|
||||
keysets.append({'kic': byte, 'kid': byte,
|
||||
'kicKey': kic_key, 'kidKey': kid_key})
|
||||
keyset = {'kic': byte, 'kid': byte,
|
||||
'kicKey': kic_key, 'kidKey': kid_key}
|
||||
if counter is not None:
|
||||
keyset['cntr'] = counter
|
||||
keysets.append(keyset)
|
||||
if not keysets:
|
||||
skip('line %d: no usable keyset' % row_no)
|
||||
continue
|
||||
|
||||
@@ -37,7 +37,7 @@ from osmocom.tlv import BER_TLV_IE
|
||||
from osmocom.utils import rpad
|
||||
|
||||
|
||||
VERSION = '3.32.0'
|
||||
VERSION = '3.32.1'
|
||||
|
||||
MAX_ENVELOPE_SEGMENTS = 5 # max SMS segments for outgoing C-APDU in ENVELOPE
|
||||
|
||||
@@ -11610,7 +11610,8 @@ class PysimHandler(BaseHTTPRequestHandler):
|
||||
name=str(body.get('name') or ''),
|
||||
algorithm16=algorithm16,
|
||||
tars=tars,
|
||||
tar_keyset=tar_keyset)
|
||||
tar_keyset=tar_keyset,
|
||||
start_counter=body.get('start_counter'))
|
||||
except ValueError as e:
|
||||
resp = {'error': str(e)}
|
||||
self._send_json(resp, 400)
|
||||
|
||||
Reference in New Issue
Block a user