diff --git a/card_writer.lua b/card_writer.lua new file mode 100644 index 0000000..d0a1317 --- /dev/null +++ b/card_writer.lua @@ -0,0 +1,138 @@ +local io = require("io") +local os = require("os") +local event = require("event") +local component = require("component") +local serialization = require("serialization") + +local dataCard = component.data +local cardReader = component.os_magreader +local cardWriter = component.os_cardwriter + + +KEY_FILENAME = 'aes_key' + +GREEN_LED = 4 +YELLOW_LED = 2 +RED_LED = 1 + + +local function generate_key() + local key = dataCard.random(128 / 8) + local iv = dataCard.random(128 / 8) + + local key64 = dataCard.encode64(key) + local iv64 = dataCard.encode64(iv) + + local file = io.open(KEY_FILENAME, 'w') + if not file then + print('Could not open file for writing') + os.exit(3) + end + + file:write(key64, '\n') + file:write(iv64, '\n') +end + +---Load the key from file +---@return string key +---@return string iv +local function load_key() + local file = io.open(KEY_FILENAME, 'r') + if not file then + print('Missing key file!') + os.exit(4) + end + local key64 = file:read('*l') + local iv64 = file:read('*l') + + if not key64 or not iv64 then + print('Invalid key file!') + os.exit(5) + end + + file:close() + + local key = dataCard.decode64(key64) + local iv = dataCard.decode64(iv64) + + return key, iv +end + +local function read_card() + cardReader.swipeIndicator(false) -- control led indicators manually + cardReader.setLightState(YELLOW_LED) + + print('Swipe the card on the reader...') + + local _, _, _, cardData, cardUniqueId, isCardLocked, _ = event.pull('magData') + cardReader.setLightState(GREEN_LED) + + print('Data: ', cardData) + print('CUID: ', cardUniqueId) + print('Locked:', isCardLocked) + + os.sleep(1) + + cardReader.setLightState(0) -- turn light indicators off + + print('Decrypt? [y/N]') + local ch = io.read() + + if ch ~= 'y' then + return -- exit + end + + local key, iv = load_key() + + -- process the data + local enc = dataCard.decode64(cardData) + local dec = dataCard.decrypt(enc, key, iv) + local data = serialization.unserialize(dec) + + print('Owner:', data.owner) + print('Access:', table.concat(data.access, ',')) +end + +local function write_card() + local claims = { + owner = 'player', + access = { + 'entry', 'lab' + } + } + + local key, iv = load_key() + + -- process the data + local data = serialization.serialize(claims, false) + local enc = dataCard.encrypt(data, key, iv) + local enc64 = dataCard.encode64(enc) + print(string.len(enc64)) + + -- Prompt for the card's display name + print('Enter card name:') + local displayName = io.read() + + print('Insert the card into the writer...') + + -- wait for the user to insert the card + _, _ = event.pull('cardInsert') + + cardWriter.write(enc64, displayName) +end + +local subcommand = ... +if not subcommand then + print('Usage: card_writer ') + os.exit(1) +end +if subcommand == 'genkey' then + generate_key() +elseif subcommand == 'read' then + read_card() +elseif subcommand == 'write' then + write_card() +else + print('Unknown action: ' .. subcommand) + os.exit(2) +end