You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
139 lines
3.1 KiB
139 lines
3.1 KiB
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 <genkey|read|write>')
|
|
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
|