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