v3.26.0: per-TAR default keysets (the preset/SCP80/RAM rework)
Every preset TAR entry carries `keyset` (int 1-15) - the keyset every
operation addressed to that TAR uses: mandatory for any non-zero MSL
(the counters are keyset-linked), optional for MSL 00 (allowed: some
cards reject the no-security 00/00 KIc/KID form). The store fills it
automatically when the preset has a single keyset, the validation
refuses an entry naming an undefined keyset, and the schema is 6 (a v5
file loads leniently; editing it forces the fix).
The keyset selectors are gone: the SCP80 TAR field became a select of
the preset's entries (applying the TAR's keyset to the form and seeding
the SPI1 from its MSL); the RAM operations use the preset's ISD role
entry (the PWA sends only the preset id, the ISD TAR, SPI and the
counter override - the server resolves the keyset and the keys:
presets.tar_keyset, _preset_tar_keyset, _resolve_operation_keyset,
_op_keyset, used by send-ota's APDU path, ram-install, ram-install-app
and cap-compat); the counter probe and the test runner's scp80 steps
default to their TAR's keyset (an explicit kvn stays an override). A
security TAR without a keyset refuses the operation ("set it in the
Cards tab") - never a silent keyless send - and the start buttons wait
for a usable operation-TAR keyset.
The TAR probe checks the preset's TAR list only (the standard
TAR_PROBE_TARS list and the custom-TAR localStorage are gone; a `tars`
list selects a subset, a TAR outside the preset is refused), each row
using its own MSL and default keyset. The Cards editor's TAR table
gained a Keyset column (the only keyset preselected, an amber marker
when a security MSL lacks one).
Docs: help EN/RU, api.md's tar-probe contract, both AGENTS. Tests: the
store (the field, the auto-fill, the schema, the string forms), the
server resolution (send-ota + the refusal, the probe's per-row keysets
and refusals), the PWA (the TAR select, the RAM ISD resolution, the
keyset-free requests) - several fixtures updated for the new schema.
891 frontend + 885 Python; sw cache simple-v434.
This commit is contained in:
+13
-10
@@ -30,9 +30,9 @@ const FNS = ['berLenStr', 'buildApdu', 'escHtml', 'esc', 'chainInit', 'chainRamB
|
||||
'spCntrLow', 'ramCntrLowHtml', 'ramCntrLowPresetIdx', 'ramCntrLowView', 'ramShowCntrLow',
|
||||
'ramCntrLowBox', 'ramCntrLowClear',
|
||||
'spKeysetKvnOf', 'spKeysetList', 'spKeysetFor', 'spKeysetCheck',
|
||||
'spKeysetOptionsHtml', 'spPresetIdx', 'tarPresetIdx',
|
||||
'cardsKeysetsFromForm', 'spKeysetSync', 'spKeysetApply', 'spKeysetChanged',
|
||||
'ramKeysetChanged', 'ramPresetIdx', 'spKeysetGuard', 'ramKeysetGuard',
|
||||
'spTarOptionsHtml', 'spTarRender', 'spSpi1Seed', 'spTarKeysetGuard', 'cardsTarKeysetCell', 'cardsTarKeysetFromForm', 'cardsTarKeysetRefresh', 'cardsTarRowsRender', 'cardsTarRowHtml', 'cardsTarsFromTable', 'cardsFreeTarsFromForm', 'spPresetIdx', 'tarPresetIdx',
|
||||
'cardsKeysetsFromForm', 'spKeysetSync', 'spKeysetApply',
|
||||
'ramPresetIdx', 'spKeysetGuard', 'ramKeysetGuard',
|
||||
'ramCardIdxAfterRemove', 'ramClearResults', 'ramHideProgress', 'ramOpChanged', 'ramRender', 'ramApplyCard', 'ramExecute', 'decodePrivileges', 'ramActionBtn', 'ramCapToolkitMode', 'ramOpProgressText',
|
||||
'jcAidNorm', 'jcAidName', 'jcAidSuffix', 'jcAidHtml'];
|
||||
let code = '';
|
||||
@@ -1038,13 +1038,12 @@ test('every SCP80/RAM flow checks the low counter and stops', () => {
|
||||
assert.ok(go.includes('cardsEdit('), go);
|
||||
assert.ok(go.includes("getElementById('cards-ks-' + row + '-cntr')"), go);
|
||||
// the notice's sync probe posts to the bounded server endpoint with the
|
||||
// preset, the keyset the failed operation used and its SPI/TAR
|
||||
// preset, the operation's TAR (v3.26.0: the RAM view uses the ISD entry,
|
||||
// the server resolves the keyset) and its SPI
|
||||
const sync = extractFunc(html, 'ramSyncCounter');
|
||||
assert.ok(sync.includes("'/api/counter-probe'"), sync);
|
||||
assert.ok(sync.includes("own = view === 'sp'"), sync);
|
||||
assert.ok(sync.includes('kvnOf(own)'), sync);
|
||||
assert.ok(sync.includes('kvnOf(other)'), sync);
|
||||
assert.ok(sync.includes('spKeysetSync()'), 'the keyset labels must refresh');
|
||||
assert.ok(sync.includes("view === 'ram' ? cardsRoleTar(preset, 'isd')"), sync);
|
||||
assert.ok(sync.includes('spKeysetSync()'), 'the availability must refresh');
|
||||
assert.ok(sync.includes('spCntrPlaceholder()'),
|
||||
'the stored value must refresh the field placeholder (the field stays an override)');
|
||||
assert.ok(sync.includes("ramListingSpi2('40')"),
|
||||
@@ -1372,9 +1371,13 @@ test('getRamSpParams reads the computed SPI2 byte, not the base select', () => {
|
||||
assert.ok(/spi2: document\.getElementById\('sp-spi2-hex'\)/.test(fn), fn);
|
||||
});
|
||||
|
||||
test('getRamSpParams normalises the packet TAR to three bytes', () => {
|
||||
test('getRamSpParams sends the preset ISD TAR and no keyset fields (v3.26.0)', () => {
|
||||
// the server resolves the keyset from the preset's ISD TAR entry - the
|
||||
// PWA sends only the preset id, the ISD TAR, SPI and the counter override
|
||||
const fn = extractFunc(html, 'getRamSpParams');
|
||||
assert.ok(/tar:[\s\S]*?padEnd\(6, '0'\)\.slice\(0, 6\),/.test(fn), fn);
|
||||
assert.ok(fn.includes("tar: preset ? cardsRoleTar(preset, 'isd') : ''"), fn);
|
||||
assert.ok(!fn.includes('kic:'), 'the keyset fields are resolved server-side');
|
||||
assert.ok(!fn.includes('kicKey:'), 'the keys travel from the preset store');
|
||||
});
|
||||
|
||||
test('ramListingSpi2 requests the SMS-submit PoR for the listing queries', () => {
|
||||
|
||||
Reference in New Issue
Block a user