mirror of
https://github.com/brunoos/luasec.git
synced 2024-11-08 06:28:26 +01:00
Merge branch 'master' of https://github.com/brunoos/luasec
This commit is contained in:
commit
9e93748671
@ -19,7 +19,8 @@ conn = ssl.wrap(conn, params)
|
||||
|
||||
-- Comment the lines to not send a name
|
||||
--conn:sni("servera.br")
|
||||
conn:sni("serveraa.br")
|
||||
--conn:sni("serveraa.br")
|
||||
conn:sni("serverb.br")
|
||||
|
||||
assert(conn:dohandshake())
|
||||
--
|
||||
|
@ -39,10 +39,12 @@ local conn = server:accept()
|
||||
conn = ssl.wrap(conn, ctx01)
|
||||
|
||||
-- Configure the name map
|
||||
conn:sni({
|
||||
local sni_map = {
|
||||
["servera.br"] = ctx01,
|
||||
["serveraa.br"] = ctx02,
|
||||
})
|
||||
}
|
||||
|
||||
conn:sni(sni_map, true)
|
||||
|
||||
assert(conn:dohandshake())
|
||||
--
|
||||
|
@ -14,7 +14,11 @@
|
||||
#endif
|
||||
|
||||
#if (LUA_VERSION_NUM == 501)
|
||||
#define lua_rawlen(L, i) lua_objlen(L, i)
|
||||
#define setfuncs(L, R) luaL_register(L, NULL, R)
|
||||
#define lua_rawlen(L, i) lua_objlen(L, i)
|
||||
#define luaL_newlib(L, R) do { lua_newtable(L); luaL_register(L, NULL, R); } while(0)
|
||||
#else
|
||||
#define setfuncs(L, R) luaL_setfuncs(L, R, 0)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -429,7 +429,7 @@ static int set_cipher(lua_State *L)
|
||||
static int set_depth(lua_State *L)
|
||||
{
|
||||
SSL_CTX *ctx = lsec_checkcontext(L, 1);
|
||||
SSL_CTX_set_verify_depth(ctx, luaL_checkint(L, 2));
|
||||
SSL_CTX_set_verify_depth(ctx, (int)luaL_checkinteger(L, 2));
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
@ -723,39 +723,19 @@ int lsec_getmode(lua_State *L, int idx)
|
||||
/**
|
||||
* Registre the module.
|
||||
*/
|
||||
#if (LUA_VERSION_NUM == 501)
|
||||
LSEC_API int luaopen_ssl_context(lua_State *L)
|
||||
{
|
||||
luaL_newmetatable(L, "SSL:DH:Registry"); /* Keep all DH callbacks */
|
||||
luaL_newmetatable(L, "SSL:Verify:Registry"); /* Keep all verify flags */
|
||||
luaL_newmetatable(L, "SSL:Context");
|
||||
luaL_register(L, NULL, meta);
|
||||
setfuncs(L, meta);
|
||||
|
||||
/* Create __index metamethods for context */
|
||||
lua_newtable(L);
|
||||
luaL_register(L, NULL, meta_index);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
/* Register the module */
|
||||
luaL_register(L, "ssl.context", funcs);
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
LSEC_API int luaopen_ssl_context(lua_State *L)
|
||||
{
|
||||
luaL_newmetatable(L, "SSL:DH:Registry"); /* Keep all DH callbacks */
|
||||
luaL_newmetatable(L, "SSL:Verify:Registry"); /* Keep all verify flags */
|
||||
luaL_newmetatable(L, "SSL:Context");
|
||||
luaL_setfuncs(L, meta, 0);
|
||||
|
||||
/* Create __index metamethods for context */
|
||||
lua_newtable(L);
|
||||
luaL_setfuncs(L, meta_index, 0);
|
||||
luaL_newlib(L, meta_index);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
/* Return the module */
|
||||
lua_newtable(L);
|
||||
luaL_setfuncs(L, funcs, 0);
|
||||
luaL_newlib(L, funcs);
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
@ -12,22 +12,18 @@ local ltn12 = require("ltn12")
|
||||
local http = require("socket.http")
|
||||
local url = require("socket.url")
|
||||
|
||||
local table = require("table")
|
||||
local string = require("string")
|
||||
local try = socket.try
|
||||
|
||||
local try = socket.try
|
||||
local type = type
|
||||
local pairs = pairs
|
||||
local getmetatable = getmetatable
|
||||
|
||||
module("ssl.https")
|
||||
|
||||
_VERSION = "0.5"
|
||||
_COPYRIGHT = "LuaSec 0.5 - Copyright (C) 2009-2014 PUC-Rio"
|
||||
|
||||
-- Default settings
|
||||
PORT = 443
|
||||
--
|
||||
-- Module
|
||||
--
|
||||
local _M = {
|
||||
_VERSION = "0.5",
|
||||
_COPYRIGHT = "LuaSec 0.5 - Copyright (C) 2009-2014 PUC-Rio",
|
||||
PORT = 443,
|
||||
}
|
||||
|
||||
-- TLS configuration
|
||||
local cfg = {
|
||||
protocol = "tlsv1",
|
||||
options = "all",
|
||||
@ -40,7 +36,7 @@ local cfg = {
|
||||
|
||||
-- Insert default HTTPS port.
|
||||
local function default_https_port(u)
|
||||
return url.build(url.parse(u, {port = PORT}))
|
||||
return url.build(url.parse(u, {port = _M.PORT}))
|
||||
end
|
||||
|
||||
-- Convert an URL to a table according to Luasocket needs.
|
||||
@ -113,7 +109,7 @@ end
|
||||
-- @param body optional (string)
|
||||
-- @return (string if url == string or 1), code, headers, status
|
||||
--
|
||||
function request(url, body)
|
||||
local function request(url, body)
|
||||
local result_table = {}
|
||||
local stringrequest = type(url) == "string"
|
||||
if stringrequest then
|
||||
@ -136,3 +132,11 @@ function request(url, body)
|
||||
end
|
||||
return res, code, headers, status
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Export module
|
||||
--
|
||||
|
||||
_M.request = request
|
||||
|
||||
return _M
|
||||
|
103
src/ssl.c
103
src/ssl.c
@ -330,7 +330,7 @@ static int meth_setfd(lua_State *L)
|
||||
p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
|
||||
if (ssl->state != LSEC_STATE_NEW)
|
||||
luaL_argerror(L, 1, "invalid SSL object state");
|
||||
ssl->sock = luaL_checkint(L, 2);
|
||||
ssl->sock = (t_socket)luaL_checkinteger(L, 2);
|
||||
socket_setnonblocking(&ssl->sock);
|
||||
SSL_set_fd(ssl->ssl, (int)ssl->sock);
|
||||
return 0;
|
||||
@ -406,18 +406,24 @@ static int meth_want(lua_State *L)
|
||||
*/
|
||||
static int meth_compression(lua_State *L)
|
||||
{
|
||||
#if !defined(OPENSSL_NO_COMP)
|
||||
const COMP_METHOD *comp;
|
||||
#endif
|
||||
p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
|
||||
if (ssl->state != LSEC_STATE_CONNECTED) {
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, "closed");
|
||||
return 2;
|
||||
}
|
||||
#if !defined(OPENSSL_NO_COMP)
|
||||
comp = SSL_get_current_compression(ssl->ssl);
|
||||
if (comp)
|
||||
lua_pushstring(L, SSL_COMP_get_name(comp));
|
||||
else
|
||||
lua_pushnil(L);
|
||||
#else
|
||||
lua_pushnil(L);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -436,7 +442,7 @@ static int meth_getpeercertificate(lua_State *L)
|
||||
return 2;
|
||||
}
|
||||
/* Default to the first cert */
|
||||
n = luaL_optint(L, 2, 1);
|
||||
n = (int)luaL_optinteger(L, 2, 1);
|
||||
/* This function is 1-based, but OpenSSL is 0-based */
|
||||
--n;
|
||||
if (n < 0) {
|
||||
@ -660,6 +666,7 @@ static int meth_info(lua_State *L)
|
||||
|
||||
static int sni_cb(SSL *ssl, int *ad, void *arg)
|
||||
{
|
||||
int strict;
|
||||
SSL_CTX *newctx = NULL;
|
||||
SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
|
||||
lua_State *L = ((p_context)SSL_CTX_get_app_data(ctx))->L;
|
||||
@ -667,41 +674,54 @@ static int sni_cb(SSL *ssl, int *ad, void *arg)
|
||||
/* No name, use default context */
|
||||
if (!name)
|
||||
return SSL_TLSEXT_ERR_NOACK;
|
||||
/* Search for the name in the map */
|
||||
/* Retrieve struct from registry */
|
||||
luaL_getmetatable(L, "SSL:SNI:Registry");
|
||||
lua_pushlightuserdata(L, (void*)ssl);
|
||||
lua_gettable(L, -2);
|
||||
/* Strict search? */
|
||||
lua_pushstring(L, "strict");
|
||||
lua_gettable(L, -2);
|
||||
strict = lua_toboolean(L, -1);
|
||||
lua_pop(L, 1);
|
||||
/* Search for the name in the map */
|
||||
lua_pushstring(L, "map");
|
||||
lua_gettable(L, -2);
|
||||
lua_pushstring(L, name);
|
||||
lua_gettable(L, -2);
|
||||
if (lua_isuserdata(L, -1))
|
||||
newctx = lsec_checkcontext(L, -1);
|
||||
lua_pop(L, 3);
|
||||
lua_pop(L, 4);
|
||||
/* Found, use this context */
|
||||
if (newctx) {
|
||||
SSL_set_SSL_CTX(ssl, newctx);
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
}
|
||||
/* Not found, but use initial context */
|
||||
if (!strict)
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
||||
}
|
||||
|
||||
static int meth_sni(lua_State *L)
|
||||
{
|
||||
int strict;
|
||||
SSL_CTX *aux;
|
||||
const char *name;
|
||||
p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
|
||||
SSL_CTX *ctx = SSL_get_SSL_CTX(ssl->ssl);
|
||||
p_context pctx = (p_context)SSL_CTX_get_app_data(ctx);
|
||||
switch (pctx->mode) {
|
||||
case LSEC_MODE_CLIENT:
|
||||
if (pctx->mode == LSEC_MODE_CLIENT) {
|
||||
name = luaL_checkstring(L, 2);
|
||||
SSL_set_tlsext_host_name(ssl->ssl, name);
|
||||
break;
|
||||
case LSEC_MODE_SERVER:
|
||||
return 0;
|
||||
} else if (pctx->mode == LSEC_MODE_SERVER) {
|
||||
luaL_checktype(L, 2, LUA_TTABLE);
|
||||
strict = lua_toboolean(L, 3);
|
||||
/* Check if the table contains only (string -> context) */
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, 2)) {
|
||||
luaL_checkstring(L, 3);
|
||||
aux = lsec_checkcontext(L, 4);
|
||||
luaL_checkstring(L, -2);
|
||||
aux = lsec_checkcontext(L, -1);
|
||||
/* Set callback in every context */
|
||||
SSL_CTX_set_tlsext_servername_callback(aux, sni_cb);
|
||||
/* leave the next key on the stack */
|
||||
@ -710,15 +730,31 @@ static int meth_sni(lua_State *L)
|
||||
/* Save table in the register */
|
||||
luaL_getmetatable(L, "SSL:SNI:Registry");
|
||||
lua_pushlightuserdata(L, (void*)ssl->ssl);
|
||||
lua_newtable(L);
|
||||
lua_pushstring(L, "map");
|
||||
lua_pushvalue(L, 2);
|
||||
lua_settable(L, -3);
|
||||
lua_pushstring(L, "strict");
|
||||
lua_pushboolean(L, strict);
|
||||
lua_settable(L, -3);
|
||||
lua_settable(L, -3);
|
||||
/* Set callback in the default context */
|
||||
SSL_CTX_set_tlsext_servername_callback(ctx, sni_cb);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int meth_getsniname(lua_State *L)
|
||||
{
|
||||
p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
|
||||
const char *name = SSL_get_servername(ssl->ssl, TLSEXT_NAMETYPE_host_name);
|
||||
if (name)
|
||||
lua_pushstring(L, name);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int meth_copyright(lua_State *L)
|
||||
{
|
||||
lua_pushstring(L, "LuaSec 0.5 - Copyright (C) 2006-2011 Bruno Silvestre"
|
||||
@ -742,6 +778,7 @@ static luaL_Reg methods[] = {
|
||||
{"getpeerchain", meth_getpeerchain},
|
||||
{"getpeerverification", meth_getpeerverification},
|
||||
{"getpeerfinished", meth_getpeerfinished},
|
||||
{"getsniname", meth_getsniname},
|
||||
{"getstats", meth_getstats},
|
||||
{"setstats", meth_setstats},
|
||||
{"dirty", meth_dirty},
|
||||
@ -779,7 +816,6 @@ static luaL_Reg funcs[] = {
|
||||
/**
|
||||
* Initialize modules.
|
||||
*/
|
||||
#if (LUA_VERSION_NUM == 501)
|
||||
LSEC_API int luaopen_ssl_core(lua_State *L)
|
||||
{
|
||||
/* Initialize SSL */
|
||||
@ -799,49 +835,12 @@ LSEC_API int luaopen_ssl_core(lua_State *L)
|
||||
|
||||
/* Register the functions and tables */
|
||||
luaL_newmetatable(L, "SSL:Connection");
|
||||
luaL_register(L, NULL, meta);
|
||||
setfuncs(L, meta);
|
||||
|
||||
lua_newtable(L);
|
||||
luaL_register(L, NULL, methods);
|
||||
luaL_newlib(L, methods);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
luaL_register(L, "ssl.core", funcs);
|
||||
lua_pushnumber(L, SOCKET_INVALID);
|
||||
lua_setfield(L, -2, "invalidfd");
|
||||
luaL_newlib(L, funcs);
|
||||
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
LSEC_API int luaopen_ssl_core(lua_State *L)
|
||||
{
|
||||
/* Initialize SSL */
|
||||
if (!SSL_library_init()) {
|
||||
lua_pushstring(L, "unable to initialize SSL library");
|
||||
lua_error(L);
|
||||
}
|
||||
OpenSSL_add_all_algorithms();
|
||||
SSL_load_error_strings();
|
||||
|
||||
#if defined(WITH_LUASOCKET)
|
||||
/* Initialize internal library */
|
||||
socket_open();
|
||||
#endif
|
||||
|
||||
luaL_newmetatable(L, "SSL:SNI:Registry");
|
||||
|
||||
/* Register the functions and tables */
|
||||
luaL_newmetatable(L, "SSL:Connection");
|
||||
luaL_setfuncs(L, meta, 0);
|
||||
|
||||
lua_newtable(L);
|
||||
luaL_setfuncs(L, methods, 0);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_newtable(L);
|
||||
luaL_setfuncs(L, funcs, 0);
|
||||
lua_pushnumber(L, SOCKET_INVALID);
|
||||
lua_setfield(L, -2, "invalidfd");
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
27
src/ssl.lua
27
src/ssl.lua
@ -8,13 +8,7 @@ local core = require("ssl.core")
|
||||
local context = require("ssl.context")
|
||||
local x509 = require("ssl.x509")
|
||||
|
||||
module("ssl", package.seeall)
|
||||
|
||||
_VERSION = "0.5"
|
||||
_COPYRIGHT = core.copyright()
|
||||
|
||||
-- Export
|
||||
loadcertificate = x509.load
|
||||
local unpack = table.unpack or unpack
|
||||
|
||||
-- We must prevent the contexts to be collected before the connections,
|
||||
-- otherwise the C registry will be cleared.
|
||||
@ -37,7 +31,7 @@ end
|
||||
--
|
||||
--
|
||||
--
|
||||
function newcontext(cfg)
|
||||
local function newcontext(cfg)
|
||||
local succ, msg, ctx
|
||||
-- Create the context
|
||||
ctx, msg = context.create(cfg.protocol)
|
||||
@ -115,7 +109,7 @@ end
|
||||
--
|
||||
--
|
||||
--
|
||||
function wrap(sock, cfg)
|
||||
local function wrap(sock, cfg)
|
||||
local ctx, msg
|
||||
if type(cfg) == "table" then
|
||||
ctx, msg = newcontext(cfg)
|
||||
@ -126,7 +120,7 @@ function wrap(sock, cfg)
|
||||
local s, msg = core.create(ctx)
|
||||
if s then
|
||||
core.setfd(s, sock:getfd())
|
||||
sock:setfd(core.invalidfd)
|
||||
sock:setfd(-1)
|
||||
registry[s] = ctx
|
||||
return s
|
||||
end
|
||||
@ -170,3 +164,16 @@ end
|
||||
--
|
||||
core.setmethod("info", info)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Export module
|
||||
--
|
||||
|
||||
local _M = {
|
||||
_VERSION = "0.5",
|
||||
_COPYRIGHT = core.copyright(),
|
||||
loadcertificate = x509.load,
|
||||
newcontext = newcontext,
|
||||
wrap = wrap,
|
||||
}
|
||||
|
||||
return _M
|
||||
|
67
src/x509.c
67
src/x509.c
@ -20,6 +20,11 @@
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
|
||||
@ -88,8 +93,10 @@ static void push_asn1_string(lua_State* L, ASN1_STRING *string, int encode)
|
||||
{
|
||||
int len;
|
||||
unsigned char *data;
|
||||
if (!string)
|
||||
if (!string) {
|
||||
lua_pushnil(L);
|
||||
return;
|
||||
}
|
||||
switch (encode) {
|
||||
case LSEC_AI5_STRING:
|
||||
lua_pushlstring(L, (char*)ASN1_STRING_data(string),
|
||||
@ -101,6 +108,8 @@ static void push_asn1_string(lua_State* L, ASN1_STRING *string, int encode)
|
||||
lua_pushlstring(L, (char*)data, len);
|
||||
OPENSSL_free(data);
|
||||
}
|
||||
else
|
||||
lua_pushnil(L);
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,6 +128,31 @@ static int push_asn1_time(lua_State *L, ASN1_UTCTIME *tm)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a human readable IP address.
|
||||
*/
|
||||
static void push_asn1_ip(lua_State *L, ASN1_STRING *string)
|
||||
{
|
||||
unsigned char *ip = ASN1_STRING_data(string);
|
||||
char dst[INET6_ADDRSTRLEN];
|
||||
int typ;
|
||||
switch(ASN1_STRING_length(string)) {
|
||||
case 4:
|
||||
typ = AF_INET;
|
||||
break;
|
||||
case 16:
|
||||
typ = AF_INET6;
|
||||
break;
|
||||
default:
|
||||
lua_pushnil(L);
|
||||
return;
|
||||
}
|
||||
if(inet_ntop(typ, ip, dst, INET6_ADDRSTRLEN))
|
||||
lua_pushstring(L, dst);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@ -258,7 +292,7 @@ int meth_extensions(lua_State* L)
|
||||
case GEN_IPADD:
|
||||
lua_pushstring(L, "iPAddress");
|
||||
push_subtable(L, -2);
|
||||
push_asn1_string(L, general_name->d.iPAddress, px->encode);
|
||||
push_asn1_ip(L, general_name->d.iPAddress);
|
||||
lua_rawseti(L, -2, lua_rawlen(L, -2)+1);
|
||||
lua_pop(L, 1);
|
||||
break;
|
||||
@ -532,39 +566,16 @@ static luaL_Reg funcs[] = {
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
#if (LUA_VERSION_NUM == 501)
|
||||
|
||||
LSEC_API int luaopen_ssl_x509(lua_State *L)
|
||||
{
|
||||
/* Register the functions and tables */
|
||||
luaL_newmetatable(L, "SSL:Certificate");
|
||||
luaL_register(L, NULL, meta);
|
||||
setfuncs(L, meta);
|
||||
|
||||
lua_newtable(L);
|
||||
luaL_register(L, NULL, methods);
|
||||
luaL_newlib(L, methods);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
luaL_register(L, "ssl.x509", funcs);
|
||||
luaL_newlib(L, funcs);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
LSEC_API int luaopen_ssl_x509(lua_State *L)
|
||||
{
|
||||
/* Register the functions and tables */
|
||||
luaL_newmetatable(L, "SSL:Certificate");
|
||||
luaL_setfuncs(L, meta, 0);
|
||||
|
||||
lua_newtable(L);
|
||||
luaL_setfuncs(L, methods, 0);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_newtable(L);
|
||||
luaL_setfuncs(L, funcs, 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user