From df71240a27741d252c8146ec8389feb4f4becc7a Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 30 Sep 2020 10:10:57 +0200 Subject: [PATCH] fix calypso lua script --- client/lualibs/commands.lua | 28 ++++++------ client/lualibs/read14b.lua | 24 +++++----- client/luascripts/hf_14b_calypso.lua | 66 +++++++++++++++++----------- 3 files changed, 68 insertions(+), 50 deletions(-) diff --git a/client/lualibs/commands.lua b/client/lualibs/commands.lua index 11227b8ac..440118fb6 100644 --- a/client/lualibs/commands.lua +++ b/client/lualibs/commands.lua @@ -93,8 +93,10 @@ Command = { o.data = data return o end, - parse = function (packet) - local count, cmd, arg1, arg2, arg3, data = bin.unpack('LLLLH511', packet) + parse = function(packet) + local count, cmd, arg1, arg2, arg3, data = bin.unpack('LLLL', packet) + local length = #packet - count + 1 + count, data = bin.unpack('H'..length, packet, count) return Command:new{cmd = cmd, arg1 = arg1, arg2 = arg2, arg3 = arg3, data = data} end } @@ -121,26 +123,28 @@ end -- @param command - the usb packet to send -- @param ignoreresponse - if set to true, we don't read the device answer packet -- which is usually recipe for fail. If not sent, the host will wait 2s for a --- response of type CMD_ACK +-- response of type CMD_ACK or like NG use the CMD as ack.. -- @return packet,nil if successful -- nil, errormessage if unsuccessful -function Command:sendMIX( ignore_response, timeout ) +function Command:sendMIX( ignore_response, timeout, use_cmd_ack) + if timeout == nil then timeout = TIMEOUT end local data = self.data local cmd = self.cmd - local arg1, arg2, arg3 = self.arg1, self.arg2, self.arg3 + local arg1, arg2, arg3 = self.arg1, self.arg2, self.arg3 local err, msg = core.SendCommandMIX(cmd, arg1, arg2, arg3, data) if err == nil then return err, msg end - if ignore_response then return true, nil end + + local ack = _commands.CMD_ACK + if use_cmd_ack then + ack = cmd + end - if timeout == nil then timeout = TIMEOUT end - - local response, msg = core.WaitForResponseTimeout(_commands.CMD_ACK, timeout) + local response, msg = core.WaitForResponseTimeout(ack, timeout) if response == nil then return nil, 'Error, waiting for response timed out :: '..msg end - -- lets digest data = nil cmd = nil @@ -157,15 +161,13 @@ function Command:sendMIX( ignore_response, timeout ) return packed, nil; end function Command:sendNG( ignore_response, timeout ) + if timeout == nil then timeout = TIMEOUT end local data = self.data local cmd = self.cmd local err, msg = core.SendCommandNG(cmd, data) if err == nil then return nil, msg end if ignore_response then return true, nil end - - if timeout == nil then timeout = TIMEOUT end - local response, msg = core.WaitForResponseTimeout(cmd, timeout) if response == nil then return nil, 'Error, waiting for response timed out :: '..msg diff --git a/client/lualibs/read14b.lua b/client/lualibs/read14b.lua index b1688552f..7547bd866 100644 --- a/client/lualibs/read14b.lua +++ b/client/lualibs/read14b.lua @@ -15,17 +15,18 @@ local cmds = require('commands') local utils = require('utils') -- Shouldn't take longer than 2.5 seconds -local TIMEOUT = 2500 +local TIMEOUT = 2000 local ISO14B_COMMAND = { - ISO14B_CONNECT = 1, - ISO14B_DISCONNECT = 2, - ISO14B_APDU = 4, - ISO14B_RAW = 8, + ISO14B_CONNECT = 0x1, + ISO14B_DISCONNECT = 0x2, + ISO14B_APDU = 0x4, + ISO14B_RAW = 0x8, ISO14B_REQUEST_TRIGGER = 0x10, ISO14B_APPEND_CRC = 0x20, ISO14B_SELECT_STD = 0x40, ISO14B_SELECT_SR = 0x80, + ISO14B_SET_TIMEOUT = 0x100, } local function parse14443b(data) @@ -74,9 +75,11 @@ local function read14443b(disconnect) arg1 = flags } - local result, err = command:sendMIX() + info = nil + + local result, err = command:sendMIX(false, TIMEOUT, true) if result then - local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL',result) + local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL', result) if arg0 == 0 then data = string.sub(result, count) info, err = parse14443b(data) @@ -88,12 +91,10 @@ local function read14443b(disconnect) end if err then - print(err) return nil, err end - return info + return info, nil end - --- -- Waits for a mifare card to be placed within the vicinity of the reader. -- @return if successful: an table containing card info @@ -102,12 +103,11 @@ local function waitFor14443b() print('Waiting for card... press Enter to quit') while not core.kbd_enter_pressed() do res, err = read14443b(false) - if res then return res end + if res then return res, err end -- err means that there was no response from card end return nil, 'Aborted by user' end - --- -- turns on the HF field. local function connect14443b() diff --git a/client/luascripts/hf_14b_calypso.lua b/client/luascripts/hf_14b_calypso.lua index 0439ac800..fcd58d478 100644 --- a/client/luascripts/hf_14b_calypso.lua +++ b/client/luascripts/hf_14b_calypso.lua @@ -7,7 +7,7 @@ local ansicolors = require('ansicolors') copyright = '' author = 'Iceman' -version = 'v1.0.2' +version = 'v1.0.3' desc = [[ This is a script to communicate with a CALYSPO / 14443b tag using the '14b raw' commands ]] @@ -30,12 +30,13 @@ device-side. ]] local function calypso_parse(result) - local r = Command.parse(result) - local len = r.arg2 * 2 - r.data = string.sub(r.data, 0, len); - print('GOT:', r.data) - if r.arg1 == 0 then - return r, nil + local r = Command.parse(result) + if r.arg1 >= 0 then + local len = r.arg2 * 2 + if len > 0 then + r.data = string.sub(r.data, 0, len); + return r, nil + end end return nil,nil end @@ -123,12 +124,19 @@ local function calypso_send_cmd_raw(data, ignoreresponse ) arg2 = #data/2, -- LEN of data, half the length of the ASCII-string hex string data = data} -- data bytes (commands etc) - result, err = command:sendMIX(ignoreresponse) + local use_cmd_ack = true + result, err = command:sendMIX(ignoreresponse, 2000, use_cmd_ack) if result then - local r = calypso_parse(result) - return r, nil + local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL', result) + if arg0 >= 0 then + return calypso_parse(result) + else + err = 'card response failed' + end + else + err = 'No response from card' end - return respone, err + return result, err end --- -- calypso_card_num : Reads card number from ATR and @@ -136,23 +144,22 @@ end local function calypso_card_num(card) if not card then return end local card_num = tonumber( card.uid:sub(1,8),16 ) - print('Card UID', card.uid) - print('Card Number', card_num) + print('') + print('Card UID ' ..ansicolors.green..card.uid:format('%x')..ansicolors.reset) + print('Card Number ' ..ansicolors.green..string.format('%u', card_num)..ansicolors.reset) + print('-----------------------') end --- -- analyse CALYPSO apdu status bytes. local function calypso_apdu_status(apdu) -- last two is CRC -- next two is APDU status bytes. - local status = false local mess = 'FAIL' local sw = apdu:sub( #apdu-7, #apdu-4) desc, err = iso7816.tostring(sw) - print ('SW', sw, desc, err ) - - status = ( sw == '9000' ) - - return status + --print ('SW', sw, desc, err ) + local status = ( sw == '9000' ) + return status, desc, err end local _calypso_cmds = { @@ -215,7 +222,7 @@ function main(args) if o == 'b' then bytes = a end end - lib14b.connect() +-- lib14b.connect() -- Select 14b tag. card, err = lib14b.waitFor14443b() @@ -241,14 +248,23 @@ function main(args) --for i = 1,10 do --result, err = calypso_send_cmd_raw('0294a40800043f000002',false) --select ICC file for i, apdu in spairs(_calypso_cmds) do - print('>>', i ) + print('>> '..ansicolors.yellow..i..ansicolors.reset) apdu = apdu:gsub('%s+', '') result, err = calypso_send_cmd_raw(apdu , false) - if result then - calypso_apdu_status(result.data) - print('<<', result.data ) + if err then + print('<< '..err) else - print('<< no answer') + if result then + local status, desc, err = calypso_apdu_status(result.data) + local d = result.data:sub(3, #result.data) + if status then + print('<< '..d..' ('..ansicolors.green..'ok'..ansicolors.reset..')') + else + print('<< '..d..' '..ansicolors.red..err..ansicolors.reset ) + end + else + print('<< no answer') + end end end lib14b.disconnect()