From 85e425889176571ec383601b7433eb5dc388ce3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D1=82=D0=BE=D0=BD=20=D0=A2=D1=80=D0=BE=D1=88?= =?UTF-8?q?=D0=B8=D0=BD?= Date: Sat, 8 Aug 2026 09:58:38 +0300 Subject: [PATCH] fix secured packet encryption offset, add Send to Card button, pCntr fix --- index.html | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/index.html b/index.html index 7c0e80f..4f8726d 100644 --- a/index.html +++ b/index.html @@ -743,6 +743,7 @@ + @@ -1743,11 +1744,10 @@ function genSp() { const apdu = hexToBytes(apduHex); + const macLen = hasMac ? 8 : 0; const pCntr = (8 - (apdu.length % 8)) % 8; const pCntrByte = pCntr; - const macLen = hasMac ? 8 : 0; - const spiOff = 4; const kicOff = 6; const secDataOff = 17 + macLen; @@ -1784,10 +1784,9 @@ function genSp() { } if (ciphering && kicKey) { - const cipherLen = packetLen - kicOff; - const toEncrypt = packet.subarray(kicOff, packetLen); + const toEncrypt = packet.subarray(secDataOff, packetLen); const encrypted = des3CbcEncrypt(toEncrypt, kicKey, new Uint8Array(8)); - packet.set(encrypted, kicOff); + packet.set(encrypted, secDataOff); } resultEl.value = bytesToHex(packet); @@ -2647,6 +2646,34 @@ async function pysimApdu() { pysimRefresh(); } +async function pysimSendOta() { + const connectedRow = document.getElementById('pysim-connected-row'); + if (!connectedRow || connectedRow.classList.contains('hidden')) { + alert('Card reader server is not connected'); + return; + } + const sp = document.getElementById('sp-result').value.replace(/[^0-9a-fA-F]/g, '').toUpperCase(); + if (!sp) { alert('No secured packet to send. Generate a secure packet first.'); return; } + const statusEl = document.getElementById('pysim-status'); + statusEl.innerHTML = 'Sending OTA...'; + try { + const data = await pysimFetch('/api/send-ota', { sp }); + if (data.success) { + if (data.response_data) { + document.getElementById('resp-data').value = data.response_data; + document.getElementById('resp-sw1').value = data.sw.slice(0, 2); + document.getElementById('resp-sw2').value = data.sw.slice(2, 4); + switchTab('response'); + } + statusEl.innerHTML = 'OTA sent. SW: ' + data.sw + ''; + } else { + statusEl.innerHTML = 'OTA failed: ' + (data.error || 'SW: ' + data.sw) + ''; + } + } catch (e) { + statusEl.innerHTML = 'Error: ' + esc(e.message) + ''; + } +} + // ===== pysim sub-tabs ===== let pysimCmdHistory = []; let pysimCmdHistIdx = -1;