release: v3.9.1 - the counter probe sends a fixed read-only APDU
- The probe no longer takes a caller-supplied `apdu`: it always sends the read-only SELECT MF (the counter advances on the packet's security acceptance whatever the applet answers - 6A86/6D00 are normal there), so no caller can turn the sync probe into a write. - Version 3.9.1: server VERSION, pyproject.toml and the PWA header; sw cache simple-v357; docs/api.md and the repo AGENTS.md updated, and the workspace AGENTS.md gains the v3.9.1 history entry (its "Currently" line was stale at v3.7.1).
This commit is contained in:
+6
-6
@@ -252,7 +252,7 @@ import also accepts presets exported by the older localStorage-based builds.
|
|||||||
Sync a preset's SCP80 counter with the card. The card accepts only a counter
|
Sync a preset's SCP80 counter with the card. The card accepts only a counter
|
||||||
*above* its own (TS 102 225 §5.1.1, SPI1 b5b4 = `10`) and updates it only when
|
*above* its own (TS 102 225 §5.1.1, SPI1 b5b4 = `10`) and updates it only when
|
||||||
the packet is accepted, so rejected attempts change nothing; the probe walks a
|
the packet is accepted, so rejected attempts change nothing; the probe walks a
|
||||||
doubling ladder (`start+1`, `+2`, `+4`, …) with a read-only command until one
|
doubling ladder (`start+1`, `+2`, `+4`, …) with a fixed read-only command until one
|
||||||
is accepted, then persists `accepted+1` (monotonic) into the keyset. The
|
is accepted, then persists `accepted+1` (monotonic) into the keyset. The
|
||||||
search stops at a ceiling and after a bounded number of packets, so it can
|
search stops at a ceiling and after a bounded number of packets, so it can
|
||||||
never run towards the 40-bit maximum, where the card blocks the counter. The
|
never run towards the 40-bit maximum, where the card blocks the counter. The
|
||||||
@@ -261,15 +261,15 @@ the packet's, TS 102 225 §5.2 Table 3), which is why this probe exists.
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{"preset_id": "…", "kvn": 2, "tar": "000000", "spi1": "16", "spi2": "21",
|
{"preset_id": "…", "kvn": 2, "tar": "000000", "spi1": "16", "spi2": "21",
|
||||||
"cntr": "0001000000", "ceiling": "FFFFFFFF", "max_attempts": 40,
|
"cntr": "0001000000", "ceiling": "FFFFFFFF", "max_attempts": 40}
|
||||||
"apdu": "00A40000023F00"}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
All fields except `preset_id` are optional: `kvn` picks a keyset (the first
|
All fields except `preset_id` are optional: `kvn` picks a keyset (the first
|
||||||
otherwise), `tar`/`spi1`/`spi2` default to the preset's values, `cntr` to the
|
otherwise), `tar`/`spi1`/`spi2` default to the preset's values, `cntr` to the
|
||||||
keyset's counter, `ceiling` to `FFFFFFFF` (must stay below `FFFFFFFFFF`),
|
keyset's counter, `ceiling` to `FFFFFFFF` (must stay below `FFFFFFFFFF`) and
|
||||||
`max_attempts` to 40 (clamped to 1–64), and `apdu` to a read-only `SELECT MF`
|
`max_attempts` to 40 (clamped to 1–64). The probe always sends the read-only
|
||||||
(the probe command should never modify anything). A SPI1 without a counter
|
`SELECT MF` - the counter advances on the packet's security acceptance whatever
|
||||||
|
the applet answers (`6A86`/`6D00` are normal there). A SPI1 without a counter
|
||||||
check is refused (400).
|
check is refused (400).
|
||||||
|
|
||||||
**Response:** `{"success": true, "accepted_cntr": "0001000000",
|
**Response:** `{"success": true, "accepted_cntr": "0001000000",
|
||||||
|
|||||||
+1
-1
@@ -1801,7 +1801,7 @@
|
|||||||
// ===== Version =====
|
// ===== Version =====
|
||||||
// Single source of truth for the PWA version: shown in the header and used
|
// Single source of truth for the PWA version: shown in the header and used
|
||||||
// by the server version check in pysimConnect().
|
// by the server version check in pysimConnect().
|
||||||
const SIMPLE_VERSION = '3.9.0';
|
const SIMPLE_VERSION = '3.9.1';
|
||||||
document.getElementById('app-version').textContent = 'v' + SIMPLE_VERSION;
|
document.getElementById('app-version').textContent = 'v' + SIMPLE_VERSION;
|
||||||
|
|
||||||
// ===== Tab switching =====
|
// ===== Tab switching =====
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
const CACHE = 'simple-v356';
|
const CACHE = 'simple-v357';
|
||||||
const URLS = [
|
const URLS = [
|
||||||
'index.html',
|
'index.html',
|
||||||
'help.html',
|
'help.html',
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "pysim-simple-server"
|
name = "pysim-simple-server"
|
||||||
version = "3.9.0"
|
version = "3.9.1"
|
||||||
description = "HTTP REST server wrapping pysim for the SIMple PWA"
|
description = "HTTP REST server wrapping pysim for the SIMple PWA"
|
||||||
requires-python = ">=3.8"
|
requires-python = ">=3.8"
|
||||||
# pysim is a git-only dependency installed explicitly by setup.bat/setup.sh.
|
# pysim is a git-only dependency installed explicitly by setup.bat/setup.sh.
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ from osmocom.tlv import BER_TLV_IE
|
|||||||
from osmocom.utils import rpad
|
from osmocom.utils import rpad
|
||||||
|
|
||||||
|
|
||||||
VERSION = '3.9.0'
|
VERSION = '3.9.1'
|
||||||
|
|
||||||
MAX_ENVELOPE_SEGMENTS = 5 # max SMS segments for outgoing C-APDU in ENVELOPE
|
MAX_ENVELOPE_SEGMENTS = 5 # max SMS segments for outgoing C-APDU in ENVELOPE
|
||||||
|
|
||||||
@@ -1668,7 +1668,10 @@ def _counter_probe_params(preset, body):
|
|||||||
'spi1': spi1,
|
'spi1': spi1,
|
||||||
'spi2': str(body.get('spi2') or preset.get('spi2') or '21').strip().upper(),
|
'spi2': str(body.get('spi2') or preset.get('spi2') or '21').strip().upper(),
|
||||||
'tar': str(body.get('tar') or preset.get('tar') or '000000').strip().upper(),
|
'tar': str(body.get('tar') or preset.get('tar') or '000000').strip().upper(),
|
||||||
'apdu': str(body.get('apdu') or COUNTER_PROBE_DEFAULT_APDU).replace(' ', '').upper(),
|
# the probe command is fixed: read-only SELECT MF, which every applet
|
||||||
|
# answers (an error SW is fine - the counter advances on the packet's
|
||||||
|
# security acceptance, not on the command's own result)
|
||||||
|
'apdu': COUNTER_PROBE_DEFAULT_APDU,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user