v3.20.0 (review fixes): the PoR decode uses the effective counter; the PWA fallback matches the server's seed
Two boundary flaws found reviewing v3.20.0: - /api/send-ota decoded the PoR with the request's `cntr`, not the counter the packet was actually built with. With the new seeding an omitted counter is the normal case, so a warning ENVELOPE's verdict - notably the live card's cntr_low PoR - could fail its RC/CC check and be lost (the success and the failure path are both fixed). Tests pin the decode counter on both paths; the failure path also echoes the effective `cntr`. - the PWA's effective counter (preview / verify / the older-server fallback) fell back to the preset's first keyset and then 1, while the server's empty seed builds counter 0 (no preset / kvn 0 / an unknown keyset). A manual form or a keyless packet then produced a spurious "Verify vs pySim" MISMATCH and a preview that differed from the delivered packet. spPresetCounterValue()/spCntrEffective() now mirror _preset_counter_seed() exactly: the packet's matched keyset, else 0. - the `OTA SEND: counter not tracked` line reflects the effective counter (a seeded value is logged too); docs/api.md records that the seed uses the packet's keyset whatever SPI1.b5b4 says. Tests: 823 frontend + 737 Python; sw cache simple-v394.
This commit is contained in:
@@ -64,6 +64,10 @@ function fakeEnv(selValue, selId, presetCntr) {
|
||||
'sp-kid-idx', 'sp-kid-alg', 'sp-tar', 'sp-cntr', 'sp-kic-key', 'sp-kid-key']) {
|
||||
els[id] = { value: '' };
|
||||
}
|
||||
// the combined key bytes the server reads (updateSpKic maintains them in
|
||||
// the real form): the fake preset's keyset resolves to kvn 1
|
||||
els['sp-kic-hex'] = { value: '15' };
|
||||
els['sp-kid-hex'] = { value: '15' };
|
||||
els[selId || 'sp-card-sel'] = { value: selValue };
|
||||
globalThis.document = { getElementById: id => els[id] || null };
|
||||
globalThis.cards = [{ name: 'C', cntr: presetCntr,
|
||||
@@ -143,6 +147,22 @@ test('the counter +/- buttons start from the preset value and create an override
|
||||
assert.strictEqual(env.els['sp-cntr'].value, '0000000020');
|
||||
});
|
||||
|
||||
test('spCntrEffective mirrors the server seed: matched keyset, else 0', () => {
|
||||
const env = fakeEnv('0', 'sp-card-sel', '0000000020');
|
||||
assert.strictEqual(spCntrEffective(), '0000000020');
|
||||
env.els['sp-cntr'].value = '0000000042'; // a typed override wins
|
||||
assert.strictEqual(spCntrEffective(), '0000000042');
|
||||
env.els['sp-cntr'].value = '';
|
||||
env.els['sp-kic-hex'].value = '00'; // keyless: no keyset
|
||||
env.els['sp-kid-hex'].value = '00';
|
||||
assert.strictEqual(spCntrEffective(), '0000000000',
|
||||
'the server seeds nothing for kvn 0 - the packet carries 0');
|
||||
env.els['sp-kic-hex'].value = '15';
|
||||
env.els['sp-kid-hex'].value = '15';
|
||||
globalThis.cards = []; // no preset: no seed
|
||||
assert.strictEqual(spCntrEffective(), '0000000000');
|
||||
});
|
||||
|
||||
test('spPorAccepted treats a missing PoR and por_ok as accepted', () => {
|
||||
assert.strictEqual(spPorAccepted(undefined), true);
|
||||
assert.strictEqual(spPorAccepted({ response_status: 'por_ok' }), true);
|
||||
|
||||
Reference in New Issue
Block a user