mirror of
https://github.com/vxcontrol/soldr-lua-extras.git
synced 2026-07-18 17:45:29 -04:00
303 lines
6.8 KiB
Lua
303 lines
6.8 KiB
Lua
local openssl = require'openssl'
|
|
local io = require'io'
|
|
|
|
local M = {}
|
|
|
|
M["_VERSION"] = "LuaCrypto 0.3.1"
|
|
M["_COPYRIGHT"] = "Copyright (C) 2014 GeorgeZhao";
|
|
M["_DESCRIPTION"] = "crypto is a high level Lua wrapper for OpenSSL based on lua-openssl";
|
|
|
|
-----------crypto------------------
|
|
function M.hex(s)
|
|
local s = openssl.hex(s)
|
|
return string.lower(s)
|
|
end
|
|
M.digest = openssl.digest
|
|
local dm = {}
|
|
dm.__call = function(self,alg,msg,raw)
|
|
raw = raw or true
|
|
return M.digest.digest(alg,msg)
|
|
end
|
|
setmetatable(M.digest,dm)
|
|
|
|
M.hmac = openssl.hmac
|
|
-----------crypto encrypt/decrypt compat----------
|
|
local cipher = openssl.cipher
|
|
local C = {}
|
|
|
|
C.__index = {
|
|
new = function(alg,key,iv)
|
|
local c = cipher.encrypt_new(alg,key,iv)
|
|
if c then
|
|
local I = c:info()
|
|
if (iv and #iv>I.iv_length) then
|
|
error('invalid iv')
|
|
end
|
|
if(#key>I.key_length) then
|
|
error('invalid key')
|
|
end
|
|
local t = {}
|
|
t.ctx = c
|
|
setmetatable(t,C)
|
|
return t
|
|
end
|
|
end,
|
|
update = function(self,input)
|
|
return self.ctx:update(input)
|
|
end,
|
|
final = function(self)
|
|
return self.ctx:final()
|
|
end
|
|
}
|
|
|
|
C.__call = function(self,alg,input,key,iv)
|
|
local c = cipher.get(alg)
|
|
local I = c:info()
|
|
if (iv and #iv>I.iv_length) then
|
|
error 'invalid iv'
|
|
end
|
|
if(#key>I.key_length) then
|
|
error 'invalid key'
|
|
end
|
|
local ret, msg = cipher.encrypt(alg,input,key,iv)
|
|
return ret,msg
|
|
end
|
|
|
|
setmetatable(C,C)
|
|
M.encrypt = C
|
|
|
|
local D = {}
|
|
|
|
D.__index = {
|
|
new = function(alg,key,iv)
|
|
local c = cipher.decrypt_new(alg,key,iv)
|
|
if c then
|
|
local I = c:info()
|
|
if (iv and #iv>I.iv_length) then
|
|
error('invalid iv')
|
|
end
|
|
if(#key>I.key_length) then
|
|
error('invalid key')
|
|
end
|
|
local t = {}
|
|
t.ctx = c
|
|
setmetatable(t,D)
|
|
return t
|
|
end
|
|
end,
|
|
update = function(self,input)
|
|
return self.ctx:update(input)
|
|
end,
|
|
final = function(self)
|
|
return self.ctx:final()
|
|
end
|
|
}
|
|
|
|
D.__call = function(self,alg,input,key,iv)
|
|
local c = cipher.get(alg)
|
|
local I = c:info()
|
|
if (iv and #iv>I.iv_length) then
|
|
error('invalid iv')
|
|
end
|
|
if(#key>I.key_length) then
|
|
error('invalid key')
|
|
end
|
|
local r,s = cipher.decrypt(alg,input,key,iv)
|
|
return r,s
|
|
end
|
|
|
|
setmetatable(D,D)
|
|
M.decrypt = D
|
|
|
|
-----------crypto random compat------------------
|
|
local R = {}
|
|
function R.load(file)
|
|
return openssl.rand_load(file)
|
|
end
|
|
|
|
function R.write(file)
|
|
return openssl.rand_write(file)
|
|
end
|
|
|
|
function R.cleanup()
|
|
return openssl.rand_cleanup()
|
|
end
|
|
|
|
function R.status()
|
|
return openssl.rand_status()
|
|
end
|
|
|
|
function R.pseudo_bytes(len)
|
|
return openssl.random(len,false)
|
|
end
|
|
|
|
function R.bytes(len)
|
|
return openssl.random(len,true)
|
|
end
|
|
|
|
M.rand = R
|
|
|
|
-----------crypto pkey compat------------------
|
|
local P = {}
|
|
local pkey = openssl.pkey
|
|
|
|
local PKEY_M = {}
|
|
PKEY_M.__index = {}
|
|
function PKEY_M.__index.to_pem(self,ispriv, israw)
|
|
israw = israw or false
|
|
if (ispriv) then
|
|
return self.evp_pkey:export(true, israw)
|
|
else
|
|
return self.evp_pkey:is_private()
|
|
and self.evp_pkey:get_public():export(true, israw)
|
|
or self.evp_pkey:export(true, israw)
|
|
end
|
|
end
|
|
|
|
function PKEY_M.__index.write(self,pubfile,prifile)
|
|
local PUB,PRI = self:to_pem(false), self:to_pem(true)
|
|
local f = io.open(pubfile,'w+')
|
|
if f then
|
|
f:write(PUB)
|
|
f:close()
|
|
end
|
|
local f = io.open(prifile,'w+')
|
|
if f then
|
|
f:write(PRI)
|
|
f:close()
|
|
end
|
|
end
|
|
|
|
function P.read(file,ispriv)
|
|
local f = io.open(file,'r')
|
|
if f then
|
|
local pem = f:read("*all")
|
|
f:close()
|
|
return P.from_pem(pem,ispriv)
|
|
end
|
|
end
|
|
|
|
function P.from_pem(pem, ispriv)
|
|
local k = pkey.read (pem, ispriv,'pem')
|
|
if k then
|
|
local key = {}
|
|
key.evp_pkey = k
|
|
setmetatable(key,PKEY_M)
|
|
return key
|
|
end
|
|
end
|
|
|
|
function P.generate(alg,bits)
|
|
local k = pkey.new (alg,bits)
|
|
if k then
|
|
local key = {}
|
|
key.evp_pkey = k
|
|
setmetatable(key,PKEY_M)
|
|
return key
|
|
end
|
|
end
|
|
|
|
M.pkey = P
|
|
|
|
------------------------------------------
|
|
function M.sign(alg,input,prikey)
|
|
local pk = prikey.evp_pkey
|
|
return pkey.sign(pk,input,alg)
|
|
end
|
|
|
|
function M.verify(alg,input,sig,pubkey)
|
|
local pk = pubkey.evp_pkey
|
|
return pkey.verify(pk,input,sig,alg)
|
|
end
|
|
|
|
|
|
-----------------crypto seal/open compat
|
|
local S = {}
|
|
S.__index = {
|
|
new = function(alg,pubkey)
|
|
local c,key,iv = pkey.seal_init(pubkey.evp_pkey,alg)
|
|
if c then
|
|
local t = {}
|
|
t.ctx = c
|
|
t.key = key
|
|
t.iv = iv
|
|
setmetatable(t,S)
|
|
return t
|
|
end
|
|
end,
|
|
update = function(self,data)
|
|
return pkey.seal_update(self.ctx,data)
|
|
end,
|
|
final = function(self)
|
|
local s = pkey.seal_final(self.ctx)
|
|
return s,self.key,self.iv
|
|
end,
|
|
}
|
|
S.__call = function(self,alg,input,pubkey)
|
|
local msg, key,iv = pkey.seal(pubkey.evp_pkey, input, alg)
|
|
return msg,key,iv
|
|
end
|
|
|
|
setmetatable(S,S)
|
|
|
|
M.seal = S
|
|
|
|
local O = {}
|
|
O.__index = {
|
|
new = function(alg,privkey, ekey, iv)
|
|
local c,key,iv = pkey.open_init(privkey.evp_pkey,ekey,iv,alg)
|
|
if c then
|
|
local t = {}
|
|
t.ctx = c
|
|
t.key = key
|
|
t.iv = iv
|
|
setmetatable(t,O)
|
|
return t
|
|
end
|
|
end,
|
|
update = function(self,data)
|
|
return pkey.open_update(self.ctx,data)
|
|
end,
|
|
final = function(self)
|
|
local s = pkey.open_final(self.ctx)
|
|
return s
|
|
end,
|
|
}
|
|
O.__call = function(self,alg,input,prikey,ek,iv)
|
|
return pkey.open(prikey.evp_pkey,input,ek,iv,alg)
|
|
end
|
|
|
|
setmetatable(O,O)
|
|
|
|
M.open = O
|
|
|
|
----------------crypto pki compat------------
|
|
local X = {}
|
|
X.__index = {
|
|
add_pem = function(self,pem)
|
|
local ret,x = pcall(openssl.x509.read,pem)
|
|
if ret then
|
|
self[#self+1] = x
|
|
return x
|
|
end
|
|
return nil
|
|
end,
|
|
verify_pem = function(self,pem)
|
|
local ret,x = pcall(openssl.x509.read,pem)
|
|
if ret then
|
|
local store = openssl.x509.store.new(self)
|
|
return x:check(store)
|
|
end
|
|
return false
|
|
end
|
|
}
|
|
|
|
function M.x509_ca()
|
|
local t = {}
|
|
setmetatable(t,X)
|
|
return t
|
|
end
|
|
|
|
----------------------------------------------
|
|
return M
|