aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/GNUmakefile136
-rw-r--r--src/compat52.h160
-rw-r--r--src/openssl.c866
-rw-r--r--src/openssl.ocsp.basic.lua3
-rw-r--r--src/openssl.ocsp.response.lua3
5 files changed, 852 insertions, 316 deletions
diff --git a/src/GNUmakefile b/src/GNUmakefile
index 015a93c..e257ba6 100644
--- a/src/GNUmakefile
+++ b/src/GNUmakefile
@@ -16,66 +16,46 @@ include $(d)/../GNUmakefile
#
# C O M P I L A T I O N F L A G S
#
-OS_$(d) = $(shell $(d)/../mk/vendor.os)
-CC_$(d) = $(shell env CC="$(CC) "$(d)/../mk/vendor.cc)
-LUAPATH_$(d) = $(shell env CC="$(CC)" CPPFLAGS="$(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" $(<D)/../mk/luapath -krxm3 -I$(DESTDIR)$(includedir) -I/usr/include -I/usr/local/include -P$(DESTDIR)$(bindir) -P$(bindir) -L$(DESTDIR)$(libdir) -L$(libdir) -v$(1) $(2))
-
-CPPFLAGS_$(d) = $(CPPFLAGS_$(abspath $(@D)/../..)) -DLUA_COMPAT_APIINTCASTS -DHAVE_CONFIG_H
-CFLAGS_$(d) = $(CFLAGS_$(abspath $(@D)/../..))
-LDFLAGS_$(d) = $(LDFLAGS_$(abspath $(@D)/../..))
-SOFLAGS_$(d) = $(SOFLAGS_$(abspath $(@D)/../..))
-
-ifeq ($(CC_$(d)), sunpro)
-CPPFLAGS_$(d) += -DOPENSSL_NO_EC
-endif
-
-LDFLAGS_$(d) += -lssl -lcrypto -lpthread -lm
-
-# NetBSD, FreeBSD, OpenBSD (and presumably descendants) lack any libdl;
-# dlopen, et al are part of libc.
-ifneq ($(patsubst %BSD,BSD,$(OS_$(d))), BSD)
-LDFLAGS_$(d) += -ldl
-endif
-
+CPPFLAGS_$(d) = $(ALL_CPPFLAGS) -DHAVE_CONFIG_H -DCOMPAT53_PREFIX=luaossl
+CFLAGS_$(d) = $(ALL_CFLAGS)
+SOFLAGS_$(d) = $(ALL_SOFLAGS)
+LDFLAGS_$(d) = $(ALL_LDFLAGS)
+LIBS_$(d) = $(ALL_LIBS)
#
# C O M P I L A T I O N R U L E S
#
+OBJS_$(d) = openssl.o ../vendor/compat53/c-api/compat-5.3.o
+
$(d)/config.h: $(abspath $(d)/..)/config.h
$(CP) $< $@
define BUILD_$(d)
-.SECONDARY: liblua$(1)-openssl openssl$(1)
+$$(d)/$(1)/openssl.so: $$(addprefix $$(d)/$(1)/, $$(OBJS_$(d)))
+ $$(CC) -o $$@ $$^ $$(SOFLAGS_$$(abspath $$(@D)/..)) $$(LDFLAGS_$$(abspath $$(@D)/..)) $$(LIBS_$$(abspath $$(@D)/..))
-$$(d)/$(1)/openssl.so: $$(d)/$(1)/openssl.o
- $$(CC) -o $$@ $$^ $$(SOFLAGS_$$(abspath $$(@D)/..)) $$(SOFLAGS) $$(LDFLAGS_$$(abspath $$(@D)/..)) $$(LDFLAGS)
-
-$$(d)/$(1)/openssl.o: $$(d)/openssl.c $$(d)/compat52.h $$(d)/config.h
- test "$$(notdir $$(@D))" = "$$(call LUAPATH_$$(<D), $$(notdir $$(@D)), version)"
+$$(d)/$(1)/%.o: $$(d)/%.c $$(d)/../vendor/compat53/c-api/compat-5.3.h $$(d)/config.h
$$(MKDIR) -p $$(@D)
- $$(CC) $$(CFLAGS_$$(<D)) $$(CFLAGS) $$(call LUAPATH_$$(<D), $$(notdir $$(@D)), cppflags) $$(CPPFLAGS_$$(<D)) $$(CPPFLAGS) -c -o $$@ $$<
+ $$(CC) $$(CFLAGS_$$(<D)) $$(ALL_LUA$(subst .,,$(1))_CPPFLAGS) $$(CPPFLAGS_$$(<D)) -c -o $$@ $$<
+
+.SECONDARY: liblua$(1)-openssl openssl$(1) openssl
-liblua$(1)-openssl openssl$(1): $$(d)/$(1)/openssl.so
+liblua$(1)-openssl openssl$(1) openssl: $$(d)/$(1)/openssl.so
endef # BUILD_$(d)
$(eval $(call BUILD_$(d),5.1))
-
$(eval $(call BUILD_$(d),5.2))
-
$(eval $(call BUILD_$(d),5.3))
ifneq "$(filter $(abspath $(d)/..)/%, $(abspath $(firstword $(MAKEFILE_LIST))))" ""
-.SECONDARY: all5.1 all5.2 all
+.SECONDARY: all all5.1 all5.2 all5.3
all5.1: liblua5.1-openssl
-
all5.2: liblua5.2-openssl
-
all5.3: liblua5.3-openssl
-
-all: all5.1 all5.2
+all: $(foreach API,$(strip $(LUA_APIS)),all$(API))
endif
@@ -85,13 +65,13 @@ endif
#
define INSTALL_$(d)
-LUAC$(1)_$(d) = $$(or $$(call LUAPATH_$(d), $(1), luac), true)
-
MODS$(1)_$(d) = \
$$(DESTDIR)$(2)/_openssl.so \
$$(DESTDIR)$(3)/openssl.lua \
$$(DESTDIR)$(3)/openssl/auxlib.lua \
$$(DESTDIR)$(3)/openssl/bignum.lua \
+ $$(DESTDIR)$(3)/openssl/ocsp/basic.lua \
+ $$(DESTDIR)$(3)/openssl/ocsp/response.lua \
$$(DESTDIR)$(3)/openssl/pkey.lua \
$$(DESTDIR)$(3)/openssl/pubkey.lua \
$$(DESTDIR)$(3)/openssl/x509.lua \
@@ -114,42 +94,34 @@ MODS$(1)_$(d) = \
.SECONDARY: liblua$(1)-openssl-install openssl$(1)-install
-$$(DESTDIR)$(2)/_openssl.so: $$(d)/$(1)/openssl.so
- $$(MKDIR) -p $$(@D)
- $$(CP) -fp $$< $$@
+liblua$(1)-openssl-install openssl$(1)-install: $$(MODS$(1)_$$(d))
-$$(DESTDIR)$(3)/openssl.lua: $$(d)/openssl.lua
- $$(LUAC$(1)_$(d)) -p $$<
+$$(DESTDIR)$(2)/_openssl.so: $$(d)/$(1)/openssl.so
$$(MKDIR) -p $$(@D)
$$(CP) -p $$< $$@
-$$(DESTDIR)$(3)/openssl/%.lua: $$(d)/openssl.%.lua
- $$(LUAC$(1)_$(d)) -p $$<
+$$(DESTDIR)$(3)/%.lua: $$(d)/%.lua
+ $$(LUAC$(subst .,,$(1))) -p $$<
$$(MKDIR) -p $$(@D)
$$(CP) -p $$< $$@
-# pubkey.lua used to be symbolic link to pkey.lua, but that caused packaging
-# headaches. Now it's a stub, but the cp -p in the inference rule will copy
-# to the target of the symbolic link, so we need a special install rule to
-# clean up the mess.
-$$(DESTDIR)$(3)/openssl/pubkey.lua: $$(d)/openssl.pubkey.lua
- $$(LUAC$(1)_$(d)) -p $$<
+$$(DESTDIR)$(3)/openssl/%.lua: $$(d)/openssl.%.lua
+ $$(LUAC$(subst .,,$(1))) -p $$<
$$(MKDIR) -p $$(@D)
- $$(RM) -f $$@
$$(CP) -p $$< $$@
-$$(DESTDIR)$(3)/openssl/x509/%.lua: $$(d)/openssl.x509.%.lua
- $$(LUAC$(1)_$(d)) -p $$<
+$$(DESTDIR)$(3)/openssl/ocsp/%.lua: $$(d)/ocsp.%.lua
+ $$(LUAC$(subst .,,$(1))) -p $$<
$$(MKDIR) -p $$(@D)
$$(CP) -p $$< $$@
-$$(DESTDIR)$(3)/openssl/ssl/%.lua: $$(d)/openssl.ssl.%.lua
- $$(LUAC$(1)_$(d)) -p $$<
+$$(DESTDIR)$(3)/openssl/x509/%.lua: $$(d)/x509.%.lua
+ $$(LUAC$(subst .,,$(1))) -p $$<
$$(MKDIR) -p $$(@D)
$$(CP) -p $$< $$@
-$$(DESTDIR)$(3)/openssl/ssl/%.lua: $$(d)/openssl.ssl.%.lua
- $$(LUAC$(1)_$(d)) -p $$<
+$$(DESTDIR)$(3)/openssl/ssl/%.lua: $$(d)/ssl.%.lua
+ $$(LUAC$(subst .,,$(1))) -p $$<
$$(MKDIR) -p $$(@D)
$$(CP) -p $$< $$@
@@ -159,6 +131,7 @@ liblua$(1)-openssl-install openssl$(1)-install: $$(MODS$(1)_$$(d))
liblua$(1)-openssl-uninstall openssl$(1)-uninstall:
$$(RM) -f $$(MODS$(1)_$(d))
+ -$$(RMDIR) $$(DESTDIR)$(3)/openssl/ocsp
-$$(RMDIR) $$(DESTDIR)$(3)/openssl/x509
-$$(RMDIR) $$(DESTDIR)$(3)/openssl/ssl
-$$(RMDIR) $$(DESTDIR)$(3)/openssl
@@ -166,31 +139,24 @@ liblua$(1)-openssl-uninstall openssl$(1)-uninstall:
endef # INSTALL_$(d)
$(eval $(call INSTALL_$(d),5.1,$$(lua51cpath),$$(lua51path)))
-
$(eval $(call INSTALL_$(d),5.2,$$(lua52cpath),$$(lua52path)))
-
$(eval $(call INSTALL_$(d),5.3,$$(lua53cpath),$$(lua53path)))
ifneq "$(filter $(abspath $(d)/..)/%, $(abspath $(firstword $(MAKEFILE_LIST))))" ""
+
.SECONDARY: install5.1 install5.2 install5.3 install
install5.1: liblua5.1-openssl-install
-
install5.2: liblua5.2-openssl-install
-
install5.3: liblua5.3-openssl-install
-
-install: install5.1 install5.2
+install: $(foreach API,$(strip $(LUA_APIS)),install$(API))
.PHONY: uninstall5.1 uninstall5.2 uninstall5.3 uninstall
uninstall5.1: liblua5.1-openssl-uninstall
-
uninstall5.2: liblua5.2-openssl-uninstall
-
uninstall5.3: liblua5.3-openssl-uninstall
-
-uninstall: uninstall5.1 uninstall5.2
+uninstall: $(foreach API,$(strip $(LUA_APIS)),uninstall$(API))
endif
@@ -201,7 +167,7 @@ endif
.PHONY: $(d)/clean $(d)/clean~ clean clean~
$(d)/clean:
- $(RM) -fr $(@D)/*.so $(@D)/*.o $(@D)/*.dSYM $(@D)/5.1 $(@D)/5.2 $(@D)/5.3
+ $(RM) -fr $(@D)/config.h $(@D)/*.dSYM $(@D)/5.1 $(@D)/5.2 $(@D)/5.3
$(d)/clean~: $(d)/clean
$(RM) -f $(@D)/*~
@@ -218,27 +184,27 @@ clean~: $(d)/clean~
$(d)/help:
@echo
- @echo "ext/ targets:"
+ @echo "src/ targets:"
@echo ""
- @echo " all - build all binary targets"
- @echo "openssl - invokes openssl5.1 and openssl5.2"
- @echo "openssl5.1 - build 5.1/openssl.so"
- @echo "openssl5.2 - build 5.2/openssl.so"
- @echo "openssl5.3 - build 5.3/openssl.so"
- @echo "install - invokes install5.1 and install5.2"
- @echo "install5.1 - install openssl Lua 5.1 modules"
- @echo "install5.2 - install openssl Lua 5.2 modules"
- @echo "install5.3 - install openssl Lua 5.3 modules"
- @echo "uninstall - invokes uninstall5.1 and uninstall5.2"
+ @echo " all - build all API targets"
+ @echo " all5.1 - build 5.1/openssl.so"
+ @echo " all5.2 - build 5.2/openssl.so"
+ @echo " all5.3 - build 5.3/openssl.so"
+ @echo " install - install all API targets"
+ @echo " install5.1 - install openssl Lua 5.1 modules"
+ @echo " install5.2 - install openssl Lua 5.2 modules"
+ @echo " install5.3 - install openssl Lua 5.3 modules"
+ @echo " uninstall - uninstall all API targets"
@echo "uninstall5.1 - uninstall openssl Lua 5.1 modules"
@echo "uninstall5.2 - uninstall openssl Lua 5.2 modules"
@echo "uninstall5.3 - uninstall openssl Lua 5.3 modules"
- @echo " clean - rm binary targets, object files, debugging symbols, etc"
- @echo " clean~ - clean + rm *~"
- @echo " help - echo this help message"
+ @echo " clean - rm binary targets, object files, debugging symbols, etc"
+ @echo " clean~ - clean + rm *~"
+ @echo " help - echo this help message"
@echo ""
@echo "Some important Make variables:"
@echo ""
+ @echo ' LUA_APIS - default Lua APIs to target ($(LUA_APIS))'
@echo " prefix - path to install root ($(value prefix))"
@echo ' lua51path - install path for Lua 5.1 modules ($(value lua51path))'
@echo 'lua51cpath - install path for Lua 5.1 C modules ($(value lua51cpath))'
@@ -247,6 +213,10 @@ $(d)/help:
@echo ' lua53path - install path for Lua 5.3 modules ($(value lua53path))'
@echo 'lua53cpath - install path for Lua 5.3 C modules ($(value lua53cpath))'
@echo ""
+ @echo 'LUA51_CPPFLAGS - cpp flags for Lua 5.1 headers ($(LUA51_CPPFLAGS))'
+ @echo 'LUA52_CPPFLAGS - cpp flags for Lua 5.2 headers ($(LUA52_CPPFLAGS))'
+ @echo 'LUA53_CPPFLAGS - cpp flags for Lua 5.3 headers ($(LUA53_CPPFLAGS))'
+ @echo ""
@echo "(NOTE: all the common GNU-style paths are supported, including"
@echo "prefix, bindir, libdir, datadir, includedir, and DESTDIR.)"
@echo ""
diff --git a/src/compat52.h b/src/compat52.h
deleted file mode 100644
index 0057b3c..0000000
--- a/src/compat52.h
+++ /dev/null
@@ -1,160 +0,0 @@
-/* ==========================================================================
- * compat52.h - Routines for Lua 5.2 compatibility
- * --------------------------------------------------------------------------
- * Copyright (c) 2012 William Ahern
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to permit
- * persons to whom the Software is furnished to do so, subject to the
- * following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
- * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- * ==========================================================================
- */
-#if LUA_VERSION_NUM < 502
-
-#define LUA_OK 0
-
-
-static void luaL_setmetatable(lua_State *L, const char *tname) {
- luaL_getmetatable(L, tname);
- lua_setmetatable(L, -2);
-} /* luaL_setmetatable() */
-
-
-static int lua_absindex(lua_State *L, int idx) {
- return (idx > 0 || idx <= LUA_REGISTRYINDEX)? idx : lua_gettop(L) + idx + 1;
-} /* lua_absindex() */
-
-
-static void *luaL_testudata(lua_State *L, int arg, const char *tname) {
- void *p = lua_touserdata(L, arg);
- int eq;
-
- if (!p || !lua_getmetatable(L, arg))
- return 0;
-
- luaL_getmetatable(L, tname);
- eq = lua_rawequal(L, -2, -1);
- lua_pop(L, 2);
-
- return (eq)? p : 0;
-} /* luaL_testudate() */
-
-
-static void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup) {
- int i, t = lua_absindex(L, -1 - nup);
-
- for (; l->name; l++) {
- for (i = 0; i < nup; i++)
- lua_pushvalue(L, -nup);
- lua_pushcclosure(L, l->func, nup);
- lua_setfield(L, t, l->name);
- }
-
- lua_pop(L, nup);
-} /* luaL_setfuncs() */
-
-
-#define luaL_newlibtable(L, l) \
- lua_createtable(L, 0, (sizeof (l) / sizeof *(l)) - 1)
-
-#define luaL_newlib(L, l) \
- (luaL_newlibtable((L), (l)), luaL_setfuncs((L), (l), 0))
-
-
-static void luaL_requiref(lua_State *L, const char *modname, lua_CFunction openf, int glb) {
- lua_pushcfunction(L, openf);
- lua_pushstring(L, modname);
- lua_call(L, 1, 1);
-
- lua_getglobal(L, "package");
- lua_getfield(L, -1, "loaded");
- lua_pushvalue(L, -3);
- lua_setfield(L, -2, modname);
-
- lua_pop(L, 2);
-
- if (glb) {
- lua_pushvalue(L, -1);
- lua_setglobal(L, modname);
- }
-} /* luaL_requiref() */
-
-
-#define lua_resume(L, from, nargs) lua_resume((L), (nargs))
-
-
-static void lua_rawgetp(lua_State *L, int index, const void *p) {
- index = lua_absindex(L, index);
- lua_pushlightuserdata(L, (void *)p);
- lua_rawget(L, index);
-} /* lua_rawgetp() */
-
-static void lua_rawsetp(lua_State *L, int index, const void *p) {
- index = lua_absindex(L, index);
- lua_pushlightuserdata(L, (void *)p);
- lua_pushvalue(L, -2);
- lua_rawset(L, index);
- lua_pop(L, 1);
-} /* lua_rawsetp() */
-
-
-#ifndef LUA_UNSIGNED
-#define LUA_UNSIGNED unsigned
-#endif
-
-typedef LUA_UNSIGNED lua_Unsigned;
-
-
-static void lua_pushunsigned(lua_State *L, lua_Unsigned n) {
- lua_pushnumber(L, (lua_Number)n);
-} /* lua_pushunsigned() */
-
-static lua_Unsigned luaL_checkunsigned(lua_State *L, int arg) {
- return (lua_Unsigned)luaL_checknumber(L, arg);
-} /* luaL_checkunsigned() */
-
-
-static lua_Unsigned luaL_optunsigned(lua_State *L, int arg, lua_Unsigned def) {
- return (lua_Unsigned)luaL_optnumber(L, arg, (lua_Number)def);
-} /* luaL_optunsigned() */
-
-
-#ifndef LUA_FILEHANDLE /* Not defined by earlier LuaJIT releases */
-#define LUA_FILEHANDLE "FILE*"
-#endif
-
-/*
- * Lua 5.1 userdata is a simple FILE *, while LuaJIT is a struct with the
- * first member a FILE *, similar to Lua 5.2.
- */
-typedef struct luaL_Stream {
- FILE *f;
-} luaL_Stream;
-
-
-#define lua_rawlen(...) lua_objlen(__VA_ARGS__)
-
-
-#define lua_pushstring(...) lua52_pushstring(__VA_ARGS__)
-
-static const char *lua52_pushstring(lua_State *L, const char *s) {
- (lua_pushstring)(L, s);
- return lua_tostring(L, -1);
-} /* lua52_pushstring() */
-
-
-#endif /* LUA_VERSION_NUM < 502 */
diff --git a/src/openssl.c b/src/openssl.c
index 8217deb..a3e5637 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -69,14 +69,13 @@
#include <openssl/hmac.h>
#include <openssl/rand.h>
#include <openssl/des.h>
+#include <openssl/ocsp.h>
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
-#if LUA_VERSION_NUM < 502
-#include "compat52.h"
-#endif
+#include "../vendor/compat53/c-api/compat-5.3.h"
#define GNUC_2VER(M, m, p) (((M) * 10000) + ((m) * 100) + (p))
#define GNUC_PREREQ(M, m, p) (__GNUC__ > 0 && GNUC_2VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) >= GNUC_2VER((M), (m), (p)))
@@ -270,6 +269,10 @@
#define HAVE_SSL_CTX_SET_ALPN_SELECT_CB HAVE_SSL_CTX_SET_ALPN_PROTOS
#endif
+#ifndef HAVE_SSL_CTX_SET_TLSEXT_SERVERNAME_CALLBACK
+#define HAVE_SSL_CTX_SET_TLSEXT_SERVERNAME_CALLBACK OPENSSL_PREREQ(1,0,0)
+#endif
+
#ifndef HAVE_SSL_CTX_SET1_CERT_STORE
#define HAVE_SSL_CTX_SET1_CERT_STORE (HAVE_SSL_CTX_set1_cert_store || 0) /* backwards compatible with old macro name */
#endif
@@ -282,6 +285,14 @@
#define HAVE_SSL_CTX_CERT_STORE (!OPENSSL_PREREQ(1,1,0))
#endif
+#ifndef HAVE_SSL_CTX_SET_TLSEXT_STATUS_TYPE
+#define HAVE_SSL_CTX_SET_TLSEXT_STATUS_TYPE OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_SSL_CTX_GET_TLSEXT_STATUS_TYPE
+#define HAVE_SSL_CTX_GET_TLSEXT_STATUS_TYPE OPENSSL_PREREQ(1,1,0)
+#endif
+
#ifndef HAVE_SSL_GET0_ALPN_SELECTED
#define HAVE_SSL_GET0_ALPN_SELECTED HAVE_SSL_CTX_SET_ALPN_PROTOS
#endif
@@ -302,6 +313,14 @@
#define HAVE_SSL_SET1_PARAM OPENSSL_PREREQ(1,0,2)
#endif
+#ifndef HAVE_SSL_GET_CLIENT_RANDOM
+#define HAVE_SSL_GET_CLIENT_RANDOM OPENSSL_PREREQ(1,1,0)
+#endif
+
+#ifndef HAVE_SSL_GET_TLSEXT_STATUS_TYPE
+#define HAVE_SSL_GET_TLSEXT_STATUS_TYPE OPENSSL_PREREQ(1,1,0)
+#endif
+
#ifndef HAVE_SSL_UP_REF
#define HAVE_SSL_UP_REF OPENSSL_PREREQ(1,1,0)
#endif
@@ -314,6 +333,10 @@
#define HAVE_SSLV2_SERVER_METHOD (!OPENSSL_PREREQ(1,1,0) && !defined OPENSSL_NO_SSL2)
#endif
+#ifndef HAVE_X509_GET_SIGNATURE_NID
+#define HAVE_X509_GET_SIGNATURE_NID OPENSSL_PREREQ(1,0,2)
+#endif
+
#ifndef HAVE_X509_STORE_REFERENCES
#define HAVE_X509_STORE_REFERENCES (!OPENSSL_PREREQ(1,1,0))
#endif
@@ -392,6 +415,8 @@
#define DIGEST_CLASS "EVP_MD_CTX*"
#define HMAC_CLASS "HMAC_CTX*"
#define CIPHER_CLASS "EVP_CIPHER_CTX*"
+#define OCSP_RESPONSE_CLASS "OCSP_RESPONSE*"
+#define OCSP_BASICRESP_CLASS "OCSP_BASICRESP*"
#if __GNUC__
@@ -669,6 +694,44 @@ static void *loadfield_udata(lua_State *L, int index, const char *k, const char
} /* loadfield_udata() */
+/* Forward declaration */
+static SSL *ssl_push(lua_State *, SSL *);
+
+/* push an ssl object into lua in a way that is safe from OOM
+ * Lua 5.1 does not support normally returning values from lua_cpcall
+ * to return a value, we instead return it via an error object
+ */
+static int ssl_pushsafe_helper(lua_State *L) {
+ ssl_push(L, lua_touserdata(L, 1));
+#if LUA_VERSION_NUM <= 501
+ return lua_error(L);
+#else
+ return 1;
+#endif
+}
+
+static int ssl_pushsafe(lua_State *L, SSL *ssl) {
+ int status;
+#if LUA_VERSION_NUM <= 501
+ status = lua_cpcall(L, ssl_pushsafe_helper, ssl);
+ if (status == LUA_ERRRUN)
+ status = LUA_OK;
+ else if (status == LUA_OK)
+ /* this should be impossible */
+ status = LUA_ERRRUN;
+ else
+ lua_pop(L, 1);
+#else
+ lua_pushcfunction(L, ssl_pushsafe_helper);
+ lua_pushlightuserdata(L, ssl);
+ status = lua_pcall(L, 1, 1, 0);
+ if (status != LUA_OK)
+ lua_pop(L, 1);
+#endif
+ return status;
+}
+
+
/*
* Auxiliary C routines
*
@@ -920,7 +983,7 @@ static void auxL_pushinteger(lua_State *L, auxL_Integer i) {
}
} /* auxL_pushinteger() */
-NOTUSED static void auxL_pushunsigned(lua_State *L, auxL_Unsigned i) {
+static void auxL_pushunsigned(lua_State *L, auxL_Unsigned i) {
if (i <= lua_IntegerMax) {
lua_pushinteger(L, i);
} else if (i == (auxL_Unsigned)(lua_Number)i) {
@@ -1571,6 +1634,18 @@ static void compat_RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) {
} /* compat_RSA_set0_key() */
#endif
+#if !HAVE_SSL_GET_CLIENT_RANDOM
+#define SSL_get_client_random(...) compat_SSL_get_client_random(__VA_ARGS__)
+static size_t compat_SSL_get_client_random(const SSL *ssl, unsigned char *out, size_t outlen) {
+ if (outlen == 0)
+ return sizeof(ssl->s3->client_random);
+ if (outlen > sizeof(ssl->s3->client_random))
+ outlen = sizeof(ssl->s3->client_random);
+ memcpy(out, ssl->s3->client_random, outlen);
+ return outlen;
+}
+#endif
+
#if !HAVE_SSL_CLIENT_VERSION
#define SSL_client_version(...) compat_SSL_client_version(__VA_ARGS__)
@@ -1627,6 +1702,10 @@ static int compat_SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm) {
#define X509_get0_ext(crt, i) X509_get_ext((crt), (i))
#endif
+#if !HAVE_X509_GET_SIGNATURE_NID
+#define X509_get_signature_nid(crt) OBJ_obj2nid((crt)->sig_alg->algorithm)
+#endif
+
#if !HAVE_X509_CRL_GET0_EXT
#define X509_CRL_get0_ext(crt, i) X509_CRL_get_ext((crt), (i))
#endif
@@ -1914,6 +1993,7 @@ struct ex_data {
enum {
EX_SSL_CTX_ALPN_SELECT_CB,
+ EX_SSL_CTX_TLSEXT_SERVERNAME_CB,
};
static struct ex_type {
@@ -1923,6 +2003,7 @@ static struct ex_type {
int (*set_ex_data)();
} ex_type[] = {
[EX_SSL_CTX_ALPN_SELECT_CB] = { CRYPTO_EX_INDEX_SSL_CTX, -1, &SSL_CTX_get_ex_data, &SSL_CTX_set_ex_data },
+ [EX_SSL_CTX_TLSEXT_SERVERNAME_CB] = { CRYPTO_EX_INDEX_SSL_CTX, -1, &SSL_CTX_get_ex_data, &SSL_CTX_set_ex_data },
};
#if OPENSSL_PREREQ(1,1,0)
@@ -3074,6 +3155,7 @@ static int pk_new(lua_State *L) {
unsigned exp = 65537;
int curve = NID_X9_62_prime192v1;
const char *id;
+ const char *dhparam = NULL;
lua_Number n;
if (!lua_istable(L, 1))
@@ -3115,6 +3197,9 @@ static int pk_new(lua_State *L) {
luaL_argerror(L, 1, lua_pushfstring(L, "%s: invalid curve", id));
}
+ /* dhparam field can contain a PEM encoded string. */
+ loadfield(L, 1, "dhparam", LUA_TSTRING, &dhparam);
+
creat:
if (!(*ud = EVP_PKEY_new()))
return auxL_error(L, auxL_EOPENSSL, "pkey.new");
@@ -3152,9 +3237,23 @@ creat:
case EVP_PKEY_DH: {
DH *dh;
- if (!(dh = DH_generate_parameters(bits, exp, 0, 0)))
+ /* DH Parameter Generation can take a long time, therefore we look
+ * at the "dhparam" field, provided by the user.
+ * The "dhparam" field takes precedence over "bits"
+ */
+ if (dhparam) {
+ BIO *bio = BIO_new_mem_buf((void*)dhparam, strlen(dhparam));
+ if (!bio)
+ return auxL_error(L, auxL_EOPENSSL, "pkey.new");
+
+ dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
+ BIO_free(bio);
+ if (!dh)
+ return auxL_error(L, auxL_EOPENSSL, "pkey.new");
+ } else if (!(dh = DH_generate_parameters(bits, exp, 0, 0)))
return auxL_error(L, auxL_EOPENSSL, "pkey.new");
+
if (!DH_generate_key(dh)) {
DH_free(dh);
return auxL_error(L, auxL_EOPENSSL, "pkey.new");
@@ -3420,7 +3519,7 @@ static int pk_decrypt(lua_State *L) {
if (lua_istable(L, 3)) {
if (base_type == EVP_PKEY_RSA) {
lua_getfield(L, 3, "rsaPadding");
- rsaPadding = luaL_optint(L, -1, rsaPadding);
+ rsaPadding = luaL_optinteger(L, -1, rsaPadding);
lua_pop(L, 1);
}
}
@@ -3479,7 +3578,7 @@ static int pk_encrypt(lua_State *L) {
if (lua_istable(L, 3)) {
if (base_type == EVP_PKEY_RSA) {
lua_getfield(L, 3, "rsaPadding");
- rsaPadding = luaL_optint(L, -1, rsaPadding);
+ rsaPadding = luaL_optinteger(L, -1, rsaPadding);
lua_pop(L, 1);
}
}
@@ -4401,7 +4500,7 @@ static int ecg_new(lua_State *L) {
return 1;
}
case LUA_TNUMBER: {
- int nid = luaL_checkint(L, 2);
+ int nid = luaL_checkinteger(L, 2);
if (!ecg_push_by_nid(L, nid))
goto sslerr;
@@ -4970,6 +5069,25 @@ static _Bool xe_new_isder(const char *value, _Bool *crit) {
return 0;
} /* xs_new_isder() */
+static CONF* loadconf(lua_State *L, int idx) {
+ CONF *conf;
+ size_t len;
+ const char *cdata = luaL_checklstring(L, idx, &len);
+ BIO *bio = getbio(L);
+ if (BIO_write(bio, cdata, len) < 0)
+ return NULL;
+
+ if (!(conf = NCONF_new(NULL)))
+ return NULL;
+
+ if (!NCONF_load_bio(conf, bio, NULL)) {
+ NCONF_free(conf);
+ return NULL;
+ }
+
+ return conf;
+}
+
static int xe_new(lua_State *L) {
const char *name = luaL_checkstring(L, 1);
const char *value = luaL_checkstring(L, 2);
@@ -4978,42 +5096,87 @@ static int xe_new(lua_State *L) {
CONF *conf = NULL;
X509V3_CTX cbuf = { 0 }, *ctx = NULL;
X509_EXTENSION **ud;
+ _Bool crit;
lua_settop(L, 3);
ud = prepsimple(L, X509_EXT_CLASS);
- if (!lua_isnil(L, 3)) {
+ if (xe_new_isder(value, &crit)) {
size_t len;
- const char *cdata = luaL_checklstring(L, 3, &len);
- _Bool crit;
+ const char *cdata = lua_tolstring(L, 3, &len);
+ if (!(obj = OBJ_txt2obj(name, 0)))
+ goto error;
+ if (!(oct = ASN1_STRING_new()))
+ goto error;
+ if (!ASN1_STRING_set(oct, cdata, len))
+ goto error;
+ if (!(*ud = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct)))
+ goto error;
- if (xe_new_isder(value, &crit)) {
- if (!(obj = OBJ_txt2obj(name, 0)))
- goto error;
- if (!(oct = ASN1_STRING_new()))
- goto error;
- if (!ASN1_STRING_set(oct, cdata, len))
- goto error;
- if (!(*ud = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct)))
+ ASN1_OBJECT_free(obj);
+ ASN1_STRING_free(oct);
+
+ return 1;
+ }
+
+ switch (lua_type(L, 3)) {
+ case LUA_TNONE:
+ case LUA_TNIL:
+ break;
+ case LUA_TSTRING: {
+ if (!(conf = loadconf(L, 3)))
+ goto error;
+
+ ctx = &cbuf;
+ X509V3_set_nconf(ctx, conf);
+ break;
+ }
+ case LUA_TTABLE: {
+ X509 *issuer = NULL;
+ X509 *subject = NULL;
+ X509_REQ *request = NULL;
+ X509_CRL *crl = NULL;
+ int flags = 0;
+
+ ctx = &cbuf;
+
+ if (lua_getfield(L, 3, "db") != LUA_TNIL) {
+ if (!(conf = loadconf(L, -1)))
goto error;
+ X509V3_set_nconf(ctx, conf);
+ }
+ lua_pop(L, 1);
- ASN1_OBJECT_free(obj);
- ASN1_STRING_free(oct);
+ if (lua_getfield(L, 3, "issuer") != LUA_TNIL) {
+ issuer = checksimple(L, -1, X509_CERT_CLASS);
+ }
+ lua_pop(L, 1);
- return 1;
+ if (lua_getfield(L, 3, "subject") != LUA_TNIL) {
+ subject = checksimple(L, -1, X509_CERT_CLASS);
}
+ lua_pop(L, 1);
- BIO *bio = getbio(L);
- if (BIO_puts(bio, cdata) < 0)
- goto error;
+ if (lua_getfield(L, 3, "request") != LUA_TNIL) {
+ request = checksimple(L, -1, X509_CSR_CLASS);
+ }
+ lua_pop(L, 1);
- if (!(conf = NCONF_new(NULL)))
- goto error;
- if (!NCONF_load_bio(conf, bio, NULL))
- goto error;
+ if (lua_getfield(L, 3, "crl") != LUA_TNIL) {
+ crl = checksimple(L, -1, X509_CRL_CLASS);
+ }
+ lua_pop(L, 1);
- ctx = &cbuf;
- X509V3_set_nconf(ctx, conf);
+ if (lua_getfield(L, 3, "flags") != LUA_TNIL) {
+ flags = luaL_checkinteger(L, -1);
+ }
+ lua_pop(L, 1);
+
+ X509V3_set_ctx(ctx, issuer, subject, request, crl, flags);
+ break;
+ }
+ default:
+ return luaL_argerror(L, 3, "invalid extra parameter (expected string, table or nil)");
}
/*
@@ -5257,7 +5420,7 @@ static int xc_getVersion(lua_State *L) {
static int xc_setVersion(lua_State *L) {
X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
- int version = luaL_checkint(L, 2);
+ int version = luaL_checkinteger(L, 2);
if (!X509_set_version(crt, version - 1))
return luaL_error(L, "x509.cert:setVersion: %d: invalid version", version);
@@ -5804,11 +5967,11 @@ static int xc_setBasicConstraint(lua_State *L) {
lua_pop(L, 1);
lua_getfield(L, 2, "pathLen");
- pathLen = luaL_optint(L, -1, pathLen);
+ pathLen = luaL_optinteger(L, -1, pathLen);
lua_pop(L, 1);
lua_getfield(L, 2, "pathLenConstraint");
- pathLen = luaL_optint(L, -1, pathLen);
+ pathLen = luaL_optinteger(L, -1, pathLen);
lua_pop(L, 1);
if (!(bs = BASIC_CONSTRAINTS_new()))
@@ -5825,7 +5988,7 @@ static int xc_setBasicConstraint(lua_State *L) {
case 1:
/* FALL THROUGH */
case 2:
- pathLen = luaL_checkint(L, 3);
+ pathLen = luaL_checkinteger(L, 3);
break;
}
@@ -5947,6 +6110,40 @@ static int xc_getExtensionCount(lua_State *L) {
} /* xc_getExtensionCount() */
+static int sk_openssl_string__gc(lua_State *L) {
+ STACK_OF(OPENSSL_STRING) **res = lua_touserdata(L, 1);
+
+ if (*res) {
+ sk_OPENSSL_STRING_free(*res);
+ *res = NULL;
+ }
+
+ return 0;
+} /* sk_openssl_string__gc() */
+
+
+static int xc_getOCSP(lua_State *L) {
+ X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
+ STACK_OF(OPENSSL_STRING) **res = prepsimple(L, NULL, &sk_openssl_string__gc);
+ int num, i;
+
+ *res = X509_get1_ocsp(crt);
+ if (!*res)
+ return 0;
+
+ num = sk_OPENSSL_STRING_num(*res);
+ luaL_checkstack(L, num, "too many authorityInfoAccess");
+ for (i = 0; i < num; i++) {
+ lua_pushstring(L, sk_OPENSSL_STRING_value(*res, i));
+ }
+
+ sk_OPENSSL_STRING_free(*res);
+ *res = NULL;
+
+ return num;
+} /* xc_getOCSP */
+
+
static int xc_isIssuedBy(lua_State *L) {
X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
X509 *issuer = checksimple(L, 2, X509_CERT_CLASS);
@@ -6029,23 +6226,17 @@ static int xc_getPublicKeyDigest(lua_State *L) {
} /* xc_getPublicKeyDigest() */
-#if 0
-/*
- * TODO: X509_get_signature_type always seems to return NID_undef. Are we
- * using it wrong or is it broken?
- */
static int xc_getSignatureName(lua_State *L) {
X509 *crt = checksimple(L, 1, X509_CERT_CLASS);
int nid;
- if (NID_undef == (nid = X509_get_signature_type(crt)))
+ if (NID_undef == (nid = X509_get_signature_nid(crt)))
return 0;
auxL_pushnid(L, nid);
return 1;
} /* xc_getSignatureName() */
-#endif
static int xc_sign(lua_State *L) {
@@ -6188,13 +6379,12 @@ static const auxL_Reg xc_methods[] = {
{ "addExtension", &xc_addExtension },
{ "getExtension", &xc_getExtension },
{ "getExtensionCount", &xc_getExtensionCount },
+ { "getOCSP", &xc_getOCSP },
{ "isIssuedBy", &xc_isIssuedBy },
{ "getPublicKey", &xc_getPublicKey },
{ "setPublicKey", &xc_setPublicKey },
{ "getPublicKeyDigest", &xc_getPublicKeyDigest },
-#if 0
{ "getSignatureName", &xc_getSignatureName },
-#endif
{ "sign", &xc_sign },
{ "text", &xc_text },
{ "tostring", &xc__tostring },
@@ -6286,7 +6476,7 @@ static int xr_getVersion(lua_State *L) {
static int xr_setVersion(lua_State *L) {
X509_REQ *csr = checksimple(L, 1, X509_CSR_CLASS);
- int version = luaL_checkint(L, 2);
+ int version = luaL_checkinteger(L, 2);
if (!X509_REQ_set_version(csr, version - 1))
return luaL_error(L, "x509.csr:setVersion: %d: invalid version", version);
@@ -6591,7 +6781,7 @@ static int xx_getVersion(lua_State *L) {
static int xx_setVersion(lua_State *L) {
X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS);
- int version = luaL_checkint(L, 2);
+ int version = luaL_checkinteger(L, 2);
if (!X509_CRL_set_version(crl, version - 1))
return luaL_error(L, "x509.crl:setVersion: %d: invalid version", version);
@@ -6642,7 +6832,7 @@ static int xx_getNextUpdate(lua_State *L) {
updateby = timeutc(time);
if (isfinite(updateby))
- lua_pushnumber(L, 1);
+ lua_pushnumber(L, updateby);
else
lua_pushnil(L);
@@ -6832,6 +7022,19 @@ static int xx_sign(lua_State *L) {
} /* xx_sign() */
+static int xx_verify(lua_State *L) {
+ X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS);
+ EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS);
+
+ if (!X509_CRL_verify(crl, key))
+ return auxL_error(L, auxL_EOPENSSL, "x509.crl:verify");
+
+ lua_pushboolean(L, 1);
+
+ return 1;
+} /* xx_verify() */
+
+
static int xx_text(lua_State *L) {
X509_CRL *crl = checksimple(L, 1, X509_CRL_CLASS);
@@ -6901,6 +7104,7 @@ static const auxL_Reg xx_methods[] = {
{ "getExtension", &xx_getExtension },
{ "getExtensionCount", &xx_getExtensionCount },
{ "sign", &xx_sign },
+ { "verify", &xx_verify },
{ "text", &xx_text },
{ "tostring", &xx__tostring },
{ NULL, NULL },
@@ -7180,7 +7384,7 @@ static int xs_verify(lua_State *L) {
X509 *crt = checksimple(L, 2, X509_CERT_CLASS);
STACK_OF(X509) *chain = NULL, **proof;
X509_STORE_CTX *ctx = NULL;
- int nr = 0, ok, why;
+ int ok, why;
/* pre-allocate space for a successful return */
lua_settop(L, 3);
@@ -7215,27 +7419,24 @@ static int xs_verify(lua_State *L) {
case 1: /* verified */
if (!(*proof = X509_STORE_CTX_get1_chain(ctx)))
goto eossl;
+ X509_STORE_CTX_free(ctx);
lua_pushboolean(L, 1);
lua_pushvalue(L, -2);
- nr = 2;
- break;
+ return 2;
case 0: /* not verified */
why = X509_STORE_CTX_get_error(ctx);
+ X509_STORE_CTX_free(ctx);
lua_pushboolean(L, 0);
lua_pushstring(L, X509_verify_cert_error_string(why));
- nr = 2;
- break;
+ return 2;
default:
goto eossl;
}
- X509_STORE_CTX_free(ctx);
-
- return nr;
eossl:
if (ctx)
X509_STORE_CTX_free(ctx);
@@ -7428,6 +7629,57 @@ static int p12_interpose(lua_State *L) {
} /* p12_interpose() */
+static int p12_parse(lua_State *L) {
+ /* parse a p12 binary string and return the parts */
+ PKCS12 *p12;
+
+ /* gather input parameters */
+ size_t len;
+ const char *blob = luaL_checklstring(L, 1, &len);
+ const char *passphrase = luaL_optstring(L, 2, NULL);
+
+ /* prepare return values */
+ EVP_PKEY **ud_pkey = prepsimple(L, PKEY_CLASS);
+ X509 **ud_cert = prepsimple(L, X509_CERT_CLASS);
+ STACK_OF(X509) **ud_chain = prepsimple(L, X509_CHAIN_CLASS);
+ /* Note: *ud_chain must be initialised to NULL, which prepsimple does. */
+
+ /* read PKCS#12 data into OpenSSL memory buffer */
+ BIO *bio = BIO_new_mem_buf((void*)blob, len);
+ if (!bio)
+ return auxL_error(L, auxL_EOPENSSL, "pkcs12.parse");
+ p12 = d2i_PKCS12_bio(bio, NULL);
+ BIO_free(bio);
+ if (!p12)
+ return auxL_error(L, auxL_EOPENSSL, "pkcs12.parse");
+
+ /* the p12 pointer holds the data we're interested in */
+ int rc = PKCS12_parse(p12, passphrase, ud_pkey, ud_cert, ud_chain);
+ PKCS12_free(p12);
+ if (!rc)
+ auxL_error(L, auxL_EOPENSSL, "pkcs12.parse");
+
+ /* replace the return values by nil if the ud pointers are NULL */
+ if (*ud_pkey == NULL) {
+ lua_pushnil(L);
+ lua_replace(L, -4);
+ }
+
+ if (*ud_cert == NULL) {
+ lua_pushnil(L);
+ lua_replace(L, -3);
+ }
+
+ /* other certificates (a chain, STACK_OF(X509) *) */
+ if (*ud_chain == NULL) {
+ lua_pop(L, 1);
+ lua_pushnil(L);
+ }
+
+ return 3;
+} /* p12_parse() */
+
+
static int p12__tostring(lua_State *L) {
PKCS12 *p12 = checksimple(L, 1, PKCS12_CLASS);
BIO *bio = getbio(L);
@@ -7471,6 +7723,7 @@ static const auxL_Reg p12_metatable[] = {
static const auxL_Reg p12_globals[] = {
{ "new", &p12_new },
{ "interpose", &p12_interpose },
+ { "parse", &p12_parse },
{ NULL, NULL },
};
@@ -7690,8 +7943,8 @@ static int sx_getParam(lua_State *L) {
static int sx_setVerify(lua_State *L) {
SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS);
- int mode = luaL_optint(L, 2, -1);
- int depth = luaL_optint(L, 3, -1);
+ int mode = luaL_optinteger(L, 2, -1);
+ int depth = luaL_optinteger(L, 3, -1);
if (mode != -1)
SSL_CTX_set_verify(ctx, mode, 0);
@@ -7855,9 +8108,8 @@ static int sx_setAlpnProtos(lua_State *L) {
} /* sx_setAlpnProtos() */
#endif
-#if HAVE_SSL_CTX_SET_ALPN_SELECT_CB
-static SSL *ssl_push(lua_State *, SSL *);
+#if HAVE_SSL_CTX_SET_ALPN_SELECT_CB
static int sx_setAlpnSelect_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *_ctx) {
SSL_CTX *ctx = _ctx;
lua_State *L = NULL;
@@ -7875,12 +8127,12 @@ static int sx_setAlpnSelect_cb(SSL *ssl, const unsigned char **out, unsigned cha
otop = lua_gettop(L) - n;
- /* TODO: Install temporary panic handler to catch OOM errors */
-
/* pass SSL object as 1st argument */
- ssl_push(L, ssl);
+ if (ssl_pushsafe(L, ssl))
+ goto fatal;
lua_insert(L, otop + 3);
+ /* TODO: Install temporary panic handler to catch OOM errors */
/* pass table of protocol names as 2nd argument */
pushprotos(L, in, inlen);
lua_insert(L, otop + 4);
@@ -7952,6 +8204,116 @@ static int sx_setAlpnSelect(lua_State *L) {
#endif
+#if HAVE_SSL_CTX_SET_TLSEXT_SERVERNAME_CALLBACK
+static int sx_setHostNameCallback_cb(SSL *ssl, int *ad, void *_ctx) {
+ SSL_CTX *ctx = _ctx;
+ lua_State *L = NULL;
+ size_t n;
+ int otop, status, ret = SSL_TLSEXT_ERR_ALERT_FATAL;
+
+ *ad = SSL_AD_INTERNAL_ERROR;
+
+ /* expect at least one value: closure */
+ if ((n = ex_getdata(&L, EX_SSL_CTX_TLSEXT_SERVERNAME_CB, ctx)) < 1)
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
+
+ otop = lua_gettop(L) - n;
+
+ /* pass SSL object as 1st argument */
+ if (ssl_pushsafe(L, ssl))
+ goto done;
+
+ lua_insert(L, otop + 2);
+
+ if (LUA_OK != (status = lua_pcall(L, 1 + (n - 1), 2, 0)))
+ goto done;
+
+ /* callback should return a boolean for OK/NOACK
+ * or nil + an integer for a controlled error
+ * everything else will be a fatal internal error
+ */
+ if (lua_isboolean(L, -2)) {
+ ret = lua_toboolean(L, -2) ? SSL_TLSEXT_ERR_OK : SSL_TLSEXT_ERR_NOACK;
+ } else {
+ ret = SSL_TLSEXT_ERR_ALERT_FATAL;
+ if (lua_isnil(L, -2) && lua_isinteger(L, -1))
+ *ad = lua_tointeger(L, -1);
+ }
+
+done:
+ lua_settop(L, otop);
+
+ return ret;
+} /* sx_setHostNameCallback_cb() */
+
+
+static int sx_setHostNameCallback(lua_State *L) {
+ SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS);
+ int error;
+
+ luaL_checktype(L, 2, LUA_TFUNCTION);
+
+ if ((error = ex_setdata(L, EX_SSL_CTX_TLSEXT_SERVERNAME_CB, ctx, lua_gettop(L) - 1))) {
+ if (error > 0) {
+ return luaL_error(L, "unable to set hostname selection callback: %s", aux_strerror(error));
+ } else if (error == auxL_EOPENSSL && !ERR_peek_error()) {
+ return luaL_error(L, "unable to set hostname selection callback: Unknown internal error");
+ } else {
+ return auxL_error(L, error, "ssl.context:setHostNameCallback");
+ }
+ }
+ SSL_CTX_set_tlsext_servername_callback(ctx, sx_setHostNameCallback_cb);
+ SSL_CTX_set_tlsext_servername_arg(ctx, ctx);
+
+ lua_pushboolean(L, 1);
+
+ return 1;
+} /* sx_setHostNameCallback() */
+#endif
+
+
+int TLSEXT_STATUSTYPEs[] = { TLSEXT_STATUSTYPE_ocsp };
+const char *TLSEXT_STATUSTYPEs_names[] = { "ocsp", NULL };
+#define checkTLSEXT_STATUSTYPE(L, idx) \
+ (TLSEXT_STATUSTYPEs[luaL_checkoption((L), (idx), NULL, TLSEXT_STATUSTYPEs_names)])
+
+
+#if HAVE_SSL_CTX_SET_TLSEXT_STATUS_TYPE
+static int sx_setTLSextStatusType(lua_State *L) {
+ SSL_CTX *ctx = checksimple(L, 1, SSL_CTX_CLASS);
+ int type = checkTLSEXT_STATUSTYPE(L, 2);
+
+ if(!SSL_CTX_set_tlsext_status_type(ctx, type))
+ return auxL_error(L, auxL_EOPENSSL, "ssl.context:setTLSextStatusType");
+
+ lua_pushboolean(L, 1);
+
+ return 1;
+} /* sx_setTLSextStatusType() */
+#endif
+
+
+#if HAVE_SSL_CTX_GET_TLSEXT_STATUS_TYPE
+static int sx_getTLSextStatusType(lua_State *L) {
+ SSL_CTX *ctx = checksimple(L, 1, SSL_CLASS);
+
+ int type = SSL_CTX_get_tlsext_status_type(ctx);
+ switch(type) {
+ case -1:
+ lua_pushnil(L);
+ break;
+ case TLSEXT_STATUSTYPE_ocsp:
+ lua_pushliteral(L, "ocsp");
+ break;
+ default:
+ luaL_error(L, "unknown TLS extension %d", type);
+ }
+
+ return 1;
+} /* sx_getTLSextStatusType() */
+#endif
+
+
static int sx__gc(lua_State *L) {
SSL_CTX **ud = luaL_checkudata(L, 1, SSL_CTX_CLASS);
@@ -7987,6 +8349,15 @@ static const auxL_Reg sx_methods[] = {
#if HAVE_SSL_CTX_SET_ALPN_SELECT_CB
{ "setAlpnSelect", &sx_setAlpnSelect },
#endif
+#if HAVE_SSL_CTX_SET_TLSEXT_SERVERNAME_CALLBACK
+ { "setHostNameCallback", &sx_setHostNameCallback },
+#endif
+#if HAVE_SSL_CTX_SET_TLSEXT_STATUS_TYPE
+ { "setTLSextStatusType", &sx_setTLSextStatusType },
+#endif
+#if HAVE_SSL_CTX_GET_TLSEXT_STATUS_TYPE
+ { "getTLSextStatusType", &sx_getTLSextStatusType },
+#endif
{ NULL, NULL },
};
@@ -8098,6 +8469,18 @@ static int ssl_interpose(lua_State *L) {
} /* ssl_interpose() */
+static int ssl_setContext(lua_State *L) {
+ SSL *ssl = checksimple(L, 1, SSL_CLASS);
+ SSL_CTX *ctx = checksimple(L, 2, SSL_CTX_CLASS);
+
+ if (!SSL_set_SSL_CTX(ssl, ctx))
+ return auxL_error(L, auxL_EOPENSSL, "ssl.setContext");
+
+ lua_pushboolean(L, 1);
+
+ return 1;
+} /* ssl_setContext() */
+
static int ssl_setOptions(lua_State *L) {
SSL *ssl = checksimple(L, 1, SSL_CLASS);
auxL_Integer options = auxL_checkinteger(L, 2);
@@ -8159,6 +8542,33 @@ static int ssl_getParam(lua_State *L) {
} /* ssl_getParam() */
+static int ssl_setVerify(lua_State *L) {
+ SSL *ssl = checksimple(L, 1, SSL_CLASS);
+ int mode = luaL_optinteger(L, 2, -1);
+ int depth = luaL_optinteger(L, 3, -1);
+
+ if (mode != -1)
+ SSL_set_verify(ssl, mode, 0);
+
+ if (depth != -1)
+ SSL_set_verify_depth(ssl, depth);
+
+ lua_pushboolean(L, 1);
+
+ return 1;
+} /* ssl_setVerify() */
+
+
+static int ssl_getVerify(lua_State *L) {
+ SSL *ssl = checksimple(L, 1, SSL_CLASS);
+
+ lua_pushinteger(L, SSL_get_verify_mode(ssl));
+ lua_pushinteger(L, SSL_get_verify_depth(ssl));
+
+ return 2;
+} /* ssl_getVerify() */
+
+
static int ssl_getVerifyResult(lua_State *L) {
SSL *ssl = checksimple(L, 1, SSL_CLASS);
long res = SSL_get_verify_result(ssl);
@@ -8168,6 +8578,44 @@ static int ssl_getVerifyResult(lua_State *L) {
} /* ssl_getVerifyResult() */
+static int ssl_setCertificate(lua_State *L) {
+ SSL *ssl = checksimple(L, 1, SSL_CLASS);
+ X509 *crt = X509_dup(checksimple(L, 2, X509_CERT_CLASS));
+ int ok;
+
+ ok = SSL_use_certificate(ssl, crt);
+ X509_free(crt);
+
+ if (!ok)
+ return auxL_error(L, auxL_EOPENSSL, "ssl:setCertificate");
+
+ lua_pushboolean(L, 1);
+
+ return 1;
+} /* ssl_setCertificate() */
+
+
+static int ssl_setPrivateKey(lua_State *L) {
+ SSL *ssl = checksimple(L, 1, SSL_CLASS);
+ EVP_PKEY *key = checksimple(L, 2, PKEY_CLASS);
+ /*
+ * NOTE: No easy way to dup the key, but a shared reference should
+ * be okay as keys are less mutable than certificates.
+ *
+ * FIXME: SSL_use_PrivateKey will return true even if the
+ * EVP_PKEY object has no private key. Instead, we'll just get a
+ * segfault during the SSL handshake. We need to check that a
+ * private key is actually defined in the object.
+ */
+ if (!SSL_use_PrivateKey(ssl, key))
+ return auxL_error(L, auxL_EOPENSSL, "ssl:setPrivateKey");
+
+ lua_pushboolean(L, 1);
+
+ return 1;
+} /* ssl_setPrivateKey() */
+
+
static int ssl_getPeerCertificate(lua_State *L) {
SSL *ssl = checksimple(L, 1, SSL_CLASS);
X509 **x509 = prepsimple(L, X509_CERT_CLASS);
@@ -8284,6 +8732,31 @@ static int ssl_getVersion(lua_State *L) {
} /* ssl_getVersion() */
+static int ssl_getClientRandom(lua_State *L) {
+ SSL *ssl = checksimple(L, 1, SSL_CLASS);
+ luaL_Buffer B;
+ size_t len;
+ unsigned char *out;
+
+ len = SSL_get_client_random(ssl, NULL, 0);
+#if LUA_VERSION_NUM < 502
+ if (LUAL_BUFFERSIZE < len)
+ luaL_error(L, "ssl:getClientRandom: LUAL_BUFFERSIZE(%d) < SSL_get_client_random(ssl, NULL, 0)", (int)LUAL_BUFFERSIZE, (int)len);
+ luaL_buffinit(L, &B);
+ out = (unsigned char*)luaL_prepbuffer(&B);
+ len = SSL_get_client_random(ssl, out, len);
+ luaL_addsize(&B, len);
+ luaL_pushresult(&B);
+#else
+ out = (unsigned char*)luaL_buffinitsize(L, &B, len);
+ len = SSL_get_client_random(ssl, out, len);
+ luaL_pushresultsize(&B, len);
+#endif
+
+ return 1;
+} /* ssl_getClientRandom() */
+
+
static int ssl_getClientVersion(lua_State *L) {
SSL *ssl = checksimple(L, 1, SSL_CLASS);
int format = luaL_checkoption(L, 2, "d", (const char *[]){ "d", ".", "f", NULL });
@@ -8354,6 +8827,87 @@ static int ssl_setAlpnProtos(lua_State *L) {
#endif
+static int ssl_setTLSextStatusType(lua_State *L) {
+ SSL *ssl = checksimple(L, 1, SSL_CLASS);
+ int type = checkTLSEXT_STATUSTYPE(L, 2);
+
+ if(!SSL_set_tlsext_status_type(ssl, type))
+ return auxL_error(L, auxL_EOPENSSL, "ssl:setTLSextStatusType");
+
+ lua_pushboolean(L, 1);
+
+ return 1;
+} /* ssl_setTLSextStatusType() */
+
+
+#if HAVE_SSL_GET_TLSEXT_STATUS_TYPE
+static int ssl_getTLSextStatusType(lua_State *L) {
+ SSL *ssl = checksimple(L, 1, SSL_CLASS);
+
+ int type = SSL_get_tlsext_status_type(ssl);
+ switch(type) {
+ case -1:
+ lua_pushnil(L);
+ break;
+ case TLSEXT_STATUSTYPE_ocsp:
+ lua_pushliteral(L, "ocsp");
+ break;
+ default:
+ luaL_error(L, "unknown TLS extension %d", type);
+ }
+
+ return 1;
+} /* ssl_getTLSextStatusType() */
+#endif
+
+
+static int ssl_setTLSextStatusOCSPResp(lua_State *L) {
+ SSL *ssl = checksimple(L, 1, SSL_CLASS);
+ OCSP_RESPONSE *or = testsimple(L, 2, OCSP_RESPONSE_CLASS);
+
+ unsigned char *resp = NULL;
+ long resp_len;
+
+ if (or) {
+ resp_len = i2d_OCSP_RESPONSE(or, &resp);
+ if (resp_len <= 0)
+ return auxL_error(L, auxL_EOPENSSL, "ssl:setTLSextStatusOCSPResp");
+ } else {
+ resp_len = 0;
+ }
+
+ if (!SSL_set_tlsext_status_ocsp_resp(ssl, resp, resp_len))
+ return auxL_error(L, auxL_EOPENSSL, "ssl:setTLSextStatusOCSPResp");
+
+ lua_pushboolean(L, 1);
+
+ return 1;
+} /* ssl_setTLSextStatusOCSPResp() */
+
+
+static int ssl_getTLSextStatusOCSPResp(lua_State *L) {
+ SSL *ssl = checksimple(L, 1, SSL_CLASS);
+
+ OCSP_RESPONSE **ud = prepsimple(L, OCSP_RESPONSE_CLASS);
+ const unsigned char *resp;
+ long resp_len;
+
+ resp_len = SSL_get_tlsext_status_ocsp_resp(ssl, &resp);
+ if (resp == NULL) {
+ lua_pushnil(L);
+ return 1;
+ }
+ if (resp_len == -1)
+ return auxL_error(L, auxL_EOPENSSL, "ssl:getTLSextStatusOCSPResp");
+
+ *ud = d2i_OCSP_RESPONSE(NULL, &resp, resp_len);
+ if(*ud == NULL)
+ return auxL_error(L, auxL_EOPENSSL, "ssl:getTLSextStatusOCSPResp");
+
+ return 1;
+} /* ssl_getTLSextStatusOCSPResp() */
+
+
static int ssl__gc(lua_State *L) {
SSL **ud = luaL_checkudata(L, 1, SSL_CLASS);
@@ -8367,12 +8921,17 @@ static int ssl__gc(lua_State *L) {
static const auxL_Reg ssl_methods[] = {
+ { "setContext", &ssl_setContext },
{ "setOptions", &ssl_setOptions },
{ "getOptions", &ssl_getOptions },
{ "clearOptions", &ssl_clearOptions },
{ "setParam", &ssl_setParam },
{ "getParam", &ssl_getParam },
+ { "setVerify", &ssl_setVerify },
+ { "getVerify", &ssl_getVerify },
{ "getVerifyResult", &ssl_getVerifyResult },
+ { "setCertificate", &ssl_setCertificate },
+ { "setPrivateKey", &ssl_setPrivateKey },
{ "getPeerCertificate", &ssl_getPeerCertificate },
{ "getPeerChain", &ssl_getPeerChain },
{ "getCipherInfo", &ssl_getCipherInfo },
@@ -8382,6 +8941,7 @@ static const auxL_Reg ssl_methods[] = {
{ "getHostName", &ssl_getHostName },
{ "setHostName", &ssl_setHostName },
{ "getVersion", &ssl_getVersion },
+ { "getClientRandom", &ssl_getClientRandom },
{ "getClientVersion", &ssl_getClientVersion },
#if HAVE_SSL_GET0_ALPN_SELECTED
{ "getAlpnSelected", &ssl_getAlpnSelected },
@@ -8389,6 +8949,12 @@ static const auxL_Reg ssl_methods[] = {
#if HAVE_SSL_SET_ALPN_PROTOS
{ "setAlpnProtos", &ssl_setAlpnProtos },
#endif
+ { "setTLSextStatusType", &ssl_setTLSextStatusType },
+#if HAVE_SSL_GET_TLSEXT_STATUS_TYPE
+ { "getTLSextStatusType", &ssl_getTLSextStatusType },
+#endif
+ { "setTLSextStatusOCSPResp", &ssl_setTLSextStatusOCSPResp },
+ { "getTLSextStatusOCSPResp", &ssl_getTLSextStatusOCSPResp },
{ NULL, NULL },
};
@@ -9126,6 +9692,166 @@ int luaopen__openssl_cipher(lua_State *L) {
/*
+ * OCSP_RESPONSE - openssl.ocsp.response
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+static int or_tostring(lua_State *L) {
+ OCSP_RESPONSE *resp = checksimple(L, 1, OCSP_RESPONSE_CLASS);
+ BIO *bio = getbio(L);
+ size_t len;
+ char *bytes;
+
+ if (!OCSP_RESPONSE_print(bio, resp, 0))
+ return auxL_error(L, auxL_EOPENSSL, "OCSP_RESPONSE:tostring");
+
+ len = BIO_get_mem_data(bio, &bytes);
+ lua_pushlstring(L, bytes, len);
+
+ return 1;
+} /* or__tostring() */
+
+
+static int or_toPEM(lua_State *L) {
+ OCSP_RESPONSE *resp = checksimple(L, 1, OCSP_RESPONSE_CLASS);
+ BIO *bio = getbio(L);
+ size_t len;
+ char *bytes;
+
+ if (!PEM_write_bio_OCSP_RESPONSE(bio, resp))
+ return auxL_error(L, auxL_EOPENSSL, "OCSP_RESPONSE:toPEM");
+
+ len = BIO_get_mem_data(bio, &bytes);
+ lua_pushlstring(L, bytes, len);
+
+ return 1;
+} /* or_toPEM() */
+
+
+static int or_getBasic(lua_State *L) {
+ OCSP_RESPONSE *resp = checksimple(L, 1, OCSP_RESPONSE_CLASS);
+
+ OCSP_BASICRESP **basic = prepsimple(L, OCSP_BASICRESP_CLASS);
+
+ *basic = OCSP_response_get1_basic(resp);
+ if (!*basic)
+ return auxL_error(L, auxL_EOPENSSL, "OCSP_RESPONSE:getBasic");
+
+ return 1;
+} /* or_getBasic() */
+
+
+static int or__gc(lua_State *L) {
+ OCSP_RESPONSE **ud = luaL_checkudata(L, 1, OCSP_RESPONSE_CLASS);
+
+ if (*ud) {
+ OCSP_RESPONSE_free(*ud);
+ *ud = NULL;
+ }
+
+ return 0;
+} /* or__gc() */
+
+static const auxL_Reg or_methods[] = {
+ { "tostring", &or_tostring },
+ { "toPEM", &or_toPEM },
+ { "getBasic", &or_getBasic },
+ { NULL, NULL },
+};
+
+static const auxL_Reg or_metatable[] = {
+ { "__tostring", &or_tostring },
+ { "__gc", &or__gc },
+ { NULL, NULL },
+};
+
+static const auxL_Reg or_globals[] = {
+ { NULL, NULL },
+};
+
+int luaopen__openssl_ocsp_response(lua_State *L) {
+ initall(L);
+
+ auxL_newlib(L, or_globals, 0);
+
+ return 1;
+} /* luaopen__openssl_ocsp_response() */
+
+
+/*
+ * OCSP_BASICRESP - openssl.ocsp.basic
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+static int ob_verify(lua_State *L) {
+ OCSP_BASICRESP *basic = checksimple(L, 1, OCSP_BASICRESP_CLASS);
+ STACK_OF(X509) *certs = testsimple(L, 2, X509_CHAIN_CLASS);
+ X509_STORE *store = testsimple(L, 3, X509_STORE_CLASS);
+ unsigned long flags = luaL_optinteger(L, 4, 0);
+
+ int res = OCSP_basic_verify(basic, certs, store, flags);
+ if (res == -1)
+ return auxL_error(L, auxL_EOPENSSL, "OCSP_BASICRESP:verify");
+
+ lua_pushboolean(L, res);
+ if (res) {
+ return 1;
+ } else {
+ auxL_pusherror(L, auxL_EOPENSSL, NULL);
+ return 2;
+ }
+} /* ob_verify() */
+
+
+static int ob__gc(lua_State *L) {
+ OCSP_BASICRESP **ud = luaL_checkudata(L, 1, OCSP_BASICRESP_CLASS);
+
+ if (*ud) {
+ OCSP_BASICRESP_free(*ud);
+ *ud = NULL;
+ }
+
+ return 0;
+} /* or__gc() */
+
+
+static const auxL_Reg ob_methods[] = {
+ { "verify", &ob_verify },
+ { NULL, NULL },
+};
+
+static const auxL_Reg ob_metatable[] = {
+ { "__gc", &ob__gc },
+ { NULL, NULL },
+};
+
+static const auxL_Reg ob_globals[] = {
+ { NULL, NULL },
+};
+
+static const auxL_IntegerReg ob_verify_flags[] = {
+ { "NOSIGS", OCSP_NOSIGS},
+ { "NOVERIFY", OCSP_NOVERIFY},
+ { "NOCHAIN", OCSP_NOCHAIN},
+ { "NOCHECKS", OCSP_NOCHECKS},
+ { "NOEXPLICIT", OCSP_NOEXPLICIT},
+ { "TRUSTOTHER", OCSP_TRUSTOTHER},
+ { "NOINTERN", OCSP_NOINTERN},
+ { "TRUSTOTHER", OCSP_TRUSTOTHER},
+ { NULL, 0 },
+};
+
+int luaopen__openssl_ocsp_basic(lua_State *L) {
+ initall(L);
+
+ auxL_newlib(L, ob_globals, 0);
+ auxL_setintegers(L, ob_verify_flags);
+
+ return 1;
+} /* luaopen__openssl_ocsp_basic() */
+
+
+/*
* Rand - openssl.rand
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
@@ -9322,7 +10048,7 @@ static int rand_add(lua_State *L) {
static int rand_bytes(lua_State *L) {
- int size = luaL_checkint(L, 1);
+ int size = luaL_checkinteger(L, 1);
luaL_Buffer B;
int count = 0, n;
@@ -9438,11 +10164,7 @@ static int rand_uniform(lua_State *L) {
} else {
unsigned long long N, m;
- if (sizeof (lua_Unsigned) >= sizeof r) {
- N = luaL_checkunsigned(L, 1);
- } else {
- N = luaL_checknumber(L, 1);
- }
+ N = auxL_checkunsigned(L, 1);
luaL_argcheck(L, N > 1, 1, lua_pushfstring(L, "[0, %d): interval is empty", (int)N));
@@ -9455,11 +10177,7 @@ static int rand_uniform(lua_State *L) {
r = r % N;
}
- if (sizeof (lua_Unsigned) >= sizeof r) {
- lua_pushunsigned(L, r);
- } else {
- lua_pushnumber(L, r);
- }
+ auxL_pushunsigned(L, r);
return 1;
} /* rand_uniform() */
@@ -9690,5 +10408,7 @@ static void initall(lua_State *L) {
auxL_addclass(L, DIGEST_CLASS, md_methods, md_metatable, 0);
auxL_addclass(L, HMAC_CLASS, hmac_methods, hmac_metatable, 0);
auxL_addclass(L, CIPHER_CLASS, cipher_methods, cipher_metatable, 0);
+ auxL_addclass(L, OCSP_RESPONSE_CLASS, or_methods, or_metatable, 0);
+ auxL_addclass(L, OCSP_BASICRESP_CLASS, ob_methods, ob_metatable, 0);
} /* initall() */
diff --git a/src/openssl.ocsp.basic.lua b/src/openssl.ocsp.basic.lua
new file mode 100644
index 0000000..355faf7
--- /dev/null
+++ b/src/openssl.ocsp.basic.lua
@@ -0,0 +1,3 @@
+local ob = require "_openssl.ocsp.basic"
+
+return ob
diff --git a/src/openssl.ocsp.response.lua b/src/openssl.ocsp.response.lua
new file mode 100644
index 0000000..2226096
--- /dev/null
+++ b/src/openssl.ocsp.response.lua
@@ -0,0 +1,3 @@
+local ocsp_response = require "_openssl.ocsp.response"
+
+return ocsp_response