NIXIO: TLS-Support, bugfixes

This commit is contained in:
Steven Barth 2009-02-22 22:49:23 +00:00
parent da6f427d81
commit d2b11117f2
15 changed files with 1153 additions and 16 deletions

View file

@ -202,6 +202,16 @@ define Package/luci-json/install
endef
define Package/luci-nixio
$(call Package/luci/libtemplate)
TITLE:=NIXIO Socket Library
endef
define Package/luci-nixio/install
$(call Package/luci/install/template,$(1),libs/nixio)
endef
define Package/luci-sys
$(call Package/luci/libtemplate)
TITLE:=LuCI Linux/POSIX system library
@ -764,6 +774,9 @@ endif
ifneq ($(CONFIG_PACKAGE_luci-json),)
PKG_SELECTED_MODULES+=libs/json
endif
ifneq ($(CONFIG_PACKAGE_luci-nixio),)
PKG_SELECTED_MODULES+=libs/nixio
endif
ifneq ($(CONFIG_PACKAGE_luci-uci),)
PKG_SELECTED_MODULES+=libs/uci
endif
@ -933,6 +946,7 @@ $(eval $(call BuildPackage,luci-fastindex))
$(eval $(call BuildPackage,luci-http))
$(eval $(call BuildPackage,luci-ipkg))
$(eval $(call BuildPackage,luci-json))
$(eval $(call BuildPackage,luci-nixio))
$(eval $(call BuildPackage,luci-uci))
$(eval $(call BuildPackage,luci-sys))
$(eval $(call BuildPackage,luci-web))

1
libs/nixio/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
axTLS

View file

@ -2,13 +2,54 @@ include ../../build/config.mk
include ../../build/module.mk
include ../../build/gccconfig.mk
AXTLS_VERSION = 1.2.1
AXTLS_DIR = axTLS
AXTLS_FILE = $(AXTLS_DIR)-$(AXTLS_VERSION).tar.gz
NIXIO_TLS ?= axtls
NIXIO_OBJ = src/nixio.o src/socket.o src/sockopt.o src/bind.o src/address.o \
src/poll.o src/io.o src/file.o src/splice.o src/tls-context.o \
src/tls-socket.o
ifeq ($(NIXIO_TLS),axtls)
TLS_CFLAGS = -IaxTLS/{ssl,crypto,config} -include src/openssl-compat.h
TLS_LDFLAGS =
TLS_DEPENDS = src/openssl-compat.o
NIXIO_OBJ += src/openssl-compat.o src/libaxtls.a
endif
ifeq ($(NIXIO_TLS),openssl)
TLS_LDFLAGS = -lssl
endif
%.o: %.c
$(COMPILE) $(LUA_CFLAGS) $(FPIC) -c -o $@ $<
compile: src/nixio.o src/socket.o src/sockopt.o src/bind.o src/address.o src/poll.o src/io.o src/file.o src/splice.o
$(LINK) $(SHLIB_FLAGS) -o src/nixio.so src/*.o
src/tls-context.o: $(TLS_DEPENDS) src/tls-context.c
$(COMPILE) $(LUA_CFLAGS) $(FPIC) $(TLS_CFLAGS) -c -o $@ src/tls-context.c
src/tls-socket.o: $(TLS_DEPENDS) src/tls-socket.c
$(COMPILE) $(LUA_CFLAGS) $(FPIC) $(TLS_CFLAGS) -c -o $@ src/tls-socket.c
src/openssl-compat.o: src/libaxtls.a src/openssl-compat.c
$(COMPILE) $(LUA_CFLAGS) $(FPIC) $(TLS_CFLAGS) -c -o $@ src/openssl-compat.c
compile: $(NIXIO_OBJ)
$(LINK) $(SHLIB_FLAGS) $(TLS_LDFLAGS) -o src/nixio.so $(NIXIO_OBJ)
mkdir -p dist$(LUA_LIBRARYDIR)
cp src/nixio.so dist$(LUA_LIBRARYDIR)/nixio.so
$(AXTLS_DIR)/.prepared: $(AXTLS_FILE)
rm -rf $(AXTLS_DIR)
tar xvfz $(AXTLS_FILE)
cp axtls-config/{.config,config.h} $(AXTLS_DIR)/config
touch $@
src/libaxtls.a: $(AXTLS_DIR)/.prepared
$(MAKE) -C $(AXTLS_DIR) CC=$(CC) CFLAGS="$(CFLAGS) $(EXTRA_CFLAGS) $(FPIC) -Wall -pedantic -I../config -I../ssl -I../crypto" LDFLAGS="$(LDFLAGS)" OS="$(OS)" clean all
cp -p $(AXTLS_DIR)/_stage/libaxtls.a src
clean: luaclean
rm -f src/*.o src/*.so
rm -f src/*.o src/*.so src/*.a
rm -rf $(AXTLS_DIR)

View file

@ -0,0 +1,112 @@
#
# Automatically generated make config: don't edit
#
HAVE_DOT_CONFIG=y
CONFIG_PLATFORM_LINUX=y
# CONFIG_PLATFORM_CYGWIN is not set
# CONFIG_PLATFORM_WIN32 is not set
#
# General Configuration
#
PREFIX="/usr"
# CONFIG_DEBUG is not set
CONFIG_STRIP_UNWANTED_SECTIONS=y
# CONFIG_VISUAL_STUDIO_7_0 is not set
# CONFIG_VISUAL_STUDIO_8_0 is not set
CONFIG_VISUAL_STUDIO_7_0_BASE=""
CONFIG_VISUAL_STUDIO_8_0_BASE=""
CONFIG_EXTRA_CFLAGS_OPTIONS="-fpic"
CONFIG_EXTRA_LDFLAGS_OPTIONS=""
#
# SSL Library
#
# CONFIG_SSL_SERVER_ONLY is not set
# CONFIG_SSL_CERT_VERIFICATION is not set
CONFIG_SSL_ENABLE_CLIENT=y
# CONFIG_SSL_FULL_MODE is not set
# CONFIG_SSL_SKELETON_MODE is not set
# CONFIG_SSL_PROT_LOW is not set
CONFIG_SSL_PROT_MEDIUM=y
# CONFIG_SSL_PROT_HIGH is not set
CONFIG_SSL_USE_DEFAULT_KEY=y
CONFIG_SSL_PRIVATE_KEY_LOCATION=""
CONFIG_SSL_PRIVATE_KEY_PASSWORD=""
CONFIG_SSL_X509_CERT_LOCATION=""
CONFIG_SSL_GENERATE_X509_CERT=y
CONFIG_SSL_X509_COMMON_NAME=""
CONFIG_SSL_X509_ORGANIZATION_NAME=""
CONFIG_SSL_X509_ORGANIZATION_UNIT_NAME=""
CONFIG_SSL_ENABLE_V23_HANDSHAKE=y
CONFIG_SSL_HAS_PEM=y
# CONFIG_SSL_USE_PKCS12 is not set
CONFIG_SSL_EXPIRY_TIME=24
CONFIG_X509_MAX_CA_CERTS=4
CONFIG_SSL_MAX_CERTS=2
CONFIG_SSL_CTX_MUTEXING=y
CONFIG_USE_DEV_URANDOM=y
# CONFIG_WIN32_USE_CRYPTO_LIB is not set
# CONFIG_OPENSSL_COMPATIBLE is not set
# CONFIG_PERFORMANCE_TESTING is not set
# CONFIG_SSL_TEST is not set
# CONFIG_AXHTTPD is not set
# CONFIG_HTTP_STATIC_BUILD is not set
CONFIG_HTTP_PORT=0
CONFIG_HTTP_HTTPS_PORT=0
CONFIG_HTTP_SESSION_CACHE_SIZE=0
CONFIG_HTTP_WEBROOT=""
CONFIG_HTTP_TIMEOUT=0
# CONFIG_HTTP_HAS_CGI is not set
CONFIG_HTTP_CGI_EXTENSIONS=""
# CONFIG_HTTP_ENABLE_LUA is not set
CONFIG_HTTP_LUA_PREFIX=""
CONFIG_HTTP_LUA_CGI_LAUNCHER=""
# CONFIG_HTTP_BUILD_LUA is not set
# CONFIG_HTTP_DIRECTORIES is not set
# CONFIG_HTTP_HAS_AUTHORIZATION is not set
# CONFIG_HTTP_HAS_IPV6 is not set
# CONFIG_HTTP_ENABLE_DIFFERENT_USER is not set
CONFIG_HTTP_USER=""
# CONFIG_HTTP_VERBOSE is not set
# CONFIG_HTTP_IS_DAEMON is not set
#
# Language Bindings
#
# CONFIG_BINDINGS is not set
# CONFIG_CSHARP_BINDINGS is not set
# CONFIG_VBNET_BINDINGS is not set
CONFIG_DOT_NET_FRAMEWORK_BASE=""
# CONFIG_JAVA_BINDINGS is not set
CONFIG_JAVA_HOME=""
# CONFIG_PERL_BINDINGS is not set
CONFIG_PERL_CORE=""
CONFIG_PERL_LIB=""
# CONFIG_LUA_BINDINGS is not set
CONFIG_LUA_CORE=""
#
# Samples
#
# CONFIG_SAMPLES is not set
# CONFIG_C_SAMPLES is not set
# CONFIG_CSHARP_SAMPLES is not set
# CONFIG_VBNET_SAMPLES is not set
# CONFIG_JAVA_SAMPLES is not set
# CONFIG_PERL_SAMPLES is not set
# CONFIG_LUA_SAMPLES is not set
#
# BigInt Options
#
# CONFIG_BIGINT_CLASSICAL is not set
# CONFIG_BIGINT_MONTGOMERY is not set
CONFIG_BIGINT_BARRETT=y
CONFIG_BIGINT_CRT=y
# CONFIG_BIGINT_KARATSUBA is not set
MUL_KARATSUBA_THRESH=0
SQU_KARATSUBA_THRESH=0
CONFIG_BIGINT_SLIDING_WINDOW=y
CONFIG_BIGINT_SQUARE=y
# CONFIG_BIGINT_CHECK_ON is not set

View file

@ -0,0 +1,113 @@
/*
* Automatically generated header file: don't edit
*/
#define HAVE_DOT_CONFIG 1
#define CONFIG_PLATFORM_LINUX 1
#undef CONFIG_PLATFORM_CYGWIN
#undef CONFIG_PLATFORM_WIN32
/*
* General Configuration
*/
#define PREFIX "/usr"
#undef CONFIG_DEBUG
#define CONFIG_STRIP_UNWANTED_SECTIONS 1
#undef CONFIG_VISUAL_STUDIO_7_0
#undef CONFIG_VISUAL_STUDIO_8_0
#define CONFIG_VISUAL_STUDIO_7_0_BASE ""
#define CONFIG_VISUAL_STUDIO_8_0_BASE ""
#define CONFIG_EXTRA_CFLAGS_OPTIONS "-fpic"
#define CONFIG_EXTRA_LDFLAGS_OPTIONS ""
/*
* SSL Library
*/
#undef CONFIG_SSL_SERVER_ONLY
#undef CONFIG_SSL_CERT_VERIFICATION
#define CONFIG_SSL_ENABLE_CLIENT 1
#undef CONFIG_SSL_FULL_MODE
#undef CONFIG_SSL_SKELETON_MODE
#undef CONFIG_SSL_PROT_LOW
#define CONFIG_SSL_PROT_MEDIUM 1
#undef CONFIG_SSL_PROT_HIGH
#define CONFIG_SSL_USE_DEFAULT_KEY 1
#define CONFIG_SSL_PRIVATE_KEY_LOCATION ""
#define CONFIG_SSL_PRIVATE_KEY_PASSWORD ""
#define CONFIG_SSL_X509_CERT_LOCATION ""
#define CONFIG_SSL_GENERATE_X509_CERT 1
#define CONFIG_SSL_X509_COMMON_NAME ""
#define CONFIG_SSL_X509_ORGANIZATION_NAME ""
#define CONFIG_SSL_X509_ORGANIZATION_UNIT_NAME ""
#define CONFIG_SSL_ENABLE_V23_HANDSHAKE 1
#define CONFIG_SSL_HAS_PEM 1
#undef CONFIG_SSL_USE_PKCS12
#define CONFIG_SSL_EXPIRY_TIME 24
#define CONFIG_X509_MAX_CA_CERTS 4
#define CONFIG_SSL_MAX_CERTS 2
#define CONFIG_SSL_CTX_MUTEXING 1
#define CONFIG_USE_DEV_URANDOM 1
#undef CONFIG_WIN32_USE_CRYPTO_LIB
#undef CONFIG_OPENSSL_COMPATIBLE
#undef CONFIG_PERFORMANCE_TESTING
#undef CONFIG_SSL_TEST
#undef CONFIG_AXHTTPD
#undef CONFIG_HTTP_STATIC_BUILD
#define CONFIG_HTTP_PORT
#define CONFIG_HTTP_HTTPS_PORT
#define CONFIG_HTTP_SESSION_CACHE_SIZE
#define CONFIG_HTTP_WEBROOT ""
#define CONFIG_HTTP_TIMEOUT
#undef CONFIG_HTTP_HAS_CGI
#define CONFIG_HTTP_CGI_EXTENSIONS ""
#undef CONFIG_HTTP_ENABLE_LUA
#define CONFIG_HTTP_LUA_PREFIX ""
#define CONFIG_HTTP_LUA_CGI_LAUNCHER ""
#undef CONFIG_HTTP_BUILD_LUA
#undef CONFIG_HTTP_DIRECTORIES
#undef CONFIG_HTTP_HAS_AUTHORIZATION
#undef CONFIG_HTTP_HAS_IPV6
#undef CONFIG_HTTP_ENABLE_DIFFERENT_USER
#define CONFIG_HTTP_USER ""
#undef CONFIG_HTTP_VERBOSE
#undef CONFIG_HTTP_IS_DAEMON
/*
* Language Bindings
*/
#undef CONFIG_BINDINGS
#undef CONFIG_CSHARP_BINDINGS
#undef CONFIG_VBNET_BINDINGS
#define CONFIG_DOT_NET_FRAMEWORK_BASE ""
#undef CONFIG_JAVA_BINDINGS
#define CONFIG_JAVA_HOME ""
#undef CONFIG_PERL_BINDINGS
#define CONFIG_PERL_CORE ""
#define CONFIG_PERL_LIB ""
#undef CONFIG_LUA_BINDINGS
#define CONFIG_LUA_CORE ""
/*
* Samples
*/
#undef CONFIG_SAMPLES
#undef CONFIG_C_SAMPLES
#undef CONFIG_CSHARP_SAMPLES
#undef CONFIG_VBNET_SAMPLES
#undef CONFIG_JAVA_SAMPLES
#undef CONFIG_PERL_SAMPLES
#undef CONFIG_LUA_SAMPLES
/*
* BigInt Options
*/
#undef CONFIG_BIGINT_CLASSICAL
#undef CONFIG_BIGINT_MONTGOMERY
#define CONFIG_BIGINT_BARRETT 1
#define CONFIG_BIGINT_CRT 1
#undef CONFIG_BIGINT_KARATSUBA
#define MUL_KARATSUBA_THRESH
#define SQU_KARATSUBA_THRESH
#define CONFIG_BIGINT_SLIDING_WINDOW 1
#define CONFIG_BIGINT_SQUARE 1
#undef CONFIG_BIGINT_CHECK_ON

View file

@ -20,6 +20,7 @@ module "nixio.util"
local BUFFERSIZE = 8096
local socket = nixio.socket_meta
local tls_socket = nixio.tls_socket_meta
function socket.recvall(self, len)
local block, code, msg = self:recv(len)
@ -46,6 +47,7 @@ function socket.recvall(self, len)
return (#data > 1 and table.concat(data) or data[1]), nil, nil, 0
end
tls_socket.recvall = socket.recvall
function socket.sendall(self, data)
local total, block = 0
@ -66,6 +68,7 @@ function socket.sendall(self, data)
return total + sent, nil, nil, ""
end
tls_socket.sendall = socket.sendall
function socket.linesource(self, limit)
limit = limit or BUFFERSIZE
@ -101,6 +104,7 @@ function socket.linesource(self, limit)
end
end
end
tls_socket.linesource = socket.linesource
function socket.blocksource(self, bs, limit)
bs = bs or BUFFERSIZE
@ -128,4 +132,5 @@ function socket.blocksource(self, bs, limit)
return block
end
end
end
end
tls_socket.blocksource = socket.blocksource

View file

@ -33,7 +33,11 @@ static int nixio_file(lua_State *L) {
return nixio__perror(L);
}
FILE **udata = lua_newuserdata(L, sizeof(FILE**));
FILE **udata = lua_newuserdata(L, sizeof(FILE*));
if (!udata) {
return luaL_error(L, "out of memory");
}
*udata = file;
luaL_getmetatable(L, NIXIO_FILE_META);
@ -50,7 +54,11 @@ static int nixio_pipe(lua_State *L) {
}
luaL_getmetatable(L, NIXIO_FILE_META);
udata = lua_newuserdata(L, sizeof(FILE**));
udata = lua_newuserdata(L, sizeof(FILE*));
if (!udata) {
return luaL_error(L, "out of memory");
}
if (!(*udata = fdopen(pipefd[0], "r"))) {
return nixio__perror(L);
}

View file

@ -36,8 +36,8 @@ static int nixio_sock__sendto(lua_State *L, int to) {
socklen_t alen = 0;
if (to) {
const char *address = luaL_checklstring(L, 2, NULL);
uint16_t port = (uint16_t)luaL_checkinteger(L, 3);
const char *address = luaL_checklstring(L, 3, NULL);
uint16_t port = (uint16_t)luaL_checkinteger(L, 4);
struct sockaddr_storage addrstor;
addr = (struct sockaddr*)&addrstor;
if (sock->domain == AF_INET) {
@ -65,7 +65,7 @@ static int nixio_sock__sendto(lua_State *L, int to) {
do {
sent = sendto(sock->fd, data, len, 0, addr, alen);
} while(sent == -1 && errno == EINTR);
if (len >= 0) {
if (sent >= 0) {
lua_pushinteger(L, sent);
return 1;
} else {

View file

@ -118,6 +118,8 @@ LUALIB_API int luaopen_nixio(lua_State *L) {
nixio_open_poll(L);
nixio_open_io(L);
nixio_open_splice(L);
nixio_open_tls_context(L);
nixio_open_tls_socket(L);
/* module version */
lua_pushnumber(L, VERSION);

View file

@ -3,6 +3,8 @@
#define NIXIO_META "nixio.socket"
#define NIXIO_FILE_META "nixio.file"
#define NIXIO_TLS_CTX_META "nixio.tls.ctx"
#define NIXIO_TLS_SOCK_META "nixio.tls.sock"
#define NIXIO_BUFFERSIZE 8096
#define _FILE_OFFSET_BITS 64
@ -43,6 +45,8 @@ void nixio_open_address(lua_State *L);
void nixio_open_poll(lua_State *L);
void nixio_open_io(lua_State *L);
void nixio_open_splice(lua_State *L);
void nixio_open_tls_context(lua_State *L);
void nixio_open_tls_socket(lua_State *L);
/* Method functions */

View file

@ -0,0 +1,297 @@
/*
* Copyright (c) 2007, Cameron Rich
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the axTLS project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Enable a subset of openssl compatible functions. We don't aim to be 100%
* compatible - just to be able to do basic ports etc.
*
* Only really tested on mini_httpd, so I'm not too sure how extensive this
* port is.
*/
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "ssl.h"
static char *key_password = NULL;
void *SSLv23_server_method(void) { return NULL; }
void *SSLv3_server_method(void) { return NULL; }
void *TLSv1_server_method(void) { return NULL; }
void *SSLv23_client_method(void) { return NULL; }
void *SSLv3_client_method(void) { return NULL; }
void *TLSv1_client_method(void) { return NULL; }
void *SSLv23_method(void) { return NULL; }
void *TLSv1_method(void) { return NULL; }
SSL_CTX * SSL_CTX_new(void *meth)
{
SSL_CTX *ssl_ctx = ssl_ctx_new(SSL_SERVER_VERIFY_LATER, 5);
return ssl_ctx;
}
void SSL_CTX_free(SSL_CTX * ssl_ctx)
{
ssl_ctx_free(ssl_ctx);
}
SSL * SSL_new(SSL_CTX *ssl_ctx)
{
SSL *ssl;
ssl = ssl_new(ssl_ctx, -1); /* fd is set later */
return ssl;
}
int SSL_set_fd(SSL *s, int fd)
{
s->client_fd = fd;
return 1; /* always succeeds */
}
int SSL_accept(SSL *ssl)
{
ssl->next_state = HS_CLIENT_HELLO;
while (ssl_read(ssl, NULL) == SSL_OK)
{
if (ssl->next_state == HS_CLIENT_HELLO)
return 1; /* we're done */
}
return -1;
}
int SSL_connect(SSL *ssl)
{
SET_SSL_FLAG(SSL_IS_CLIENT);
int stat = do_client_connect(ssl);
ssl_display_error(stat);
return (stat == SSL_OK) ? 1 : -1;
}
void SSL_free(SSL *ssl)
{
ssl_free(ssl);
}
int SSL_read(SSL *ssl, void *buf, int num)
{
uint8_t *read_buf;
int ret;
while ((ret = ssl_read(ssl, &read_buf)) == SSL_OK);
if (ret > SSL_OK)
{
memcpy(buf, read_buf, ret > num ? num : ret);
}
return ret;
}
int SSL_write(SSL *ssl, const void *buf, int num)
{
return ssl_write(ssl, buf, num);
}
int SSL_CTX_use_certificate_file(SSL_CTX *ssl_ctx, const char *file, int type)
{
return (ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CERT, file, NULL) == SSL_OK);
}
int SSL_CTX_use_PrivateKey_file(SSL_CTX *ssl_ctx, const char *file, int type)
{
return (ssl_obj_load(ssl_ctx, SSL_OBJ_RSA_KEY, file, key_password) == SSL_OK);
}
int SSL_CTX_use_certificate_ASN1(SSL_CTX *ssl_ctx, int len, const uint8_t *d)
{
return (ssl_obj_memory_load(ssl_ctx,
SSL_OBJ_X509_CERT, d, len, NULL) == SSL_OK);
}
int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const unsigned char *sid_ctx,
unsigned int sid_ctx_len)
{
return 1;
}
int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx)
{
return 1;
}
int SSL_CTX_use_certificate_chain_file(SSL_CTX *ssl_ctx, const char *file)
{
return (ssl_obj_load(ssl_ctx,
SSL_OBJ_X509_CERT, file, NULL) == SSL_OK);
}
int SSL_shutdown(SSL *ssl)
{
return 1;
}
/*** get/set session ***/
SSL_SESSION *SSL_get1_session(SSL *ssl)
{
return (SSL_SESSION *)ssl_get_session_id(ssl); /* note: wrong cast */
}
int SSL_set_session(SSL *ssl, SSL_SESSION *session)
{
memcpy(ssl->session_id, (uint8_t *)session, SSL_SESSION_ID_SIZE);
return 1;
}
void SSL_SESSION_free(SSL_SESSION *session) { }
/*** end get/set session ***/
long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
{
return 0;
}
void SSL_CTX_set_verify(SSL_CTX *ctx, int mode,
int (*verify_callback)(int, void *)) {
if (mode & SSL_VERIFY_PEER) {
ctx->options &= ~SSL_SERVER_VERIFY_LATER;
ctx->options |= SSL_CLIENT_AUTHENTICATION;
} else {
ctx->options |= SSL_SERVER_VERIFY_LATER;
ctx->options &= ~SSL_CLIENT_AUTHENTICATION;
}
}
void SSL_CTX_set_verify_depth(SSL_CTX *ctx,int depth) { }
int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
const char *CApath)
{
return 1;
}
void *SSL_load_client_CA_file(const char *file)
{
return (void *)file;
}
void SSL_CTX_set_client_CA_list(SSL_CTX *ssl_ctx, void *file)
{
ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CERT, (const char *)file, NULL);
}
void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, void *cb) { }
void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u)
{
key_password = (char *)u;
}
int SSL_peek(SSL *ssl, void *buf, int num)
{
memcpy(buf, ssl->bm_data, num);
return num;
}
void SSL_set_bio(SSL *ssl, void *rbio, void *wbio) { }
long SSL_get_verify_result(const SSL *ssl)
{
return ssl_handshake_status(ssl);
}
int SSL_state(SSL *ssl)
{
return 0x03; // ok state
}
/** end of could do better list */
void *SSL_get_peer_certificate(const SSL *ssl)
{
return &ssl->ssl_ctx->certs[0];
}
int SSL_clear(SSL *ssl)
{
return 1;
}
int SSL_CTX_check_private_key(const SSL_CTX *ctx)
{
return 1;
}
int SSL_CTX_set_cipher_list(SSL_CTX *s, const char *str)
{
return 1;
}
int SSL_get_error(const SSL *ssl, int ret)
{
ssl_display_error(ret);
return 0; /* TODO: return proper return code */
}
void SSL_CTX_set_options(SSL_CTX *ssl_ctx, int option) {}
int SSL_library_init(void ) { return 1; }
void SSL_load_error_strings(void ) {}
void ERR_print_errors_fp(FILE *fp) {}
long SSL_CTX_get_timeout(const SSL_CTX *ssl_ctx) {
return CONFIG_SSL_EXPIRY_TIME*3600; }
long SSL_CTX_set_timeout(SSL_CTX *ssl_ctx, long t) {
return SSL_CTX_get_timeout(ssl_ctx); }
void BIO_printf(FILE *f, const char *format, ...)
{
va_list(ap);
va_start(ap, format);
vfprintf(f, format, ap);
va_end(ap);
}
void* BIO_s_null(void) { return NULL; }
FILE *BIO_new(bio_func_type_t func)
{
if (func == BIO_s_null)
return fopen("/dev/null", "r");
else
return NULL;
}
FILE *BIO_new_fp(FILE *stream, int close_flag) { return stream; }
int BIO_free(FILE *a) { if (a != stdout && a != stderr) fclose(a); return 1; }

View file

@ -0,0 +1,144 @@
/*
* Copyright (c) 2007, Cameron Rich
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the axTLS project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Enable a subset of openssl compatible functions. We don't aim to be 100%
* compatible - just to be able to do basic ports etc.
*
* Only really tested on mini_httpd, so I'm not too sure how extensive this
* port is.
*/
#include "config.h"
#define WITH_AXTLS 1
#define WITHOUT_OPENSSL 1
#define SSL_OP_NO_SSLv3 0x02000000L
#define SSL_OP_NO_SSLv2 0x01000000L
#define SSL_FILETYPE_PEM 1
#define SSL_VERIFY_NONE 0x00
#define SSL_VERIFY_PEER 0x01
#define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02
#define SSL_VERIFY_CLIENT_ONCE 0x03
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "ssl.h"
void *SSLv23_server_method(void);
void *SSLv3_server_method(void);
void *TLSv1_server_method(void);
void *SSLv23_client_method(void);
void *SSLv3_client_method(void);
void *TLSv1_client_method(void);
void *SSLv23_method(void);
void *TLSv1_method(void);
typedef void * (*ssl_func_type_t)(void);
typedef void * (*bio_func_type_t)(void);
SSL_CTX * SSL_CTX_new(void *meth);
void SSL_CTX_free(SSL_CTX * ssl_ctx);
SSL * SSL_new(SSL_CTX *ssl_ctx);
int SSL_set_fd(SSL *s, int fd);
int SSL_accept(SSL *ssl);
int SSL_connect(SSL *ssl);
void SSL_free(SSL *ssl);
int SSL_read(SSL *ssl, void *buf, int num);
int SSL_write(SSL *ssl, const void *buf, int num);
int SSL_CTX_use_certificate_file(SSL_CTX *ssl_ctx, const char *file, int type);
int SSL_CTX_use_PrivateKey_file(SSL_CTX *ssl_ctx, const char *file, int type);
int SSL_CTX_use_certificate_ASN1(SSL_CTX *ssl_ctx, int len, const uint8_t *d);
int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const unsigned char *sid_ctx,
unsigned int sid_ctx_len);
int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx);
int SSL_CTX_use_certificate_chain_file(SSL_CTX *ssl_ctx, const char *file);
int SSL_shutdown(SSL *ssl);
/*** get/set session ***/
SSL_SESSION *SSL_get1_session(SSL *ssl);
int SSL_set_session(SSL *ssl, SSL_SESSION *session);
void SSL_SESSION_free(SSL_SESSION *session);
/*** end get/set session ***/
long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg);
void SSL_CTX_set_verify(SSL_CTX *ctx, int mode,
int (*verify_callback)(int, void *));
void SSL_CTX_set_verify_depth(SSL_CTX *ctx,int depth);
int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
const char *CApath);
void *SSL_load_client_CA_file(const char *file);
void SSL_CTX_set_client_CA_list(SSL_CTX *ssl_ctx, void *file);
void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, void *cb);
void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u);
int SSL_peek(SSL *ssl, void *buf, int num);
void SSL_set_bio(SSL *ssl, void *rbio, void *wbio);
long SSL_get_verify_result(const SSL *ssl);
int SSL_state(SSL *ssl);
/** end of could do better list */
void *SSL_get_peer_certificate(const SSL *ssl);
int SSL_clear(SSL *ssl);
int SSL_CTX_check_private_key(const SSL_CTX *ctx);
int SSL_CTX_set_cipher_list(SSL_CTX *s, const char *str);
int SSL_get_error(const SSL *ssl, int ret);
void SSL_CTX_set_options(SSL_CTX *ssl_ctx, int option);
int SSL_library_init(void );
void SSL_load_error_strings(void );
void ERR_print_errors_fp(FILE *fp);
long SSL_CTX_get_timeout(const SSL_CTX *ssl_ctx);
long SSL_CTX_set_timeout(SSL_CTX *ssl_ctx, long t);
void BIO_printf(FILE *f, const char *format, ...);
void* BIO_s_null(void);
FILE *BIO_new(bio_func_type_t func);
FILE *BIO_new_fp(FILE *stream, int close_flag);
int BIO_free(FILE *a);

View file

@ -34,6 +34,9 @@ static int nixio_socket(lua_State *L) {
const char *proto = lua_tolstring(L, 3, NULL);
nixio_sock *sock = lua_newuserdata(L, sizeof(nixio_sock));
if (!sock) {
return luaL_error(L, "out of memory");
}
if (!strcmp(domain, "inet")) {
sock->domain = AF_INET;
@ -142,17 +145,12 @@ static const luaL_reg R[] = {
static const luaL_reg M[] = {
{"close", nixio_sock_close},
{"shutdown", nixio_sock_shutdown},
{"__gc", nixio_sock__gc},
{"__tostring", nixio_sock__tostring},
{NULL, NULL}
};
void nixio_open_socket(lua_State *L) {
luaL_getmetatable(L, NIXIO_META);
lua_pushcfunction(L, nixio_sock__gc);
lua_setfield(L, -2, "__gc");
lua_pushcfunction(L, nixio_sock__tostring);
lua_setfield(L, -2, "__tostring");
lua_pop(L, 1);
luaL_register(L, NULL, R);
lua_pushvalue(L, -2);

View file

@ -0,0 +1,202 @@
/*
* nixio - Linux I/O library for lua
*
* Copyright (C) 2009 Steven Barth <steven@midlink.org>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "nixio.h"
#include "string.h"
#ifndef WITHOUT_OPENSSL
#include <openssl/ssl.h>
#endif
static SSL_CTX* nixio__checktlsctx(lua_State *L) {
SSL_CTX **ctx = (SSL_CTX **)luaL_checkudata(L, 1, NIXIO_TLS_CTX_META);
luaL_argcheck(L, *ctx, 1, "invalid context");
return *ctx;
}
static int nixio__tls_perror(lua_State *L, int code) {
lua_pushnil(L);
lua_pushinteger(L, code);
return 2;
}
static int nixio__tls_pstatus(lua_State *L, int code) {
if (code == 1) {
lua_pushboolean(L, 1);
return 1;
} else {
return nixio__tls_perror(L, code);
}
}
static int nixio_tls_ctx(lua_State * L) {
const char *method = luaL_optlstring(L, 1, "tlsv1", NULL);
SSL_CTX **ctx = lua_newuserdata(L, sizeof(SSL_CTX *));
if (!ctx) {
return luaL_error(L, "out of memory");
}
/* create userdata */
luaL_getmetatable(L, NIXIO_TLS_CTX_META);
lua_setmetatable(L, -2);
if (!strcmp(method, "tlsv1")) {
*ctx = SSL_CTX_new(TLSv1_method());
} else if (!strcmp(method, "sslv23")) {
*ctx = SSL_CTX_new(SSLv23_method());
} else {
return luaL_argerror(L, 1, "supported values: tlsv1, sslv23");
}
SSL_CTX_set_options(*ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
if (!(*ctx)) {
return luaL_error(L, "unable to create TLS context");
}
return 1;
}
static int nixio_tls_ctx_create(lua_State *L) {
SSL_CTX *ctx = nixio__checktlsctx(L);
int fd = nixio__checkfd(L, 2);
SSL **sock = lua_newuserdata(L, sizeof(SSL *));
if (!sock) {
return luaL_error(L, "out of memory");
}
/* create userdata */
luaL_getmetatable(L, NIXIO_TLS_SOCK_META);
lua_setmetatable(L, -2);
*sock = SSL_new(ctx);
if (!(*sock)) {
return nixio__tls_perror(L, 0);
}
if (SSL_set_fd(*sock, fd) != 1) {
return nixio__tls_perror(L, 0);
}
return 1;
}
static int nixio_tls_ctx_set_cert(lua_State *L) {
SSL_CTX *ctx = nixio__checktlsctx(L);
const char *cert = luaL_checkstring(L, 2);
return nixio__tls_pstatus(L, SSL_CTX_use_certificate_chain_file(ctx, cert));
}
static int nixio_tls_ctx_set_key(lua_State *L) {
SSL_CTX *ctx = nixio__checktlsctx(L);
const char *cert = luaL_checkstring(L, 2);
const int ktype = SSL_FILETYPE_PEM;
return nixio__tls_pstatus(L, SSL_CTX_use_PrivateKey_file(ctx, cert, ktype));
}
static int nixio_tls_ctx_set_ciphers(lua_State *L) {
SSL_CTX *ctx = nixio__checktlsctx(L);
size_t len;
const char *ciphers = luaL_checklstring(L, 2, &len);
luaL_argcheck(L, len < 255, 2, "cipher string too long");
return nixio__tls_pstatus(L, SSL_CTX_set_cipher_list(ctx, ciphers));
}
static int nixio_tls_ctx_set_verify_depth(lua_State *L) {
SSL_CTX *ctx = nixio__checktlsctx(L);
const int depth = luaL_checkinteger(L, 2);
SSL_CTX_set_verify_depth(ctx, depth);
return 0;
}
static int nixio_tls_ctx_set_verify(lua_State *L) {
SSL_CTX *ctx = nixio__checktlsctx(L);
const int j = lua_gettop(L);
int flags = 0;
for (int i=2; i<=j; i++) {
const char *flag = luaL_checkstring(L, i);
if (!strcmp(flag, "none")) {
flags |= SSL_VERIFY_NONE;
} else if (!strcmp(flag, "peer")) {
flags |= SSL_VERIFY_PEER;
} else if (!strcmp(flag, "verify_fail_if_no_peer_cert")) {
flags |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
} else if (!strcmp(flag, "client_once")) {
flags |= SSL_VERIFY_CLIENT_ONCE;
} else {
return luaL_argerror(L, i, "supported values: none, peer, "
"verify_fail_if_no_peer_cert, client_once");
}
}
SSL_CTX_set_verify(ctx, flags, NULL);
return 0;
}
static int nixio_tls_ctx__gc(lua_State *L) {
SSL_CTX **ctx = (SSL_CTX **)luaL_checkudata(L, 1, NIXIO_TLS_CTX_META);
if (*ctx) {
SSL_CTX_free(*ctx);
*ctx = NULL;
}
return 0;
}
static int nixio_tls_ctx__tostring(lua_State *L) {
SSL_CTX *ctx = nixio__checktlsctx(L);
lua_pushfstring(L, "nixio TLS context: %p", ctx);
return 1;
}
/* module table */
static const luaL_reg R[] = {
{"tls", nixio_tls_ctx},
{NULL, NULL}
};
/* ctx function table */
static const luaL_reg CTX_M[] = {
{"set_cert", nixio_tls_ctx_set_cert},
{"set_key", nixio_tls_ctx_set_key},
{"set_ciphers", nixio_tls_ctx_set_ciphers},
{"set_verify_depth", nixio_tls_ctx_set_verify_depth},
{"set_verify", nixio_tls_ctx_set_verify},
{"create", nixio_tls_ctx_create},
{"__gc", nixio_tls_ctx__gc},
{"__tostring", nixio_tls_ctx__tostring},
{NULL, NULL}
};
void nixio_open_tls_context(lua_State *L) {
/* initialize tls library */
SSL_load_error_strings();
SSL_library_init();
/* register module functions */
luaL_register(L, NULL, R);
/* create context metatable */
luaL_newmetatable(L, NIXIO_TLS_CTX_META);
lua_pushvalue(L, -1);
lua_setfield(L, -2, "__index");
luaL_register(L, NULL, CTX_M);
lua_pop(L, 1);
}

196
libs/nixio/src/tls-socket.c Normal file
View file

@ -0,0 +1,196 @@
/*
* nixio - Linux I/O library for lua
*
* Copyright (C) 2009 Steven Barth <steven@midlink.org>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "nixio.h"
#include "string.h"
#ifndef WITHOUT_OPENSSL
#include <openssl/ssl.h>
#endif
static int nixio__tls_sock_perror(lua_State *L, SSL *sock, int code) {
lua_pushnil(L);
lua_pushinteger(L, code);
lua_pushinteger(L, SSL_get_error(sock, code));
return 3;
}
static int nixio__tls_sock_pstatus(lua_State *L, SSL *sock, int code) {
if (code == 1) {
lua_pushboolean(L, 1);
return 1;
} else {
return nixio__tls_sock_perror(L, sock, code);
}
}
static SSL* nixio__checktlssock(lua_State *L) {
SSL **sock = (SSL **)luaL_checkudata(L, 1, NIXIO_TLS_SOCK_META);
luaL_argcheck(L, *sock, 1, "invalid context");
return *sock;
}
static int nixio_tls_sock_recv(lua_State *L) {
SSL *sock = nixio__checktlssock(L);
int req = luaL_checkinteger(L, 2);
luaL_argcheck(L, req >= 0, 2, "out of range");
/* We limit the readsize to NIXIO_BUFFERSIZE */
req = (req > NIXIO_BUFFERSIZE) ? NIXIO_BUFFERSIZE : req;
#ifndef WITH_AXTLS
char buffer[NIXIO_BUFFERSIZE];
int readc = SSL_read(sock, buffer, req);
if (readc < 0) {
return nixio__tls_sock_pstatus(L, sock, readc);
} else {
lua_pushlstring(L, buffer, readc);
return 1;
}
#else
if (!req) {
lua_pushliteral(L, "");
return 1;
}
/* AXTLS doesn't handle buffering for us, so we have to hack around*/
int buflen = 0;
lua_getmetatable(L, 1);
lua_getfield(L, -1, "_axbuffer");
if (lua_isstring(L, -1)) {
buflen = lua_objlen(L, -1);
}
if (req < buflen) {
const char *axbuf = lua_tostring(L, -1);
lua_pushlstring(L, axbuf, req);
lua_pushlstring(L, axbuf + req, buflen - req);
lua_setfield(L, -4, "_axbuffer");
return 1;
} else {
if (!lua_isstring(L, -1)) {
lua_pop(L, 1);
lua_pushliteral(L, "");
}
char *axbuf;
int axread;
/* while handshake pending */
while ((axread = ssl_read(sock, (uint8_t**)&axbuf)) == SSL_OK);
if (axread < 0) {
/* There is an error */
if (axread != SSL_ERROR_CONN_LOST) {
lua_pushliteral(L, "");
lua_setfield(L, -3, "_axbuffer");
return nixio__tls_sock_perror(L, sock, axread);
} else {
lua_pushliteral(L, "");
}
} else {
int stillwant = req - buflen;
if (stillwant < axread) {
/* we got more data than we need */
lua_pushlstring(L, axbuf, stillwant);
lua_concat(L, 2);
/* remaining data goes into the buffer */
lua_pushlstring(L, axbuf + stillwant, axread - stillwant);
} else {
lua_pushlstring(L, axbuf, axread);
lua_concat(L, 2);
lua_pushliteral(L, "");
}
}
lua_setfield(L, -3, "_axbuffer");
return 1;
}
#endif
}
static int nixio_tls_sock_send(lua_State *L) {
SSL *sock = nixio__checktlssock(L);
size_t len;
ssize_t sent;
const char *data = luaL_checklstring(L, 2, &len);
sent = SSL_write(sock, data, len);
if (sent > 0) {
lua_pushinteger(L, sent);
return 1;
} else {
return nixio__tls_sock_pstatus(L, sock, len);
}
}
static int nixio_tls_sock_accept(lua_State *L) {
SSL *sock = nixio__checktlssock(L);
return nixio__tls_sock_pstatus(L, sock, SSL_accept(sock));
}
static int nixio_tls_sock_connect(lua_State *L) {
SSL *sock = nixio__checktlssock(L);
return nixio__tls_sock_pstatus(L, sock, SSL_connect(sock));
}
static int nixio_tls_sock_shutdown(lua_State *L) {
SSL *sock = nixio__checktlssock(L);
return nixio__tls_sock_pstatus(L, sock, SSL_shutdown(sock));
}
static int nixio_tls_sock__gc(lua_State *L) {
SSL **sock = (SSL **)luaL_checkudata(L, 1, NIXIO_TLS_SOCK_META);
if (*sock) {
SSL_free(*sock);
*sock = NULL;
}
return 0;
}
static int nixio_tls_sock__tostring(lua_State *L) {
SSL *sock = nixio__checktlssock(L);
lua_pushfstring(L, "nixio TLS socket: %p", sock);
return 1;
}
/* ctx function table */
static const luaL_reg M[] = {
{"recv", nixio_tls_sock_recv},
{"send", nixio_tls_sock_send},
{"accept", nixio_tls_sock_accept},
{"connect", nixio_tls_sock_connect},
{"shutdown", nixio_tls_sock_shutdown},
{"__gc", nixio_tls_sock__gc},
{"__tostring", nixio_tls_sock__tostring},
{NULL, NULL}
};
void nixio_open_tls_socket(lua_State *L) {
/* create socket metatable */
luaL_newmetatable(L, NIXIO_TLS_SOCK_META);
luaL_register(L, NULL, M);
lua_pushvalue(L, -1);
lua_setfield(L, -2, "__index");
lua_setfield(L, -2, "tls_socket_meta");
}