-
-
Save rphillips/b20ae3ef6819f410dcf5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local ssl = require('./ssl') | |
local ctx = ssl.new_ctx( { | |
protocol = "TLSv1_client", | |
verify = {"none"} | |
} ) | |
ssl.connect('104.130.131.136', 443, ctx, function(self) | |
p(self) | |
self:write('GET / HTTP/1.0\r\n\r\n') | |
end) | |
uv.run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local uv = require('uv') | |
local openssl=require'openssl' | |
local ssl = openssl.ssl | |
local bio = openssl.bio | |
local bit = require'bit' | |
local print = print | |
local M = {} | |
local function load(path) | |
local f = io.open(path,'rb') | |
if f then | |
local c = f:read('*a') | |
f:close() | |
return c | |
end | |
end | |
function M.new_ctx(params) | |
params = params or {} | |
local protocol = params.protocol or 'SSLv3_client' | |
local ctx = ssl.ctx_new(protocol, params.ciphers) | |
local xkey,xcert = nil,nil | |
if (params.certificate) then | |
xcert = assert(x509.read(load(params.certificate))) | |
end | |
if params.key then | |
if (type(params.password)=='nil') then | |
xkey = assert(pkey.read(load(params.key),true,'pem')) | |
elseif (type(params.password)=='string') then | |
xkey = assert(pkey.read(load(params.key),true,'pem',params.password)) | |
elseif (type(params.password)=='function') then | |
local p = assert(params.password()) | |
xkey = assert(pkey.read(load(params.key),true,'pem',p)) | |
end | |
assert(ctx:use(xkey, xcert)) | |
end | |
if(params.cafile or params.capath) then | |
ctx:verify_locations(params.cafile,params.capath) | |
end | |
local unpack = unpack or table.unpack | |
if(params.verify) then | |
ctx:set_verify(params.verify) | |
end | |
if params.options and #params.options>0 then | |
local args = {} | |
for i=1,#params.options do | |
table.insert(arg,params.options[i]) | |
end | |
ctx:options(ssl.none) | |
end | |
if params.verifyext then | |
ctx:set_cert_verify(params.verifyext) | |
end | |
if params.dhparam then | |
ctx:set_tmp('dh',params.dhparam) | |
end | |
if params.curve then | |
ctx:set_tmp('ecdh',params.curve) | |
end | |
return ctx | |
end | |
local S = {} | |
S.__index = { | |
read = function(self, socket) | |
uv.read_start(socket, function(socket, err, chunk) | |
if self.ondata then | |
self:ondata(chunk) | |
end | |
end) | |
end, | |
handshake = function(self, connected_cb) | |
if not self.connecting then | |
self.ondata = function(self, chunk) | |
if chunk then | |
self.inp:write(chunk) | |
self:handshake(connected_cb) | |
end | |
end | |
self:read(self.socket) | |
self.connecting = true | |
end | |
local ret, msg = self.ssl:handshake() | |
if ret == nil then | |
else | |
local i, o = self.out:pending() | |
if i > 0 then | |
local data = self.out:read() | |
uv.write(self.socket, data, function() | |
self:handshake(connected_cb) | |
end) | |
return | |
end | |
if ret == false then | |
return | |
end | |
self.connected = true | |
self.connecting = nil | |
self.ondata = function(socket, chunk) | |
if not chunk then | |
return | |
end | |
local ret,err = self.inp:write(chunk) | |
if ret==nil then | |
return | |
end | |
local i,o = self.inp:pending() | |
if i>0 then | |
local ret, msg = self.ssl:read() | |
if ret then | |
p(ret) | |
self:ondata(ret) | |
end | |
end | |
if o > 0 then | |
assert(false,'never here') | |
end | |
end | |
connected_cb(self) | |
end | |
return self.connected | |
end, | |
shutdown = function(self,callback) | |
if not self.shutdown then | |
self.ssl:shutdown() | |
uv.close(self.socket) | |
if callback then | |
callback(self) | |
end | |
self.shutdown = true | |
end | |
end, | |
close = function(self) | |
if self.connected then | |
if self.onclose then | |
self.onclose(self) | |
end | |
self:shutdown() | |
if self.ssl then | |
self.ssl:shutdown() | |
end | |
self.ssl = nil | |
if self.inp then self.inp:close() end | |
if self.out then self.out:close() end | |
self.out,self.inp = nil,nil | |
if self.mode then | |
--server mode | |
uv.unref(self.socket) | |
end | |
uv.close(self.socket) | |
self.connected = nil | |
self.socket = nil | |
end | |
end, | |
write = function(self, data, cb) | |
if not self.ssl then | |
return | |
end | |
local ret,err = self.ssl:write(data) | |
if ret==nil then | |
return | |
end | |
local i, o = self.out:pending() | |
if i > 0 then | |
uv.write(self.socket, self.out:read(), cb) | |
end | |
if o > 0 then | |
assert(false,'never here') | |
end | |
end | |
} | |
function M.new_ssl(ctx,socket,server) | |
local s = {} | |
s.inp, s.out = bio.mem(8192), bio.mem(8192) | |
s.socket = socket | |
s.mode = server and server or false | |
s.ssl = ctx:ssl(s.inp,s.out,s.mode) | |
uv.tcp_nodelay(socket, true) | |
setmetatable(s,S) | |
return s | |
end | |
function M.connect(host,port,ctx,connected_cb) | |
if type(ctx)=='table' then | |
ctx = ssl.new_ctx(ctx) | |
end | |
local socket = uv.new_tcp() | |
local scli = M.new_ssl(ctx, socket) | |
uv.tcp_connect(socket, host, port, function(socket) | |
scli:handshake(function(scli) | |
if connected_cb then | |
connected_cb(scli) | |
end | |
end) | |
end) | |
return scli | |
end | |
function M.error() | |
return openssl.error(true) | |
end | |
return M |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment